1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 02:49:06 +00:00

version 1.2020.1

This commit is contained in:
Arnaud Roques 2020-02-18 22:24:31 +01:00
parent 19b9eb3534
commit 4cad5546ac
194 changed files with 4759 additions and 1634 deletions

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2020.1-SNAPSHOT</version>
<version>1.2020.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>

View File

@ -94,11 +94,11 @@ public enum FontParam {
SEQUENCE_GROUP_HEADER(13, Font.BOLD), //
PARTICIPANT(14, Font.PLAIN), //
PARTICIPANT_STEREOTYPE(14, Font.ITALIC), //
SEQUENCE_TITLE(14, Font.BOLD), //
STATE(14, Font.PLAIN), //
STATE_ATTRIBUTE(12, Font.PLAIN), //
LEGEND(14, Font.PLAIN), //
TITLE(18, Font.PLAIN), //
// SEQUENCE_TITLE(14, Font.BOLD), //
CAPTION(14, Font.PLAIN), //
SWIMLANE_TITLE(18, Font.PLAIN), //
FOOTER(10, Font.PLAIN, "#888888", FontParamConstant.FAMILY), //

View File

@ -75,10 +75,11 @@ import net.sourceforge.plantuml.nwdiag.NwDiagramFactory;
import net.sourceforge.plantuml.openiconic.PSystemListOpenIconicFactory;
import net.sourceforge.plantuml.openiconic.PSystemOpenIconicFactory;
import net.sourceforge.plantuml.oregon.PSystemOregonFactory;
import net.sourceforge.plantuml.project3.GanttDiagramFactory;
import net.sourceforge.plantuml.project.GanttDiagramFactory;
import net.sourceforge.plantuml.salt.PSystemSaltFactory;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.sprite.ListSpriteDiagramFactory;
import net.sourceforge.plantuml.sprite.StdlibDiagramFactory;
import net.sourceforge.plantuml.sprite.PSystemListInternalSpritesFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.StatsUtilsIncrement;
@ -88,6 +89,7 @@ import net.sourceforge.plantuml.version.License;
import net.sourceforge.plantuml.version.PSystemLicenseFactory;
import net.sourceforge.plantuml.version.PSystemVersionFactory;
import net.sourceforge.plantuml.wbs.WBSDiagramFactory;
import net.sourceforge.plantuml.wire.WireDiagramFactory;
public class PSystemBuilder {
@ -178,6 +180,7 @@ public class PSystemBuilder {
}
factories.add(new PSystemDefinitionFactory());
factories.add(new ListSpriteDiagramFactory(skinParam));
factories.add(new StdlibDiagramFactory(skinParam));
factories.add(new PSystemMathFactory(DiagramType.MATH));
factories.add(new PSystemLatexFactory(DiagramType.LATEX));
// factories.add(new PSystemStatsFactory());
@ -200,6 +203,7 @@ public class PSystemBuilder {
factories.add(new PSystemDedicationFactory());
factories.add(new TimingDiagramFactory());
factories.add(new HelpFactory());
factories.add(new WireDiagramFactory());
return factories;
}

View File

@ -52,7 +52,7 @@ import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.html.CucaDiagramHtmlMaker;
import net.sourceforge.plantuml.png.PngSplitter;
import net.sourceforge.plantuml.project3.GanttDiagram;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
public class PSystemUtils {

View File

@ -153,6 +153,8 @@ public class Pipe {
final String s = readOneLine();
if (s == null) {
closed = true;
} else if (s.startsWith("@@@format ")) {
manageFormat(s);
} else {
sb.append(s);
sb.append(BackSlash.NEWLINE);
@ -171,6 +173,14 @@ public class Pipe {
return source;
}
private void manageFormat(String s) {
if (s.contains("png")) {
option.setFileFormatOption(new FileFormatOption(FileFormat.PNG));
} else if (s.contains("svg")) {
option.setFileFormatOption(new FileFormatOption(FileFormat.SVG));
}
}
private String readOneLine() throws IOException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (true) {

View File

@ -62,6 +62,14 @@ public class Pragma {
return isDefine("horizontallinebetweendifferentpackageallowed");
}
public boolean backToLegacyPackage() {
return isDefine("backtolegacypackage");
}
public boolean useNewPackage() {
return isDefine("usenewpackage");
}
public boolean useVerticalIf() {
final String teoz = getValue("useverticalif");
return "true".equalsIgnoreCase(teoz) || "on".equalsIgnoreCase(teoz);

View File

@ -36,5 +36,5 @@
package net.sourceforge.plantuml;
public enum UmlDiagramType {
SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, HELP
SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, WIRE, HELP
}

View File

@ -51,8 +51,8 @@ import net.sourceforge.plantuml.command.Command;
import net.sourceforge.plantuml.command.CommandFootboxIgnored;
import net.sourceforge.plantuml.command.CommandRankDir;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.command.note.FactoryNoteActivityCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnLinkCommand;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteActivity;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnLink;
public class ActivityDiagramFactory extends UmlDiagramFactory {
@ -79,11 +79,11 @@ public class ActivityDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandEndPartition());
cmds.add(new CommandLinkLongActivity());
final FactoryNoteActivityCommand factoryNoteActivityCommand = new FactoryNoteActivityCommand();
final CommandFactoryNoteActivity factoryNoteActivityCommand = new CommandFactoryNoteActivity();
cmds.add(factoryNoteActivityCommand.createSingleLine());
cmds.add(factoryNoteActivityCommand.createMultiLine(false));
final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand();
final CommandFactoryNoteOnLink factoryNoteOnLinkCommand = new CommandFactoryNoteOnLink();
cmds.add(factoryNoteOnLinkCommand.createSingleLine());
cmds.add(factoryNoteOnLinkCommand.createMultiLine(false));

View File

@ -371,10 +371,10 @@ public class ActivityDiagram3 extends UmlDiagram {
return CommandExecutionResult.error("Cannot find if");
}
public void startRepeat(HtmlColor color, Display label) {
public void startRepeat(HtmlColor color, Display label, BoxStyle boxStyleIn, Colors colors) {
manageSwimlaneStrategy();
final InstructionRepeat instructionRepeat = new InstructionRepeat(swinlanes.getCurrentSwimlane(), current(),
nextLinkRenderer(), color, label);
nextLinkRenderer(), color, label, boxStyleIn, colors);
current().add(instructionRepeat);
setCurrent(instructionRepeat);
setNextLinkRendererInternal(LinkRendering.none());

View File

@ -111,6 +111,7 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory {
cmds.add(new CommandGroupEnd3());
cmds.add(new CommandArrow3());
cmds.add(new CommandArrowLong3());
cmds.add(new CommandRepeat3());
cmds.add(new CommandActivity3());
cmds.add(new CommandIf4());
cmds.add(new CommandIf2());
@ -126,7 +127,6 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory {
cmds.add(new CommandCase());
cmds.add(new CommandEndSwitch());
cmds.add(new CommandRepeat3());
cmds.add(new CommandRepeatWhile3());
cmds.add(new CommandRepeatWhile3Multilines());
cmds.add(new CommandBackward3());

View File

@ -55,8 +55,9 @@ public class InstructionRepeat implements Instruction {
private final LinkRendering nextLinkRenderer;
private final Swimlane swimlane;
private Swimlane swimlaneOut;
private final HtmlColor color;
// private final HtmlColor color;
private boolean killed = false;
private final BoxStyle boxStyleIn;
private Display backward = Display.NULL;
private Display test = Display.NULL;
@ -66,13 +67,15 @@ public class InstructionRepeat implements Instruction {
private boolean testCalled = false;
private LinkRendering endRepeatLinkRendering = LinkRendering.none();
private LinkRendering backRepeatLinkRendering = LinkRendering.none();
private final Colors colors;
public boolean containsBreak() {
return repeatList.containsBreak();
}
public InstructionRepeat(Swimlane swimlane, Instruction parent, LinkRendering nextLinkRenderer, HtmlColor color,
Display startLabel) {
Display startLabel, BoxStyle boxStyleIn, Colors colors) {
this.boxStyleIn = boxStyleIn;
this.startLabel = startLabel;
this.parent = parent;
this.swimlane = swimlane;
@ -80,7 +83,7 @@ public class InstructionRepeat implements Instruction {
if (nextLinkRenderer == null) {
throw new IllegalArgumentException();
}
this.color = color;
this.colors = colors;
}
private boolean isLastOfTheParent() {
@ -100,11 +103,11 @@ public class InstructionRepeat implements Instruction {
}
public Ftile createFtile(FtileFactory factory) {
final Ftile back = Display.isNull(backward) ? null : factory.activity(backward, swimlane, BoxStyle.PLAIN,
Colors.empty());
final Ftile result = factory.repeat(swimlane, swimlaneOut, startLabel,
factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering), test, yes, out, color,
backRepeatLinkRendering, back, isLastOfTheParent());
final Ftile back = Display.isNull(backward) ? null
: factory.activity(backward, swimlane, BoxStyle.PLAIN, Colors.empty());
final Ftile decorateOut = factory.decorateOut(repeatList.createFtile(factory), endRepeatLinkRendering);
final Ftile result = factory.repeat(boxStyleIn, swimlane, swimlaneOut, startLabel, decorateOut, test, yes, out,
colors, backRepeatLinkRendering, back, isLastOfTheParent());
if (killed) {
return new FtileKilled(result);
}

View File

@ -35,8 +35,10 @@
*/
package net.sourceforge.plantuml.activitydiagram3.command;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3;
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
@ -45,8 +47,11 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
public class CommandRepeat3 extends SingleLineCommand2<ActivityDiagram3> {
@ -56,20 +61,39 @@ public class CommandRepeat3 extends SingleLineCommand2<ActivityDiagram3> {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandRepeat3.class.getName(), RegexLeaf.start(), //
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
ColorParser.exp4(), //
new RegexLeaf("repeat"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("LABEL", ":(.*?)")), //
new RegexLeaf(";?"), //
new RegexOptional(new RegexLeaf("STYLE", CommandActivity3.ENDING_GROUP)), //
// new RegexLeaf(";?"), //
RegexLeaf.end());
}
private static ColorParser color() {
return ColorParser.simpleColor(ColorType.BACK);
}
@Override
protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) {
final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0));
final Display label = Display.getWithNewlines(arg.get("LABEL", 0));
final BoxStyle boxStyle;
final String styleString = arg.get("STYLE", 0);
if (styleString == null) {
boxStyle = BoxStyle.PLAIN;
} else {
boxStyle = BoxStyle.fromChar(styleString.charAt(0));
}
Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet());
final String stereo = arg.get("STEREO", 0);
if (stereo != null) {
final Stereotype stereotype = new Stereotype(stereo);
colors = colors.applyStereotype(stereotype, diagram.getSkinParam(), ColorParam.activityBackground);
}
diagram.startRepeat(color, label);
diagram.startRepeat(color, label, boxStyle, colors);
return CommandExecutionResult.ok();
}

View File

@ -77,9 +77,9 @@ public interface FtileFactory {
public Ftile assembly(Ftile tile1, Ftile tile2);
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut);
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, LinkRendering backRepeatLinkRendering,
Ftile backward, boolean noOut);
public Ftile createWhile(Swimlane swimlane, Ftile whileBlock, Display test, Display yes, Display out,
LinkRendering afterEndwhile, HtmlColor color, Instruction specialOut);

View File

@ -85,8 +85,8 @@ public class FtileFactoryDelegator implements FtileFactory {
final LinkRendering linkRendering = tile.getInLinkRendering();
if (linkRendering == null) {
if (SkinParam.USE_STYLES()) {
final Style style = getDefaultStyleDefinitionArrow().getMergedStyle(
skinParam().getCurrentStyleBuilder());
final Style style = getDefaultStyleDefinitionArrow()
.getMergedStyle(skinParam().getCurrentStyleBuilder());
return Rainbow.build(style, skinParam().getIHtmlColorSet());
} else {
color = Rainbow.build(skinParam());
@ -96,8 +96,8 @@ public class FtileFactoryDelegator implements FtileFactory {
}
if (color.size() == 0) {
if (SkinParam.USE_STYLES()) {
final Style style = getDefaultStyleDefinitionArrow().getMergedStyle(
skinParam().getCurrentStyleBuilder());
final Style style = getDefaultStyleDefinitionArrow()
.getMergedStyle(skinParam().getCurrentStyleBuilder());
return Rainbow.build(style, skinParam().getIHtmlColorSet());
} else {
color = Rainbow.build(skinParam());
@ -179,10 +179,10 @@ public class FtileFactoryDelegator implements FtileFactory {
return factory.assembly(tile1, tile2);
}
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut) {
return factory.repeat(swimlane, swimlaneOut, startLabel, repeat, test, yes, out, color,
return factory.repeat(boxStyleIn, swimlane, swimlaneOut, startLabel, repeat, test, yes, out, colors,
backRepeatLinkRendering, backward, noOut);
}

View File

@ -59,6 +59,7 @@ import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
@ -73,31 +74,36 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
}
@Override
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, final Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut) {
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel,
final Ftile repeat, Display test, Display yes, Display out, Colors colors,
LinkRendering backRepeatLinkRendering, Ftile backward, boolean noOut) {
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
final HtmlColor borderColor;
final HtmlColor backColor;
final HtmlColor diamondColor;
final Rainbow arrowColor;
final FontConfiguration fcDiamond;
final FontConfiguration fcArrow;
if (SkinParam.USE_STYLES()) {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(
skinParam().getCurrentStyleBuilder());
final Style styleDiamond = getDefaultStyleDefinitionDiamond().getMergedStyle(
skinParam().getCurrentStyleBuilder());
final Style styleArrow = getDefaultStyleDefinitionArrow()
.getMergedStyle(skinParam().getCurrentStyleBuilder());
final Style styleDiamond = getDefaultStyleDefinitionDiamond()
.getMergedStyle(skinParam().getCurrentStyleBuilder());
borderColor = styleDiamond.value(PName.LineColor).asColor(skinParam().getIHtmlColorSet());
backColor = styleDiamond.value(PName.BackGroundColor).asColor(skinParam().getIHtmlColorSet());
diamondColor = styleDiamond.value(PName.BackGroundColor).asColor(skinParam().getIHtmlColorSet());
arrowColor = Rainbow.build(styleArrow, skinParam().getIHtmlColorSet());
fcDiamond = styleDiamond.getFontConfiguration(skinParam().getIHtmlColorSet());
fcArrow = styleArrow.getFontConfiguration(skinParam().getIHtmlColorSet());
} else {
borderColor = getRose().getHtmlColor(skinParam(), ColorParam.activityDiamondBorder);
backColor = color == null ? getRose().getHtmlColor(skinParam(), ColorParam.activityDiamondBackground)
: color;
// diamondColor = color == null ? getRose().getHtmlColor(skinParam(),
// ColorParam.activityDiamondBackground) : color;
if (colors.getColor(ColorType.BACK) != null && Display.isNull(startLabel)) {
diamondColor = colors.getColor(ColorType.BACK);
} else {
diamondColor = getRose().getHtmlColor(skinParam(), ColorParam.activityDiamondBackground);
}
arrowColor = Rainbow.build(skinParam());
fcDiamond = new FontConfiguration(skinParam(), FontParam.ACTIVITY_DIAMOND, null);
fcArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null);
@ -106,18 +112,17 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
final LinkRendering endRepeatLinkRendering = repeat.getOutLinkRendering();
final Rainbow endRepeatLinkColor = endRepeatLinkRendering == null ? null : endRepeatLinkRendering.getRainbow();
final Ftile backStart = Display.isNull(startLabel) ? null : this.activity(startLabel, swimlane, BoxStyle.PLAIN,
Colors.empty());
final Ftile entry = getEntry(swimlane, startLabel, colors, boxStyleIn);
Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, backStart, repeat, test, yes,
out, borderColor, backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(),
fcDiamond, fcArrow, backward, noOut);
Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, entry, repeat, test, yes, out,
borderColor, diamondColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), fcDiamond,
fcArrow, backward, noOut);
final List<WeldingPoint> weldingPoints = repeat.getWeldingPoints();
if (weldingPoints.size() > 0) {
// printAllChild(repeat);
final Ftile diamondBreak = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane);
final Ftile diamondBreak = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, swimlane);
result = assembly(FtileUtils.addHorizontalMargin(result, 10, 0), diamondBreak);
final Genealogy genealogy = new Genealogy(result);
@ -129,8 +134,8 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
final UTranslate tr2 = genealogy.getTranslate(diamondBreak, ug.getStringBounder());
final Dimension2D dimDiamond = diamondBreak.calculateDimension(ug.getStringBounder());
final Snake snake = new Snake(getFtile1().arrowHorizontalAlignment(), arrowColor, Arrows
.asToRight());
final Snake snake = new Snake(getFtile1().arrowHorizontalAlignment(), arrowColor,
Arrows.asToRight());
snake.addPoint(tr1.getDx(), tr1.getDy());
snake.addPoint(0, tr1.getDy());
snake.addPoint(0, tr2.getDy() + dimDiamond.getHeight() / 2);
@ -151,4 +156,12 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
}
return result;
}
private Ftile getEntry(Swimlane swimlane, Display startLabel, Colors colors, BoxStyle boxStyleIn) {
if (Display.isNull(startLabel)) {
return null;
}
// final Colors colors = Colors.empty().add(ColorType.BACK, back);
return this.activity(startLabel, swimlane, boxStyleIn, colors);
}
}

View File

@ -111,8 +111,8 @@ class FtileRepeat extends AbstractFtile {
}
public static Ftile create(LinkRendering backRepeatLinkRendering, Swimlane swimlane, Swimlane swimlaneOut,
Ftile backStart, Ftile repeat, Display test, Display yes, Display out, HtmlColor borderColor,
HtmlColor backColor, Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle,
Ftile entry, Ftile repeat, Display test, Display yes, Display out, HtmlColor borderColor,
HtmlColor diamondColor, Rainbow arrowColor, Rainbow endRepeatLinkColor, ConditionStyle conditionStyle,
ISkinSimple spriteContainer, FontConfiguration fcDiamond, FontConfiguration fcArrow, Ftile backward,
boolean noOut) {
@ -126,10 +126,10 @@ class FtileRepeat extends AbstractFtile {
final Ftile diamond1;
// assert swimlane == repeat.getSwimlaneIn();
if (backStart == null) {
diamond1 = new FtileDiamond(repeat.skinParam(), backColor, borderColor, repeat.getSwimlaneIn());
if (entry == null) {
diamond1 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, repeat.getSwimlaneIn());
} else {
diamond1 = backStart;
diamond1 = entry;
}
final FtileRepeat result;
if (conditionStyle == ConditionStyle.INSIDE) {
@ -137,16 +137,16 @@ class FtileRepeat extends AbstractFtile {
if (noOut && Display.isNull(test)) {
diamond2 = new FtileEmpty(repeat.skinParam());
} else {
diamond2 = new FtileDiamondInside(repeat.skinParam(), backColor, borderColor, swimlaneOut, tbTest)
diamond2 = new FtileDiamondInside(repeat.skinParam(), diamondColor, borderColor, swimlaneOut, tbTest)
.withEast(yesTb).withSouth(outTb);
}
result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward);
} else if (conditionStyle == ConditionStyle.DIAMOND) {
final Ftile diamond2 = new FtileDiamond(repeat.skinParam(), backColor, borderColor, swimlane)
final Ftile diamond2 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, swimlane)
.withEast(tbTest);
result = new FtileRepeat(repeat, diamond1, diamond2, tbTest, backward);
} else if (conditionStyle == ConditionStyle.FOO1) {
final Ftile diamond2 = new FtileDiamondFoo1(repeat.skinParam(), backColor, borderColor, swimlane, tbTest);
final Ftile diamond2 = new FtileDiamondFoo1(repeat.skinParam(), diamondColor, borderColor, swimlane, tbTest);
result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward);
} else {
throw new IllegalStateException();

View File

@ -122,7 +122,8 @@ public class VCompactFactory implements FtileFactory {
}
public Ftile spot(Swimlane swimlane, String spot, HtmlColor color) {
// final HtmlColor color = rose.getHtmlColor(skinParam, ColorParam.activityBackground);
// final HtmlColor color = rose.getHtmlColor(skinParam,
// ColorParam.activityBackground);
final UFont font = skinParam.getFont(null, false, FontParam.ACTIVITY);
return new FtileCircleSpot(skinParam(), swimlane, spot, font, color);
}
@ -140,8 +141,10 @@ public class VCompactFactory implements FtileFactory {
}
public Ftile activity(Display label, Swimlane swimlane, BoxStyle boxStyle, Colors colors) {
// final HtmlColor borderColor = rose.getHtmlColor(skinParam, ColorParam.activityBorder);
// final HtmlColor backColor = color == null ? rose.getHtmlColor(skinParam, ColorParam.activityBackground) :
// final HtmlColor borderColor = rose.getHtmlColor(skinParam,
// ColorParam.activityBorder);
// final HtmlColor backColor = color == null ? rose.getHtmlColor(skinParam,
// ColorParam.activityBackground) :
// color;
final UFont font = skinParam.getFont(null, false, FontParam.ACTIVITY);
return FtileBox.create(colors.mute(skinParam), label, swimlane, boxStyle);
@ -159,9 +162,9 @@ public class VCompactFactory implements FtileFactory {
return new FtileAssemblySimple(tile1, tile2);
}
public Ftile repeat(Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat, Display test,
Display yes, Display out, HtmlColor color, LinkRendering backRepeatLinkRendering, Ftile backward,
boolean noOut) {
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, LinkRendering backRepeatLinkRendering,
Ftile backward, boolean noOut) {
return repeat;
}

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.classdiagram;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.ISkinSimple;
@ -53,6 +54,7 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Ident;
import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.SuperGroup;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram;

View File

@ -67,12 +67,14 @@ import net.sourceforge.plantuml.command.CommandPackageEmpty;
import net.sourceforge.plantuml.command.CommandPage;
import net.sourceforge.plantuml.command.CommandRankDir;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.command.note.FactoryNoteCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnEntityCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnLinkCommand;
import net.sourceforge.plantuml.command.note.FactoryTipOnEntityCommand;
import net.sourceforge.plantuml.command.note.CommandConstraintOnLinks;
import net.sourceforge.plantuml.command.note.CommandFactoryNote;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnEntity;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnLink;
import net.sourceforge.plantuml.command.note.CommandFactoryTipOnEntity;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilines;
import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementParenthesis;
import net.sourceforge.plantuml.descdiagram.command.CommandNewpage;
import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject;
@ -112,6 +114,7 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandCreateEntityObject());
cmds.add(new CommandAllowMixing());
cmds.add(new CommandCreateElementParenthesis());
cmds.add(new CommandLayoutNewLine());
cmds.add(new CommandPackage());
@ -121,7 +124,7 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandCreateElementFull2(Mode.NORMAL_KEYWORD));
cmds.add(new CommandCreateElementFull2(Mode.WITH_MIX_PREFIX));
final FactoryNoteCommand factoryNoteCommand = new FactoryNoteCommand();
final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote();
cmds.add(factoryNoteCommand.createSingleLine());
cmds.add(new CommandNamespace());
@ -134,12 +137,12 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandImport());
final FactoryTipOnEntityCommand factoryTipOnEntityCommand = new FactoryTipOnEntityCommand("a", new RegexLeaf(
final CommandFactoryTipOnEntity factoryTipOnEntityCommand = new CommandFactoryTipOnEntity("a", new RegexLeaf(
"ENTITY", "(" + CommandCreateClass.CODE_NO_DOTDOT + "|[%g][^%g]+[%g])::([%g][^%g]+[%g]|[^%s]+)"));
cmds.add(factoryTipOnEntityCommand.createMultiLine(true));
cmds.add(factoryTipOnEntityCommand.createMultiLine(false));
final FactoryNoteOnEntityCommand factoryNoteOnEntityCommand = new FactoryNoteOnEntityCommand("class",
final CommandFactoryNoteOnEntity factoryNoteOnEntityCommand = new CommandFactoryNoteOnEntity("class",
new RegexLeaf("ENTITY", "(" + CommandCreateClass.CODE + "|[%g][^%g]+[%g])"));
cmds.add(factoryNoteOnEntityCommand.createSingleLine());
cmds.add(new CommandUrl());
@ -148,9 +151,10 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
cmds.add(factoryNoteOnEntityCommand.createMultiLine(false));
cmds.add(factoryNoteCommand.createMultiLine(false));
final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand();
final CommandFactoryNoteOnLink factoryNoteOnLinkCommand = new CommandFactoryNoteOnLink();
cmds.add(factoryNoteOnLinkCommand.createSingleLine());
cmds.add(factoryNoteOnLinkCommand.createMultiLine(false));
cmds.add(new CommandConstraintOnLinks());
cmds.add(new CommandDiamondAssociation());

View File

@ -247,6 +247,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2<ClassDiagra
result = diagram.getLeafSmart(ident);
if (result != null) {
// result = diagram.getOrCreateLeaf(ident, code, null, null);
diagram.setLastEntity(result);
if (result.muteToType(type, null) == false) {
return null;
}

View File

@ -82,15 +82,15 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
new RegexLeaf("HEADER", "@([\\d.]+)"), //
RegexLeaf.spaceOneOrMore() //
)), new RegexOr( //
new RegexLeaf("ENT1", getClassIdentifier()),//
new RegexLeaf("COUPLE1", COUPLE)), //
new RegexLeaf("ENT1", getClassIdentifier()), //
new RegexLeaf("COUPLE1", COUPLE)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("FIRST_LABEL", "[%g]([^%g]+)[%g]")), //
RegexLeaf.spaceZeroOrMore(), //
new RegexConcat(
//
//
new RegexLeaf("ARROW_HEAD1", "([%s]+[ox]|[)#\\[<*+^}]|[<\\[]\\||\\}o|\\}\\||\\|o|\\|\\|)?"), //
new RegexLeaf("ARROW_BODY1", "([-=.]+)"), //
new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
@ -208,24 +208,24 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
final Matcher2 m1 = p1.matcher(labelLink);
if (m1.matches()) {
firstLabel = m1.group(1);
labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(
StringUtils.trin(m1.group(2)), "\""));
labelLink = StringUtils.trin(StringUtils
.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m1.group(2)), "\""));
secondLabel = m1.group(3);
} else {
final Pattern2 p2 = MyPattern.cmpile("^[%g]([^%g]+)[%g]([^%g]+)$");
final Matcher2 m2 = p2.matcher(labelLink);
if (m2.matches()) {
firstLabel = m2.group(1);
labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(
StringUtils.trin(m2.group(2)), "\""));
labelLink = StringUtils.trin(StringUtils
.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m2.group(2)), "\""));
secondLabel = null;
} else {
final Pattern2 p3 = MyPattern.cmpile("^([^%g]+)[%g]([^%g]+)[%g]$");
final Matcher2 m3 = p3.matcher(labelLink);
if (m3.matches()) {
firstLabel = null;
labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(
StringUtils.trin(m3.group(1)), "\""));
labelLink = StringUtils.trin(StringUtils
.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m3.group(1)), "\""));
secondLabel = m3.group(2);
}
}
@ -281,8 +281,8 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
if (diagram.V1972()) {
return diagram.getGroupVerySmart(ident);
}
final Code tap = ident.toCode(diagram);
return diagram.getGroup(tap);
// final Code tap = ident.toCode(diagram);
return diagram.getGroup(code);
}
if (diagram.V1972()) {
final IEntity result = pure.size() == 1 ? diagram.getLeafVerySmart(ident) : diagram.getLeafStrict(ident);
@ -361,10 +361,10 @@ final public class CommandLinkClass extends SingleLineCommand2<AbstractClassOrOb
private CommandExecutionResult executePackageLink(AbstractClassOrObjectDiagram diagram, RegexResult arg) {
final String ent1String = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("ENT1", 0), "\"");
final String ent2String = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("ENT2", 0), "\"");
final IEntity cl1 = diagram.V1972() ? diagram.getGroupVerySmart(diagram.buildLeafIdent(ent1String)) : diagram
.getGroup(diagram.buildCode(ent1String));
final IEntity cl2 = diagram.V1972() ? diagram.getGroupVerySmart(diagram.buildLeafIdent(ent2String)) : diagram
.getGroup(diagram.buildCode(ent2String));
final IEntity cl1 = diagram.V1972() ? diagram.getGroupVerySmart(diagram.buildLeafIdent(ent1String))
: diagram.getGroup(diagram.buildCode(ent1String));
final IEntity cl2 = diagram.V1972() ? diagram.getGroupVerySmart(diagram.buildLeafIdent(ent2String))
: diagram.getGroup(diagram.buildCode(ent2String));
final LinkType linkType = getLinkType(arg);
final Direction dir = getDirection(arg);

View File

@ -100,6 +100,14 @@ public class BlocLines implements Iterable<StringLocated> {
return new BlocLines(result);
}
public static BlocLines fromArray(String[] array) {
final List<StringLocated> result = new ArrayList<StringLocated>();
for (String single : array) {
result.add(new StringLocated(single, null));
}
return new BlocLines(result);
}
public static BlocLines getWithNewlines(String s) {
final List<StringLocated> result = new ArrayList<StringLocated>();
for (String cs : BackSlash.getWithNewlines(s)) {

View File

@ -52,14 +52,14 @@ import net.sourceforge.plantuml.sprite.Sprite;
import net.sourceforge.plantuml.sprite.SpriteColorBuilder4096;
import net.sourceforge.plantuml.sprite.SpriteGrayLevel;
public final class FactorySpriteCommand implements SingleMultiFactoryCommand<WithSprite> {
public final class CommandFactorySprite implements SingleMultiFactoryCommand<WithSprite> {
private IRegex getRegexConcatMultiLine() {
return RegexConcat.build(FactorySpriteCommand.class.getName() + "multi", RegexLeaf.start(), //
return RegexConcat.build(CommandFactorySprite.class.getName() + "multi", RegexLeaf.start(), //
new RegexLeaf("sprite"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\$?"), //
new RegexLeaf("NAME", "([\\p{L}0-9_]+)"), //
new RegexLeaf("NAME", "([-.\\p{L}0-9_]+)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("DIM", "\\[(\\d+)x(\\d+)/(?:(\\d+)(z)?|(color))\\]")), //
RegexLeaf.spaceZeroOrMore(), //
@ -67,11 +67,11 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand<Wit
}
private IRegex getRegexConcatSingleLine() {
return RegexConcat.build(FactorySpriteCommand.class.getName() + "single", RegexLeaf.start(), //
return RegexConcat.build(CommandFactorySprite.class.getName() + "single", RegexLeaf.start(), //
new RegexLeaf("sprite"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\$?"), //
new RegexLeaf("NAME", "([\\p{L}0-9_]+)"), //
new RegexLeaf("NAME", "([-.\\p{L}0-9_]+)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("DIM", "\\[(\\d+)x(\\d+)/(?:(\\d+)(z)|(color))\\]")), //
RegexLeaf.spaceOneOrMore(), //

View File

@ -241,7 +241,7 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory {
cmds.add(new CommandScaleMaxWidthAndHeight());
cmds.add(new CommandAffineTransform());
cmds.add(new CommandAffineTransformMultiline());
final FactorySpriteCommand factorySpriteCommand = new FactorySpriteCommand();
final CommandFactorySprite factorySpriteCommand = new CommandFactorySprite();
cmds.add(factorySpriteCommand.createMultiLine(false));
cmds.add(factorySpriteCommand.createSingleLine());
cmds.add(new CommandSpriteFile());

View File

@ -0,0 +1,101 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.command.note;
import java.util.List;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.Command;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.CommandMultilines2;
import net.sourceforge.plantuml.command.CommandPackage;
import net.sourceforge.plantuml.command.MultilinesStrategy;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.Stereotag;
import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
public final class CommandConstraintOnLinks extends SingleLineCommand2<CucaDiagram> {
public CommandConstraintOnLinks() {
super(getRegexConcat());
}
private static IRegex getRegexConcat() {
return RegexConcat.build(CommandConstraintOnLinks.class.getName(), RegexLeaf.start(), //
new RegexLeaf("constraint"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("on"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("links"), //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf(":"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("NOTE", "(.*)"), RegexLeaf.end());
}
private static ColorParser color() {
return ColorParser.simpleColor(ColorType.BACK);
}
@Override
protected CommandExecutionResult executeArg(CucaDiagram diagram, LineLocation location, RegexResult arg) {
final List<Link> links = diagram.getTwoLastLinks();
if (links == null) {
return CommandExecutionResult.error("Cannot put constraint on two last links");
}
final BlocLines note = BlocLines.getWithNewlines(arg.get("NOTE", 0));
return diagram.constraintOnLinks(links.get(0), links.get(1), note.toDisplay());
}
}

View File

@ -57,10 +57,10 @@ import net.sourceforge.plantuml.cucadiagram.Stereotag;
import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
public final class FactoryNoteCommand implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
public final class CommandFactoryNote implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
private IRegex getRegexConcatMultiLine() {
return RegexConcat.build(FactoryNoteCommand.class.getName() + "multi", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNote.class.getName() + "multi", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("as"), //
@ -75,7 +75,7 @@ public final class FactoryNoteCommand implements SingleMultiFactoryCommand<Abstr
}
private IRegex getRegexConcatSingleLine() {
return RegexConcat.build(FactoryNoteCommand.class.getName() + "single", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNote.class.getName() + "single", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("[%g]"), //

View File

@ -65,10 +65,10 @@ import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.utils.UniqueSequence;
public final class FactoryNoteActivityCommand implements SingleMultiFactoryCommand<ActivityDiagram> {
public final class CommandFactoryNoteActivity implements SingleMultiFactoryCommand<ActivityDiagram> {
private IRegex getRegexConcatMultiLine() {
return RegexConcat.build(FactoryNoteActivityCommand.class.getName() + "multi", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNoteActivity.class.getName() + "multi", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left|top|bottom)"), //
@ -78,7 +78,7 @@ public final class FactoryNoteActivityCommand implements SingleMultiFactoryComma
}
private IRegex getRegexConcatSingleLine() {
return RegexConcat.build(FactoryNoteActivityCommand.class.getName() + "single", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNoteActivity.class.getName() + "single", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left|top|bottom)"), //

View File

@ -69,18 +69,18 @@ import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.utils.UniqueSequence;
public final class FactoryNoteOnEntityCommand implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
private final IRegex partialPattern;
private final String key;
public FactoryNoteOnEntityCommand(String key, IRegex partialPattern) {
public CommandFactoryNoteOnEntity(String key, IRegex partialPattern) {
this.partialPattern = partialPattern;
this.key = key;
}
private IRegex getRegexConcatSingleLine(IRegex partialPattern) {
return RegexConcat.build(FactoryNoteOnEntityCommand.class.getName() + key + "single", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNoteOnEntity.class.getName() + key + "single", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left|top|bottom)"), //
@ -109,7 +109,7 @@ public final class FactoryNoteOnEntityCommand implements SingleMultiFactoryComma
private IRegex getRegexConcatMultiLine(IRegex partialPattern, final boolean withBracket) {
if (withBracket) {
return RegexConcat.build(FactoryNoteOnEntityCommand.class.getName() + key + "multi" + withBracket,
return RegexConcat.build(CommandFactoryNoteOnEntity.class.getName() + key + "multi" + withBracket,
RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
@ -131,7 +131,7 @@ public final class FactoryNoteOnEntityCommand implements SingleMultiFactoryComma
RegexLeaf.end() //
);
}
return RegexConcat.build(FactoryNoteOnEntityCommand.class.getName() + key + "multi" + withBracket,
return RegexConcat.build(CommandFactoryNoteOnEntity.class.getName() + key + "multi" + withBracket,
RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //

View File

@ -57,10 +57,10 @@ import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
public final class FactoryNoteOnLinkCommand implements SingleMultiFactoryCommand<CucaDiagram> {
public final class CommandFactoryNoteOnLink implements SingleMultiFactoryCommand<CucaDiagram> {
private IRegex getRegexConcatSingleLine() {
return RegexConcat.build(FactoryNoteOnLinkCommand.class.getName() + "single", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNoteOnLink.class.getName() + "single", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left|top|bottom)?"), //
@ -77,7 +77,7 @@ public final class FactoryNoteOnLinkCommand implements SingleMultiFactoryCommand
}
private IRegex getRegexConcatMultiLine() {
return RegexConcat.build(FactoryNoteOnLinkCommand.class.getName() + "multi", RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryNoteOnLink.class.getName() + "multi", RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left|top|bottom)?"), //

View File

@ -61,19 +61,19 @@ import net.sourceforge.plantuml.cucadiagram.LinkDecor;
import net.sourceforge.plantuml.cucadiagram.LinkType;
import net.sourceforge.plantuml.graphic.color.ColorParser;
public final class FactoryTipOnEntityCommand implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
public final class CommandFactoryTipOnEntity implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
private final IRegex partialPattern;
private final String key;
public FactoryTipOnEntityCommand(String key, IRegex partialPattern) {
public CommandFactoryTipOnEntity(String key, IRegex partialPattern) {
this.partialPattern = partialPattern;
this.key = key;
}
private RegexConcat getRegexConcatMultiLine(IRegex partialPattern, final boolean withBracket) {
if (withBracket) {
return RegexConcat.build(FactoryTipOnEntityCommand.class.getName() + key + withBracket, RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryTipOnEntity.class.getName() + key + withBracket, RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left)"), //
@ -90,7 +90,7 @@ public final class FactoryTipOnEntityCommand implements SingleMultiFactoryComman
RegexLeaf.end() //
);
}
return RegexConcat.build(FactoryTipOnEntityCommand.class.getName() + key + withBracket, RegexLeaf.start(), //
return RegexConcat.build(CommandFactoryTipOnEntity.class.getName() + key + withBracket, RegexLeaf.start(), //
new RegexLeaf("note"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("POSITION", "(right|left)"), //

View File

@ -38,13 +38,16 @@ package net.sourceforge.plantuml.core;
import net.sourceforge.plantuml.utils.StartUtils;
public enum DiagramType {
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, NW, MINDMAP, WBS, UNKNOWN;
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, NW, MINDMAP, WBS, WIRE, UNKNOWN;
static public DiagramType getTypeFromArobaseStart(String s) {
s = s.toLowerCase();
// if (s.startsWith("@startuml2")) {
// return UML2;
// }
if (StartUtils.startsWithSymbolAnd("startwire", s)) {
return WIRE;
}
if (StartUtils.startsWithSymbolAnd("startbpm", s)) {
return BPM;
}

View File

@ -71,11 +71,13 @@ public class AtomImg extends AbstractAtom implements Atom {
private final BufferedImage image;
private final double scale;
private final Url url;
private AtomImg(BufferedImage image, double scale, Url url) {
private final String rawFileName;
private AtomImg(BufferedImage image, double scale, Url url, String rawFileName) {
this.image = image;
this.scale = scale;
this.url = url;
this.rawFileName = rawFileName;
}
public static Atom createQrcode(String flash, double scale) {
@ -84,7 +86,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (im == null) {
im = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
}
return new AtomImg(new UImage(im).scaleNearestNeighbor(scale).getImage(), 1, null);
return new AtomImg(new UImage(null, im).scaleNearestNeighbor(scale).getImage(), 1, null, null);
}
public static Atom create(String src, ImgValign valign, int vspace, double scale, Url url) {
@ -118,7 +120,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (read == null) {
return AtomText.create("(Cannot decode: " + f.getCanonicalPath() + ")", fc);
}
return new AtomImg(FileUtils.ImageIO_read(f), scale, url);
return new AtomImg(FileUtils.ImageIO_read(f), scale, url, src);
} catch (IOException e) {
return AtomText.create("ERROR " + e.toString(), fc);
}
@ -130,7 +132,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (read == null) {
return AtomText.create("(Cannot decode: " + source + ")", fc);
}
return new AtomImg(read, scale, url);
return new AtomImg(read, scale, url, null);
}
private static Atom build(String text, final FontConfiguration fc, URL source, double scale, Url url)
@ -139,7 +141,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (read == null) {
return AtomText.create("(Cannot decode: " + text + ")", fc);
}
return new AtomImg(read, scale, url);
return new AtomImg(read, scale, url, source.getPath());
}
// Added by Alain Corbiere
@ -178,7 +180,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (url != null) {
ug.startUrl(url);
}
ug.draw(new UImage(image).scale(scale));
ug.draw(new UImage(rawFileName, image).scale(scale));
if (url != null) {
ug.closeAction();
}

View File

@ -99,7 +99,7 @@ public class AtomMath extends AbstractAtom implements Atom {
final SvgString svg = math.getSvg(scale, fore, back);
ug.draw(new UImageSvg(svg));
} else {
final UImage image = new UImage(math.getImage(scale, fore, back), math.getFormula());
final UImage image = new UImage(null, math.getImage(scale, fore, back), math.getFormula());
ug.draw(image);
}
}

View File

@ -90,13 +90,12 @@ public class AtomText extends AbstractAtom implements Atom {
public static Atom create(String text, FontConfiguration fontConfiguration) {
return new AtomText(text, fontConfiguration, null, ZERO, ZERO);
}
// public static AtomText createHeading(String text, FontConfiguration fontConfiguration, int order) {
// fontConfiguration = FOO(fontConfiguration, order);
// return new AtomText(text, fontConfiguration, null, ZERO, ZERO);
// }
public static Atom createUrl(Url url, FontConfiguration fontConfiguration, ISkinSimple skinSimple) {
fontConfiguration = fontConfiguration.hyperlink();
final Display display = Display.getWithNewlines(url.getLabel());
@ -113,8 +112,8 @@ public class AtomText extends AbstractAtom implements Atom {
private static Atom createAtomText(final String text, Url url, FontConfiguration fontConfiguration,
ISkinSimple skinSimple) {
final Pattern p = Pattern.compile(Splitter.openiconPattern + "|" + Splitter.spritePattern2 + "|"
+ Splitter.imgPatternNoSrcColon);
final Pattern p = Pattern.compile(
Splitter.openiconPattern + "|" + Splitter.spritePattern2 + "|" + Splitter.imgPatternNoSrcColon);
final Matcher m = p.matcher(text);
final List<Atom> result = new ArrayList<Atom>();
while (m.find()) {
@ -176,14 +175,15 @@ public class AtomText extends AbstractAtom implements Atom {
return text + " " + fontConfiguration;
}
private AtomText(String text, FontConfiguration style, Url url, DelayedDouble marginLeft, DelayedDouble marginRight) {
private AtomText(String text, FontConfiguration style, Url url, DelayedDouble marginLeft,
DelayedDouble marginRight) {
if (text.contains("" + BackSlash.hiddenNewLine())) {
throw new IllegalArgumentException(text);
}
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.text = StringUtils.manageTildeArobaseStart(StringUtils.manageUnicodeNotationUplus(StringUtils
.manageAmpDiese(StringUtils.showComparatorCharacters(CharHidder.unhide(text)))));
this.text = StringUtils.manageTildeArobaseStart(StringUtils.manageUnicodeNotationUplus(
StringUtils.manageAmpDiese(StringUtils.showComparatorCharacters(CharHidder.unhide(text)))));
this.fontConfiguration = style;
this.url = url;
}
@ -234,42 +234,43 @@ public class AtomText extends AbstractAtom implements Atom {
}
public void drawU(UGraphic ug) {
if (ug.matchesProperty("SPECIALTXT")) {
ug.draw(this);
return;
}
if (url != null) {
ug.startUrl(url);
}
HtmlColor textColor = fontConfiguration.getColor();
FontConfiguration useFontConfiguration = fontConfiguration;
if (textColor instanceof HtmlColorAutomatic && ug.getParam().getBackcolor() != null) {
textColor = ((HtmlColorSimple) ug.getParam().getBackcolor()).opposite();
useFontConfiguration = fontConfiguration.changeColor(textColor);
}
if (marginLeft != ZERO) {
ug = ug.apply(new UTranslate(marginLeft.getDouble(ug.getStringBounder()), 0));
}
if (ug.matchesProperty("SPECIALTXT")) {
ug.draw(this);
} else {
HtmlColor textColor = fontConfiguration.getColor();
FontConfiguration useFontConfiguration = fontConfiguration;
if (textColor instanceof HtmlColorAutomatic && ug.getParam().getBackcolor() != null) {
textColor = ((HtmlColorSimple) ug.getParam().getBackcolor()).opposite();
useFontConfiguration = fontConfiguration.changeColor(textColor);
}
if (marginLeft != ZERO) {
ug = ug.apply(new UTranslate(marginLeft.getDouble(ug.getStringBounder()), 0));
}
final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true);
final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true);
double x = 0;
// final int ypos = fontConfiguration.getSpace();
final Dimension2D rect = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), text);
final double descent = getDescent();
final double ypos = rect.getHeight() - descent;
if (tokenizer.hasMoreTokens()) {
final double tabSize = getTabSize(ug.getStringBounder());
while (tokenizer.hasMoreTokens()) {
final String s = tokenizer.nextToken();
if (s.equals("\t")) {
final double remainder = x % tabSize;
x += tabSize - remainder;
} else {
final UText utext = new UText(s, useFontConfiguration);
final Dimension2D dim = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), s);
ug.apply(new UTranslate(x, ypos)).draw(utext);
x += dim.getWidth();
double x = 0;
// final int ypos = fontConfiguration.getSpace();
final Dimension2D rect = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), text);
final double descent = getDescent();
final double ypos = rect.getHeight() - descent;
if (tokenizer.hasMoreTokens()) {
final double tabSize = getTabSize(ug.getStringBounder());
while (tokenizer.hasMoreTokens()) {
final String s = tokenizer.nextToken();
if (s.equals("\t")) {
final double remainder = x % tabSize;
x += tabSize - remainder;
} else {
final UText utext = new UText(s, useFontConfiguration);
final Dimension2D dim = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(),
s);
ug.apply(new UTranslate(x, ypos)).draw(utext);
x += dim.getWidth();
}
}
}
}

View File

@ -107,7 +107,7 @@ public class Bodier {
private boolean isMethod(String s) {
if (type == LeafType.ANNOTATION || type == LeafType.ABSTRACT_CLASS || type == LeafType.CLASS
|| type == LeafType.INTERFACE || type == LeafType.ENUM) {
return MemberImpl.isMethod(s);
return Member.isMethod(s);
}
return false;
}
@ -123,7 +123,7 @@ public class Bodier {
if (s.length() == 0 && methodsToDisplay.size() == 0) {
continue;
}
final Member m = new MemberImpl(s, true, manageModifier);
final Member m = new Member(s, true, manageModifier);
if (hides == null || hides.contains(m.getVisibilityModifier()) == false) {
methodsToDisplay.add(m);
}
@ -151,7 +151,7 @@ public class Bodier {
if (s.length() == 0 && fieldsToDisplay.size() == 0) {
continue;
}
final Member m = new MemberImpl(s, false, manageModifier);
final Member m = new Member(s, false, manageModifier);
if (hides == null || hides.contains(m.getVisibilityModifier()) == false) {
fieldsToDisplay.add(m);
}
@ -187,7 +187,7 @@ public class Bodier {
}
final List<String> result = new ArrayList<String>();
for (String s : rawBody) {
final Member m = new MemberImpl(s, isMethod(s), manageModifier);
final Member m = new Member(s, isMethod(s), manageModifier);
if (hides.contains(m.getVisibilityModifier()) == false) {
result.add(s);
}

View File

@ -170,7 +170,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo
align, skinParam, CreoleMode.FULL);
blocks.add(bloc);
} else {
final Member m = new MemberImpl(s, MemberImpl.isMethod(s), manageModifier);
final Member m = new Member(s, Member.isMethod(s), manageModifier);
members.add(m);
if (m.getUrl() != null) {
urls.add(m.getUrl());
@ -179,7 +179,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo
}
}
if (inEllipse && members.size() == 0) {
members.add(new MemberImpl("", false, false));
members.add(new Member("", false, false));
}
blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align, stereotype,
entity), separator, title));

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker;
@ -69,10 +70,36 @@ import net.sourceforge.plantuml.xmlsc.StateDiagramScxmlMaker;
public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, PortionShower {
static private final boolean G1972 = false;
// private String namespaceSeparator = ".";
// private String namespaceSeparator1 = GO1972 ? "::" : ".";
private String namespaceSeparator = null;
private boolean namespaceSeparatorHasBeenSet = false;
public final boolean V1972() {
if (getPragma().backToLegacyPackage()) {
return false;
}
if (getPragma().useNewPackage()) {
return true;
}
if (G1972)
return true;
return false;
}
public final boolean mergeIntricated() {
if (getNamespaceSeparator() == null) {
return false;
}
return this.V1972() && this.getUmlDiagramType() == UmlDiagramType.CLASS;
}
public Set<SuperGroup> getAllSuperGroups() {
return entityFactory.getAllSuperGroups();
}
private int horizontalPages = 1;
private int verticalPages = 1;
@ -105,13 +132,15 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return this.stacks2.get(stacks2.size() - 1);
}
private String namespaceSeparator = ".";
final public void setNamespaceSeparator(String namespaceSeparator) {
this.namespaceSeparatorHasBeenSet = true;
this.namespaceSeparator = namespaceSeparator;
}
final public String getNamespaceSeparator() {
if (namespaceSeparatorHasBeenSet == false) {
return V1972() ? "::" : ".";
}
return namespaceSeparator;
}
@ -135,6 +164,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return false;
}
final public void setLastEntity(ILeaf foo) {
this.lastEntity = foo;
}
final protected ILeaf getOrCreateLeafDefault(Ident idNewLong, Code code, LeafType type, USymbol symbol) {
checkNotNull(idNewLong);
if (type == null) {
@ -182,7 +215,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
}
final public Ident buildLeafIdent(String id) {
return getLastID().add(id, namespaceSeparator);
return getLastID().add(id, getNamespaceSeparator());
}
final public Ident buildLeafIdentSpecial(String id) {
@ -196,7 +229,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
}
final public Ident buildFullyQualified(String id) {
return entityFactory.buildFullyQualified(getLastID(), Ident.empty().add(id, namespaceSeparator));
return entityFactory.buildFullyQualified(getLastID(), Ident.empty().add(id, getNamespaceSeparator()));
}
final public Code buildCode(String s) {
@ -260,7 +293,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
}
gotoGroupInternalWithNamespace(ident, code, display, code, type, parent);
} else if (strategy == NamespaceStrategy.SINGLE) {
final Ident newIdLong = buildLeafIdentSpecial(ident.toString(this.namespaceSeparator));
final Ident newIdLong = buildLeafIdentSpecial(ident.toString(this.getNamespaceSeparator()));
gotoGroupExternal(newIdLong, code, display, null, type, parent);
stacks2.add(newIdLong);
} else {
@ -363,7 +396,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return;
}
final boolean mutation;
if (namespaceSeparator == null)
if (getNamespaceSeparator() == null)
mutation = entityFactory.getLeafVerySmart(idNewLong) != null;
else
mutation = entityFactory.getLeafStrict(idNewLong) != null;
@ -491,6 +524,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return entityFactory.getRootGroup();
}
public SuperGroup getRootSuperGroup() {
return entityFactory.getRootSuperGroup();
}
public final Collection<ILeaf> getLeafsvalues() {
return entityFactory.leafs2();
}
@ -606,6 +643,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
throw new UnsupportedOperationException();
}
entityFactory.buildSuperGroups();
final CucaDiagramFileMaker maker = this.isUseJDot()
? new CucaDiagramFileMakerJDot(this, fileFormatOption.getDefaultStringBounder())
: new CucaDiagramFileMakerSvek(this);
@ -807,6 +846,21 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return null;
}
final public List<Link> getTwoLastLinks() {
final List<Link> result = new ArrayList<Link>();
final List<Link> links = getLinks();
for (int i = links.size() - 1; i >= 0; i--) {
final Link link = links.get(i);
if (link.getEntity1().getLeafType() != LeafType.NOTE && link.getEntity2().getLeafType() != LeafType.NOTE) {
result.add(link);
if (result.size() == 2) {
return Collections.unmodifiableList(result);
}
}
}
return null;
}
private ILeaf lastEntity = null;
final public ILeaf getLastEntity() {
@ -854,4 +908,11 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
entityFactory.incRawLayout();
}
public CommandExecutionResult constraintOnLinks(Link link1, Link link2, Display display) {
final LinkConstraint linkConstraint = new LinkConstraint(link1, link2, display);
link1.setLinkConstraint(linkConstraint);
link2.setLinkConstraint(linkConstraint);
return CommandExecutionResult.ok();
}
}

View File

@ -36,10 +36,17 @@
package net.sourceforge.plantuml.cucadiagram;
import java.util.Collection;
import java.util.Set;
public interface GroupHierarchy {
public IGroup getRootGroup();
public SuperGroup getRootSuperGroup();
public Collection<IGroup> getChildrenGroups(IGroup parent);
public Set<SuperGroup> getAllSuperGroups();
public boolean isEmpty(IGroup g);
}

View File

@ -281,4 +281,12 @@ public class Ident implements Code {
return parts.size();
}
public Ident getPrefix(int toIndex) {
return new Ident(this.parts.subList(0, toIndex));
}
public Ident getSuffix(int fromIndex) {
return new Ident(this.parts.subList(fromIndex, this.parts.size()));
}
}

View File

@ -115,11 +115,10 @@ public class Link extends WithLinkType implements Hideable, Removeable {
public UComment commentForSvg() {
if (type.looksLikeRevertedForSvg()) {
return new UComment("reverse link " + getEntity1().getCodeGetName() + " to "
+ getEntity2().getCodeGetName());
return new UComment(
"reverse link " + getEntity1().getCodeGetName() + " to " + getEntity2().getCodeGetName());
}
return new UComment("link " + getEntity1().getCodeGetName() + " to "
+ getEntity2().getCodeGetName());
return new UComment("link " + getEntity1().getCodeGetName() + " to " + getEntity2().getCodeGetName());
}
public Link(IEntity cl1, IEntity cl2, LinkType type, Display label, int length, StyleBuilder styleBuilder) {
@ -196,6 +195,7 @@ public class Link extends WithLinkType implements Hideable, Removeable {
result.port1 = this.port2;
result.port2 = this.port1;
result.url = this.url;
result.linkConstraint = this.linkConstraint;
return result;
}
@ -253,11 +253,11 @@ public class Link extends WithLinkType implements Hideable, Removeable {
}
public EntityPort getEntityPort1(Bibliotekon bibliotekon) {
return new EntityPort(bibliotekon.getShapeUid((ILeaf) cl1), port1);
return new EntityPort(bibliotekon.getNodeUid((ILeaf) cl1), port1);
}
public EntityPort getEntityPort2(Bibliotekon bibliotekon) {
return new EntityPort(bibliotekon.getShapeUid((ILeaf) cl2), port2);
return new EntityPort(bibliotekon.getNodeUid((ILeaf) cl2), port2);
}
@Override
@ -474,7 +474,8 @@ public class Link extends WithLinkType implements Hideable, Removeable {
public boolean hasEntryPoint() {
return (getEntity1().isGroup() == false && ((ILeaf) getEntity1()).getEntityPosition() != EntityPosition.NORMAL)
|| (getEntity2().isGroup() == false && ((ILeaf) getEntity2()).getEntityPosition() != EntityPosition.NORMAL);
|| (getEntity2().isGroup() == false
&& ((ILeaf) getEntity2()).getEntityPosition() != EntityPosition.NORMAL);
}
public boolean hasTwoEntryPointsSameContainer() {
@ -570,4 +571,14 @@ public class Link extends WithLinkType implements Hideable, Removeable {
return umlType;
}
private LinkConstraint linkConstraint;
public void setLinkConstraint(LinkConstraint linkConstraint) {
this.linkConstraint = linkConstraint;
}
public final LinkConstraint getLinkConstraint() {
return linkConstraint;
}
}

View File

@ -0,0 +1,106 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.cucadiagram;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class LinkConstraint {
private final Link link1;
private final Link link2;
private final Display display;
private double x1;
private double y1;
private double x2;
private double y2;
public LinkConstraint(Link link1, Link link2, Display display) {
this.link1 = link1;
this.link2 = link2;
this.display = display;
}
public void setPosition(Link link, Point2D pt) {
if (link == link1) {
x1 = pt.getX();
y1 = pt.getY();
} else if (link == link2) {
x2 = pt.getX();
y2 = pt.getY();
} else {
throw new IllegalArgumentException();
}
}
public void drawMe(UGraphic ug, ISkinParam skinParam) {
if (x1 == 0 && y1 == 0) {
return;
}
if (x2 == 0 && y2 == 0) {
return;
}
ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK));
// ug.apply(new UTranslate(x1, y1)).draw(new URectangle(10, 10));
// ug.apply(new UTranslate(x2, y2)).draw(new URectangle(10, 10));
final ULine line = new ULine(x2 - x1, y2 - y1);
ug = ug.apply(new UStroke(3, 3, 1));
ug.apply(new UTranslate(x1, y1)).draw(line);
final TextBlock label = display.create(new FontConfiguration(skinParam, FontParam.ARROW, null),
HorizontalAlignment.CENTER, skinParam);
final Dimension2D dimLabel = label.calculateDimension(ug.getStringBounder());
final double x = (x1 + x2) / 2 - dimLabel.getWidth() / 2;
final double y = (y1 + y2) / 2 - dimLabel.getHeight() / 2;
label.drawU(ug.apply(new UTranslate(x, y)));
}
}

View File

@ -35,20 +35,171 @@
*/
package net.sourceforge.plantuml.cucadiagram;
import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.skin.VisibilityModifier;
public interface Member {
public class Member {
public Url getUrl();
private final String display;
private final boolean staticModifier;
private final boolean abstractModifier;
private final Url url;
private final boolean hasUrl;
public String getDisplay(boolean withVisibilityChar);
private final VisibilityModifier visibilityModifier;
public boolean hasUrl();
@Override
public String toString() {
return super.toString() + " " + display;
}
public VisibilityModifier getVisibilityModifier();
public Member(String tmpDisplay, boolean isMethod, boolean manageModifier) {
tmpDisplay = tmpDisplay.replaceAll("(?i)\\{(method|field)\\}\\s*", "");
if (manageModifier) {
final Pattern2 finalUrl = MyPattern.cmpile("^(.*?)(?:\\[(" + UrlBuilder.getRegexp() + ")\\])?$");
final Matcher2 matcher = finalUrl.matcher(tmpDisplay);
if (matcher.matches() == false) {
throw new IllegalStateException();
}
tmpDisplay = matcher.group(1);
final String urlString = matcher.group(2);
if (urlString == null) {
this.url = null;
} else {
this.url = new UrlBuilder(null, ModeUrl.STRICT).getUrl(urlString);
}
} else {
this.url = null;
}
this.hasUrl = this.url != null;
final String lower = StringUtils.goLowerCase(tmpDisplay);
public boolean isStatic();
if (manageModifier) {
this.staticModifier = lower.contains("{static}") || lower.contains("{classifier}");
this.abstractModifier = lower.contains("{abstract}");
String displayClean = tmpDisplay.replaceAll("(?i)\\{(static|classifier|abstract)\\}\\s*", "").trim();
if (displayClean.length() == 0) {
displayClean = " ";
}
public boolean isAbstract();
if (VisibilityModifier.isVisibilityCharacter(displayClean)) {
visibilityModifier = VisibilityModifier.getVisibilityModifier(displayClean, isMethod == false);
this.display = StringUtils.trin(Guillemet.GUILLEMET.manageGuillemet(displayClean.substring(1)));
} else {
this.display = Guillemet.GUILLEMET.manageGuillemet(displayClean);
visibilityModifier = null;
}
} else {
this.staticModifier = false;
this.visibilityModifier = null;
this.abstractModifier = false;
tmpDisplay = StringUtils.trin(tmpDisplay);
this.display = tmpDisplay.length() == 0 ? " " : Guillemet.GUILLEMET.manageGuillemet(StringUtils
.trin(tmpDisplay));
}
}
public String getDisplay(boolean withVisibilityChar) {
if (withVisibilityChar) {
return getDisplayWithVisibilityChar();
}
return getDisplayWithoutVisibilityChar();
}
private String getDisplayWithoutVisibilityChar() {
// assert display.length() == 0 || VisibilityModifier.isVisibilityCharacter(display.charAt(0)) == false;
return display;
}
private String getDisplayWithVisibilityChar() {
if (isPrivate()) {
return "-" + display;
}
if (isPublic()) {
return "+" + display;
}
if (isPackagePrivate()) {
return "~" + display;
}
if (isProtected()) {
return "#" + display;
}
if (isIEMandatory()) {
return "*" + display;
}
return display;
}
@Override
public boolean equals(Object obj) {
final Member other = (Member) obj;
return this.display.equals(other.display);
}
@Override
public int hashCode() {
return display.hashCode();
}
public final boolean isStatic() {
return staticModifier;
}
public final boolean isAbstract() {
return abstractModifier;
}
private boolean isPrivate() {
return visibilityModifier == VisibilityModifier.PRIVATE_FIELD
|| visibilityModifier == VisibilityModifier.PRIVATE_METHOD;
}
private boolean isProtected() {
return visibilityModifier == VisibilityModifier.PROTECTED_FIELD
|| visibilityModifier == VisibilityModifier.PROTECTED_METHOD;
}
private boolean isPublic() {
return visibilityModifier == VisibilityModifier.PUBLIC_FIELD
|| visibilityModifier == VisibilityModifier.PUBLIC_METHOD;
}
private boolean isPackagePrivate() {
return visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_FIELD
|| visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_METHOD;
}
private boolean isIEMandatory() {
return visibilityModifier == VisibilityModifier.IE_MANDATORY;
}
public final VisibilityModifier getVisibilityModifier() {
return visibilityModifier;
}
public final Url getUrl() {
return url;
}
public boolean hasUrl() {
return hasUrl;
}
public static boolean isMethod(String s) {
// s = UrlBuilder.purgeUrl(s);
if (s.contains("{method}")) {
return true;
}
if (s.contains("{field}")) {
return false;
}
return s.contains("(") || s.contains(")");
}
}

View File

@ -1,205 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.cucadiagram;
import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.skin.VisibilityModifier;
public class MemberImpl implements Member {
private final String display;
private final boolean staticModifier;
private final boolean abstractModifier;
private final Url url;
private final boolean hasUrl;
private final VisibilityModifier visibilityModifier;
@Override
public String toString() {
return super.toString() + " " + display;
}
public MemberImpl(String tmpDisplay, boolean isMethod, boolean manageModifier) {
tmpDisplay = tmpDisplay.replaceAll("(?i)\\{(method|field)\\}\\s*", "");
if (manageModifier) {
final Pattern2 finalUrl = MyPattern.cmpile("^(.*?)(?:\\[(" + UrlBuilder.getRegexp() + ")\\])?$");
final Matcher2 matcher = finalUrl.matcher(tmpDisplay);
if (matcher.matches() == false) {
throw new IllegalStateException();
}
tmpDisplay = matcher.group(1);
final String urlString = matcher.group(2);
if (urlString == null) {
this.url = null;
} else {
this.url = new UrlBuilder(null, ModeUrl.STRICT).getUrl(urlString);
}
} else {
this.url = null;
}
this.hasUrl = this.url != null;
final String lower = StringUtils.goLowerCase(tmpDisplay);
if (manageModifier) {
this.staticModifier = lower.contains("{static}") || lower.contains("{classifier}");
this.abstractModifier = lower.contains("{abstract}");
String displayClean = tmpDisplay.replaceAll("(?i)\\{(static|classifier|abstract)\\}\\s*", "").trim();
if (displayClean.length() == 0) {
displayClean = " ";
}
if (VisibilityModifier.isVisibilityCharacter(displayClean)) {
visibilityModifier = VisibilityModifier.getVisibilityModifier(displayClean, isMethod == false);
this.display = StringUtils.trin(Guillemet.GUILLEMET.manageGuillemet(displayClean.substring(1)));
} else {
this.display = Guillemet.GUILLEMET.manageGuillemet(displayClean);
visibilityModifier = null;
}
} else {
this.staticModifier = false;
this.visibilityModifier = null;
this.abstractModifier = false;
tmpDisplay = StringUtils.trin(tmpDisplay);
this.display = tmpDisplay.length() == 0 ? " " : Guillemet.GUILLEMET.manageGuillemet(StringUtils
.trin(tmpDisplay));
}
}
public String getDisplay(boolean withVisibilityChar) {
if (withVisibilityChar) {
return getDisplayWithVisibilityChar();
}
return getDisplayWithoutVisibilityChar();
}
private String getDisplayWithoutVisibilityChar() {
// assert display.length() == 0 || VisibilityModifier.isVisibilityCharacter(display.charAt(0)) == false;
return display;
}
private String getDisplayWithVisibilityChar() {
if (isPrivate()) {
return "-" + display;
}
if (isPublic()) {
return "+" + display;
}
if (isPackagePrivate()) {
return "~" + display;
}
if (isProtected()) {
return "#" + display;
}
if (isIEMandatory()) {
return "*" + display;
}
return display;
}
@Override
public boolean equals(Object obj) {
final MemberImpl other = (MemberImpl) obj;
return this.display.equals(other.display);
}
@Override
public int hashCode() {
return display.hashCode();
}
public final boolean isStatic() {
return staticModifier;
}
public final boolean isAbstract() {
return abstractModifier;
}
private boolean isPrivate() {
return visibilityModifier == VisibilityModifier.PRIVATE_FIELD
|| visibilityModifier == VisibilityModifier.PRIVATE_METHOD;
}
private boolean isProtected() {
return visibilityModifier == VisibilityModifier.PROTECTED_FIELD
|| visibilityModifier == VisibilityModifier.PROTECTED_METHOD;
}
private boolean isPublic() {
return visibilityModifier == VisibilityModifier.PUBLIC_FIELD
|| visibilityModifier == VisibilityModifier.PUBLIC_METHOD;
}
private boolean isPackagePrivate() {
return visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_FIELD
|| visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_METHOD;
}
private boolean isIEMandatory() {
return visibilityModifier == VisibilityModifier.IE_MANDATORY;
}
public final VisibilityModifier getVisibilityModifier() {
return visibilityModifier;
}
public final Url getUrl() {
return url;
}
public boolean hasUrl() {
return hasUrl;
}
public static boolean isMethod(String s) {
// s = UrlBuilder.purgeUrl(s);
if (s.contains("{method}")) {
return true;
}
if (s.contains("{field}")) {
return false;
}
return s.contains("(") || s.contains(")");
}
}

View File

@ -33,14 +33,21 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.cucadiagram;
public interface Instant extends Value, Comparable<Instant> {
import java.util.HashSet;
import java.util.Set;
public Instant increment();
public class SuperGroup {
public Instant decrement();
private final Set<IGroup> groups = new HashSet<IGroup>();
public String toShortString();
public SuperGroup(IGroup g) {
this.groups.add(g);
}
public IGroup getFirstGroup() {
return groups.iterator().next();
}
}

View File

@ -75,6 +75,10 @@ final public class DotData implements PortionShower {
private final ColorMapper colorMapper;
private final EntityFactory entityFactory;
public EntityFactory getEntityFactory() {
return entityFactory;
}
public DotData(IGroup topParent, List<Link> links, Collection<ILeaf> leafs, UmlDiagramType umlDiagramType,
ISkinParam skinParam, GroupHierarchy groupHierarchy, PortionShower portionShower, ColorMapper colorMapper,
EntityFactory entityFactory, boolean isHideEmptyDescriptionForState, DotMode dotMode,

View File

@ -38,13 +38,17 @@ package net.sourceforge.plantuml.cucadiagram.entity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Bodier;
import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
@ -58,6 +62,10 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Ident;
import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.SuperGroup;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.skin.VisibilityModifier;
public final class EntityFactory {
@ -73,14 +81,104 @@ public final class EntityFactory {
private int rawLayout;
private final IGroup rootGroup = new GroupRoot(this);
private final SuperGroup rootSuperGroup = new SuperGroup(rootGroup);
private final List<HideOrShow2> hides2;
private final List<HideOrShow2> removed;
/* private */ final public CucaDiagram namespaceSeparator;
// private final boolean mergeIntricated;
private Map<IGroup, ILeaf> emptyGroupsAsNode = new HashMap<IGroup, ILeaf>();
public ILeaf getLeafForEmptyGroup(IGroup g) {
return emptyGroupsAsNode.get(g);
}
public SuperGroup getRootSuperGroup() {
return rootSuperGroup;
}
private Set<SuperGroup> superGroups = null;
final Map<IGroup, SuperGroup> groupToSuper = new LinkedHashMap<IGroup, SuperGroup>();
public Set<SuperGroup> getAllSuperGroups() {
return Collections.unmodifiableSet(superGroups);
}
public void buildSuperGroups() {
superGroups = new HashSet<SuperGroup>();
for (IGroup g : groups2.values()) {
final SuperGroup sg = new SuperGroup(g);
superGroups.add(sg);
groupToSuper.put(g, sg);
}
}
public ILeaf createLeafForEmptyGroup(IGroup g, ISkinParam skinParam) {
final ILeaf folder = this.createLeaf(g.getIdent(), g.getCode(), g.getDisplay(), LeafType.EMPTY_PACKAGE,
g.getParentContainer(), null, this.namespaceSeparator.getNamespaceSeparator());
((EntityImpl) folder).setOriginalGroup(g);
final USymbol symbol = g.getUSymbol();
folder.setUSymbol(symbol);
folder.setStereotype(g.getStereotype());
if (g.getUrl99() != null) {
folder.addUrl(g.getUrl99());
}
if (g.getColors(skinParam).getColor(ColorType.BACK) == null) {
final ColorParam param = symbol == null ? ColorParam.packageBackground : symbol.getColorParamBack();
final HtmlColor c1 = skinParam.getHtmlColor(param, g.getStereotype(), false);
folder.setSpecificColorTOBEREMOVED(ColorType.BACK, c1 == null ? skinParam.getBackgroundColor() : c1);
} else {
folder.setSpecificColorTOBEREMOVED(ColorType.BACK, g.getColors(skinParam).getColor(ColorType.BACK));
}
emptyGroupsAsNode.put(g, folder);
return folder;
}
public Display getIntricatedDisplay(Ident ident) {
final Set<Ident> known = new HashSet<Ident>(groups2.keySet());
known.removeAll(hiddenBecauseOfIntrication);
String sep = namespaceSeparator.getNamespaceSeparator();
if (sep == null) {
sep = ".";
}
for (int check = ident.size() - 1; check > 0; check--) {
if (known.contains(ident.getPrefix(check))) {
// if (hiddenBecauseOfIntrication.contains(ident.getPrefix(check)) == false) {
return Display.getWithNewlines(ident.getSuffix(check).toString(sep))
.withCreoleMode(CreoleMode.SIMPLE_LINE);
}
}
return Display.getWithNewlines(ident.toString(sep)).withCreoleMode(CreoleMode.SIMPLE_LINE);
}
private final Collection<Ident> hiddenBecauseOfIntrication = new ArrayList<Ident>();
public IGroup isIntricated(IGroup parent) {
final int leafs = parent.getLeafsDirect().size();
final Collection<IGroup> children = parent.getChildren();
if (leafs == 0 && children.size() == 1) {
final IGroup g = children.iterator().next();
if (g.getLeafsDirect().size() == 0 && g.getChildren().size() == 0
&& g.getGroupType() == GroupType.PACKAGE) {
return null;
}
for (Link link : this.getLinks()) {
if (link.contains(parent)) {
return null;
}
}
((EntityImpl) g).setIntricated(true);
hiddenBecauseOfIntrication.add(parent.getIdent());
return g;
}
return null;
}
public EntityFactory(List<HideOrShow2> hides2, List<HideOrShow2> removed, CucaDiagram namespaceSeparator) {
this.hides2 = hides2;
this.removed = removed;
this.namespaceSeparator = namespaceSeparator;
// this.mergeIntricated = namespaceSeparator.mergeIntricated();
// if (OptionFlags.V1972(namespaceSeparator)) {
// this.leafsByCode = null;
@ -400,9 +498,10 @@ public final class EntityFactory {
if (result != null) {
return result;
}
System.err.println("getParentContainer::groups2=" + groups2);
result = createGroup(parent, parent, Display.getWithNewlines(parent.getName()), null, GroupType.PACKAGE,
null, Collections.<VisibilityModifier>emptySet(), namespaceSeparator.getNamespaceSeparator());
// System.err.println("getParentContainer::groups2=" + groups2);
final Display display = Display.getWithNewlines(parent.getName());
result = createGroup(parent, parent, display, null, GroupType.PACKAGE, null,
Collections.<VisibilityModifier>emptySet(), namespaceSeparator.getNamespaceSeparator());
addGroup(result);
return result;
}
@ -412,4 +511,5 @@ public final class EntityFactory {
return parentContainer;
}
}

View File

@ -45,12 +45,15 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.Guillemet;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Bodier;
import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.Display;
@ -79,7 +82,7 @@ import net.sourceforge.plantuml.svek.SingleStrategy;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.utils.UniqueSequence;
final class EntityImpl implements ILeaf, IGroup {
final public class EntityImpl implements ILeaf, IGroup {
private final EntityFactory entityFactory;
@ -232,6 +235,9 @@ final class EntityImpl implements ILeaf, IGroup {
}
public Display getDisplay() {
if (intricated) {
return entityFactory.getIntricatedDisplay(ident);
}
return display;
}
@ -261,7 +267,8 @@ final class EntityImpl implements ILeaf, IGroup {
@Override
public String toString() {
// return super.toString() + code + " " + display + "(" + leafType + ")[" + groupType + "] " + xposition + " "
// return super.toString() + code + " " + display + "(" + leafType + ")[" +
// groupType + "] " + xposition + " "
// + getUid();
if (entityFactory.namespaceSeparator.V1972())
return getUid() + " " + ident + " " + display + "(" + leafType + ")[" + groupType + "]";
@ -435,46 +442,51 @@ final class EntityImpl implements ILeaf, IGroup {
if (dest.isGroup() == false) {
throw new UnsupportedOperationException();
}
System.err.println("moveEntitiesTo1972::before1::groups2=" + entityFactory.groups2());
// System.err.println("moveEntitiesTo1972::before1::groups2=" +
// entityFactory.groups2());
final Ident firstIdent = getIdent();
final Ident destIdent = dest.getIdent();
System.err.println("moveEntitiesTo1972::this=" + firstIdent);
System.err.println("moveEntitiesTo1972::dest=" + destIdent);
// System.err.println("moveEntitiesTo1972::this=" + firstIdent);
// System.err.println("moveEntitiesTo1972::dest=" + destIdent);
if (destIdent.startsWith(firstIdent) == false) {
throw new UnsupportedOperationException();
}
System.err.println("moveEntitiesTo1972::before2::groups2=" + entityFactory.groups2());
// System.err.println("moveEntitiesTo1972::before2::groups2=" +
// entityFactory.groups2());
for (ILeaf ent : new ArrayList<ILeaf>(entityFactory.leafs2())) {
Ident ident = ent.getIdent();
if (ident.equals(firstIdent) == false && ident.startsWith(firstIdent)
&& ident.startsWith(destIdent) == false) {
System.err.print("moving leaf ident1=" + ident);
// System.err.print("moving leaf ident1=" + ident);
entityFactory.leafs2.remove(ident);
ident = ident.move(firstIdent, destIdent);
System.err.println(" to ident2=" + ident);
// System.err.println(" to ident2=" + ident);
((EntityImpl) ent).ident = ident;
((EntityImpl) ent).code = ident;
entityFactory.leafs2.put(ident, ent);
}
}
System.err.println("moveEntitiesTo1972::before3::groups2=" + entityFactory.groups2());
// System.err.println("moveEntitiesTo1972::before3::groups2=" +
// entityFactory.groups2());
for (IGroup ent : new ArrayList<IGroup>(entityFactory.groups2())) {
Ident ident = ent.getIdent();
System.err.println("found=" + ident + " " + ident.startsWith(firstIdent) + " "
+ ident.startsWith(destIdent));
// System.err.println("found=" + ident + " " + ident.startsWith(firstIdent) + "
// "
// + ident.startsWith(destIdent));
if (ident.equals(firstIdent) == false && ident.startsWith(firstIdent)
&& ident.startsWith(destIdent) == false) {
System.err.print("moving gr ident1=" + ident);
// System.err.print("moving gr ident1=" + ident);
entityFactory.groups2.remove(ident);
ident = ident.move(firstIdent, destIdent);
System.err.println(" to ident2=" + ident);
// System.err.println(" to ident2=" + ident);
((EntityImpl) ent).ident = ident;
((EntityImpl) ent).code = ident;
entityFactory.groups2.put(ident, ent);
System.err.println("-->groups2=" + entityFactory.groups2());
// System.err.println("-->groups2=" + entityFactory.groups2());
}
}
System.err.println("moveEntitiesTo1972::after::groups2=" + entityFactory.groups2());
// System.err.println("moveEntitiesTo1972::after::groups2=" +
// entityFactory.groups2());
// for (IGroup g : dest.getChildren()) {
// // ((EntityImpl) g).parentContainer = dest;
// throw new IllegalStateException();
@ -757,4 +769,21 @@ final class EntityImpl implements ILeaf, IGroup {
return legend;
}
private boolean intricated;
public void setIntricated(boolean intricated) {
this.intricated = intricated;
}
private IGroup originalGroup;
public void setOriginalGroup(IGroup originalGroup) {
this.originalGroup = originalGroup;
}
public IGroup getOriginalGroup() {
return originalGroup;
}
}

View File

@ -49,9 +49,9 @@ import net.sourceforge.plantuml.command.CommandFootboxIgnored;
import net.sourceforge.plantuml.command.CommandPage;
import net.sourceforge.plantuml.command.CommandRankDir;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.command.note.FactoryNoteCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnEntityCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnLinkCommand;
import net.sourceforge.plantuml.command.note.CommandFactoryNote;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnEntity;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnLink;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.descdiagram.command.CommandArchimate;
@ -92,10 +92,10 @@ public class DescriptionDiagramFactory extends UmlDiagramFactory {
//
cmds.add(new CommandPackageWithUSymbol());
cmds.add(new CommandEndPackage());
final FactoryNoteCommand factoryNoteCommand = new FactoryNoteCommand();
final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote();
cmds.add(factoryNoteCommand.createMultiLine(false));
final FactoryNoteOnEntityCommand factoryNoteOnEntityCommand = new FactoryNoteOnEntityCommand("desc",
final CommandFactoryNoteOnEntity factoryNoteOnEntityCommand = new CommandFactoryNoteOnEntity("desc",
new RegexOr("ENTITY", //
new RegexLeaf("[\\p{L}0-9_.]+"), //
new RegexLeaf("\\(\\)[%s]*[\\p{L}0-9_.]+"), //
@ -117,7 +117,7 @@ public class DescriptionDiagramFactory extends UmlDiagramFactory {
cmds.add(factoryNoteOnEntityCommand.createMultiLine(false));
cmds.add(factoryNoteCommand.createMultiLine(false));
final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand();
final CommandFactoryNoteOnLink factoryNoteOnLinkCommand = new CommandFactoryNoteOnLink();
cmds.add(factoryNoteOnLinkCommand.createSingleLine());
cmds.add(factoryNoteOnLinkCommand.createMultiLine(false));

View File

@ -0,0 +1,242 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.descdiagram.command;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.classdiagram.ClassDiagram;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Ident;
import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.descdiagram.DescriptionDiagram;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.graphic.color.Colors;
public class CommandCreateElementParenthesis extends SingleLineCommand2<ClassDiagram> {
public CommandCreateElementParenthesis() {
super(getRegexConcat());
}
private static IRegex getRegexConcat() {
return RegexConcat.build(CommandCreateElementParenthesis.class.getName(), RegexLeaf.start(), //
new RegexLeaf("\\(\\)[%s]+"), //
color2().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOr(//
new RegexLeaf("CODE1", CommandCreateElementFull.CODE_WITH_QUOTE), //
new RegexConcat(//
new RegexLeaf("DISPLAY2", CommandCreateElementFull.DISPLAY), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("STEREOTYPE2", "(\\<\\<.+\\>\\>)")//
)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE2", CommandCreateElementFull.CODE)), //
new RegexConcat(//
new RegexLeaf("CODE3", CommandCreateElementFull.CODE), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("STEREOTYPE3", "(\\<\\<.+\\>\\>)") //
)), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("as"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("DISPLAY3", CommandCreateElementFull.DISPLAY)), //
new RegexConcat(//
new RegexLeaf("DISPLAY4", CommandCreateElementFull.DISPLAY_WITHOUT_QUOTE), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("STEREOTYPE4", "(\\<\\<.+\\>\\>)") //
)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE4", CommandCreateElementFull.CODE)) //
), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STEREOTYPE", "(\\<\\<.+\\>\\>)") //
)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), RegexLeaf.end());
}
private static ColorParser color() {
return ColorParser.simpleColor(ColorType.BACK);
}
private static ColorParser color2() {
return ColorParser.simpleColor(ColorType.BACK, "COLOR2");
}
// private static final String CODE_CORE = "[\\p{L}0-9_.]+|\\(\\)[%s]*[\\p{L}0-9_.]+|\\(\\)[%s]*[%g][^%g]+[%g]|:[^:]+:|\\([^()]+\\)|\\[[^\\[\\]]+\\]";
// public static final String CODE = "(" + CODE_CORE + ")";
// public static final String CODE_WITH_QUOTE = "(" + CODE_CORE + "|[%g].+?[%g])";
//
// private static final String DISPLAY_CORE = "[%g].+?[%g]|:[^:]+:|\\([^()]+\\)|\\[[^\\[\\]]+\\]";
// public static final String DISPLAY = "(" + DISPLAY_CORE + ")";
// public static final String DISPLAY_WITHOUT_QUOTE = "(" + DISPLAY_CORE + "|[\\p{L}0-9_.]+)";
@Override
final protected boolean isForbidden(CharSequence line) {
if (line.toString().matches("^[\\p{L}0-9_.]+$")) {
return true;
}
return false;
}
@Override
protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) {
String codeRaw = arg.getLazzy("CODE", 0);
final String displayRaw = arg.getLazzy("DISPLAY", 0);
final String symbol = "interface";
final LeafType type;
final USymbol usymbol;
type = LeafType.DESCRIPTION;
usymbol = USymbol.getFromString(symbol, diagram.getSkinParam());
final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw);
final Ident ident = diagram.buildLeafIdent(idShort);
final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort);
if (!diagram.V1972() && diagram.isGroup(code)) {
return CommandExecutionResult.error("This element (" + code.getName() + ") is already defined");
}
if (diagram.V1972() && diagram.isGroupStrict(ident)) {
return CommandExecutionResult.error("This element (" + ident.getName() + ") is already defined");
}
String display = displayRaw;
if (display == null) {
display = code.getName();
}
display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(display);
final String stereotype = arg.getLazzy("STEREOTYPE", 0);
if (existsWithBadType3(diagram, code, ident, type, usymbol)) {
return CommandExecutionResult.error("This element (" + code.getName() + ") is already defined");
}
final IEntity entity = diagram.getOrCreateLeaf(ident, code, type, usymbol);
entity.setDisplay(Display.getWithNewlines(display));
entity.setUSymbol(usymbol);
if (stereotype != null) {
entity.setStereotype(new Stereotype(stereotype, diagram.getSkinParam().getCircledCharacterRadius(),
diagram.getSkinParam().getFont(null, false, FontParam.CIRCLED_CHARACTER),
diagram.getSkinParam().getIHtmlColorSet()));
}
final String urlString = arg.get("URL", 0);
if (urlString != null) {
final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), ModeUrl.STRICT);
final Url url = urlBuilder.getUrl(urlString);
entity.addUrl(url);
}
Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet());
final HtmlColor lineColor = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("LINECOLOR", 1));
if (lineColor != null) {
colors = colors.add(ColorType.LINE, lineColor);
}
entity.setColors(colors);
// entity.setSpecificColorTOBEREMOVED(ColorType.BACK,
// diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR",
// 0)));
return CommandExecutionResult.ok();
}
public static boolean existsWithBadType3(AbstractEntityDiagram diagram, Code code, Ident ident, LeafType type,
USymbol usymbol) {
if (diagram.V1972()) {
if (diagram.leafExistSmart(ident) == false) {
return false;
}
final ILeaf other = diagram.getLeafSmart(ident);
if (other.getLeafType() != type) {
return true;
}
if (usymbol != null && other.getUSymbol() != usymbol) {
return true;
}
return false;
} else {
if (diagram.leafExist(code) == false) {
return false;
}
final ILeaf other = diagram.getLeaf(code);
if (other.getLeafType() != type) {
return true;
}
if (usymbol != null && other.getUSymbol() != usymbol) {
return true;
}
return false;
}
}
private char getCharEncoding(final String codeRaw) {
return codeRaw != null && codeRaw.length() > 2 ? codeRaw.charAt(0) : 0;
}
}

View File

@ -71,24 +71,24 @@ public class PSystemDonors extends AbstractPSystem {
private static final int COLS = 6;
private static final int FREE_LINES = 6;
public static final String DONORS = "6_C902mFU3XMJbc44wzsvvsjcZxOY0eHBCyJYiF08fxk1iGVuDxfSR-H_YAwqhrlcX5jsPhYFACe5WGz"
+ "tYRN3DlSsmEncfYlaZlpHhymBmn9Q4C2N8Sx8ZvLXfGWbehklqpSdcuT5-9WXmgX75BSio7JYHWNmTFc"
+ "zIrbijRaGSBf_cywBUuU2c6MPYkSZqQe_GEd6AjhBdS_Yheqwk8kLQrkXHhJgOjZk2eqogi7lhPGCYey"
+ "DCvtG8jPCTb3f4JhnX6YHcU6aPgqpiaJUMh_KI-WJUToJOcS2UKnIYIwRYkTsNVG_OBabn0AkM2Bm08g"
+ "7BuJj7Ljn4X2CcWOwibeRBbconCt377enBxyer7KkATaUXhQ965Ne2JgQnoGz4eZMiJiz6P09SzeCQD9"
+ "KbVcJNXy7PQcQ1qqt0iMOPQq2Qi9v4te2P_mLPTCpl5ILF2cfoIFPflGKDasuDxCwDjSInBbVxSnS-Qx"
+ "HxLvIcUhgut_sHnorvHLosz66-qSmRs_BQHWSR50VW2zD2SgoPzbtrX8GhYtqWiPdFklNAC8d3qo5HR_"
+ "4LjQe__MbMniHIoF6mjyN5zNcfB1bbo5N8Q-fbNABPqlb9IcnkSXZvQEpoJMbCpgdQUFKJAtyl-xOILc"
+ "Li90LwQORRfUK3HMiPgUR4m4fq7tXjm4o0ke3fDRULWznA_p0Pct9ICHkGt9AEJhB-MGYnGciAO7Iim0"
+ "5ayfxI69U212JJlGsr1fHTeYzDjDUjgMZ8Nxf3yyxfePepoYaneduO-5mE669JLlfhkqxz4JU8ulpwlk"
+ "8tMi0bpBlJTSfFeP3AmhBHY1r1tHsFUoIyAXWH9Px2Ll3V4zmneN3ps-u4mM7M96c-EGvQ5oEncjz1R3"
+ "koP3tocJpTkhlyWRIBm8wo4T6OtW_M7oI2qkaOHqi1m_Mm1Yvk8LkrBWcaBLBJidc-iKfhglFeHAyEDy"
+ "0gFoBJp3MElkHN46DCgS4_DUMVFHU0qfFXPGFOS8MjA9CaTAKQQjPMJCMeEUWzR1zbFT5lJR-5R3gaBn"
+ "RH7TiTW0Q7t6DAFtS0Cy4Ifg5Rpaf330Nxz-JG_6EiJujPVDY8DaSqaCeGAQqtznMfflnz0IrblqVzks"
+ "lQsSF_zUHtPm6esxhog8deB0_rsKd8EchlEf-c_WWoJYW9MOjN4IAo-DtWWa9JYE3rPHJqqpwdToHhaj"
+ "jUYTnuSg_NQgn84vDoo_QAKeXoznohQtXbEbP3_-nk8aXuP_YYfhChagfJKnefhOsL6Sfx7lKOgxhbf1"
+ "17FW4e6zN_zqckOXO_QBbJaC1qD-FY9T3k6kXRMOriPfWVtYhEyjRLqouN_92ByKQzhEwc6wSVnRsWNA"
+ "lXr9mdWKi7PAd2Ua1lyb0m00";
public static final String DONORS = "6qOA02mFU3XMJbc44wzsfuUeUc2VR6qyRpkVqESmi8ZJNK3y1jWxFUutqbz4LxhtJJEYBLjJd6SKnOAW"
+ "nzlacc6RUtiWLXFpLN9dtkWNveKX2Mr8WEjmHyIdof0IVEycQbqbNzfRkOJbCk0By7OGIqNtNoPkJxUE"
+ "2t6mGuLG3YdksVytfxRkNbM58LrMhTFH5Ih0gi0ZOdS_QdDfrCPtKvlUX09qAd45DrMLy7hZfYBDuAxZ"
+ "N3gqw1GZpI8bNZUE43SwC_JKfF1ByaH6vZ_g1RJfNAufaJEXF4Q9HDTjVqVs7PG_BNb1H48ks2ImW4gE"
+ "m0cANXinFY8oQEZgIMDihcRC4oyCAUZ4lloZKTIufsHw6bfyH5s1ahYlSG3Iatgqu6nXDA2i9rkCQ9Ag"
+ "C_CbtByEorDwpJJS3nPHbhG9hYd8cz0JFk6hBfcSuwMeuIy_JVB8rmGQBbi6t9iEVOjhaqIvdMsQkVDf"
+ "KssUqjdgQkD_DeVSDMNLyfjHH2D7SEzl2obON5e0FmAzD2SgoPzb7rd8Xd1jfHVITQvUkHeHBjcGgM9T"
+ "_eWjh-d_wE9ocn7Bus2HpvwlCqt9G4jTYLo6lj3AvhRE5qfAK-FpoAEbupFXcgpPlUFqFihcDF-_RYip"
+ "un80dPbY5dJze1YifjNmP0CHc1QwFUGcG5v0TPZSoiFg4R_E1mHlAYCHXGrAB-Hzi-MGYnGciBmxIdG0"
+ "9ayfxU4Zve48HUs2daQLUgGiGh_TfATjsPYuJ_fWVzPW3FAOpjOu2Nyi18umpAf5ixvR-m8z1LUvNEPL"
+ "Ty_Fgm3M5juBBbBz90DwfGKZ8hL6DFQzx99mQA0mYxFahI6-PrXZvQ7x1vpMeatCQ3CVCWsI6ybgfRSO"
+ "tZKP_kOXgzcnMkGvi4V4PaWpenMyFveyKejBV4Hqi9mWMm0Ivk8LU_72dIjLkPoSRAvJcEgnMWiLyhla"
+ "4rYgmCBJWxNo7i0piaUnSpZlbJKVZTUGuda1bNAOe2wTA7Ea56NQMY33rghrRBGEjf_gM31lurivAmw5"
+ "jqrqrhX1mHGsdHAuqOYHA2SQ5NhPay80V_twbNfoKmSPl_QooJYriY6MGgMSByiNfw3nTWoj-rlqVzks"
+ "lQsSF_zUDvkSUkFjAmNGSv0S_nxAhAEBajNzDFWRR9WCSC1AAjeuuSf3Isy5aXRinpk3gFFjZEQTd2ot"
+ "f1QzSlvGsT_zoIm7LtF3YejwYdBu4gTiUsi45M_x_ZS6MpaC_4LKcPFXwgzUBICAnFOsuZoDVOzIt5cL"
+ "11BCZii4pdxrqscQXupPHoYp7Yu2-Vc8T3c4XnRKqhGuJWHMnHdUUwTroOJ_9JU9kEgdh2tLGq_ZL6vg"
+ "5sZuTYMA6qQ1uI9cny3uTfEJ5RZvfeTwgBOVwVGN4oSkAeRTtdDs0W00";
/*
* Special thanks to our sponsors and donors:
@ -110,8 +110,8 @@ public class PSystemDonors extends AbstractPSystem {
final List<TextBlock> cols = getCols(getDonors(), COLS, FREE_LINES);
return new UDrawable() {
public void drawU(UGraphic ug) {
final TextBlockBackcolored header = GraphicStrings.createBlackOnWhite(Arrays
.asList("<b>Special thanks to our sponsors and donors !"));
final TextBlockBackcolored header = GraphicStrings
.createBlackOnWhite(Arrays.asList("<b>Special thanks to our sponsors and donors !"));
header.drawU(ug);
final StringBounder stringBounder = ug.getStringBounder();
ug = ug.apply(new UTranslate(0, header.calculateDimension(stringBounder).getHeight()));
@ -143,7 +143,8 @@ public class PSystemDonors extends AbstractPSystem {
private List<String> getDonors() throws IOException {
final List<String> lines = new ArrayList<String>();
final Transcoder t = new TranscoderImpl(new AsciiEncoder(), new StringCompressorNone(), new CompressionBrotli());
final Transcoder t = new TranscoderImpl(new AsciiEncoder(), new StringCompressorNone(),
new CompressionBrotli());
final String s = t.decode(DONORS).replace('*', '.');
final StringTokenizer st = new StringTokenizer(s, BackSlash.NEWLINE);
while (st.hasMoreTokens()) {

View File

@ -42,298 +42,209 @@ import java.util.List;
public class QuoteUtils {
static private final List<String> quotes = Arrays
.asList("Ur'f qrnq, Wvz.",
"Ol Tenogune'f unzzre, ol gur fbaf bs Jbeina, lbh funyy or niratrq.",
"Ebnqf? Jurer jr'er tbvat, jr qba'g arrq ebnqf.",
"Gur gvzr vf bhg bs wbvag.",
"P'rfg phevrhk purm yrf znevaf pr orfbva qr snver qrf cuenfrf.",
"V'z gnyxvat nobhg gur bgure Crgre, gur bar ba gur bgure fvqr.",
"Znl gur Sbepr or jvgu lbh!",
"Arire tvir hc, arire fheeraqre...",
"Unfgn yn ivfgn, onol.",
"Url, Qbp, jr orggre onpx hc. Jr qba'g unir rabhtu ebnq gb trg hc gb 88.",
"Terrgvatf, Cebsrffbe Snyxra. Funyy jr cynl n tnzr?",
"V pna'g punatr gur ynj bs culfvpf!",
"N fgenatr tnzr. Gur bayl jvaavat zbir vf abg gb cynl.",
"V'z gur Tngrxrrcre, ner lbh gur Xrlznfgre?",
"V nz gur Znfgre Pbageby Cebtenz. Ab bar Hfre jebgr zr.",
"Yvsr? Qba'g gnyx gb zr nobhg yvsr.",
"V nyjnlf gubhtug fbzrguvat jnf shaqnzragnyyl jebat jvgu gur havirefr.",
"N ebobg znl abg vawher n uhzna orvat be, guebhtu vanpgvba, nyybj n uhzna orvat gb pbzr gb unez.",
"Fheeraqre znl or bhe bayl bcgvba.",
"Fvk ol avar. Sbegl gjb.",
"Vg'f yvsr, Wvz, ohg abg nf jr xabj vg.",
"Qba'g Cnavp!",
"Jung qb lbh zrna? Na Nsevpna be Rhebcrna fjnyybj?",
"V arrq lbhe obbgf lbhe pybgurf naq lbhe zbgbeplpyr",
"Lbh sbetbg gb fnl cyrnfr...",
"Lbh unir qvrq bs qlfragrel.",
"Jbhyqa'g lbh cersre n avpr tnzr bs purff?",
"Jura lbh unir ryvzvangrq gur vzcbffvoyr, jungrire erznvaf, ubjrire vzcebonoyr, zhfg or gur gehgu.",
"V xabj abj jul lbh pel. Ohg vg'f fbzrguvat V pna arire qb.",
"Erfvfgnapr vf shgvyr. Lbh jvyy or nffvzvyngrq.",
"Nalguvat qvssrerag vf tbbq.",
"Penpxrq ol Nyqb Erfrg naq Ynherag Ehrvy.",
"V'z obgu. V'z n pryroevgl va na rzretrapl.",
"Qb lbh xabj guvf terng terng cbyvfu npgbe, Wbfrcu Ghen?",
"Gb vasvavgl naq orlbaq!",
"Fcnpr: gur svany sebagvre...",
"Fhe zba ovyyrg, grarm, l n rpevg Fnvag-Ynmner, p'rfg zrf lrhk bh dhbv ?",
"Gur obl vf vzcbegnag. Ur unf gb yvir.",
"Bapr hcba n gvzr va n tnynkl sne, sne njnl...",
"Naq lbh xabj gurer'f n ybat ybat jnl nurnq bs lbh...",
"Na nyyretl gb bkltra? Ryz oyvtug?",
"Ohg nybef lbh ner Serapu!",
"A'nv-wr qbap gnag irph dhr cbhe prggr vasnzvr?",
"Fbzrguvat vf ebggra va gur Fgngr bs Qraznex.",
"Url, jung qb lbh jnag? Zvenpyrf?",
"1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ",
"Jung gur uryy vf n tvtnjngg?",
"V arrq n inpngvba.",
"Ba qrienvg wnznvf dhvggre Zbagnhona.",
"Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...",
"Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...",
"Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag",
"Ornz zr hc, Fpbggl.",
"Gurer vf ab fcbba.",
"Sbyybj gur juvgr enoovg.",
"Arire fraq n uhzna gb qb n znpuvar'f wbo.",
"Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.",
"V qba'g guvax jr'er va Xnafnf nalzber.",
"Yhxr, V nz lbhe sngure.",
"Oybbq, Fjrng naq Grnef",
"Ubhfgba, jr unir n ceboyrz.",
"Xrlobneq snvyher, cerff nal xrl gb pbagvahr",
"Ovt zvfgnxr!",
"Ubj znal HZY qrfvtaref qbrf vg gnxr gb punatr n yvtugohyo ?",
"Qb lbh yvxr zbivrf nobhg tynqvngbef ?",
"Gur fcvevg bs yrneavat vf n ynfgvat sebagvre.",
"Vg vf phevbhf sbe fnvybef guvf arrq sbe znxvat fragraprf.",
"Ubcvat sbe gur orfg, ohg rkcrpgvat gur jbefg",
"Gur jvyy gb tb ba jura V'z uheg qrrc vafvqr.",
"Vs vg oyrrqf, jr pna xvyy vg.",
"Ubhfgba, V unir n onq srryvat nobhg guvf zvffvba.",
"Znzn nyjnlf fnvq yvsr jnf yvxr n obk bs pubpbyngrf. Lbh arire xabj jung lbh'er tbaan trg.",
"Ol gur jnl, vf gurer nalbar ba obneq jub xabjf ubj gb syl n cynar?",
"Qnir, guvf pbairefngvba pna freir ab checbfr nalzber. Tbbqolr.",
"Vg pna bayl or nggevohgnoyr gb uhzna reebe.",
"Ybbxf yvxr V cvpxrq gur jebat jrrx gb dhvg fzbxvat.",
"Lbh uhznaf npg fb fgenatr. Rirelguvat lbh perngr vf hfrq gb qrfgebl.",
"Jurer qvq lbh yrnea ubj gb artbgvngr yvxr gung?",
"Fve, ner lbh pynffvsvrq nf uhzna?",
"Jr'er abg tbaan znxr vg, ner jr?",
"Vg'f va lbhe angher gb qrfgebl lbhefryirf.",
"Gur zber pbagnpg V unir jvgu uhznaf, gur zber V yrnea.",
"Jbhyq vg fnir lbh n ybg bs gvzr vs V whfg tnir hc naq jrag znq abj?",
"Ernyvgl vf serdhragyl vanpphengr.",
"Qba'g oryvrir nalguvat lbh ernq ba gur arg. Rkprcg guvf. Jryy, vapyhqvat guvf, V fhccbfr.",
"N phc bs grn jbhyq erfgber zl abeznyvgl.",
"Nalguvat gung guvaxf ybtvpnyyl pna or sbbyrq ol fbzrguvat ryfr gung guvaxf ng yrnfg nf ybtvpnyyl nf vg qbrf.",
"Va na vasvavgr Havirefr nalguvat pna unccra.",
"Fbzrgvzrf vs lbh erprvirq na nafjre, gur dhrfgvba zvtug or gnxra njnl.",
"Cyrnfr pnyy zr Rqqvr vs vg jvyy uryc lbh gb erynk.",
"V qba'g oryvrir vg. Cebir vg gb zr naq V fgvyy jba'g oryvrir vg.",
"Gbgnyyl znq, hggre abafrafr. Ohg jr'yy qb vg orpnhfr vg'f oevyyvnag abafrafr.",
"Guvf fragrapr vf abg gehr.",
"V jbhyq engure qvr fgnaqvat guna yvir ba zl xarrf.",
"Lbh ner orvat jngpurq.",
"Qvq lbh srrq gurz nsgre zvqavtug?",
"Ubj qb lbh rkcynva fpubby gb uvture vagryyvtrapr?",
"Crbcyr fbzrgvzrf znxr zvfgnxrf.",
"Ybbx, V qba'g unir gvzr sbe n pbairefngvba evtug abj.",
"Nyy ceboyrzf va pbzchgre fpvrapr pna or fbyirq ol nabgure yriry bs vaqverpgvba",
"...rkprcg sbe gur ceboyrz bs gbb znal yriryf bs vaqverpgvba",
"V xabj orpnhfr V ohvyg vg",
"Rira gur fznyyrfg crefba pna punatr gur pbhefr bs gur shgher.",
"Vs lbh ner n sevraq, lbh fcrnx gur cnffjbeq, naq gur qbbef jvyy bcra.",
"Lbh Funyy Abg Cnff",
"73.6% Bs Nyy Fgngvfgvpf Ner Znqr Hc",
"Jr pna arvgure pbasvez abe qral gung guvf vf penfuvat",
"Jura gur orngvat bs lbhe urneg rpubrf gur orngvat bs gur qehzf",
"Arire gehfg n pbzchgre lbh pna'g guebj bhg n jvaqbj",
"Lrnu, V'z pnyz. V'z n pnyz crefba. Vf gurer fbzr ernfba V fubhyqa'g or pnyz?",
"Rirelobql whfg fgnl pnyz. Gur fvghngvba vf haqre pbageby.",
"Uvccl, lbh guvax rirelguvat vf n pbafcvenpl.",
"Gurfr thlf ner nobhg nf zhpu sha nf n gnk nhqvg.",
"Gurer vf fbzrguvat qbja gurer! Fbzrguvat abg hf.",
"V fnj n tyvzcfr bs zl shgher naq rirelguvat'f punatrq sbe zr abj.",
"Va fcnpr ab bar pna urne lbh fpernz",
"V pna'g yvr gb lbh nobhg lbhe punaprf, ohg... lbh unir zl flzcnguvrf.",
"Gurer vf na rkcynangvba sbe guvf, lbh xabj.",
"V'z nsenvq V unir fbzr onq arjf.",
"Qb zr n snibhe. Qvfpbaarpg zr. V pbhyq or erjbexrq, ohg V'yy arire or gbc bs gur yvar ntnva.",
"Gnxr vg rnfl, qba'g chfu gur yvggyr ohggba ba gur wblfgvpx!",
"V'z n irel cevingr crefba.",
"Gb fphycg na ryrcunag sebz n ovt oybpx bs zneoyr, whfg xabpx njnl nyy gur ovgf gung qba'g ybbx yvxr na ryrcunag.",
"Jub fnvq lbh pbhyq gnyx gb zr? Unir V tbg fbzrguvat ba zl snpr ?",
"Jr'ir orra guebhtu jbefg",
"Havgrq jr fgnaq",
"Jr funyy arire fheeraqre",
"Nofbyhgr ubarfgl vfa'g nyjnlf gur zbfg qvcybzngvp abe gur fnsrfg sbez bs pbzzhavpngvba jvgu rzbgvbany orvatf.",
"Vg'f... pbzcyvpngrq.",
"Qb abg bcra hagvy 1985",
"V fgvyy zrff hc ohg V'yy whfg fgneg ntnva",
"V jba'g tvir hc, ab V jba'g tvir va; Gvyy V ernpu gur raq; Naq gura V'yy fgneg ntnva",
"V jnaan gel rira gubhtu V pbhyq snvy",
"Fbzrgvzrf jr pbzr ynfg ohg jr qvq bhe orfg",
"Vs lbh frr fbzrguvat, fnl fbzrguvat",
"Va gurbel gurer vf ab qvssrerapr orgjrra gurbel naq cenpgvpr. Ohg, va cenpgvpr, gurer vf.",
"Vs V pnaabg oevat lbh pbzsbeg gura ng yrnfg V oevat lbh ubcr",
"Jr nyy zhfg yrnea sebz fznyy zvfsbeghar, pbhag gur oyrffvatf gung ner erny",
"Cercner Guerr Frnyrq Rairybcrf...",
"Lbh xabj gung guvat lbh whfg qvq? Qba'g qb gung",
"Vg gbbx zr n ybat gvzr gb haqrefgnaq gung vs lbh jnag gb qb guvf wbo jryy lbh unir gb fgnl qrgnpurq.",
"Qb lbh yvxr lbhe zbeavat grn jrnx be fgebat ?",
"Jvagre vf pbzvat",
"Jung sbbyf gurfr zbegnyf or!",
"Fbzrguvat jvpxrq guvf jnl pbzrf.",
"V guvax V trg vg, jung jnf vg? Cbxre Avtug? Onpurybe Cnegl?",
"Vg'f nyevtug gb or fpnerq. Erzrzore, gurer vf ab pbhentr jvgubhg srne.",
"Guebhtu ernqvarff naq qvfpvcyvar jr ner znfgref bs bhe sngr.",
"Jvgu terng cbjre pbzrf terng erfcbafvovyvgl",
"Vs n znpuvar pna yrnea gur inyhr bs uhzna yvsr, znlor jr pna gbb ?",
"Bayl tbvat sbejneq 'pnhfr jr pna'g svaq erirefr.",
"Jr'er abg tbaan fvg va fvyrapr, jr'er abg tbaan yvir jvgu srne",
"Oba, qnaf qvk zvahgrf wr abhf pbafvqrer pbzzr qrsvavgvirzrag creqhf.",
"Pn fren fherzrag ovra dhnaq pn fren svav.",
"Vg'f gur ynfg cvrpr bs gur chmmyr ohg lbh whfg pna'g znxr vg svg",
"Qbpgbe fnlf lbh'er pherq ohg lbh fgvyy srry gur cnva",
"Vf negvsvpvny vagryyvtrapr gur rknpg bccbfvgr bs angheny fghcvqvgl ?",
"Sbeprzrag, pn qrcraq, pn qrcnffr...",
"Gurer'f orra n cnggrea bs vafhobeqvangr orunivbe erpragyl.",
"Ab. Jr ner abg na rssrpgvir grnz.",
"Bhe wbo vf abg gb erzrzore... erzrzore?",
"Guvf vf zvffvba pbageby. Ubj ner lbh nyy qbvat guvf ybiryl zbeavat?",
"Vs lbh pbhyq frr lbhe jubyr yvsr ynvq bhg va sebag bs lbh, jbhyq lbh punatr guvatf?",
"Vf guvf n aba-mreb-fhz tnzr?",
"Abj gung'f n cebcre vagebqhpgvba.",
"Rirelguvat unf punatrq naq vg jba'g fgbc punatvat nalgvzr fbba.",
"Jung znxrf lbh qvssrerag znxrf lbh qnatrebhf",
"Qviretrapr vf rkgerzryl qnatrebhf",
"V'z Qviretrag. Naq V pna'g or pbagebyyrq",
"Znl gur bqqf or rire va lbhe snibe",
"Ab WninFpevcg senzrjbexf jrer perngrq qhevat gur jevgvat bs guvf zrffntr.",
"P'rfg cerffr-cherr dhv g'nf vagreebtr ?",
"Ybbx, nygreangvir snpgf ner abg snpgf. Gurl'er snyfrubbqf",
"Guvf vf abg n penfu, guvf vf zber bs na nygreangvir erfhyg.",
"Lbh yrnearq gb cebtenz va SBEGENA qvqa'g lbh?",
"Guvf oht vf n srngher nf qrfpevorq ol gur znexrgvat qrcnegzrag.",
"Abg rirelobql haqrefgnaqf gur uhzbe bs cebtenzzref.",
"Vs lbh yvir na beqvanel yvsr, nyy lbh'yy unir ner beqvanel fgbevrf.",
"Pbzr jvgu zr vs lbh jnag gb yvir",
"Gh y'nf gebhir bh pryhv-yn ?",
"Qb lbh ernyyl guvax lbh unir n punapr ntnvafg hf, Ze. Pbjobl?",
"Nggragvba, jubrire lbh ner, guvf punaary vf erfreirq sbe rzretrapl pnyyf bayl.",
"Qbrf vg fbhaq yvxr V'z beqrevat n cvmmn? ",
"Jr'er tbaan arrq fbzr zber SOV thlf, V thrff.",
"Trg ernql sbe ehfu ubhe",
"V unir gb jnea lbh, V'ir urneq eryngvbafuvcf onfrq ba vagrafr rkcrevraprf arire jbex.",
"Nalguvat ryfr ohg gur onfrzrag gung'yy xrrc guvf ryringbe sebz snyyvat?",
"Vf guvf grfgvat jurgure V'z n ercyvpnag be n yrfovna, Ze. Qrpxneq? ",
"V'ir qbar... dhrfgvbanoyr guvatf",
"Jbhyq lbh... yvxr gb or hctenqrq?",
"Snhg erpbaanvger... p'rfg qh oehgny!",
"Fv ba oevpbynvg cyhf fbhirag, ba nhenvg zbvaf yn grgr nhk orgvfrf.",
"Wr invf yhv snver har beqbaanapr, rg har frirer...",
"Znvf vy pbaanvg cnf Enbhy, pr zrp! vy in nibve ha erirvy cravoyr.",
"W'nv ibhyh rger qvcybzngr n pnhfr qr ibhf gbhf, rivgre dhr yr fnat pbhyr.",
"Vtabenapr oevatf punbf, abg xabjyrqtr.",
"Yrneavat vf nyjnlf n cnvashy cebprff.",
"V'z fbeel, ner lbh sebz gur cnfg ?",
"Unir lbh gevrq gheavat vg bss naq ba ntnva ?",
"Vs lbh qba'g xabj jurer lbh ner tbvat nal ebnq pna gnxr lbh gurer",
"Xrrc pnyz naq cerff Pgey-Nyg-Qry",
"Vs lbh glcr Tbbtyr vagb Tbbtyr, lbh pna oernx gur Vagrearg.",
"V unir cneg bs n cyna.",
"V'z cerggl fher gur nafjre vf: V nz Tebbg.",
"Nalguvat gung pna cbffvoyl tb jebat, qbrf",
"Cyhf pn engr, cyhf ba n qr punapr dhr pn znepur",
"Fb V thrff gur sbeghar gryyre'f evtug...",
"Jura rirelguvat'f tbar jebat fbzrubj...",
"V qba'g jnag gb yvir ba guvf cynarg nalzber",
"Oba, p'rfg y'urher bh yrf fbhiravef fr enzrarag...",
"Fhpprff pbafvfgf bs tbvat sebz snvyher gb snvyher jvgubhg ybff bs raguhfvnfz",
"Vs lbh'er tbvat guebhtu uryy, xrrc tbvat",
"Jre xnzcsg, xnaa ireyvrera. Jre avpug xnzcsg, ung fpuba ireybera.",
"P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.",
"Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.",
"Pyrneyl, lbh unir arire zrg n jbzna.",
"Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag",
"Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf",
"L'n dhrydhrf dhrfgvbaf dhv erfgrag fbhf fvyrapr...",
"Vs gurer vf ab fbyhgvba, gurer vf ab ceboyrz",
"V unir zrzbevrf, ohg V pna'g gryy vs gurl'er erny.",
"L n pbzzr ha tbhg nzre ra abhf",
"L n qrf fvyraprf dhv qvfrag ornhpbhc",
"V frr lbh'ir unq fbzr qvfpvcyvanel ceboyrzf va gur cnfg.",
"Cercnengvba vf gur xrl gb fhpprffshy, vapbafcvphbhf gvzr geniry.",
"Vg'f arire gbb yngr gb or jub lbh zvtug unir orra.",
"Rg cbhe nyyre purm Zvpxrl vyf ibag fherzrag cnf pbafgehver har tner gbhf yrf 100 zrgerf",
"Nyy lbhe onfr ner orybat gb hf",
"Znqr ba Rnegu ol uhznaf",
"Jvaaref Qba'g Hfr Qehtf",
"Lbh xabj jung fhecevfrq zr gur zbfg? Vg jnfa'g zrrgvat gurz. Vg jnf zrrgvat lbh.",
"Va jne gurer ner ab jvaaref, bayl jvqbjf",
"Vs lbh guvax guvf Havirefr vf onq, lbh fubhyq frr fbzr bs gur bguref",
"Cnp-Zna'f n onq thl?",
"Zl ernyvgl vf whfg qvssrerag guna lbhef",
"L'ra n dh'bag rffnlr, vyf bag rh qrf ceboyrzrf",
"Gb ree vf uhzna, ohg gb ernyyl sbhy guvatf hc erdhverf n pbzchgre.",
"Vs lbh oryvrir rirelguvat lbh ernq, lbh orggre abg ernq",
"Gurer vf ab ceboyrz fb onq lbh pna'g znxr vg jbefr",
"Pn p'rfg qh ybheq... Ha gehp qr znynqr.",
"V qb abg guvax, gung V guvax.. V guvax.",
"Gurer ner cynprf ybjre guna gur onfrzrag",
"Gurer ner 10 glcrf bs crbcyr: gubfr jub haqrefgnaq ovanel, naq gubfr jub qba'g.",
"Cyrnfr zvaq gur tnc orgjrra gur genva naq gur cyngsbez",
"Nfuvzbgb av tb-puhv xhqnfnv",
"Vs lbh'er erprvivat guvf genafzvffvba, znxr ab nggrzcg gb pbzr gb vgf cbvag bs bevtva.",
"Obl, qb V ungr orvat evtug nyy gur gvzr!",
"Jub funirf gur oneore jub funirf nyy gur zra jub qba'g funir gurzfryirf?",
"V haqrefgnaq uhzna rzbgvbaf, nygubhtu V qb abg srry gurz zlfrys.",
"Lbh qvqa'g fnl gur zntvp jbeq!",
"Gurer vf ab ceboyrz gung n ynpx bs fbyhgvba jba'g svanyyl erfbyir.",
"V unir n inthr srryvat bs vzcraqvat zvfsbeghar.",
"Jura lbh'er va gebhoyr, pbashfr rirelguvat",
"Jung gur uryy vf Cebwrpg Ryebaq?",
"Qba'g qvt hc gur ovt obk bs cyhgbavhz, Znex",
"Uryc vf bayl 140 zvyyvba zvyrf njnl.",
"P unf gur fcrrq naq rssvpvrapl bs nffrzoyl ynathntr pbzovarq jvgu ernqnovyvgl bs nffrzoyl ynathntr",
"Crey vf gur bayl ynathntr gung ybbxf gur fnzr orsber naq nsgre EFN rapelcgvba",
"Gur zber vg snvyf, gur zber yvxryl vg vf gung vg jvyy jbex",
"V ubcr V qvqa'g gnxr hc gbb zhpu bs lbhe gvzr", "Lbh'er tbaan arrq n ovttre obng",
"Dhnaq ibhf rgrf rzorgrf, rzoebhvyyrm gbhg", "Gurer nva'g ab phevat jung'f jebat jvgu gung guvat",
"Vs lbh cevpx hf, qb jr abg oyrrq?", "V qvq lbhe wbo bapr - V jnf tbbq ng vg.",
"Vyf cbheenvrag snver har fryrpgvba nh fgnaqneq...", "Gung'f ab jnl gb gerng n sevraq.",
"Ubjrire ornhgvshy gur fgengrtl, lbh fubhyq bppnfvbanyyl ybbx ng gur erfhygf",
"Qba'g svk vg vs vg'f abg oebxra",
"Fhqqrayl V'z gnxvat fhttrfgvbaf sebz fbzr fgebat-nez zna jvgu na VD bs zvahf 50.",
"Fur ehvaf rirelguvat fur'f va. Fur ehvaf guvatf fur'f abg rira va.",
"Byvir, V guvax lbh fubhyq xabj guvf: lbh'er n ubeevoyr npgerff.",
"Lbh'er yngr! Qb lbh unir ab pbaprcg bs gvzr ?",
"P'zba zna, yrg'f qb fbzrguvat gung ernyyl pbbxf.",
"Nh sbaq, znvagranag, yrf qvcybzngrf ceraqenvrag cyhgbg yr cnf fhe yrf ubzzrf q'npgvba.",
"Whfg zragnyyl gubhtu... ner lbh bxnl ?", "Jr xabj fur'f bxnl orpnhfr fur'f oybaq",
"Gh oyhssrf Znegbav", "Lbh thlf ner trggvat cnvq?",
"Gurer'f n erq guvatl zbivat gbjneqf gur terra guvatl... V guvax jr'er gur terra guvatl",
"Nyy flfgrzf ner shapgvbavat Pbzznaqre", "V erzrzore gung fbhaq! Gung'f n onq fbhaq!",
"V xabj vg'f uneq sbe lbh gb haqrefgnaq rira fubeg fragraprf",
"Gur havirefr vf shyy bs vagryyvtrag yvsr. Vg'f whfg orra gbb vagryyvtrag gb pbzr urer.",
"Uryyb, jbhyq lbh yvxr gb urne n GPC wbxr ?",
"Rirel snvel gnyr arrqf n tbbq byq-snfuvbarq ivyynva",
"Fvapr gurer'f ab pbapyhfvba gb gur cnenqbk gurbel, gurer'f ab jnl gb cebir gurer'f ab cnenqbk.",
"Gnxr zr guebhtu gur qnexarff gb gur oernx bs gur qnl",
"Vg znxrf gur gehgu rira zber vapbzcerurafvoyr orpnhfr rirelguvat vf arj",
"V qba'g xabj ubj ohg V fhqqrayl ybfr pbageby", "Gurer ner zbzragf jura V guvax V'z tbvat penml",
"Jbhyq gung vg jrer fb fvzcyr", "Pnyy gung n xavsr? Guvf vf n xavsr.",
"Fhe y'bprna qh grzcf dhv tyvffr...", "Snvyher serr bcrengvbaf erdhver rkcrevrapr jvgu snvyher.",
"Pngnfgebcur vf nyjnlf whfg nebhaq gur pbeare.",
"Orjner bs ohtf va gur nobir pbqr; V unir bayl cebirq vg pbeerpg, abg gevrq vg",
"V'z abg n erny cebtenzzre. V guebj gbtrgure guvatf hagvy vg jbexf gura V zbir ba",
"#qrsvar DHRFGVBA ((oo)||!(oo))", "Pbzchgref ner hfryrff. Gurl pna bayl tvir lbh nafjref",
"Gur Vagrearg? Vf gung guvat fgvyy nebhaq?",
"Va beqre gb haqrefgnaq erphefvba, bar zhfg svefg haqrefgnaq erphefvba");
static private final List<String> quotes = Arrays.asList("Ur'f qrnq, Wvz.",
"Ol Tenogune'f unzzre, ol gur fbaf bs Jbeina, lbh funyy or niratrq.",
"Ebnqf? Jurer jr'er tbvat, jr qba'g arrq ebnqf.", "Gur gvzr vf bhg bs wbvag.",
"P'rfg phevrhk purm yrf znevaf pr orfbva qr snver qrf cuenfrf.",
"V'z gnyxvat nobhg gur bgure Crgre, gur bar ba gur bgure fvqr.", "Znl gur Sbepr or jvgu lbh!",
"Arire tvir hc, arire fheeraqre...", "Unfgn yn ivfgn, onol.",
"Url, Qbp, jr orggre onpx hc. Jr qba'g unir rabhtu ebnq gb trg hc gb 88.",
"Terrgvatf, Cebsrffbe Snyxra. Funyy jr cynl n tnzr?", "V pna'g punatr gur ynj bs culfvpf!",
"N fgenatr tnzr. Gur bayl jvaavat zbir vf abg gb cynl.", "V'z gur Tngrxrrcre, ner lbh gur Xrlznfgre?",
"V nz gur Znfgre Pbageby Cebtenz. Ab bar Hfre jebgr zr.", "Yvsr? Qba'g gnyx gb zr nobhg yvsr.",
"V nyjnlf gubhtug fbzrguvat jnf shaqnzragnyyl jebat jvgu gur havirefr.",
"N ebobg znl abg vawher n uhzna orvat be, guebhtu vanpgvba, nyybj n uhzna orvat gb pbzr gb unez.",
"Fheeraqre znl or bhe bayl bcgvba.", "Fvk ol avar. Sbegl gjb.", "Vg'f yvsr, Wvz, ohg abg nf jr xabj vg.",
"Qba'g Cnavp!", "Jung qb lbh zrna? Na Nsevpna be Rhebcrna fjnyybj?",
"V arrq lbhe obbgf lbhe pybgurf naq lbhe zbgbeplpyr", "Lbh sbetbg gb fnl cyrnfr...",
"Lbh unir qvrq bs qlfragrel.", "Jbhyqa'g lbh cersre n avpr tnzr bs purff?",
"Jura lbh unir ryvzvangrq gur vzcbffvoyr, jungrire erznvaf, ubjrire vzcebonoyr, zhfg or gur gehgu.",
"V xabj abj jul lbh pel. Ohg vg'f fbzrguvat V pna arire qb.",
"Erfvfgnapr vf shgvyr. Lbh jvyy or nffvzvyngrq.", "Nalguvat qvssrerag vf tbbq.",
"Penpxrq ol Nyqb Erfrg naq Ynherag Ehrvy.", "V'z obgu. V'z n pryroevgl va na rzretrapl.",
"Qb lbh xabj guvf terng terng cbyvfu npgbe, Wbfrcu Ghen?", "Gb vasvavgl naq orlbaq!",
"Fcnpr: gur svany sebagvre...", "Fhe zba ovyyrg, grarm, l n rpevg Fnvag-Ynmner, p'rfg zrf lrhk bh dhbv ?",
"Gur obl vf vzcbegnag. Ur unf gb yvir.", "Bapr hcba n gvzr va n tnynkl sne, sne njnl...",
"Naq lbh xabj gurer'f n ybat ybat jnl nurnq bs lbh...", "Na nyyretl gb bkltra? Ryz oyvtug?",
"Ohg nybef lbh ner Serapu!", "A'nv-wr qbap gnag irph dhr cbhe prggr vasnzvr?",
"Fbzrguvat vf ebggra va gur Fgngr bs Qraznex.", "Url, jung qb lbh jnag? Zvenpyrf?",
"1.21 tvtnjnggf! 1.21 tvtnjnggf. Terng Fpbgg! ", "Jung gur uryy vf n tvtnjngg?", "V arrq n inpngvba.",
"Ba qrienvg wnznvf dhvggre Zbagnhona.", "Zl sbepr vf n cyngsbez gung lbh pna pyvzo ba...",
"Gurer'f fbzrguvat jrveq, naq vg qba'g ybbx tbbq...", "Rg evra ienvzrag ar punatr znvf gbhg rfg qvssrerag",
"Ornz zr hc, Fpbggl.", "Gurer vf ab fcbba.", "Sbyybj gur juvgr enoovg.",
"Arire fraq n uhzna gb qb n znpuvar'f wbo.", "Theh zrqvgngvba. Cerff yrsg zbhfr ohggba gb pbagvahr.",
"V qba'g guvax jr'er va Xnafnf nalzber.", "Yhxr, V nz lbhe sngure.", "Oybbq, Fjrng naq Grnef",
"Ubhfgba, jr unir n ceboyrz.", "Xrlobneq snvyher, cerff nal xrl gb pbagvahr", "Ovt zvfgnxr!",
"Ubj znal HZY qrfvtaref qbrf vg gnxr gb punatr n yvtugohyo ?", "Qb lbh yvxr zbivrf nobhg tynqvngbef ?",
"Gur fcvevg bs yrneavat vf n ynfgvat sebagvre.",
"Vg vf phevbhf sbe fnvybef guvf arrq sbe znxvat fragraprf.", "Ubcvat sbe gur orfg, ohg rkcrpgvat gur jbefg",
"Gur jvyy gb tb ba jura V'z uheg qrrc vafvqr.", "Vs vg oyrrqf, jr pna xvyy vg.",
"Ubhfgba, V unir n onq srryvat nobhg guvf zvffvba.",
"Znzn nyjnlf fnvq yvsr jnf yvxr n obk bs pubpbyngrf. Lbh arire xabj jung lbh'er tbaan trg.",
"Ol gur jnl, vf gurer nalbar ba obneq jub xabjf ubj gb syl n cynar?",
"Qnir, guvf pbairefngvba pna freir ab checbfr nalzber. Tbbqolr.",
"Vg pna bayl or nggevohgnoyr gb uhzna reebe.", "Ybbxf yvxr V cvpxrq gur jebat jrrx gb dhvg fzbxvat.",
"Lbh uhznaf npg fb fgenatr. Rirelguvat lbh perngr vf hfrq gb qrfgebl.",
"Jurer qvq lbh yrnea ubj gb artbgvngr yvxr gung?", "Fve, ner lbh pynffvsvrq nf uhzna?",
"Jr'er abg tbaan znxr vg, ner jr?", "Vg'f va lbhe angher gb qrfgebl lbhefryirf.",
"Gur zber pbagnpg V unir jvgu uhznaf, gur zber V yrnea.",
"Jbhyq vg fnir lbh n ybg bs gvzr vs V whfg tnir hc naq jrag znq abj?", "Ernyvgl vf serdhragyl vanpphengr.",
"Qba'g oryvrir nalguvat lbh ernq ba gur arg. Rkprcg guvf. Jryy, vapyhqvat guvf, V fhccbfr.",
"N phc bs grn jbhyq erfgber zl abeznyvgl.",
"Nalguvat gung guvaxf ybtvpnyyl pna or sbbyrq ol fbzrguvat ryfr gung guvaxf ng yrnfg nf ybtvpnyyl nf vg qbrf.",
"Va na vasvavgr Havirefr nalguvat pna unccra.",
"Fbzrgvzrf vs lbh erprvirq na nafjre, gur dhrfgvba zvtug or gnxra njnl.",
"Cyrnfr pnyy zr Rqqvr vs vg jvyy uryc lbh gb erynk.",
"V qba'g oryvrir vg. Cebir vg gb zr naq V fgvyy jba'g oryvrir vg.",
"Gbgnyyl znq, hggre abafrafr. Ohg jr'yy qb vg orpnhfr vg'f oevyyvnag abafrafr.",
"Guvf fragrapr vf abg gehr.", "V jbhyq engure qvr fgnaqvat guna yvir ba zl xarrf.",
"Lbh ner orvat jngpurq.", "Qvq lbh srrq gurz nsgre zvqavtug?",
"Ubj qb lbh rkcynva fpubby gb uvture vagryyvtrapr?", "Crbcyr fbzrgvzrf znxr zvfgnxrf.",
"Ybbx, V qba'g unir gvzr sbe n pbairefngvba evtug abj.",
"Nyy ceboyrzf va pbzchgre fpvrapr pna or fbyirq ol nabgure yriry bs vaqverpgvba",
"...rkprcg sbe gur ceboyrz bs gbb znal yriryf bs vaqverpgvba", "V xabj orpnhfr V ohvyg vg",
"Rira gur fznyyrfg crefba pna punatr gur pbhefr bs gur shgher.",
"Vs lbh ner n sevraq, lbh fcrnx gur cnffjbeq, naq gur qbbef jvyy bcra.", "Lbh Funyy Abg Cnff",
"73.6% Bs Nyy Fgngvfgvpf Ner Znqr Hc", "Jr pna arvgure pbasvez abe qral gung guvf vf penfuvat",
"Jura gur orngvat bs lbhe urneg rpubrf gur orngvat bs gur qehzf",
"Arire gehfg n pbzchgre lbh pna'g guebj bhg n jvaqbj",
"Lrnu, V'z pnyz. V'z n pnyz crefba. Vf gurer fbzr ernfba V fubhyqa'g or pnyz?",
"Rirelobql whfg fgnl pnyz. Gur fvghngvba vf haqre pbageby.", "Uvccl, lbh guvax rirelguvat vf n pbafcvenpl.",
"Gurfr thlf ner nobhg nf zhpu sha nf n gnk nhqvg.", "Gurer vf fbzrguvat qbja gurer! Fbzrguvat abg hf.",
"V fnj n tyvzcfr bs zl shgher naq rirelguvat'f punatrq sbe zr abj.", "Va fcnpr ab bar pna urne lbh fpernz",
"V pna'g yvr gb lbh nobhg lbhe punaprf, ohg... lbh unir zl flzcnguvrf.",
"Gurer vf na rkcynangvba sbe guvf, lbh xabj.", "V'z nsenvq V unir fbzr onq arjf.",
"Qb zr n snibhe. Qvfpbaarpg zr. V pbhyq or erjbexrq, ohg V'yy arire or gbc bs gur yvar ntnva.",
"Gnxr vg rnfl, qba'g chfu gur yvggyr ohggba ba gur wblfgvpx!", "V'z n irel cevingr crefba.",
"Gb fphycg na ryrcunag sebz n ovt oybpx bs zneoyr, whfg xabpx njnl nyy gur ovgf gung qba'g ybbx yvxr na ryrcunag.",
"Jub fnvq lbh pbhyq gnyx gb zr? Unir V tbg fbzrguvat ba zl snpr ?", "Jr'ir orra guebhtu jbefg",
"Havgrq jr fgnaq", "Jr funyy arire fheeraqre",
"Nofbyhgr ubarfgl vfa'g nyjnlf gur zbfg qvcybzngvp abe gur fnsrfg sbez bs pbzzhavpngvba jvgu rzbgvbany orvatf.",
"Vg'f... pbzcyvpngrq.", "Qb abg bcra hagvy 1985", "V fgvyy zrff hc ohg V'yy whfg fgneg ntnva",
"V jba'g tvir hc, ab V jba'g tvir va; Gvyy V ernpu gur raq; Naq gura V'yy fgneg ntnva",
"V jnaan gel rira gubhtu V pbhyq snvy", "Fbzrgvzrf jr pbzr ynfg ohg jr qvq bhe orfg",
"Vs lbh frr fbzrguvat, fnl fbzrguvat",
"Va gurbel gurer vf ab qvssrerapr orgjrra gurbel naq cenpgvpr. Ohg, va cenpgvpr, gurer vf.",
"Vs V pnaabg oevat lbh pbzsbeg gura ng yrnfg V oevat lbh ubcr",
"Jr nyy zhfg yrnea sebz fznyy zvfsbeghar, pbhag gur oyrffvatf gung ner erny",
"Cercner Guerr Frnyrq Rairybcrf...", "Lbh xabj gung guvat lbh whfg qvq? Qba'g qb gung",
"Vg gbbx zr n ybat gvzr gb haqrefgnaq gung vs lbh jnag gb qb guvf wbo jryy lbh unir gb fgnl qrgnpurq.",
"Qb lbh yvxr lbhe zbeavat grn jrnx be fgebat ?", "Jvagre vf pbzvat", "Jung sbbyf gurfr zbegnyf or!",
"Fbzrguvat jvpxrq guvf jnl pbzrf.", "V guvax V trg vg, jung jnf vg? Cbxre Avtug? Onpurybe Cnegl?",
"Vg'f nyevtug gb or fpnerq. Erzrzore, gurer vf ab pbhentr jvgubhg srne.",
"Guebhtu ernqvarff naq qvfpvcyvar jr ner znfgref bs bhe sngr.",
"Jvgu terng cbjre pbzrf terng erfcbafvovyvgl",
"Vs n znpuvar pna yrnea gur inyhr bs uhzna yvsr, znlor jr pna gbb ?",
"Bayl tbvat sbejneq 'pnhfr jr pna'g svaq erirefr.",
"Jr'er abg tbaan fvg va fvyrapr, jr'er abg tbaan yvir jvgu srne",
"Oba, qnaf qvk zvahgrf wr abhf pbafvqrer pbzzr qrsvavgvirzrag creqhf.",
"Pn fren fherzrag ovra dhnaq pn fren svav.",
"Vg'f gur ynfg cvrpr bs gur chmmyr ohg lbh whfg pna'g znxr vg svg",
"Qbpgbe fnlf lbh'er pherq ohg lbh fgvyy srry gur cnva",
"Vf negvsvpvny vagryyvtrapr gur rknpg bccbfvgr bs angheny fghcvqvgl ?",
"Sbeprzrag, pn qrcraq, pn qrcnffr...", "Gurer'f orra n cnggrea bs vafhobeqvangr orunivbe erpragyl.",
"Ab. Jr ner abg na rssrpgvir grnz.", "Bhe wbo vf abg gb erzrzore... erzrzore?",
"Guvf vf zvffvba pbageby. Ubj ner lbh nyy qbvat guvf ybiryl zbeavat?",
"Vs lbh pbhyq frr lbhe jubyr yvsr ynvq bhg va sebag bs lbh, jbhyq lbh punatr guvatf?",
"Vf guvf n aba-mreb-fhz tnzr?", "Abj gung'f n cebcre vagebqhpgvba.",
"Rirelguvat unf punatrq naq vg jba'g fgbc punatvat nalgvzr fbba.",
"Jung znxrf lbh qvssrerag znxrf lbh qnatrebhf", "Qviretrapr vf rkgerzryl qnatrebhf",
"V'z Qviretrag. Naq V pna'g or pbagebyyrq", "Znl gur bqqf or rire va lbhe snibe",
"Ab WninFpevcg senzrjbexf jrer perngrq qhevat gur jevgvat bs guvf zrffntr.",
"P'rfg cerffr-cherr dhv g'nf vagreebtr ?", "Ybbx, nygreangvir snpgf ner abg snpgf. Gurl'er snyfrubbqf",
"Guvf vf abg n penfu, guvf vf zber bs na nygreangvir erfhyg.",
"Lbh yrnearq gb cebtenz va SBEGENA qvqa'g lbh?",
"Guvf oht vf n srngher nf qrfpevorq ol gur znexrgvat qrcnegzrag.",
"Abg rirelobql haqrefgnaqf gur uhzbe bs cebtenzzref.",
"Vs lbh yvir na beqvanel yvsr, nyy lbh'yy unir ner beqvanel fgbevrf.", "Pbzr jvgu zr vs lbh jnag gb yvir",
"Gh y'nf gebhir bh pryhv-yn ?", "Qb lbh ernyyl guvax lbh unir n punapr ntnvafg hf, Ze. Pbjobl?",
"Nggragvba, jubrire lbh ner, guvf punaary vf erfreirq sbe rzretrapl pnyyf bayl.",
"Qbrf vg fbhaq yvxr V'z beqrevat n cvmmn? ", "Jr'er tbaan arrq fbzr zber SOV thlf, V thrff.",
"Trg ernql sbe ehfu ubhe",
"V unir gb jnea lbh, V'ir urneq eryngvbafuvcf onfrq ba vagrafr rkcrevraprf arire jbex.",
"Nalguvat ryfr ohg gur onfrzrag gung'yy xrrc guvf ryringbe sebz snyyvat?",
"Vf guvf grfgvat jurgure V'z n ercyvpnag be n yrfovna, Ze. Qrpxneq? ", "V'ir qbar... dhrfgvbanoyr guvatf",
"Jbhyq lbh... yvxr gb or hctenqrq?", "Snhg erpbaanvger... p'rfg qh oehgny!",
"Fv ba oevpbynvg cyhf fbhirag, ba nhenvg zbvaf yn grgr nhk orgvfrf.",
"Wr invf yhv snver har beqbaanapr, rg har frirer...",
"Znvf vy pbaanvg cnf Enbhy, pr zrp! vy in nibve ha erirvy cravoyr.",
"W'nv ibhyh rger qvcybzngr n pnhfr qr ibhf gbhf, rivgre dhr yr fnat pbhyr.",
"Vtabenapr oevatf punbf, abg xabjyrqtr.", "Yrneavat vf nyjnlf n cnvashy cebprff.",
"V'z fbeel, ner lbh sebz gur cnfg ?", "Unir lbh gevrq gheavat vg bss naq ba ntnva ?",
"Vs lbh qba'g xabj jurer lbh ner tbvat nal ebnq pna gnxr lbh gurer", "Xrrc pnyz naq cerff Pgey-Nyg-Qry",
"Vs lbh glcr Tbbtyr vagb Tbbtyr, lbh pna oernx gur Vagrearg.", "V unir cneg bs n cyna.",
"V'z cerggl fher gur nafjre vf: V nz Tebbg.", "Nalguvat gung pna cbffvoyl tb jebat, qbrf",
"Cyhf pn engr, cyhf ba n qr punapr dhr pn znepur", "Fb V thrff gur sbeghar gryyre'f evtug...",
"Jura rirelguvat'f tbar jebat fbzrubj...", "V qba'g jnag gb yvir ba guvf cynarg nalzber",
"Oba, p'rfg y'urher bh yrf fbhiravef fr enzrarag...",
"Fhpprff pbafvfgf bs tbvat sebz snvyher gb snvyher jvgubhg ybff bs raguhfvnfz",
"Vs lbh'er tbvat guebhtu uryy, xrrc tbvat",
"Jre xnzcsg, xnaa ireyvrera. Jre avpug xnzcsg, ung fpuba ireybera.",
"P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.",
"Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.", "Pyrneyl, lbh unir arire zrg n jbzna.",
"Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag",
"Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf",
"L'n dhrydhrf dhrfgvbaf dhv erfgrag fbhf fvyrapr...", "Vs gurer vf ab fbyhgvba, gurer vf ab ceboyrz",
"V unir zrzbevrf, ohg V pna'g gryy vs gurl'er erny.", "L n pbzzr ha tbhg nzre ra abhf",
"L n qrf fvyraprf dhv qvfrag ornhpbhc", "V frr lbh'ir unq fbzr qvfpvcyvanel ceboyrzf va gur cnfg.",
"Cercnengvba vf gur xrl gb fhpprffshy, vapbafcvphbhf gvzr geniry.",
"Vg'f arire gbb yngr gb or jub lbh zvtug unir orra.",
"Rg cbhe nyyre purm Zvpxrl vyf ibag fherzrag cnf pbafgehver har tner gbhf yrf 100 zrgerf",
"Nyy lbhe onfr ner orybat gb hf", "Znqr ba Rnegu ol uhznaf", "Jvaaref Qba'g Hfr Qehtf",
"Lbh xabj jung fhecevfrq zr gur zbfg? Vg jnfa'g zrrgvat gurz. Vg jnf zrrgvat lbh.",
"Va jne gurer ner ab jvaaref, bayl jvqbjf",
"Vs lbh guvax guvf Havirefr vf onq, lbh fubhyq frr fbzr bs gur bguref", "Cnp-Zna'f n onq thl?",
"Zl ernyvgl vf whfg qvssrerag guna lbhef", "L'ra n dh'bag rffnlr, vyf bag rh qrf ceboyrzrf",
"Gb ree vf uhzna, ohg gb ernyyl sbhy guvatf hc erdhverf n pbzchgre.",
"Vs lbh oryvrir rirelguvat lbh ernq, lbh orggre abg ernq",
"Gurer vf ab ceboyrz fb onq lbh pna'g znxr vg jbefr", "Pn p'rfg qh ybheq... Ha gehp qr znynqr.",
"V qb abg guvax, gung V guvax.. V guvax.", "Gurer ner cynprf ybjre guna gur onfrzrag",
"Gurer ner 10 glcrf bs crbcyr: gubfr jub haqrefgnaq ovanel, naq gubfr jub qba'g.",
"Cyrnfr zvaq gur tnc orgjrra gur genva naq gur cyngsbez", "Nfuvzbgb av tb-puhv xhqnfnv",
"Vs lbh'er erprvivat guvf genafzvffvba, znxr ab nggrzcg gb pbzr gb vgf cbvag bs bevtva.",
"Obl, qb V ungr orvat evtug nyy gur gvzr!",
"Jub funirf gur oneore jub funirf nyy gur zra jub qba'g funir gurzfryirf?",
"V haqrefgnaq uhzna rzbgvbaf, nygubhtu V qb abg srry gurz zlfrys.", "Lbh qvqa'g fnl gur zntvp jbeq!",
"Gurer vf ab ceboyrz gung n ynpx bs fbyhgvba jba'g svanyyl erfbyir.",
"V unir n inthr srryvat bs vzcraqvat zvfsbeghar.", "Jura lbh'er va gebhoyr, pbashfr rirelguvat",
"Jung gur uryy vf Cebwrpg Ryebaq?", "Qba'g qvt hc gur ovt obk bs cyhgbavhz, Znex",
"Uryc vf bayl 140 zvyyvba zvyrf njnl.",
"P unf gur fcrrq naq rssvpvrapl bs nffrzoyl ynathntr pbzovarq jvgu ernqnovyvgl bs nffrzoyl ynathntr",
"Crey vf gur bayl ynathntr gung ybbxf gur fnzr orsber naq nsgre EFN rapelcgvba",
"Gur zber vg snvyf, gur zber yvxryl vg vf gung vg jvyy jbex",
"V ubcr V qvqa'g gnxr hc gbb zhpu bs lbhe gvzr", "Lbh'er tbaan arrq n ovttre obng",
"Dhnaq ibhf rgrf rzorgrf, rzoebhvyyrm gbhg", "Gurer nva'g ab phevat jung'f jebat jvgu gung guvat",
"Vs lbh cevpx hf, qb jr abg oyrrq?", "V qvq lbhe wbo bapr - V jnf tbbq ng vg.",
"Vyf cbheenvrag snver har fryrpgvba nh fgnaqneq...", "Gung'f ab jnl gb gerng n sevraq.",
"Ubjrire ornhgvshy gur fgengrtl, lbh fubhyq bppnfvbanyyl ybbx ng gur erfhygf",
"Qba'g svk vg vs vg'f abg oebxra",
"Fhqqrayl V'z gnxvat fhttrfgvbaf sebz fbzr fgebat-nez zna jvgu na VD bs zvahf 50.",
"Fur ehvaf rirelguvat fur'f va. Fur ehvaf guvatf fur'f abg rira va.",
"Byvir, V guvax lbh fubhyq xabj guvf: lbh'er n ubeevoyr npgerff.",
"Lbh'er yngr! Qb lbh unir ab pbaprcg bs gvzr ?", "P'zba zna, yrg'f qb fbzrguvat gung ernyyl pbbxf.",
"Nh sbaq, znvagranag, yrf qvcybzngrf ceraqenvrag cyhgbg yr cnf fhe yrf ubzzrf q'npgvba.",
"Whfg zragnyyl gubhtu... ner lbh bxnl ?", "Jr xabj fur'f bxnl orpnhfr fur'f oybaq", "Gh oyhssrf Znegbav",
"Lbh thlf ner trggvat cnvq?",
"Gurer'f n erq guvatl zbivat gbjneqf gur terra guvatl... V guvax jr'er gur terra guvatl",
"Nyy flfgrzf ner shapgvbavat Pbzznaqre", "V erzrzore gung fbhaq! Gung'f n onq fbhaq!",
"V xabj vg'f uneq sbe lbh gb haqrefgnaq rira fubeg fragraprf",
"Gur havirefr vf shyy bs vagryyvtrag yvsr. Vg'f whfg orra gbb vagryyvtrag gb pbzr urer.",
"Uryyb, jbhyq lbh yvxr gb urne n GPC wbxr ?", "Rirel snvel gnyr arrqf n tbbq byq-snfuvbarq ivyynva",
"Fvapr gurer'f ab pbapyhfvba gb gur cnenqbk gurbel, gurer'f ab jnl gb cebir gurer'f ab cnenqbk.",
"Gnxr zr guebhtu gur qnexarff gb gur oernx bs gur qnl",
"Vg znxrf gur gehgu rira zber vapbzcerurafvoyr orpnhfr rirelguvat vf arj",
"V qba'g xabj ubj ohg V fhqqrayl ybfr pbageby", "Gurer ner zbzragf jura V guvax V'z tbvat penml",
"Jbhyq gung vg jrer fb fvzcyr", "Pnyy gung n xavsr? Guvf vf n xavsr.", "Fhe y'bprna qh grzcf dhv tyvffr...",
"Snvyher serr bcrengvbaf erdhver rkcrevrapr jvgu snvyher.", "Pngnfgebcur vf nyjnlf whfg nebhaq gur pbeare.",
"Orjner bs ohtf va gur nobir pbqr; V unir bayl cebirq vg pbeerpg, abg gevrq vg",
"V'z abg n erny cebtenzzre. V guebj gbtrgure guvatf hagvy vg jbexf gura V zbir ba",
"#qrsvar DHRFGVBA ((oo)||!(oo))", "Pbzchgref ner hfryrff. Gurl pna bayl tvir lbh nafjref",
"Gur Vagrearg? Vf gung guvat fgvyy nebhaq?",
"Va beqre gb haqrefgnaq erphefvba, bar zhfg svefg haqrefgnaq erphefvba",
"Obhagl Uhagvat vf n pbzcyvpngrq cebsrffvba.",
"Znahsnpghere'f cebgbpby qvpgngrf V pna abg or pncgherq. V zhfg frys-qrfgehpg.", "Snvyher vf abg na bcgvba",
"Rirelguvat snvyf nyy gur gvzr", "Gur orfg jnl gb nibvq snvyher vf gb snvy pbafgnagyl",
"Cerzngher bcgvzvmngvba vf gur ebbg bs nyy rivy", "Chgnva, w'ra nv zneer q'nibve gbhwbhef envfba");
private QuoteUtils() {
}

View File

@ -106,7 +106,8 @@ public class TextBlockUtils {
return new TextBlockMarged(textBlock, marginX1, marginX2, marginY1, marginY2);
}
public static TextBlock withMinWidth(TextBlock textBlock, double minWidth, HorizontalAlignment horizontalAlignment) {
public static TextBlock withMinWidth(TextBlock textBlock, double minWidth,
HorizontalAlignment horizontalAlignment) {
return new TextBlockMinWidth(textBlock, minWidth, horizontalAlignment);
}
@ -125,6 +126,10 @@ public class TextBlockUtils {
return new PositionableImpl(pt, textBlock.calculateDimension(stringBounder));
}
public static Positionable asPositionable(Dimension2D dim, StringBounder stringBounder, Point2D pt) {
return new PositionableImpl(pt, dim);
}
public static TextBlock mergeLR(TextBlock b1, TextBlock b2, VerticalAlignment verticallAlignment) {
return new TextBlockHorizontal(b1, b2, verticallAlignment);
}
@ -133,7 +138,8 @@ public class TextBlockUtils {
return new TextBlockVertical2(b1, b2, horizontalAlignment);
}
// public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1, TextBlockBackcolored b2,
// public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1,
// TextBlockBackcolored b2,
// HorizontalAlignment horizontalAlignment) {
// return addBackcolor(mergeTB(b1, b2, horizontalAlignment), b1.getBackcolor());
// }

View File

@ -83,6 +83,7 @@ import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.Member;
import net.sourceforge.plantuml.cucadiagram.MethodsOrFieldsArea;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
@ -102,7 +103,7 @@ import net.sourceforge.plantuml.svek.DotStringFactory;
import net.sourceforge.plantuml.svek.GeneralImageBuilder;
import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.svek.IEntityImage;
import net.sourceforge.plantuml.svek.Shape;
import net.sourceforge.plantuml.svek.Node;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UStroke;
@ -121,7 +122,6 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
private final Map<ILeaf, ST_Agnode_s> nodes = new LinkedHashMap<ILeaf, ST_Agnode_s>();
private final Map<Link, ST_Agedge_s> edges = new LinkedHashMap<Link, ST_Agedge_s>();
private final Map<IGroup, ST_Agraph_s> clusters = new LinkedHashMap<IGroup, ST_Agraph_s>();
private Map<IGroup, ILeaf> emptyGroups = new HashMap<IGroup, ILeaf>();
private final DotStringFactory dotStringFactory;
@ -141,11 +141,11 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
for (Map.Entry<ILeaf, ST_Agnode_s> ent : nodes.entrySet()) {
final ILeaf leaf = ent.getKey();
final ST_Agnode_s node = ent.getValue();
final Point2D corner = getCorner(node);
final ST_Agnode_s agnode = ent.getValue();
final Point2D corner = getCorner(agnode);
final Shape shape = dotStringFactory.getBibliotekon().getShape(leaf);
final IEntityImage image = shape.getImage();
final Node node = dotStringFactory.getBibliotekon().getNode(leaf);
final IEntityImage image = node.getImage();
image.drawU(ug.apply(new UTranslate(corner)));
}
@ -199,7 +199,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
final Cluster cluster = dotStringFactory.getBibliotekon().getCluster(group);
cluster.setPosition(llx, lly, urx, ury);
JUtils.LOG2("cluster=" + cluster);
// ug.apply(new UTranslate(llx, lly)).apply(new UChangeColor(HtmlColorUtils.BLUE))
// ug.apply(new UTranslate(llx, lly)).apply(new
// UChangeColor(HtmlColorUtils.BLUE))
// .draw(new URectangle(urx - llx, ury - lly));
cluster.drawU(ug, new UStroke(1.5), diagram.getUmlDiagramType(), diagram.getSkinParam());
}
@ -210,21 +211,9 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
continue;
}
if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) {
final ILeaf folder = diagram.getEntityFactory().createLeaf(g.getIdent(), g.getCode(), g.getDisplay(),
LeafType.EMPTY_PACKAGE, g.getParentContainer(), null, diagram.getNamespaceSeparator());
emptyGroups.put(g, folder);
final USymbol symbol = g.getUSymbol();
folder.setUSymbol(symbol);
folder.setStereotype(g.getStereotype());
if (g.getColors(diagram.getSkinParam()).getColor(ColorType.BACK) == null) {
final ColorParam param = symbol == null ? ColorParam.packageBackground : symbol.getColorParamBack();
final HtmlColor c1 = diagram.getSkinParam().getHtmlColor(param, g.getStereotype(), false);
folder.setSpecificColorTOBEREMOVED(ColorType.BACK, c1 == null ? diagram.getSkinParam()
.getBackgroundColor() : c1);
} else {
folder.setSpecificColorTOBEREMOVED(ColorType.BACK,
g.getColors(diagram.getSkinParam()).getColor(ColorType.BACK));
}
final ISkinParam skinParam = diagram.getSkinParam();
final EntityFactory entityFactory = diagram.getEntityFactory();
final ILeaf folder = entityFactory.createLeafForEmptyGroup(g, skinParam);
printEntityNew(folder);
} else {
printGroup(g);
@ -261,10 +250,11 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
final int suppWidthBecauseOfShape = uSymbol == null ? 0 : uSymbol.suppWidthBecauseOfShape();
titleAndAttributeWidth = (int) Math.max(dimLabel.getWidth(), attributeWidth) + suppWidthBecauseOfShape;
titleAndAttributeHeight = (int) (dimLabel.getHeight() + attributeHeight + marginForFields + suppHeightBecauseOfShape);
titleAndAttributeHeight = (int) (dimLabel.getHeight() + attributeHeight + marginForFields
+ suppHeightBecauseOfShape);
}
dotStringFactory.openCluster(g, titleAndAttributeWidth, titleAndAttributeHeight, title, stereo);
dotStringFactory.openCluster(titleAndAttributeWidth, titleAndAttributeHeight, title, stereo, g);
this.printEntities(g.getLeafsDirect());
printGroups(g);
@ -291,16 +281,16 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
}
private void exportEntity(ST_Agraph_s g, ILeaf leaf) {
final Shape shape = dotStringFactory.getBibliotekon().getShape(leaf);
final Node node = dotStringFactory.getBibliotekon().getNode(leaf);
// System.err.println("exportEntity " + leaf);
final ST_Agnode_s node = agnode(g, new CString(shape.getUid()), true);
agsafeset(node, new CString("shape"), new CString("box"), new CString(""));
final String width = "" + (shape.getWidth() / 72);
final String height = "" + (shape.getHeight() / 72);
agsafeset(node, new CString("width"), new CString(width), new CString(""));
agsafeset(node, new CString("height"), new CString(height), new CString(""));
final ST_Agnode_s agnode = agnode(g, new CString(node.getUid()), true);
agsafeset(agnode, new CString("shape"), new CString("box"), new CString(""));
final String width = "" + (node.getWidth() / 72);
final String height = "" + (node.getHeight() / 72);
agsafeset(agnode, new CString("width"), new CString(width), new CString(""));
agsafeset(agnode, new CString("height"), new CString(height), new CString(""));
// System.err.println("NODE " + leaf.getUid() + " " + width + " " + height);
nodes.put(leaf, node);
nodes.put(leaf, agnode);
}
private void printEntity(ILeaf ent) {
@ -308,12 +298,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
throw new IllegalStateException();
}
final IEntityImage image = printEntityInternal(ent);
final Dimension2D dim = image.calculateDimension(stringBounder);
final Shape shape = new Shape(image, image.getShapeType(), dim.getWidth(), dim.getHeight(),
dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(stringBounder),
ent.getEntityPosition());
dotStringFactory.addShape(shape);
getBibliotekon().putShape(ent, shape);
final Node node = getBibliotekon().createNode(ent, image, dotStringFactory.getColorSequence(), stringBounder);
dotStringFactory.addNode(node);
}
private TextBlock getTitleBlock(IGroup g) {
@ -361,15 +347,15 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
}
private void printCluster(ST_Agraph_s g, Cluster cluster) {
for (Shape shape : cluster.getShapes()) {
final ST_Agnode_s node = agnode(g, new CString(shape.getUid()), true);
agsafeset(node, new CString("shape"), new CString("box"), new CString(""));
final String width = "" + (shape.getWidth() / 72);
final String height = "" + (shape.getHeight() / 72);
agsafeset(node, new CString("width"), new CString(width), new CString(""));
agsafeset(node, new CString("height"), new CString(height), new CString(""));
final ILeaf leaf = dotStringFactory.getBibliotekon().getLeaf(shape);
nodes.put(leaf, node);
for (Node node : cluster.getNodes()) {
final ST_Agnode_s agnode = agnode(g, new CString(node.getUid()), true);
agsafeset(agnode, new CString("shape"), new CString("box"), new CString(""));
final String width = "" + (node.getWidth() / 72);
final String height = "" + (node.getHeight() / 72);
agsafeset(agnode, new CString("width"), new CString(width), new CString(""));
agsafeset(agnode, new CString("height"), new CString(height), new CString(""));
final ILeaf leaf = dotStringFactory.getBibliotekon().getLeaf(node);
nodes.put(leaf, agnode);
}
}
@ -411,7 +397,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
// agsafeset(node, new CString("height"), new CString(height), new CString(""));
// nodes.put(leaf, node);
// // System.err
// // .println("NODE " + leaf.getUid() + " [shape=box, width=" + width + ", height=" + height + "]");
// // .println("NODE " + leaf.getUid() + " [shape=box, width=" + width + ",
// height=" + height + "]");
// }
//
for (Link link : diagram.getLinks()) {
@ -460,7 +447,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
continue;
}
if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) {
final ILeaf folder = emptyGroups.get(g);
final EntityFactory entityFactory = diagram.getEntityFactory();
final ILeaf folder = entityFactory.getLeafForEmptyGroup(g);
exportEntity(graph, folder);
} else {
exportGroup(graph, g);
@ -476,8 +464,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
if (cluster.isLabel()) {
final double width = cluster.getTitleAndAttributeWidth();
final double height = cluster.getTitleAndAttributeHeight() - 5;
agsafeset(cluster1, new CString("label"),
Macro.createHackInitDimensionFromLabel((int) width, (int) height), new CString(""));
agsafeset(cluster1, new CString("label"), Macro.createHackInitDimensionFromLabel((int) width, (int) height),
new CString(""));
}
this.exportEntities(cluster1, group.getLeafsDirect());
this.clusters.put(group, cluster1);
@ -517,9 +505,9 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
if (n != null) {
return n;
}
final String id = getBibliotekon().getShapeUid((ILeaf) entity);
final String id = getBibliotekon().getNodeUid((ILeaf) entity);
for (Map.Entry<ILeaf, ST_Agnode_s> ent : nodes.entrySet()) {
if (id.equals(getBibliotekon().getShapeUid(ent.getKey()))) {
if (id.equals(getBibliotekon().getNodeUid(ent.getKey()))) {
return ent.getValue();
}
}
@ -543,10 +531,12 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
int length = link.getLength();
// System.err.println("length=" + length);
// if (/* pragma.horizontalLineBetweenDifferentPackageAllowed() || */link.isInvis() || length != 1) {
// if (/* pragma.horizontalLineBetweenDifferentPackageAllowed() ||
// */link.isInvis() || length != 1) {
agsafeset(e, new CString("minlen"), new CString("" + (length - 1)), new CString(""));
// }
// System.err.print("EDGE " + link.getEntity1().getUid() + "->" + link.getEntity2().getUid() + " minlen="
// System.err.print("EDGE " + link.getEntity1().getUid() + "->" +
// link.getEntity2().getUid() + " minlen="
// + (length - 1) + " ");
final TextBlock label = getLabel(link);
@ -600,12 +590,8 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
throw new IllegalStateException();
}
final IEntityImage image = printEntityInternal(ent);
final Dimension2D dim = image.calculateDimension(stringBounder);
final Shape shape = new Shape(image, image.getShapeType(), dim.getWidth(), dim.getHeight(),
dotStringFactory.getColorSequence(), ent.isTop(), image.getShield(stringBounder),
ent.getEntityPosition());
final Node shape = getBibliotekon().createNode(ent, image, dotStringFactory.getColorSequence(), stringBounder);
// dotStringFactory.addShape(shape);
getBibliotekon().putShape(ent, shape);
}
private Bibliotekon getBibliotekon() {

View File

@ -49,9 +49,9 @@ import net.sourceforge.plantuml.command.CommandPackage;
import net.sourceforge.plantuml.command.CommandPage;
import net.sourceforge.plantuml.command.CommandRankDir;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.command.note.FactoryNoteCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnEntityCommand;
import net.sourceforge.plantuml.command.note.FactoryNoteOnLinkCommand;
import net.sourceforge.plantuml.command.note.CommandFactoryNote;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnEntity;
import net.sourceforge.plantuml.command.note.CommandFactoryNoteOnLink;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.objectdiagram.command.CommandAddData;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject;
@ -78,7 +78,7 @@ public class ObjectDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandLinkClass(UmlDiagramType.OBJECT));
//
cmds.add(new CommandCreateEntityObject());
final FactoryNoteCommand factoryNoteCommand = new FactoryNoteCommand();
final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote();
cmds.add(factoryNoteCommand.createSingleLine());
cmds.add(new CommandPackage());
@ -88,7 +88,7 @@ public class ObjectDiagramFactory extends UmlDiagramFactory {
// addCommand(new CommandStereotype());
//
// addCommand(new CommandImport());
final FactoryNoteOnEntityCommand factoryNoteOnEntityCommand = new FactoryNoteOnEntityCommand("object",
final CommandFactoryNoteOnEntity factoryNoteOnEntityCommand = new CommandFactoryNoteOnEntity("object",
new RegexLeaf("ENTITY", "([\\p{L}0-9_.]+|[%g][^%g]+[%g])"));
cmds.add(factoryNoteOnEntityCommand.createSingleLine());
@ -99,7 +99,7 @@ public class ObjectDiagramFactory extends UmlDiagramFactory {
cmds.add(factoryNoteOnEntityCommand.createMultiLine(false));
cmds.add(new CommandCreateEntityObjectMultilines());
final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand();
final CommandFactoryNoteOnLink factoryNoteOnLinkCommand = new CommandFactoryNoteOnLink();
cmds.add(factoryNoteOnLinkCommand.createSingleLine());
cmds.add(factoryNoteOnLinkCommand.createMultiLine(false));

View File

@ -45,9 +45,11 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.plantuml.EnsureVisible;
import net.sourceforge.plantuml.asciiart.BasicCharArea;
@ -168,6 +170,29 @@ public class DotPath implements UShape, Moveable {
return beziers.get(0).getP1();
}
public Set<Point2D> sample() {
final Set<Point2D> result = new HashSet<Point2D>();
for (CubicCurve2D.Double bez : beziers) {
sample(bez, result);
}
return Collections.unmodifiableSet(result);
}
private static void sample(CubicCurve2D bez, Set<Point2D> result) {
final Point2D p1 = bez.getCtrlP1();
final Point2D p2 = bez.getCtrlP2();
if (bez.getFlatnessSq() > 0.5 || p1.distance(p2) > 4) {
final CubicCurve2D.Double left = new CubicCurve2D.Double();
final CubicCurve2D.Double right = new CubicCurve2D.Double();
bez.subdivide(left, right);
sample(left, result);
sample(right, result);
} else {
result.add(p1);
result.add(p2);
}
}
public PointAndAngle getMiddle() {
Point2D result = null;
double angle = 0;
@ -361,8 +386,8 @@ public class DotPath implements UShape, Moveable {
public void draw(Graphics2D g2d, double x, double y) {
final GeneralPath p = new GeneralPath();
for (CubicCurve2D.Double bez : beziers) {
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y
+ bez.ctrly2, x + bez.x2, y + bez.y2);
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2,
y + bez.ctrly2, x + bez.x2, y + bez.y2);
p.append(bez, true);
}
g2d.draw(p);
@ -379,8 +404,8 @@ public class DotPath implements UShape, Moveable {
public void drawOk(EpsGraphics eps, double x, double y) {
// boolean first = true;
for (CubicCurve2D.Double bez : beziers) {
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y
+ bez.ctrly2, x + bez.x2, y + bez.y2);
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2,
y + bez.ctrly2, x + bez.x2, y + bez.y2);
eps.epsLine(bez.x1, bez.y1, bez.x2, bez.y2);
}
}
@ -390,8 +415,8 @@ public class DotPath implements UShape, Moveable {
final boolean dashed = false;
boolean first = true;
for (CubicCurve2D.Double bez : beziers) {
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y
+ bez.ctrly2, x + bez.x2, y + bez.y2);
bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2,
y + bez.ctrly2, x + bez.x2, y + bez.y2);
if (first) {
eps.movetoNoMacro(bez.x1, bez.y1);
first = dashed;
@ -504,14 +529,14 @@ public class DotPath implements UShape, Moveable {
area.drawHLine('-', (int) (bez.y1 / pixelYPerChar), (int) (bez.x1 / pixelXPerChar),
(int) (bez.x2 / pixelXPerChar));
} /*
* else { throw new UnsupportedOperationException("bez=" + toString(bez)); }
*/
* else { throw new UnsupportedOperationException("bez=" + toString(bez)); }
*/
}
}
static String toString(CubicCurve2D.Double c) {
return "(" + c.x1 + "," + c.y1 + ") " + "(" + c.ctrlx1 + "," + c.ctrly1 + ") " + "(" + c.ctrlx2 + ","
+ c.ctrly2 + ") " + "(" + c.x2 + "," + c.y2 + ") ";
return "(" + c.x1 + "," + c.y1 + ") " + "(" + c.ctrlx1 + "," + c.ctrly1 + ") " + "(" + c.ctrlx2 + "," + c.ctrly2
+ ") " + "(" + c.x2 + "," + c.y2 + ") ";
}
@ -526,8 +551,8 @@ public class DotPath implements UShape, Moveable {
}
public static CubicCurve2D.Double reverse(CubicCurve2D curv) {
return new CubicCurve2D.Double(curv.getX2(), curv.getY2(), curv.getCtrlX2(), curv.getCtrlY2(),
curv.getCtrlX1(), curv.getCtrlY1(), curv.getX1(), curv.getY1());
return new CubicCurve2D.Double(curv.getX2(), curv.getY2(), curv.getCtrlX2(), curv.getCtrlY2(), curv.getCtrlX1(),
curv.getCtrlY1(), curv.getX1(), curv.getY1());
}
public DotPath reverse() {

View File

@ -56,7 +56,7 @@ public class Stdlib {
}
}
private static Stdlib retrieve(final String name) throws IOException {
public static Stdlib retrieve(final String name) throws IOException {
Stdlib result = all.get(name);
if (result == null) {
final DataInputStream dataStream = getDataStream(name);
@ -222,7 +222,7 @@ public class Stdlib {
public static void extractStdLib() throws IOException {
for (String name : getAll()) {
final Stdlib folder = Stdlib.retrieve(name);
folder.extractMeFull(new File("stdlib", name));
folder.extractMeFull();
}
}
@ -237,7 +237,7 @@ public class Stdlib {
return Collections.unmodifiableCollection(result);
}
private void extractMeFull(File dir) throws IOException {
private void extractMeFull() throws IOException {
final DataInputStream dataStream = getDataStream();
if (dataStream == null) {
return;
@ -280,6 +280,46 @@ public class Stdlib {
}
}
public List<String> extractAllSprites() throws IOException {
final List<String> result = new ArrayList<String>();
final DataInputStream dataStream = getDataStream();
if (dataStream == null) {
return Collections.unmodifiableList(result);
}
dataStream.readUTF();
final InputStream spriteStream = getSpriteStream();
try {
while (true) {
final String filename = dataStream.readUTF();
if (filename.equals(SEPARATOR)) {
return Collections.unmodifiableList(result);
}
while (true) {
final String s = dataStream.readUTF();
if (s.equals(SEPARATOR)) {
break;
}
if (isSpriteLine(s)) {
final Matcher m = sizePattern.matcher(s);
final boolean ok = m.find();
if (ok == false) {
throw new IOException(s);
}
final int width = Integer.parseInt(m.group(1));
final int height = Integer.parseInt(m.group(2));
final String sprite = readSprite(width, height, spriteStream);
if (s.contains("_LARGE") == false) {
result.add(s + "\n" + sprite + "}");
}
}
}
}
} finally {
dataStream.close();
spriteStream.close();
}
}
public static void addInfoVersion(List<String> strings, boolean details) {
try {
for (String name : getAll()) {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.ugraphic.UPolygon;

View File

@ -33,21 +33,20 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.util.LinkedHashSet;
import java.util.Set;
import net.sourceforge.plantuml.project.lang.Complement;
public class Resources /*implements LoadPlanable*/ {
public class Completion implements Complement {
private final Set<Resource> all = new LinkedHashSet<Resource>();
private final int completion;
// public int getLoadAt(Instant instant) {
// int result = 0;
// for (Resource res : all) {
// result += res.getLoadAt(instant);
// }
// return result;
// }
public Completion(int completion) {
this.completion = completion;
}
public final int getCompletion() {
return completion;
}
}

View File

@ -33,7 +33,9 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.project.core.Wink;
public class ConstantPlan implements LoadPlanable {
@ -51,7 +53,7 @@ public class ConstantPlan implements LoadPlanable {
return new ConstantPlan(load);
}
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
return loadPerInstant;
}

View File

@ -33,10 +33,15 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.util.Date;
import net.sourceforge.plantuml.project.core.Month;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.Subject;
public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
private final int year;
@ -65,6 +70,10 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
this.month = month;
}
public int getYear() {
return year;
}
private int internalNumber() {
return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth;
}
@ -120,7 +129,7 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
return DayOfWeek.fromH(h);
}
public InstantDay asInstantDay(DayAsDate reference) {
public Wink asInstantDay(DayAsDate reference) {
// if (this.compareTo(reference) < 0) {
// throw new IllegalArgumentException();
// }
@ -130,7 +139,39 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
current = current.next();
cmp++;
}
return new InstantDay(cmp);
return new Wink(cmp);
}
// http://www.proesite.com/timex/wkcalc.htm
public int ISO_WN() {
final int y = year;
int m = month.ordinal() + 1;
int d = dayOfMonth;
int dow = DOW(y, m, d);
int dow0101 = DOW(y, 1, 1);
if (m == 1 && 3 < dow0101 && dow0101 < 7 - (d - 1)) {
// days before week 1 of the current year have the same week number as
// the last day of the last week of the previous year
dow = dow0101 - 1;
dow0101 = DOW(y - 1, 1, 1);
m = 12;
d = 31;
} else if (m == 12 && 30 - (d - 1) < DOW(y + 1, 1, 1) && DOW(y + 1, 1, 1) < 4) {
// days after the last week of the current year have the same week number as
// the first day of the next year, (i.e. 1)
return 1;
}
return (DOW(y, 1, 1) < 4) ? 1 : 0 + 4 * (m - 1) + (2 * (m - 1) + (d - 1) + dow0101 - dow + 6) * 36 / 256;
}
private int DOW(int y, int m, int d) {
// TODO Auto-generated method stub
return 0;
}
public int compareTo(DayAsDate other) {

View File

@ -33,9 +33,11 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.Subject;
public enum DayOfWeek implements Subject, Complement {

View File

@ -33,10 +33,13 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.util.Iterator;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.Subject;
public class DaysAsDates implements Subject, Complement, Iterable<DayAsDate> {
private final DayAsDate date1;

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
public class Failable<O> {

View File

@ -33,19 +33,21 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
public class GCalendarSimple implements GCalendar {
import net.sourceforge.plantuml.project.core.Wink;
public class GCalendar {
private final DayAsDate start;
public GCalendarSimple(DayAsDate start) {
public GCalendar(DayAsDate start) {
this.start = start;
}
public DayAsDate toDayAsDate(InstantDay day) {
public DayAsDate toDayAsDate(Wink day) {
DayAsDate result = start;
final int target = day.getNumDay();
final int target = day.getWink();
int work = 0;
while (work < target) {
result = result.next();
@ -54,11 +56,11 @@ public class GCalendarSimple implements GCalendar {
return result;
}
public InstantDay fromDayAsDate(DayAsDate day) {
public Wink fromDayAsDate(DayAsDate day) {
if (day.compareTo(start) < 0) {
throw new IllegalArgumentException();
}
InstantDay result = new InstantDay(0);
Wink result = new Wink(0);
while (toDayAsDate(result).equals(day) == false) {
result = result.increment();
}

View File

@ -33,11 +33,16 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -88,6 +93,10 @@ public class GanttArrow implements UDrawable {
final double x2 = getX(dest, atEnd.getInv());
final double y2 = draw2.getY(atEnd);
if (atStart == Direction.DOWN && y2 < y1) {
y1 = draw1.getY(atStart.getInv());
}
if (this.atStart == Direction.DOWN && this.atEnd == Direction.RIGHT) {
if (x2 > x1) {
drawLine(ug, x1, y1, x1, y2, x2, y2);

View File

@ -33,9 +33,12 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.timescale.TimeScale;
public class GanttConstraint implements Complement {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
@ -55,15 +55,11 @@ import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.Scale;
import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorSetSimple;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
@ -71,16 +67,33 @@ import net.sourceforge.plantuml.graphic.IHtmlColorSet;
import net.sourceforge.plantuml.graphic.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.core.Moment;
import net.sourceforge.plantuml.project.core.MomentImpl;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.core.Resource;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskCode;
import net.sourceforge.plantuml.project.core.TaskImpl;
import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.core.TaskSeparator;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.draw.ResourceDraw;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.draw.TaskDrawRegular;
import net.sourceforge.plantuml.project.draw.TaskDrawSeparator;
import net.sourceforge.plantuml.project.draw.TimeHeader;
import net.sourceforge.plantuml.project.draw.TimeHeaderDaily;
import net.sourceforge.plantuml.project.draw.TimeHeaderSimple;
import net.sourceforge.plantuml.project.draw.TimeHeaderWeekly;
import net.sourceforge.plantuml.project.lang.ComplementColors;
import net.sourceforge.plantuml.project.lang.Subject;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class GanttDiagram extends TitledDiagram implements Subject {
@ -89,13 +102,24 @@ public class GanttDiagram extends TitledDiagram implements Subject {
private final Map<String, Task> byShortName = new HashMap<String, Task>();
private final List<GanttConstraint> constraints = new ArrayList<GanttConstraint>();
private final IHtmlColorSet colorSet = new HtmlColorSetSimple();
private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class);
private final Collection<DayAsDate> closedDayAsDate = new HashSet<DayAsDate>();
private final Collection<DayAsDate> openedDayAsDate = new HashSet<DayAsDate>();
private GCalendar calendar;
private final Instant min = new InstantDay(0);
private Instant max;
private final Map<String, Resource> resources = new LinkedHashMap<String, Resource>();
private final Map<DayAsDate, HtmlColor> colorDays = new HashMap<DayAsDate, HtmlColor>();
private final Map<DayAsDate, String> nameDays = new HashMap<DayAsDate, String>();
private PrintScale printScale = PrintScale.DAILY;
private DayAsDate today;
private GCalendar calendar;
private double totalHeight;
private Wink min = new Wink(0);
private Wink max;
private DayAsDate printStart;
private DayAsDate printEnd;
public DiagramDescription getDescription() {
return new DiagramDescription("(Project)");
@ -148,16 +172,35 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os);
}
public void setPrintScale(PrintScale printScale) {
this.printScale = printScale;
}
private TextBlockBackcolored getTextBlock() {
initMinMax();
final TimeScale timeScale = getTimeScale();
initTaskAndResourceDraws(timeScale);
if (printStart == null) {
initMinMax();
} else {
this.min = calendar.fromDayAsDate(printStart);
this.max = calendar.fromDayAsDate(printEnd);
}
final TimeHeader timeHeader;
if (calendar == null) {
timeHeader = new TimeHeaderSimple(min, max);
} else if (printScale == PrintScale.WEEKLY) {
timeHeader = new TimeHeaderWeekly(calendar, min, max, getDefaultPlan(), colorDays, nameDays);
} else {
timeHeader = new TimeHeaderDaily(calendar, min, max, getDefaultPlan(), colorDays, nameDays, printStart,
printEnd);
}
initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight());
return new TextBlockBackcolored() {
public void drawU(UGraphic ug) {
drawTimeHeader(ug, timeScale);
drawTasks(ug, timeScale);
drawConstraints(ug, timeScale);
timeHeader.drawTimeHeader(ug, totalHeight);
drawConstraints(ug, timeHeader.getTimeScale());
drawTasksRect(ug);
drawTasksTitle(ug);
drawResources(ug);
}
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
@ -165,8 +208,8 @@ public class GanttDiagram extends TitledDiagram implements Subject {
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
final double xmin = timeScale.getStartingPosition(min);
final double xmax = timeScale.getEndingPosition(max);
final double xmin = timeHeader.getTimeScale().getStartingPosition(min);
final double xmax = timeHeader.getTimeScale().getEndingPosition(max);
return new Dimension2DDouble(xmax - xmin, totalHeight);
}
@ -180,25 +223,43 @@ public class GanttDiagram extends TitledDiagram implements Subject {
};
}
private TimeScale getTimeScale() {
if (calendar == null) {
return new TimeScaleBasic();
private void drawTasksRect(UGraphic ug) {
for (Task task : tasks.values()) {
final TaskDraw draw = task.getTaskDraw();
final UTranslate move = new UTranslate(0, draw.getY());
draw.drawU(ug.apply(move));
}
return new TimeScaleBasic2(getCalendarSimple());
// return new TimeScaleWithoutWeekEnd(calendar);
}
private GCalendarSimple getCalendarSimple() {
return (GCalendarSimple) calendar;
private void drawConstraints(final UGraphic ug, TimeScale timeScale) {
for (GanttConstraint constraint : constraints) {
constraint.getUDrawable(timeScale).drawU(ug);
}
}
private void drawTasksTitle(final UGraphic ug1) {
for (Task task : tasks.values()) {
final TaskDraw draw = task.getTaskDraw();
final UTranslate move = new UTranslate(0, draw.getY());
draw.drawTitle(ug1.apply(move));
}
}
private void drawResources(UGraphic ug) {
for (Resource res : resources.values()) {
final ResourceDraw draw = res.getResourceDraw();
final UTranslate move = new UTranslate(0, draw.getY());
draw.drawU(ug.apply(move));
}
}
public final LoadPlanable getDefaultPlan() {
return new LoadPlanable() {
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
if (calendar == null) {
return 100;
}
final DayAsDate day = getCalendarSimple().toDayAsDate((InstantDay) instant);
final DayAsDate day = calendar.toDayAsDate((Wink) instant);
if (isClosed(day)) {
return 0;
}
@ -227,152 +288,8 @@ public class GanttDiagram extends TitledDiagram implements Subject {
openedDayAsDate.add(day);
}
private void drawConstraints(final UGraphic ug, TimeScale timeScale) {
for (GanttConstraint constraint : constraints) {
constraint.getUDrawable(timeScale).drawU(ug);
}
}
private double totalHeight;
private void drawTimeHeader(final UGraphic ug, TimeScale timeScale) {
final double xmin = timeScale.getStartingPosition(min);
final double xmax = timeScale.getEndingPosition(max);
if (calendar == null) {
drawSimpleDayCounter(ug, timeScale);
} else {
drawCalendar(ug, timeScale);
}
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).draw(new ULine(xmax - xmin, 0));
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(0, getHeaderHeight() - 3))
.draw(new ULine(xmax - xmin, 0));
}
private final HtmlColor veryLightGray = new HtmlColorSetSimple().getColorIfValid("#E0E8E8");
private double getHeaderHeight() {
return getTimeHeaderHeight() + getHeaderNameDayHeight();
}
private double getTimeHeaderHeight() {
if (calendar != null) {
return Y_WEEKDAY + Y_NUMDAY;
}
return 16;
}
private double getHeaderNameDayHeight() {
if (calendar != null && nameDays.size() > 0) {
return 16;
}
return 0;
}
private static final int Y_WEEKDAY = 16;
private static final int Y_NUMDAY = 28;
private void drawCalendar(final UGraphic ug, TimeScale timeScale) {
timeScale = new TimeScaleBasic();
final ULine vbar = new ULine(0, totalHeight - Y_WEEKDAY);
Month lastMonth = null;
final GCalendarSimple calendarAll = getCalendarSimple();
final Instant max2 = calendarAll.fromDayAsDate(calendar.toDayAsDate((InstantDay) max));
for (Instant i = min; i.compareTo(max2.increment()) <= 0; i = i.increment()) {
final DayAsDate day = calendarAll.toDayAsDate((InstantDay) i);
final DayOfWeek dayOfWeek = day.getDayOfWeek();
final boolean isWorkingDay = getDefaultPlan().getLoadAt(i) > 0;
final String d1 = "" + day.getDayOfMonth();
final TextBlock num = getTextBlock(d1, 10, false);
final double x1 = timeScale.getStartingPosition(i);
final double x2 = timeScale.getEndingPosition(i);
if (i.compareTo(max2.increment()) < 0) {
final TextBlock weekDay = getTextBlock(dayOfWeek.shortName(), 10, false);
final URectangle rect = new URectangle(x2 - x1 - 1, totalHeight - Y_WEEKDAY);
if (isWorkingDay) {
final HtmlColor back = colorDays.get(day);
if (back != null) {
ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(back))
.apply(new UTranslate(x1 + 1, Y_WEEKDAY)).draw(rect);
}
drawCenter(ug.apply(new UTranslate(0, Y_NUMDAY)), num, x1, x2);
drawCenter(ug.apply(new UTranslate(0, Y_WEEKDAY)), weekDay, x1, x2);
} else {
ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(veryLightGray))
.apply(new UTranslate(x1 + 1, Y_WEEKDAY)).draw(rect);
}
if (lastMonth != day.getMonth()) {
final int delta = 5;
if (lastMonth != null) {
final TextBlock lastMonthBlock = getTextBlock(lastMonth.name(), 12, true);
lastMonthBlock.drawU(ug.apply(new UTranslate(x1
- lastMonthBlock.calculateDimension(ug.getStringBounder()).getWidth() - delta, 0)));
}
final TextBlock month = getTextBlock(day.getMonth().name(), 12, true);
month.drawU(ug.apply(new UTranslate(x1 + delta, 0)));
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, 0))
.draw(new ULine(0, Y_WEEKDAY));
}
lastMonth = day.getMonth();
}
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, Y_WEEKDAY)).draw(vbar);
}
if (nameDays.size() > 0) {
String last = null;
for (Instant i = min; i.compareTo(max2.increment()) <= 0; i = i.increment()) {
final DayAsDate day = calendarAll.toDayAsDate((InstantDay) i);
final String name = nameDays.get(day);
if (name != null && name.equals(last) == false) {
final double x1 = timeScale.getStartingPosition(i);
final double x2 = timeScale.getEndingPosition(i);
final TextBlock label = getTextBlock(name, 12, false);
final double h = label.calculateDimension(ug.getStringBounder()).getHeight();
double y1 = getTimeHeaderHeight();
double y2 = getHeaderHeight();
label.drawU(ug.apply(new UTranslate(x1, Y_NUMDAY + 11)));
}
last = name;
}
}
}
private TextBlock getTextBlock(final String text, int size, boolean bold) {
return Display.getWithNewlines(text).create(getFontConfiguration(size, bold), HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
}
private void drawCenter(final UGraphic ug, final TextBlock text, final double x1, final double x2) {
final double width = text.calculateDimension(ug.getStringBounder()).getWidth();
final double delta = (x2 - x1) - width;
if (delta < 0) {
return;
}
text.drawU(ug.apply(new UTranslate(x1 + delta / 2, 0)));
}
private void drawSimpleDayCounter(final UGraphic ug, TimeScale timeScale) {
final ULine vbar = new ULine(0, totalHeight);
for (Instant i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) {
final TextBlock num = Display.getWithNewlines(i.toShortString()).create(getFontConfiguration(10, false),
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final double x1 = timeScale.getStartingPosition(i);
final double x2 = timeScale.getEndingPosition(i);
final double width = num.calculateDimension(ug.getStringBounder()).getWidth();
final double delta = (x2 - x1) - width;
if (i.compareTo(max.increment()) < 0) {
num.drawU(ug.apply(new UTranslate(x1 + delta / 2, 0)));
}
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, 0)).draw(vbar);
}
}
private void initTaskAndResourceDraws(TimeScale timeScale) {
double y = getHeaderHeight();
private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight) {
double y = headerHeight;
for (Task task : tasks.values()) {
final TaskDraw draw;
if (task instanceof TaskSeparator) {
@ -402,8 +319,8 @@ public class GanttDiagram extends TitledDiagram implements Subject {
if (task instanceof TaskSeparator) {
continue;
}
final Instant start = task.getStart();
final Instant end = task.getEnd();
final Wink start = task.getStart();
final Wink end = task.getEnd();
// if (min.compareTo(start) > 0) {
// min = start;
// }
@ -414,13 +331,13 @@ public class GanttDiagram extends TitledDiagram implements Subject {
}
if (calendar != null) {
for (DayAsDate d : colorDays.keySet()) {
final Instant instant = calendar.fromDayAsDate(d);
final Wink instant = calendar.fromDayAsDate(d);
if (instant.compareTo(max) > 0) {
max = instant;
}
}
for (DayAsDate d : nameDays.keySet()) {
final Instant instant = calendar.fromDayAsDate(d);
final Wink instant = calendar.fromDayAsDate(d);
if (instant.compareTo(max) > 0) {
max = instant;
}
@ -443,28 +360,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return result;
}
private void drawTasks(final UGraphic ug, TimeScale timeScale) {
for (Task task : tasks.values()) {
final TaskDraw draw = task.getTaskDraw();
final UTranslate move = new UTranslate(0, draw.getY());
draw.drawU(ug.apply(move));
draw.drawTitle(ug.apply(move));
}
for (Resource res : resources.values()) {
final ResourceDraw draw = res.getResourceDraw();
final UTranslate move = new UTranslate(0, draw.getY());
draw.drawU(ug.apply(move));
}
}
private FontConfiguration getFontConfiguration(int size, boolean bold) {
UFont font = UFont.serif(size);
if (bold) {
font = font.bold();
}
return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false);
}
public Task getExistingTask(String id) {
if (id == null) {
throw new IllegalArgumentException();
@ -538,7 +433,7 @@ public class GanttDiagram extends TitledDiagram implements Subject {
}
public void setStartingDate(DayAsDate start) {
this.calendar = new GCalendarSimple(start);
this.calendar = new GCalendar(start);
}
public DayAsDate getStartingDate() {
@ -552,14 +447,14 @@ public class GanttDiagram extends TitledDiagram implements Subject {
if (this.calendar == null) {
return null;
}
return ((GCalendarSimple) this.calendar).toDayAsDate(new InstantDay(nday));
return this.calendar.toDayAsDate(new Wink(nday));
}
public int daysInWeek() {
return 7 - closedDayOfWeek.size();
}
public Instant convert(DayAsDate day) {
public Wink convert(DayAsDate day) {
return calendar.fromDayAsDate(day);
}
@ -567,8 +462,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return getDefaultPlan().getLoadAt(convert(day)) > 0;
}
private final Map<String, Resource> resources = new LinkedHashMap<String, Resource>();
public void affectResource(Task result, String description) {
final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?");
final Matcher m = p.matcher(description);
@ -586,13 +479,13 @@ public class GanttDiagram extends TitledDiagram implements Subject {
public Resource getResource(String resourceName) {
Resource resource = resources.get(resourceName);
if (resource == null) {
resource = new Resource(resourceName, getDefaultPlan(), getCalendarSimple());
resource = new Resource(resourceName, getDefaultPlan(), calendar);
}
resources.put(resourceName, resource);
return resource;
}
public int getLoadForResource(Resource res, Instant i) {
public int getLoadForResource(Resource res, Wink i) {
int result = 0;
for (Task task : tasks.values()) {
if (task instanceof TaskSeparator) {
@ -604,9 +497,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return result;
}
private final Map<DayAsDate, HtmlColor> colorDays = new HashMap<DayAsDate, HtmlColor>();
private final Map<DayAsDate, String> nameDays = new HashMap<DayAsDate, String>();
public Moment getExistingMoment(String id) {
Moment result = getExistingTask(id);
if (result == null) {
@ -661,8 +551,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
colorDay(today, colors.getCenter());
}
private DayAsDate today;
public CommandExecutionResult setToday(DayAsDate date) {
this.today = date;
return CommandExecutionResult.ok();
@ -673,4 +561,9 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return CommandExecutionResult.ok();
}
public void setPrintInterval(DayAsDate start, DayAsDate end) {
this.printStart = start;
this.printEnd = end;
}
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.util.ArrayList;
import java.util.Arrays;
@ -45,11 +45,30 @@ import net.sourceforge.plantuml.command.CommandNope;
import net.sourceforge.plantuml.command.CommandScale;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.core.DiagramType;
import net.sourceforge.plantuml.project.command.CommandGanttArrow;
import net.sourceforge.plantuml.project.command.CommandGanttArrow2;
import net.sourceforge.plantuml.project.command.CommandPage;
import net.sourceforge.plantuml.project.command.CommandPrintBetween;
import net.sourceforge.plantuml.project.command.CommandPrintScale;
import net.sourceforge.plantuml.project.command.CommandSeparator;
import net.sourceforge.plantuml.project.command.NaturalCommand;
import net.sourceforge.plantuml.project.command.NaturalCommandAnd;
import net.sourceforge.plantuml.project.command.NaturalCommandAndAnd;
import net.sourceforge.plantuml.project.lang.ComplementPattern;
import net.sourceforge.plantuml.project.lang.SubjectDayAsDate;
import net.sourceforge.plantuml.project.lang.SubjectDayOfWeek;
import net.sourceforge.plantuml.project.lang.SubjectDaysAsDates;
import net.sourceforge.plantuml.project.lang.SubjectPattern;
import net.sourceforge.plantuml.project.lang.SubjectProject;
import net.sourceforge.plantuml.project.lang.SubjectResource;
import net.sourceforge.plantuml.project.lang.SubjectTask;
import net.sourceforge.plantuml.project.lang.SubjectToday;
import net.sourceforge.plantuml.project.lang.VerbPattern;
public class GanttDiagramFactory extends UmlDiagramFactory {
static private final List<SubjectPattern> subjects() {
return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(),
return Arrays.<SubjectPattern>asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(),
new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday());
}
@ -70,6 +89,8 @@ public class GanttDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandGanttArrow2());
cmds.add(new CommandSeparator());
cmds.add(new CommandPrintScale());
cmds.add(new CommandPrintBetween());
cmds.add(new CommandScale());
cmds.add(new CommandPage());
// cmds.add(new CommandScaleWidthAndHeight());
@ -102,7 +123,8 @@ public class GanttDiagramFactory extends UmlDiagramFactory {
}
for (ComplementPattern complement1 : verb1.getComplements()) {
for (ComplementPattern complement2 : verb2.getComplements()) {
cache.add(NaturalCommandAnd.create(subject, verb1, complement1, verb2, complement2));
cache.add(
NaturalCommandAnd.create(subject, verb1, complement1, verb2, complement2));
}
}
}

View File

@ -33,10 +33,24 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
public interface Load extends Value, Complement {
import net.sourceforge.plantuml.project.lang.Complement;
int getFullLoad();
public class Load implements Value, Complement {
private final int winks;
private Load(int winks) {
this.winks = winks;
}
public static Load inWinks(int winks) {
return new Load(winks);
}
public int getFullLoad() {
return winks * 100;
}
}

View File

@ -33,9 +33,11 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.project.core.Wink;
public interface LoadPlanable {
public int getLoadAt(Instant instant);
public int getLoadAt(Wink instant);
}

View File

@ -33,7 +33,9 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.project.core.Wink;
public class PlanUtils {
@ -43,7 +45,7 @@ public class PlanUtils {
public static LoadPlanable minOf(final LoadPlanable p1, final LoadPlanable p2) {
return new LoadPlanable() {
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
return Math.min(p1.getLoadAt(instant), p2.getLoadAt(instant));
}
};
@ -51,7 +53,7 @@ public class PlanUtils {
public static LoadPlanable multiply(final LoadPlanable p1, final LoadPlanable p2) {
return new LoadPlanable() {
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
return p1.getLoadAt(instant) * p2.getLoadAt(instant) / 100;
}
};

View File

@ -33,13 +33,16 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.Wink;
public class Solver3 {
private final Map<TaskAttribute, Value> values = new LinkedHashMap<TaskAttribute, Value>();
@ -53,8 +56,8 @@ public class Solver3 {
public void setData(TaskAttribute attribute, Value value) {
final Value previous = values.remove(attribute);
if (previous != null && attribute == TaskAttribute.START) {
final Instant previousInstant = (Instant) previous;
if (previousInstant.compareTo((Instant) value) > 0) {
final Wink previousInstant = (Wink) previous;
if (previousInstant.compareTo((Wink) value) > 0) {
value = previous;
}
}
@ -81,14 +84,14 @@ public class Solver3 {
if (attribute == TaskAttribute.START) {
return computeStart();
}
return LoadInDays.inDay(1);
return Load.inWinks(1);
// throw new UnsupportedOperationException(attribute.toString());
}
return result;
}
private Instant computeEnd() {
Instant current = (Instant) values.get(TaskAttribute.START);
private Wink computeEnd() {
Wink current = (Wink) values.get(TaskAttribute.START);
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
while (fullLoad > 0) {
fullLoad -= loadPlanable.getLoadAt(current);
@ -97,12 +100,15 @@ public class Solver3 {
return current.decrement();
}
private Instant computeStart() {
Instant current = (Instant) values.get(TaskAttribute.END);
private Wink computeStart() {
Wink current = (Wink) values.get(TaskAttribute.END);
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
while (fullLoad > 0) {
fullLoad -= loadPlanable.getLoadAt(current);
current = current.decrement();
if (current.getWink() <= 0) {
return current;
}
}
return current.increment();
}

View File

@ -33,7 +33,9 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.project.lang.Subject;
public class Today implements Subject {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project;
public interface Value {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@ -42,6 +42,11 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttConstraint;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskInstant;
public class CommandGanttArrow extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.Task;
public class CommandGanttArrow2 extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
public class CommandPage extends SingleLineCommand2<GanttDiagram> {

View File

@ -0,0 +1,84 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.DayAsDate;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.ComplementDate;
public class CommandPrintBetween extends SingleLineCommand2<GanttDiagram> {
private static final ComplementDate pattern = new ComplementDate();
public CommandPrintBetween() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandPrintBetween.class.getName(), RegexLeaf.start(), //
// Print between 2020/02/14 and 2020/03/04
new RegexLeaf("print"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("between"), //
RegexLeaf.spaceOneOrMore(), //
pattern.toRegex("START"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("and"), //
RegexLeaf.spaceOneOrMore(), //
pattern.toRegex("END"), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
final DayAsDate start = (DayAsDate) pattern.getComplement(diagram, arg, "START").get();
final DayAsDate end = (DayAsDate) pattern.getComplement(diagram, arg, "END").get();
diagram.setPrintInterval(start, end);
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,73 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.PrintScale;
public class CommandPrintScale extends SingleLineCommand2<GanttDiagram> {
public CommandPrintScale() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandPrintScale.class.getName(), RegexLeaf.start(), //
new RegexLeaf("printscale"), //
RegexLeaf.spaceOneOrMore(), //
new RegexOr("SCALE", //
new RegexLeaf("daily"), //
new RegexLeaf("weekly")), //
RegexLeaf.end()); //
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
final String scaleString = arg.get("SCALE", 0);
final PrintScale scale = PrintScale.fromString(scaleString);
diagram.setPrintScale(scale);
return CommandExecutionResult.ok();
}
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@ -42,6 +42,7 @@ import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
public class CommandSeparator extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command;
@ -42,6 +42,15 @@ import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.ComplementEmpty;
import net.sourceforge.plantuml.project.lang.ComplementPattern;
import net.sourceforge.plantuml.project.lang.Subject;
import net.sourceforge.plantuml.project.lang.SubjectPattern;
import net.sourceforge.plantuml.project.lang.Verb;
import net.sourceforge.plantuml.project.lang.VerbPattern;
public class NaturalCommand extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command;
@ -42,6 +42,14 @@ import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.ComplementPattern;
import net.sourceforge.plantuml.project.lang.Subject;
import net.sourceforge.plantuml.project.lang.SubjectPattern;
import net.sourceforge.plantuml.project.lang.Verb;
import net.sourceforge.plantuml.project.lang.VerbPattern;
public class NaturalCommandAnd extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command;
@ -42,6 +42,13 @@ import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.lang.Complement;
import net.sourceforge.plantuml.project.lang.ComplementPattern;
import net.sourceforge.plantuml.project.lang.Subject;
import net.sourceforge.plantuml.project.lang.SubjectPattern;
import net.sourceforge.plantuml.project.lang.Verb;
import net.sourceforge.plantuml.project.lang.VerbPattern;
public class NaturalCommandAndAnd extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,12 +33,12 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public interface Moment {
public Instant getStart();
public Wink getStart();
public Instant getEnd();
public Wink getEnd();
}

View File

@ -33,23 +33,23 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public class MomentImpl implements Moment {
private final Instant start;
private final Instant end;
private final Wink start;
private final Wink end;
public MomentImpl(Instant start, Instant end) {
public MomentImpl(Wink start, Wink end) {
this.start = start;
this.end = end;
}
public Instant getStart() {
public Wink getStart() {
return start;
}
public Instant getEnd() {
public Wink getEnd() {
return end;
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import net.sourceforge.plantuml.StringUtils;
@ -48,6 +48,14 @@ public enum Month {
this.daysPerMonth = daysPerMonth;
}
public String shortName() {
return niceName().substring(0, 3);
}
public String niceName() {
return StringUtils.capitalize(name());
}
static public String getRegexString() {
final StringBuilder sb = new StringBuilder();
for (Month month : Month.values()) {
@ -83,4 +91,5 @@ public enum Month {
public int m() {
return 3 + (ordinal() + 10) % 12;
}
}

View File

@ -33,14 +33,15 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public interface GCalendar {
public DayAsDate toDayAsDate(InstantDay day);
public DayAsDate getStartingDate();
public InstantDay fromDayAsDate(DayAsDate day);
public enum PrintScale {
DAILY, WEEKLY;
static public PrintScale fromString(String value) {
if (value.startsWith("w")) {
return WEEKLY;
}
return DAILY;
}
}

View File

@ -33,19 +33,26 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
import java.util.TreeSet;
import net.sourceforge.plantuml.project.DayAsDate;
import net.sourceforge.plantuml.project.DayOfWeek;
import net.sourceforge.plantuml.project.GCalendar;
import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.draw.ResourceDraw;
import net.sourceforge.plantuml.project.lang.Subject;
public class Resource implements Subject {
private final String name;
private ResourceDraw draw;
private final Set<Instant> closed = new TreeSet<Instant>();
private final Set<Instant> forcedOn = new TreeSet<Instant>();
private final Set<Wink> closed = new TreeSet<Wink>();
private final Set<Wink> forcedOn = new TreeSet<Wink>();
private final GCalendar calendar;
private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class);
@ -83,12 +90,12 @@ public class Resource implements Subject {
this.draw = draw;
}
public boolean isClosedAt(Instant instant) {
public boolean isClosedAt(Wink instant) {
if (this.forcedOn.contains(instant)) {
return false;
}
if (closedDayOfWeek.size() > 0 && calendar != null) {
final DayAsDate d = calendar.toDayAsDate((InstantDay) instant);
final DayAsDate d = calendar.toDayAsDate((Wink) instant);
if (closedDayOfWeek.contains(d.getDayOfWeek())) {
return true;
}
@ -96,11 +103,11 @@ public class Resource implements Subject {
return this.closed.contains(instant);
}
public void addCloseDay(Instant instant) {
public void addCloseDay(Wink instant) {
this.closed.add(instant);
}
public void addForceOnDay(Instant instant) {
public void addForceOnDay(Wink instant) {
this.forcedOn.add(instant);
}

View File

@ -33,23 +33,28 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.lang.ComplementColors;
import net.sourceforge.plantuml.project.lang.Subject;
public interface Task extends Subject, Moment {
public TaskCode getCode();
public Instant getStart();
public Wink getStart();
public Instant getEnd();
public Wink getEnd();
public Load getLoad();
public void setLoad(Load load);
public void setStart(Instant start);
public void setStart(Wink start);
public void setEnd(Instant end);
public void setEnd(Wink end);
public void setTaskDraw(TaskDraw taskDraw);
@ -63,5 +68,7 @@ public interface Task extends Subject, Moment {
public boolean isDiamond();
public void setCompletion(int completion);
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public enum TaskAttribute {
START, END, LOAD;

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public class TaskCode {

View File

@ -33,12 +33,19 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.PlanUtils;
import net.sourceforge.plantuml.project.Solver3;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.lang.ComplementColors;
public class TaskImpl implements Task, LoadPlanable {
private final TaskCode code;
@ -51,11 +58,11 @@ public class TaskImpl implements Task, LoadPlanable {
this.code = code;
this.defaultPlan = defaultPlan;
this.solver = new Solver3(this);
setStart(new InstantDay(0));
setLoad(LoadInDays.inDay(1));
setStart(new Wink(0));
setLoad(Load.inWinks(1));
}
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
LoadPlanable result = defaultPlan;
if (resources2.size() > 0) {
result = PlanUtils.multiply(defaultPlan, getRessourcePlan());
@ -64,7 +71,7 @@ public class TaskImpl implements Task, LoadPlanable {
// return PlanUtils.minOf(getLoad(), plan1).getLoadAt(instant);
}
public int loadForResource(Resource res, Instant instant) {
public int loadForResource(Resource res, Wink instant) {
if (resources2.keySet().contains(res) && instant.compareTo(getStart()) >= 0 && instant.compareTo(getEnd()) <= 0) {
if (res.isClosedAt(instant)) {
return 0;
@ -87,7 +94,7 @@ public class TaskImpl implements Task, LoadPlanable {
}
return new LoadPlanable() {
public int getLoadAt(Instant instant) {
public int getLoadAt(Wink instant) {
int result = 0;
for (Map.Entry<Resource, Integer> ent : resources2.entrySet()) {
final Resource res = ent.getKey();
@ -137,16 +144,16 @@ public class TaskImpl implements Task, LoadPlanable {
return code;
}
public Instant getStart() {
Instant result = (Instant) solver.getData(TaskAttribute.START);
public Wink getStart() {
Wink result = (Wink) solver.getData(TaskAttribute.START);
while (getLoadAt(result) == 0) {
result = result.increment();
}
return result;
}
public Instant getEnd() {
return (Instant) solver.getData(TaskAttribute.END);
public Wink getEnd() {
return (Wink) solver.getData(TaskAttribute.END);
}
public Load getLoad() {
@ -157,11 +164,11 @@ public class TaskImpl implements Task, LoadPlanable {
solver.setData(TaskAttribute.LOAD, load);
}
public void setStart(Instant start) {
public void setStart(Wink start) {
solver.setData(TaskAttribute.START, start);
}
public void setEnd(Instant end) {
public void setEnd(Wink end) {
solver.setData(TaskAttribute.END, end);
}
@ -169,7 +176,7 @@ public class TaskImpl implements Task, LoadPlanable {
private ComplementColors colors;
public void setTaskDraw(TaskDraw taskDraw) {
taskDraw.setColors(colors);
taskDraw.setColorsAndCompletion(colors, completion);
this.taskDraw = taskDraw;
}
@ -192,5 +199,11 @@ public class TaskImpl implements Task, LoadPlanable {
public boolean isDiamond() {
return this.diamond;
}
private int completion = 100;
public void setCompletion(int completion) {
this.completion = completion;
}
}

View File

@ -33,7 +33,9 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import net.sourceforge.plantuml.project.lang.Complement;
public class TaskInstant implements Complement {
@ -58,7 +60,7 @@ public class TaskInstant implements Complement {
return new TaskInstant(task, attribute, newDelta);
}
private Instant manageDelta(Instant value) {
private Wink manageDelta(Wink value) {
if (delta > 0) {
for (int i = 0; i < delta; i++) {
value = value.increment();
@ -72,7 +74,7 @@ public class TaskInstant implements Complement {
return value;
}
public Instant getInstantPrecise() {
public Wink getInstantPrecise() {
if (attribute == TaskAttribute.START) {
return manageDelta(task.getStart());
}
@ -82,7 +84,7 @@ public class TaskInstant implements Complement {
throw new IllegalStateException();
}
public Instant getInstantTheorical() {
public Wink getInstantTheorical() {
if (attribute == TaskAttribute.START) {
return manageDelta(task.getStart());
}

View File

@ -33,7 +33,11 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.lang.ComplementColors;
public class TaskSeparator implements Task {
// public static final double SPACE = 15;
@ -51,19 +55,19 @@ public class TaskSeparator implements Task {
return code;
}
public Instant getStart() {
public Wink getStart() {
throw new UnsupportedOperationException();
}
public Instant getEnd() {
public Wink getEnd() {
throw new UnsupportedOperationException();
}
public void setStart(Instant start) {
public void setStart(Wink start) {
throw new UnsupportedOperationException();
}
public void setEnd(Instant end) {
public void setEnd(Wink end) {
throw new UnsupportedOperationException();
}
@ -104,4 +108,8 @@ public class TaskSeparator implements Task {
throw new UnsupportedOperationException();
}
public void setCompletion(int completion) {
throw new UnsupportedOperationException();
}
}

View File

@ -33,39 +33,41 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.core;
public class InstantDay implements Instant {
import net.sourceforge.plantuml.project.Value;
private final int numDay;
public class Wink implements Value, Comparable<Wink> {
public InstantDay(int numDay) {
this.numDay = numDay;
private final int wink;
public Wink(int wink) {
this.wink = wink;
}
@Override
public String toString() {
return "(day +" + numDay + ")";
return "(Wink +" + wink + ")";
}
public InstantDay increment() {
return new InstantDay(numDay + 1);
public Wink increment() {
return new Wink(wink + 1);
}
public InstantDay decrement() {
return new InstantDay(numDay - 1);
public Wink decrement() {
return new Wink(wink - 1);
}
final int getNumDay() {
return numDay;
public final int getWink() {
return wink;
}
public int compareTo(Instant other) {
return this.numDay - ((InstantDay) other).numDay;
public int compareTo(Wink other) {
return this.wink - other.wink;
}
public String toShortString() {
return "" + (numDay + 1);
return "" + (wink + 1);
}
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.cucadiagram.Display;
@ -43,6 +43,10 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.Resource;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -54,11 +58,11 @@ public class ResourceDraw implements UDrawable {
private final Resource res;
private final TimeScale timeScale;
private final double y;
private final Instant min;
private final Instant max;
private final Wink min;
private final Wink max;
private final GanttDiagram gantt;
public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Instant min, Instant max) {
public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Wink min, Wink max) {
this.res = res;
this.timeScale = timeScale;
this.y = y;
@ -74,7 +78,7 @@ public class ResourceDraw implements UDrawable {
final ULine line = new ULine(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min), 0);
ug.apply(new UChangeColor(HtmlColorUtils.BLACK))
.apply(new UTranslate(0, title.calculateDimension(ug.getStringBounder()).getHeight())).draw(line);
for (Instant i = min; i.compareTo(max) <= 0; i = i.increment()) {
for (Wink i = min; i.compareTo(max) <= 0; i = i.increment()) {
final int load = gantt.getLoadForResource(res, i);
if (load > 0) {
final FontConfiguration fontConfiguration = getFontConfiguration(9, load > 100 ? HtmlColorUtils.RED

View File

@ -33,15 +33,16 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.lang.ComplementColors;
import net.sourceforge.plantuml.ugraphic.UGraphic;
public interface TaskDraw extends UDrawable {
public void setColors(ComplementColors colors);
public void setColorsAndCompletion(ComplementColors colors, int completion);
public double getY();

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.SpriteContainerEmpty;
@ -44,6 +44,10 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorSetSimple;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.core.TaskImpl;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.lang.ComplementColors;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont;
@ -61,6 +65,7 @@ public class TaskDrawRegular implements TaskDraw {
private final TimeScale timeScale;
private final double y;
private ComplementColors colors;
private int completion = 100;
private final double margin = 2;
@ -73,10 +78,15 @@ public class TaskDrawRegular implements TaskDraw {
public void drawTitle(UGraphic ug) {
final TextBlock title = Display.getWithNewlines(task.getPrettyDisplay()).create(getFontConfiguration(),
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final double shapeHeight = getShapeHeight(100);
final double titleHeight = title.calculateDimension(ug.getStringBounder()).getHeight();
final double h = (margin + shapeHeight - titleHeight) / 2;
title.drawU(ug.apply(new UTranslate(timeScale.getEndingPosition(task.getStart()), h)));
final double h = (margin + getShapeHeight() - titleHeight) / 2;
final double endingPosition;
if (isDiamond()) {
endingPosition = timeScale.getStartingPosition(task.getStart()) + getHeight();
} else {
endingPosition = timeScale.getEndingPosition(task.getStart());
}
title.drawU(ug.apply(new UTranslate(endingPosition, h)));
}
private FontConfiguration getFontConfiguration() {
@ -88,12 +98,7 @@ public class TaskDrawRegular implements TaskDraw {
final double start = timeScale.getStartingPosition(task.getStart());
ug1 = applyColors(ug1);
UGraphic ug2 = ug1.apply(new UTranslate(start + margin, margin));
final UShape shapeFull = getShape(100);
if (shapeFull instanceof UPolygon) {
ug2.draw(shapeFull);
} else {
ug2.draw(shapeFull);
}
drawShape(ug2);
}
private UGraphic applyColors(UGraphic ug) {
@ -106,25 +111,47 @@ public class TaskDrawRegular implements TaskDraw {
return ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(defaultColor));
}
private UShape getShape(int load) {
private void drawShape(UGraphic ug) {
if (isDiamond()) {
return getDiamond();
ug.draw(getDiamond());
return;
}
final Instant instantStart = task.getStart();
final Instant instantEnd = task.getEnd();
final Wink instantStart = task.getStart();
final Wink instantEnd = task.getEnd();
final double start = timeScale.getStartingPosition(instantStart);
final double end = timeScale.getEndingPosition(instantEnd);
return new URectangle(end - start - 2 * margin, getShapeHeight(load), 8, 8);
final double fullLength = end - start - 2 * margin;
if (fullLength < 10) {
return;
}
final URectangle full = new URectangle(fullLength, getShapeHeight(), 8, 8);
if (completion == 100) {
ug.draw(full);
return;
}
final double partialLength = fullLength * completion / 100.;
ug.apply(new UChangeColor(HtmlColorUtils.WHITE)).apply(new UChangeBackColor(HtmlColorUtils.WHITE)).draw(full);
if (partialLength > 2) {
final URectangle partial = new URectangle(partialLength, getShapeHeight(), 8, 8);
ug.apply(new UChangeColor(null)).draw(partial);
}
if (partialLength > 10 && partialLength < fullLength - 10) {
final URectangle patch = new URectangle(8, getShapeHeight());
ug.apply(new UChangeColor(null)).apply(new UTranslate(partialLength - 8, 0)).draw(patch);
}
ug.apply(new UChangeBackColor(null)).draw(full);
}
private double getShapeHeight(int load) {
return (getHeight() - 2 * margin) * load / 100.0;
private double getShapeHeight() {
return getHeight() - 2 * margin;
}
private boolean isDiamond() {
if (task.isDiamond()) {
final Instant instantStart = task.getStart();
final Instant instantEnd = task.getEnd();
final Wink instantStart = task.getStart();
final Wink instantEnd = task.getEnd();
return instantStart.compareTo(instantEnd) == 0;
}
return false;
@ -158,7 +185,8 @@ public class TaskDrawRegular implements TaskDraw {
return y + getHeight() / 2;
}
public void setColors(ComplementColors colors) {
public void setColorsAndCompletion(ComplementColors colors, int completion) {
this.colors = colors;
this.completion = completion;
}
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.project3;
package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.SpriteContainerEmpty;
@ -43,6 +43,10 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.project.core.TaskSeparator;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.lang.ComplementColors;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -53,11 +57,11 @@ public class TaskDrawSeparator implements TaskDraw {
private final TimeScale timeScale;
private final double y;
private final Instant min;
private final Instant max;
private final Wink min;
private final Wink max;
private final String name;
public TaskDrawSeparator(TaskSeparator task, TimeScale timeScale, double y, Instant min, Instant max) {
public TaskDrawSeparator(TaskSeparator task, TimeScale timeScale, double y, Wink min, Wink max) {
this.name = task.getName();
this.y = y;
this.timeScale = timeScale;
@ -122,7 +126,7 @@ public class TaskDrawSeparator implements TaskDraw {
return y + getHeight() / 2;
}
public void setColors(ComplementColors colors) {
public void setColorsAndCompletion(ComplementColors colors, int completion) {
}
}

View File

@ -0,0 +1,113 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.core.Wink;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import sun.security.x509.AVA;
public abstract class TimeHeader {
private final TimeScale timeScale;
protected final Wink min;
protected final Wink max;
public TimeHeader(Wink min, Wink max, TimeScale timeScale) {
this.timeScale = timeScale;
this.min = min;
this.max = max;
}
public abstract void drawTimeHeader(final UGraphic ug, double totalHeight);
public abstract double getFullHeaderHeight();
protected final void drawHline(UGraphic ug, double y) {
final double xmin = getTimeScale().getStartingPosition(min);
final double xmax = getTimeScale().getEndingPosition(max);
final ULine hline = new ULine(xmax - xmin, 0);
ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(0, y)).draw(hline);
}
final protected FontConfiguration getFontConfiguration(int size, boolean bold) {
UFont font = UFont.serif(size);
if (bold) {
font = font.bold();
}
return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false);
}
public final TimeScale getTimeScale() {
return timeScale;
}
protected final TextBlock getTextBlock(final String text, int size, boolean bold) {
return Display.getWithNewlines(text).create(getFontConfiguration(size, bold), HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
}
protected final void printCentered(UGraphic ug, TextBlock text, double start, double end) {
final double width = text.calculateDimension(ug.getStringBounder()).getWidth();
final double available = end - start;
final double diff = Math.max(0, available - width);
text.drawU(ug.apply(new UTranslate(start + diff / 2, 0)));
}
protected final void printCentered(UGraphic ug, double start, double end, TextBlock... texts) {
final double available = end - start;
for (int i = texts.length - 1; i >= 0; i--) {
final TextBlock text = texts[i];
final double width = text.calculateDimension(ug.getStringBounder()).getWidth();
if (i == 0 || width <= available) {
final double diff = Math.max(0, available - width);
text.drawU(ug.apply(new UTranslate(start + diff / 2, 0)));
return;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More