diff --git a/pom.xml b/pom.xml index e163f67e5..bec6253cb 100644 --- a/pom.xml +++ b/pom.xml @@ -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> diff --git a/src/net/sourceforge/plantuml/FontParam.java b/src/net/sourceforge/plantuml/FontParam.java index a29fc1215..1842eb5d1 100644 --- a/src/net/sourceforge/plantuml/FontParam.java +++ b/src/net/sourceforge/plantuml/FontParam.java @@ -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), // diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 0ce4e66a5..3fbbe0459 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/PSystemUtils.java b/src/net/sourceforge/plantuml/PSystemUtils.java index 060f50966..c3fe74f62 100644 --- a/src/net/sourceforge/plantuml/PSystemUtils.java +++ b/src/net/sourceforge/plantuml/PSystemUtils.java @@ -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 { diff --git a/src/net/sourceforge/plantuml/Pipe.java b/src/net/sourceforge/plantuml/Pipe.java index cb9031133..4f868072b 100644 --- a/src/net/sourceforge/plantuml/Pipe.java +++ b/src/net/sourceforge/plantuml/Pipe.java @@ -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) { diff --git a/src/net/sourceforge/plantuml/Pragma.java b/src/net/sourceforge/plantuml/Pragma.java index 59c69b60e..9e69cc7fb 100644 --- a/src/net/sourceforge/plantuml/Pragma.java +++ b/src/net/sourceforge/plantuml/Pragma.java @@ -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); diff --git a/src/net/sourceforge/plantuml/UmlDiagramType.java b/src/net/sourceforge/plantuml/UmlDiagramType.java index d2a1d76f3..68947c1cc 100644 --- a/src/net/sourceforge/plantuml/UmlDiagramType.java +++ b/src/net/sourceforge/plantuml/UmlDiagramType.java @@ -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 } diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java index 2c5146cb7..7d6c7a750 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java @@ -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)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index 2e912745d..f1c2c1c72 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -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()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java index 2a83e2060..2ef005d91 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java @@ -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()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java index ef21f3b56..40467e168 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java index 1f9dfff74..929768ce3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java @@ -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(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java index 2f38386b4..3ad653946 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java @@ -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); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java index 04cd426d1..fce49ae03 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java index 94266dd75..2086d28ea 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java @@ -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); + } } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java index b3becbd6d..3fe4b96fd 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java @@ -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(); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java index a7fe6e000..3dedf46a4 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java index 4e17c1041..16c7b1257 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -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; diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index f9c87602d..068293331 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -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()); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index e34aff45a..b6da5b900 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index e3bb06c68..ef09eba4e 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -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); diff --git a/src/net/sourceforge/plantuml/command/BlocLines.java b/src/net/sourceforge/plantuml/command/BlocLines.java index c2d49759d..74c662dce 100644 --- a/src/net/sourceforge/plantuml/command/BlocLines.java +++ b/src/net/sourceforge/plantuml/command/BlocLines.java @@ -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)) { diff --git a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java b/src/net/sourceforge/plantuml/command/CommandFactorySprite.java similarity index 94% rename from src/net/sourceforge/plantuml/command/FactorySpriteCommand.java rename to src/net/sourceforge/plantuml/command/CommandFactorySprite.java index 7c9bc6e5b..5033e9c03 100644 --- a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java +++ b/src/net/sourceforge/plantuml/command/CommandFactorySprite.java @@ -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(), // diff --git a/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java b/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java index b032a8ef4..ca71732b6 100644 --- a/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java +++ b/src/net/sourceforge/plantuml/command/UmlDiagramFactory.java @@ -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()); diff --git a/src/net/sourceforge/plantuml/command/note/CommandConstraintOnLinks.java b/src/net/sourceforge/plantuml/command/note/CommandConstraintOnLinks.java new file mode 100644 index 000000000..95dab07c9 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/note/CommandConstraintOnLinks.java @@ -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()); + } + +} diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java similarity index 96% rename from src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java rename to src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java index 1791f0f74..791a0fe5e 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java @@ -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]"), // diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java similarity index 97% rename from src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java rename to src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java index ac2e109b9..fb6176833 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteActivity.java @@ -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)"), // diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java similarity index 96% rename from src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java rename to src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java index 12f54bcb8..078b2d202 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java @@ -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(), // diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java similarity index 96% rename from src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java rename to src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java index 4023ecfe5..43e1462bf 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnLinkCommand.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnLink.java @@ -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)?"), // diff --git a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java similarity index 96% rename from src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java rename to src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java index 6cbd56e22..cea206040 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java @@ -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)"), // diff --git a/src/net/sourceforge/plantuml/core/DiagramType.java b/src/net/sourceforge/plantuml/core/DiagramType.java index db4317d06..24bfeddbe 100644 --- a/src/net/sourceforge/plantuml/core/DiagramType.java +++ b/src/net/sourceforge/plantuml/core/DiagramType.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/creole/AtomImg.java b/src/net/sourceforge/plantuml/creole/AtomImg.java index 29a164dec..7f23d9df3 100644 --- a/src/net/sourceforge/plantuml/creole/AtomImg.java +++ b/src/net/sourceforge/plantuml/creole/AtomImg.java @@ -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(); } diff --git a/src/net/sourceforge/plantuml/creole/AtomMath.java b/src/net/sourceforge/plantuml/creole/AtomMath.java index f386ef003..4815d8735 100644 --- a/src/net/sourceforge/plantuml/creole/AtomMath.java +++ b/src/net/sourceforge/plantuml/creole/AtomMath.java @@ -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); } } diff --git a/src/net/sourceforge/plantuml/creole/AtomText.java b/src/net/sourceforge/plantuml/creole/AtomText.java index e9c346d7c..2d1b61d4b 100644 --- a/src/net/sourceforge/plantuml/creole/AtomText.java +++ b/src/net/sourceforge/plantuml/creole/AtomText.java @@ -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(); + } } } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java index 911299aa0..c2e881429 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java index 2bdf76bfd..a1fef7abd 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java @@ -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)); diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index 0339e91b8..754c848a9 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -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(); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java b/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java index b951020b4..794b1c54d 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Ident.java b/src/net/sourceforge/plantuml/cucadiagram/Ident.java index 253b1591e..077b023b4 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Ident.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Ident.java @@ -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())); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index 90185ae76..ad74b7850 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -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; + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkConstraint.java b/src/net/sourceforge/plantuml/cucadiagram/LinkConstraint.java new file mode 100644 index 000000000..fc5dba195 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkConstraint.java @@ -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))); + + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Member.java b/src/net/sourceforge/plantuml/cucadiagram/Member.java index 91dbcf015..427502ad9 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Member.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Member.java @@ -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(")"); + } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java deleted file mode 100644 index 3c5b94a28..000000000 --- a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java +++ /dev/null @@ -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(")"); - } -} diff --git a/src/net/sourceforge/plantuml/project3/Instant.java b/src/net/sourceforge/plantuml/cucadiagram/SuperGroup.java similarity index 80% rename from src/net/sourceforge/plantuml/project3/Instant.java rename to src/net/sourceforge/plantuml/cucadiagram/SuperGroup.java index 280ce5198..20e69a0c1 100644 --- a/src/net/sourceforge/plantuml/project3/Instant.java +++ b/src/net/sourceforge/plantuml/cucadiagram/SuperGroup.java @@ -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(); + } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java index 45baa7f9e..803ba1e53 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java @@ -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, diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java index 4e65ca09b..be3c760fc 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java @@ -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; } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index 8eb85b7f1..019e5cbf7 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -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; + } + } diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java index 3fb4d72a0..098e63917 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagramFactory.java @@ -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)); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementParenthesis.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementParenthesis.java new file mode 100644 index 000000000..ba251cd1f --- /dev/null +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementParenthesis.java @@ -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; + } +} diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index 15e8628b5..36f2fb985 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -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()) { diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index c70d29477..1e39528fd 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -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() { } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java index 8297b19d5..e905f01cb 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -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()); // } diff --git a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java index 19595dfb2..c5fde0062 100644 --- a/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java +++ b/src/net/sourceforge/plantuml/jdot/CucaDiagramFileMakerJDot.java @@ -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() { diff --git a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java index c01efadd7..e0ccf25a6 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java +++ b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java @@ -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)); diff --git a/src/net/sourceforge/plantuml/posimo/DotPath.java b/src/net/sourceforge/plantuml/posimo/DotPath.java index 88442609e..49016688d 100644 --- a/src/net/sourceforge/plantuml/posimo/DotPath.java +++ b/src/net/sourceforge/plantuml/posimo/DotPath.java @@ -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() { diff --git a/src/net/sourceforge/plantuml/preproc/Stdlib.java b/src/net/sourceforge/plantuml/preproc/Stdlib.java index b29047a22..1332fc3aa 100644 --- a/src/net/sourceforge/plantuml/preproc/Stdlib.java +++ b/src/net/sourceforge/plantuml/preproc/Stdlib.java @@ -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()) { diff --git a/src/net/sourceforge/plantuml/project3/Arrows.java b/src/net/sourceforge/plantuml/project/Arrows.java similarity index 98% rename from src/net/sourceforge/plantuml/project3/Arrows.java rename to src/net/sourceforge/plantuml/project/Arrows.java index afa770a6c..521087deb 100644 --- a/src/net/sourceforge/plantuml/project3/Arrows.java +++ b/src/net/sourceforge/plantuml/project/Arrows.java @@ -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; diff --git a/src/net/sourceforge/plantuml/project3/Resources.java b/src/net/sourceforge/plantuml/project/Completion.java similarity index 76% rename from src/net/sourceforge/plantuml/project3/Resources.java rename to src/net/sourceforge/plantuml/project/Completion.java index d1159e667..7158898de 100644 --- a/src/net/sourceforge/plantuml/project3/Resources.java +++ b/src/net/sourceforge/plantuml/project/Completion.java @@ -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; + } } diff --git a/src/net/sourceforge/plantuml/project3/ConstantPlan.java b/src/net/sourceforge/plantuml/project/ConstantPlan.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/ConstantPlan.java rename to src/net/sourceforge/plantuml/project/ConstantPlan.java index 078ef64dd..0703b2efb 100644 --- a/src/net/sourceforge/plantuml/project3/ConstantPlan.java +++ b/src/net/sourceforge/plantuml/project/ConstantPlan.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/project3/DayAsDate.java b/src/net/sourceforge/plantuml/project/DayAsDate.java similarity index 74% rename from src/net/sourceforge/plantuml/project3/DayAsDate.java rename to src/net/sourceforge/plantuml/project/DayAsDate.java index 0a1d0ffc9..a9b0b97e3 100644 --- a/src/net/sourceforge/plantuml/project3/DayAsDate.java +++ b/src/net/sourceforge/plantuml/project/DayAsDate.java @@ -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) { diff --git a/src/net/sourceforge/plantuml/project3/DayOfWeek.java b/src/net/sourceforge/plantuml/project/DayOfWeek.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/DayOfWeek.java rename to src/net/sourceforge/plantuml/project/DayOfWeek.java index 54af9a75b..37bcdb160 100644 --- a/src/net/sourceforge/plantuml/project3/DayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/DayOfWeek.java @@ -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 { diff --git a/src/net/sourceforge/plantuml/project3/DaysAsDates.java b/src/net/sourceforge/plantuml/project/DaysAsDates.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/DaysAsDates.java rename to src/net/sourceforge/plantuml/project/DaysAsDates.java index abf96514c..612b68c1e 100644 --- a/src/net/sourceforge/plantuml/project3/DaysAsDates.java +++ b/src/net/sourceforge/plantuml/project/DaysAsDates.java @@ -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; diff --git a/src/net/sourceforge/plantuml/project3/Failable.java b/src/net/sourceforge/plantuml/project/Failable.java similarity index 97% rename from src/net/sourceforge/plantuml/project3/Failable.java rename to src/net/sourceforge/plantuml/project/Failable.java index 1263f66b6..482f1cdb2 100644 --- a/src/net/sourceforge/plantuml/project3/Failable.java +++ b/src/net/sourceforge/plantuml/project/Failable.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project; public class Failable<O> { diff --git a/src/net/sourceforge/plantuml/project3/GCalendarSimple.java b/src/net/sourceforge/plantuml/project/GCalendar.java similarity index 84% rename from src/net/sourceforge/plantuml/project3/GCalendarSimple.java rename to src/net/sourceforge/plantuml/project/GCalendar.java index 349c638e5..05090b701 100644 --- a/src/net/sourceforge/plantuml/project3/GCalendarSimple.java +++ b/src/net/sourceforge/plantuml/project/GCalendar.java @@ -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(); } diff --git a/src/net/sourceforge/plantuml/project3/GanttArrow.java b/src/net/sourceforge/plantuml/project/GanttArrow.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/GanttArrow.java rename to src/net/sourceforge/plantuml/project/GanttArrow.java index f8f0842e6..e5390b1c3 100644 --- a/src/net/sourceforge/plantuml/project3/GanttArrow.java +++ b/src/net/sourceforge/plantuml/project/GanttArrow.java @@ -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); diff --git a/src/net/sourceforge/plantuml/project3/GanttConstraint.java b/src/net/sourceforge/plantuml/project/GanttConstraint.java similarity index 88% rename from src/net/sourceforge/plantuml/project3/GanttConstraint.java rename to src/net/sourceforge/plantuml/project/GanttConstraint.java index a5bbf5db0..19c1566a0 100644 --- a/src/net/sourceforge/plantuml/project3/GanttConstraint.java +++ b/src/net/sourceforge/plantuml/project/GanttConstraint.java @@ -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 { diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java similarity index 63% rename from src/net/sourceforge/plantuml/project3/GanttDiagram.java rename to src/net/sourceforge/plantuml/project/GanttDiagram.java index b22f34344..6c6a66516 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java @@ -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; + } + } diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java similarity index 74% rename from src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java rename to src/net/sourceforge/plantuml/project/GanttDiagramFactory.java index 06ae4948f..d97972001 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java @@ -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)); } } } diff --git a/src/net/sourceforge/plantuml/project3/Load.java b/src/net/sourceforge/plantuml/project/Load.java similarity index 78% rename from src/net/sourceforge/plantuml/project3/Load.java rename to src/net/sourceforge/plantuml/project/Load.java index d74b619a3..74d807464 100644 --- a/src/net/sourceforge/plantuml/project3/Load.java +++ b/src/net/sourceforge/plantuml/project/Load.java @@ -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; + } } diff --git a/src/net/sourceforge/plantuml/project3/LoadPlanable.java b/src/net/sourceforge/plantuml/project/LoadPlanable.java similarity index 90% rename from src/net/sourceforge/plantuml/project3/LoadPlanable.java rename to src/net/sourceforge/plantuml/project/LoadPlanable.java index 11560e6c1..15a909c7c 100644 --- a/src/net/sourceforge/plantuml/project3/LoadPlanable.java +++ b/src/net/sourceforge/plantuml/project/LoadPlanable.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/project3/PlanUtils.java b/src/net/sourceforge/plantuml/project/PlanUtils.java similarity index 90% rename from src/net/sourceforge/plantuml/project3/PlanUtils.java rename to src/net/sourceforge/plantuml/project/PlanUtils.java index 8afc8e87c..0d1ce7b18 100644 --- a/src/net/sourceforge/plantuml/project3/PlanUtils.java +++ b/src/net/sourceforge/plantuml/project/PlanUtils.java @@ -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; } }; diff --git a/src/net/sourceforge/plantuml/project3/Solver3.java b/src/net/sourceforge/plantuml/project/Solver3.java similarity index 84% rename from src/net/sourceforge/plantuml/project3/Solver3.java rename to src/net/sourceforge/plantuml/project/Solver3.java index 203517de2..976ab40bd 100644 --- a/src/net/sourceforge/plantuml/project3/Solver3.java +++ b/src/net/sourceforge/plantuml/project/Solver3.java @@ -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(); } diff --git a/src/net/sourceforge/plantuml/project3/Today.java b/src/net/sourceforge/plantuml/project/Today.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/Today.java rename to src/net/sourceforge/plantuml/project/Today.java index 9a15b24b8..f7c03b3d5 100644 --- a/src/net/sourceforge/plantuml/project3/Today.java +++ b/src/net/sourceforge/plantuml/project/Today.java @@ -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 { diff --git a/src/net/sourceforge/plantuml/project3/Value.java b/src/net/sourceforge/plantuml/project/Value.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/Value.java rename to src/net/sourceforge/plantuml/project/Value.java index 18df4746b..59f98828a 100644 --- a/src/net/sourceforge/plantuml/project3/Value.java +++ b/src/net/sourceforge/plantuml/project/Value.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project; public interface Value { diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java similarity index 89% rename from src/net/sourceforge/plantuml/project3/CommandGanttArrow.java rename to src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java index 6d47510ba..72416d7f8 100644 --- a/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java +++ b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow2.java similarity index 94% rename from src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java rename to src/net/sourceforge/plantuml/project/command/CommandGanttArrow2.java index 33283a808..900dfce8c 100644 --- a/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java +++ b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow2.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/CommandPage.java b/src/net/sourceforge/plantuml/project/command/CommandPage.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/CommandPage.java rename to src/net/sourceforge/plantuml/project/command/CommandPage.java index 8c62678b8..60da3b674 100644 --- a/src/net/sourceforge/plantuml/project3/CommandPage.java +++ b/src/net/sourceforge/plantuml/project/command/CommandPage.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java b/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java new file mode 100644 index 000000000..ed436bbc1 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java @@ -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(); + } + +} diff --git a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java new file mode 100644 index 000000000..64c09ceda --- /dev/null +++ b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java @@ -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(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/CommandSeparator.java b/src/net/sourceforge/plantuml/project/command/CommandSeparator.java similarity index 95% rename from src/net/sourceforge/plantuml/project3/CommandSeparator.java rename to src/net/sourceforge/plantuml/project/command/CommandSeparator.java index 15fc31546..11e9bbfca 100644 --- a/src/net/sourceforge/plantuml/project3/CommandSeparator.java +++ b/src/net/sourceforge/plantuml/project/command/CommandSeparator.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommand.java b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java similarity index 86% rename from src/net/sourceforge/plantuml/project3/NaturalCommand.java rename to src/net/sourceforge/plantuml/project/command/NaturalCommand.java index d3b11bbaa..4266907ae 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommand.java +++ b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java b/src/net/sourceforge/plantuml/project/command/NaturalCommandAnd.java similarity index 89% rename from src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java rename to src/net/sourceforge/plantuml/project/command/NaturalCommandAnd.java index 82346d993..663c0d8b1 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommandAnd.java +++ b/src/net/sourceforge/plantuml/project/command/NaturalCommandAnd.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java b/src/net/sourceforge/plantuml/project/command/NaturalCommandAndAnd.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java rename to src/net/sourceforge/plantuml/project/command/NaturalCommandAndAnd.java index 4395d8be9..63b0d8080 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommandAndAnd.java +++ b/src/net/sourceforge/plantuml/project/command/NaturalCommandAndAnd.java @@ -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> { diff --git a/src/net/sourceforge/plantuml/project3/Moment.java b/src/net/sourceforge/plantuml/project/core/Moment.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/Moment.java rename to src/net/sourceforge/plantuml/project/core/Moment.java index fb18a4396..cea85f99a 100644 --- a/src/net/sourceforge/plantuml/project3/Moment.java +++ b/src/net/sourceforge/plantuml/project/core/Moment.java @@ -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(); } diff --git a/src/net/sourceforge/plantuml/project3/MomentImpl.java b/src/net/sourceforge/plantuml/project/core/MomentImpl.java similarity index 87% rename from src/net/sourceforge/plantuml/project3/MomentImpl.java rename to src/net/sourceforge/plantuml/project/core/MomentImpl.java index a56938456..410d3059b 100644 --- a/src/net/sourceforge/plantuml/project3/MomentImpl.java +++ b/src/net/sourceforge/plantuml/project/core/MomentImpl.java @@ -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; } diff --git a/src/net/sourceforge/plantuml/project3/Month.java b/src/net/sourceforge/plantuml/project/core/Month.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/Month.java rename to src/net/sourceforge/plantuml/project/core/Month.java index 64fe1f816..73528c4fc 100644 --- a/src/net/sourceforge/plantuml/project3/Month.java +++ b/src/net/sourceforge/plantuml/project/core/Month.java @@ -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; } + } diff --git a/src/net/sourceforge/plantuml/project3/GCalendar.java b/src/net/sourceforge/plantuml/project/core/PrintScale.java similarity index 85% rename from src/net/sourceforge/plantuml/project3/GCalendar.java rename to src/net/sourceforge/plantuml/project/core/PrintScale.java index b621e33e8..ecde6640c 100644 --- a/src/net/sourceforge/plantuml/project3/GCalendar.java +++ b/src/net/sourceforge/plantuml/project/core/PrintScale.java @@ -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; + } } diff --git a/src/net/sourceforge/plantuml/project3/Resource.java b/src/net/sourceforge/plantuml/project/core/Resource.java similarity index 79% rename from src/net/sourceforge/plantuml/project3/Resource.java rename to src/net/sourceforge/plantuml/project/core/Resource.java index 54eb1d9b5..a5cb17364 100644 --- a/src/net/sourceforge/plantuml/project3/Resource.java +++ b/src/net/sourceforge/plantuml/project/core/Resource.java @@ -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); } diff --git a/src/net/sourceforge/plantuml/project3/Task.java b/src/net/sourceforge/plantuml/project/core/Task.java similarity index 79% rename from src/net/sourceforge/plantuml/project3/Task.java rename to src/net/sourceforge/plantuml/project/core/Task.java index 0f2e8410f..74353fc61 100644 --- a/src/net/sourceforge/plantuml/project3/Task.java +++ b/src/net/sourceforge/plantuml/project/core/Task.java @@ -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); + } diff --git a/src/net/sourceforge/plantuml/project3/TaskAttribute.java b/src/net/sourceforge/plantuml/project/core/TaskAttribute.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/TaskAttribute.java rename to src/net/sourceforge/plantuml/project/core/TaskAttribute.java index f326e3778..6137ebd8e 100644 --- a/src/net/sourceforge/plantuml/project3/TaskAttribute.java +++ b/src/net/sourceforge/plantuml/project/core/TaskAttribute.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.core; public enum TaskAttribute { START, END, LOAD; diff --git a/src/net/sourceforge/plantuml/project3/TaskCode.java b/src/net/sourceforge/plantuml/project/core/TaskCode.java similarity index 97% rename from src/net/sourceforge/plantuml/project3/TaskCode.java rename to src/net/sourceforge/plantuml/project/core/TaskCode.java index e6466abc0..5ea518c0a 100644 --- a/src/net/sourceforge/plantuml/project3/TaskCode.java +++ b/src/net/sourceforge/plantuml/project/core/TaskCode.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.core; public class TaskCode { diff --git a/src/net/sourceforge/plantuml/project3/TaskImpl.java b/src/net/sourceforge/plantuml/project/core/TaskImpl.java similarity index 82% rename from src/net/sourceforge/plantuml/project3/TaskImpl.java rename to src/net/sourceforge/plantuml/project/core/TaskImpl.java index f5ed4f63d..f800558f6 100644 --- a/src/net/sourceforge/plantuml/project3/TaskImpl.java +++ b/src/net/sourceforge/plantuml/project/core/TaskImpl.java @@ -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; + } } diff --git a/src/net/sourceforge/plantuml/project3/TaskInstant.java b/src/net/sourceforge/plantuml/project/core/TaskInstant.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/TaskInstant.java rename to src/net/sourceforge/plantuml/project/core/TaskInstant.java index de638c38f..3d4d72e1e 100644 --- a/src/net/sourceforge/plantuml/project3/TaskInstant.java +++ b/src/net/sourceforge/plantuml/project/core/TaskInstant.java @@ -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()); } diff --git a/src/net/sourceforge/plantuml/project3/TaskSeparator.java b/src/net/sourceforge/plantuml/project/core/TaskSeparator.java similarity index 85% rename from src/net/sourceforge/plantuml/project3/TaskSeparator.java rename to src/net/sourceforge/plantuml/project/core/TaskSeparator.java index 093e82221..8f5942c74 100644 --- a/src/net/sourceforge/plantuml/project3/TaskSeparator.java +++ b/src/net/sourceforge/plantuml/project/core/TaskSeparator.java @@ -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(); + } + } diff --git a/src/net/sourceforge/plantuml/project3/InstantDay.java b/src/net/sourceforge/plantuml/project/core/Wink.java similarity index 72% rename from src/net/sourceforge/plantuml/project3/InstantDay.java rename to src/net/sourceforge/plantuml/project/core/Wink.java index 4a198651d..94c83dba5 100644 --- a/src/net/sourceforge/plantuml/project3/InstantDay.java +++ b/src/net/sourceforge/plantuml/project/core/Wink.java @@ -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); } } diff --git a/src/net/sourceforge/plantuml/project3/ResourceDraw.java b/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java similarity index 90% rename from src/net/sourceforge/plantuml/project3/ResourceDraw.java rename to src/net/sourceforge/plantuml/project/draw/ResourceDraw.java index 2f7e4e768..e95c35054 100644 --- a/src/net/sourceforge/plantuml/project3/ResourceDraw.java +++ b/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java @@ -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 diff --git a/src/net/sourceforge/plantuml/project3/TaskDraw.java b/src/net/sourceforge/plantuml/project/draw/TaskDraw.java similarity index 89% rename from src/net/sourceforge/plantuml/project3/TaskDraw.java rename to src/net/sourceforge/plantuml/project/draw/TaskDraw.java index e84c44594..bd2b5381d 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDraw.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDraw.java @@ -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(); diff --git a/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java similarity index 70% rename from src/net/sourceforge/plantuml/project3/TaskDrawRegular.java rename to src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java index 0ea267f01..1b8f26a0b 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java @@ -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; } } diff --git a/src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java similarity index 89% rename from src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java rename to src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java index d29f73011..e54aeb308 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java +++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawSeparator.java @@ -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) { } } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java new file mode 100644 index 000000000..982f9c82d --- /dev/null +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java @@ -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; + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java new file mode 100644 index 000000000..a0a819fef --- /dev/null +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java @@ -0,0 +1,188 @@ +/* ======================================================================== + * 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 java.util.Map; + +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.DayAsDate; +import net.sourceforge.plantuml.project.DayOfWeek; +import net.sourceforge.plantuml.project.GCalendar; +import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.core.Month; +import net.sourceforge.plantuml.project.core.Wink; +import net.sourceforge.plantuml.project.timescale.TimeScaleDaily; +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +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 TimeHeaderDaily extends TimeHeader { + + private static final int Y_POS_WEEKDAY = 16; + private static final int Y_POS_NUMDAY = 28; + + private double getTimeHeaderHeight() { + return Y_POS_NUMDAY + 13; + } + + private final HtmlColor veryLightGray = new HtmlColorSetSimple().getColorIfValid("#E0E8E8"); + + private final GCalendar calendar; + private final LoadPlanable defaultPlan; + private final Map<DayAsDate, HtmlColor> colorDays; + private final Map<DayAsDate, String> nameDays; + + public TimeHeaderDaily(GCalendar calendar, Wink min, Wink max, LoadPlanable defaultPlan, + Map<DayAsDate, HtmlColor> colorDays, Map<DayAsDate, String> nameDays, DayAsDate printStart, + DayAsDate printEnd) { + super(min, max, new TimeScaleDaily(calendar, printStart)); + this.calendar = calendar; + this.defaultPlan = defaultPlan; + this.colorDays = colorDays; + this.nameDays = nameDays; + } + + @Override + public void drawTimeHeader(final UGraphic ug, double totalHeight) { + drawCalendar(ug, totalHeight); + drawHline(ug, 0); + drawHline(ug, getFullHeaderHeight()); + + } + + private void drawCalendar(final UGraphic ug, double totalHeight) { + Month lastMonth = null; + double lastChangeMonth = -1; + Wink wink = min; + while (wink.compareTo(max) <= 0) { + final DayAsDate day = calendar.toDayAsDate(wink); + final DayOfWeek dayOfWeek = day.getDayOfWeek(); + final boolean isWorkingDay = defaultPlan.getLoadAt(wink) > 0; + final String d1 = "" + day.getDayOfMonth(); + final TextBlock num = getTextBlock(d1, 10, false); + final double x1 = getTimeScale().getStartingPosition(wink); + final double x2 = getTimeScale().getEndingPosition(wink); + double startingY = getFullHeaderHeight(); + if (wink.compareTo(max.increment()) < 0) { + final TextBlock weekDay = getTextBlock(dayOfWeek.shortName(), 10, false); + + final URectangle rect = new URectangle(x2 - x1 - 1, totalHeight - getFullHeaderHeight()); + 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, getFullHeaderHeight())).draw(rect); + } + printCentered(ug.apply(new UTranslate(0, Y_POS_WEEKDAY)), weekDay, x1, x2); + printCentered(ug.apply(new UTranslate(0, Y_POS_NUMDAY)), num, x1, x2); + } else { + ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(veryLightGray)) + .apply(new UTranslate(x1 + 1, getFullHeaderHeight())).draw(rect); + } + if (lastMonth != day.getMonth()) { + startingY = 0; + if (lastMonth != null) { + printMonth(ug, lastMonth, day.getYear(), lastChangeMonth, x1); + } + lastChangeMonth = x1; + lastMonth = day.getMonth(); + } + } + drawVbar(ug, x1, startingY, totalHeight); + wink = wink.increment(); + } + final DayAsDate day = calendar.toDayAsDate(max); + final double x1 = getTimeScale().getStartingPosition(wink); + drawVbar(ug, x1, Y_POS_WEEKDAY, totalHeight); + if (x1 > lastChangeMonth) { + printMonth(ug, lastMonth, day.getYear(), lastChangeMonth, x1); + } + + printNamedDays(ug); + + } + + private void printMonth(UGraphic ug, Month lastMonth, int year, double start, double end) { + final TextBlock tiny = getTextBlock(lastMonth.shortName(), 12, true); + final TextBlock small = getTextBlock(lastMonth.niceName(), 12, true); + final TextBlock big = getTextBlock(lastMonth.niceName() + " " + year, 12, true); + printCentered(ug, start, end, tiny, small, big); + } + + private void drawVbar(UGraphic ug, double x, double y1, double y2) { + final ULine vbar = new ULine(0, y2 - y1); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x, y1)).draw(vbar); + } + + private void printNamedDays(final UGraphic ug) { + if (nameDays.size() > 0) { + String last = null; + for (Wink wink = min; wink.compareTo(max.increment()) <= 0; wink = wink.increment()) { + final DayAsDate tmpday = calendar.toDayAsDate(wink); + final String name = nameDays.get(tmpday); + if (name != null && name.equals(last) == false) { + final double x1 = getTimeScale().getStartingPosition(wink); + final double x2 = getTimeScale().getEndingPosition(wink); + final TextBlock label = getTextBlock(name, 12, false); + final double h = label.calculateDimension(ug.getStringBounder()).getHeight(); + double y1 = getTimeHeaderHeight(); + double y2 = getFullHeaderHeight(); + label.drawU(ug.apply(new UTranslate(x1, Y_POS_NUMDAY + 11))); + } + last = name; + } + } + } + + @Override + public double getFullHeaderHeight() { + return getTimeHeaderHeight() + getHeaderNameDayHeight(); + } + + private double getHeaderNameDayHeight() { + if (nameDays.size() > 0) { + return 16; + } + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java new file mode 100644 index 000000000..2d07d261d --- /dev/null +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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.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.project.timescale.TimeScaleWink; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class TimeHeaderSimple extends TimeHeader { + + public TimeHeaderSimple(Wink min, Wink max) { + super(min, max, new TimeScaleWink()); + } + + @Override + public void drawTimeHeader(final UGraphic ug, double totalHeight) { + final double xmin = getTimeScale().getStartingPosition(min); + final double xmax = getTimeScale().getEndingPosition(max); + drawSimpleDayCounter(ug, getTimeScale(), totalHeight); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).draw(new ULine(xmax - xmin, 0)); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(0, getFullHeaderHeight() - 3)) + .draw(new ULine(xmax - xmin, 0)); + + } + + private void drawSimpleDayCounter(final UGraphic ug, TimeScale timeScale, double totalHeight) { + final ULine vbar = new ULine(0, totalHeight); + for (Wink 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); + } + } + + @Override + public double getFullHeaderHeight() { + return getTimeHeaderHeight() + getHeaderNameDayHeight(); + } + + private double getTimeHeaderHeight() { + return 16; + } + + private double getHeaderNameDayHeight() { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java new file mode 100644 index 000000000..d6433515c --- /dev/null +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java @@ -0,0 +1,188 @@ +/* ======================================================================== + * 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 java.util.Map; + +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +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.DayAsDate; +import net.sourceforge.plantuml.project.DayOfWeek; +import net.sourceforge.plantuml.project.GCalendar; +import net.sourceforge.plantuml.project.LoadPlanable; +import net.sourceforge.plantuml.project.core.Month; +import net.sourceforge.plantuml.project.core.Wink; +import net.sourceforge.plantuml.project.timescale.TimeScaleWeekly; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class TimeHeaderWeekly extends TimeHeader { + + private static final int Y_POS_NUMDAY = 16; + + private double getTimeHeaderHeight() { + return Y_POS_NUMDAY + 13; + } + + private final HtmlColor veryLightGray = new HtmlColorSetSimple().getColorIfValid("#E0E8E8"); + + private final GCalendar calendar; + private final LoadPlanable defaultPlan; + private final Map<DayAsDate, HtmlColor> colorDays; + private final Map<DayAsDate, String> nameDays; + + public TimeHeaderWeekly(GCalendar calendar, Wink min, Wink max, LoadPlanable defaultPlan, + Map<DayAsDate, HtmlColor> colorDays, Map<DayAsDate, String> nameDays) { + super(min, max, new TimeScaleWeekly(calendar)); + this.calendar = calendar; + this.defaultPlan = defaultPlan; + this.colorDays = colorDays; + this.nameDays = nameDays; + } + + @Override + public void drawTimeHeader(final UGraphic ug, double totalHeight) { + drawCalendar(ug, totalHeight); + drawHline(ug, 0); + drawHline(ug, Y_POS_NUMDAY); + drawHline(ug, getFullHeaderHeight()); + + } + + private void drawCalendar(final UGraphic ug, double totalHeight) { + Month lastMonth = null; + double lastChangeMonth = -1; + Wink wink = min; + while (wink.compareTo(max) <= 0) { + final DayAsDate day = calendar.toDayAsDate(wink); + final DayOfWeek dayOfWeek = day.getDayOfWeek(); + final String d1 = "" + day.getDayOfMonth(); + final TextBlock num = getTextBlock(d1, 10, false); + final double x1 = getTimeScale().getStartingPosition(wink); + final double x2 = getTimeScale().getEndingPosition(wink); + double startingY = getFullHeaderHeight(); + if (wink.compareTo(max.increment()) < 0) { + if (dayOfWeek == DayOfWeek.MONDAY) { + printLeft(ug.apply(new UTranslate(0, Y_POS_NUMDAY)), num, x1 + 5); + } + if (lastMonth != day.getMonth()) { + startingY = Y_POS_NUMDAY; + drawVbar(ug, x1, 0, Y_POS_NUMDAY); + if (lastMonth != null) { + printMonth(ug, lastMonth, day.getYear(), lastChangeMonth, x1); + } + lastChangeMonth = x1; + lastMonth = day.getMonth(); + } + } + if (dayOfWeek == DayOfWeek.MONDAY) { + drawVbar(ug, x1, Y_POS_NUMDAY, totalHeight); + } + wink = wink.increment(); + } + final DayAsDate day = calendar.toDayAsDate(wink); + final double x1 = getTimeScale().getStartingPosition(wink); + if (x1 > lastChangeMonth) { + printMonth(ug, lastMonth, day.getYear(), lastChangeMonth, x1); + } + + printNamedDays(ug); + + } + + private void printMonth(UGraphic ug, Month lastMonth, int year, double start, double end) { + final TextBlock small = getTextBlock(lastMonth.shortName(), 12, true); + final TextBlock big = getTextBlock(lastMonth.shortName() + " " + year, 12, true); + printCentered(ug, start, end, small, big); + } + + private void drawVbar(UGraphic ug, double x, double y1, double y2) { + final ULine vbar = new ULine(0, y2 - y1); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x, y1)).draw(vbar); + } + + private void printNamedDays(final UGraphic ug) { +// if (nameDays.size() > 0) { +// String last = null; +// for (Wink wink = min; wink.compareTo(max.increment()) <= 0; wink = wink.increment()) { +// final DayAsDate tmpday = calendar.toDayAsDate(wink); +// final String name = nameDays.get(tmpday); +// if (name != null && name.equals(last) == false) { +// final double x1 = getTimeScale().getStartingPosition(wink); +// final double x2 = getTimeScale().getEndingPosition(wink); +// final TextBlock label = getTextBlock(name, 12, false); +// final double h = label.calculateDimension(ug.getStringBounder()).getHeight(); +// double y1 = getTimeHeaderHeight(); +// double y2 = getFullHeaderHeight(); +// label.drawU(ug.apply(new UTranslate(x1, Y_POS_NUMDAY + 11))); +// } +// last = name; +// } +// } + } + + private void printLeft(UGraphic ug, TextBlock text, double start) { + text.drawU(ug.apply(new UTranslate(start, 0))); + } + + @Override + public double getFullHeaderHeight() { + return getTimeHeaderHeight() + getHeaderNameDayHeight(); + } + + private double getHeaderNameDayHeight() { +// if (nameDays.size() > 0) { +// return 16; +// } + return 0; + } + +// 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))); +// } +} diff --git a/src/net/sourceforge/plantuml/project3/Complement.java b/src/net/sourceforge/plantuml/project/lang/Complement.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/Complement.java rename to src/net/sourceforge/plantuml/project/lang/Complement.java index d9731d5f7..b20145e45 100644 --- a/src/net/sourceforge/plantuml/project3/Complement.java +++ b/src/net/sourceforge/plantuml/project/lang/Complement.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; public interface Complement { diff --git a/src/net/sourceforge/plantuml/project3/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java similarity index 88% rename from src/net/sourceforge/plantuml/project3/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java rename to src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java index 304eea13b..27f31f020 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java @@ -33,11 +33,16 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; 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.core.Moment; +import net.sourceforge.plantuml.project.core.TaskAttribute; +import net.sourceforge.plantuml.project.core.TaskInstant; public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementClose.java b/src/net/sourceforge/plantuml/project/lang/ComplementClose.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/ComplementClose.java rename to src/net/sourceforge/plantuml/project/lang/ComplementClose.java index b0059976a..e66247aa5 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementClose.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementClose.java @@ -33,11 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; 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; public class ComplementClose implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementColors.java b/src/net/sourceforge/plantuml/project/lang/ComplementColors.java similarity index 97% rename from src/net/sourceforge/plantuml/project3/ComplementColors.java rename to src/net/sourceforge/plantuml/project/lang/ComplementColors.java index a583fcd93..4bb445c1f 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementColors.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementColors.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java b/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java new file mode 100644 index 000000000..e6ff4b7f8 --- /dev/null +++ b/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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.lang; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.Completion; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; + +public class ComplementCompleted implements ComplementPattern { + + public IRegex toRegex(String suffix) { + return new RegexLeaf("COMPLEMENT" + suffix, "(\\d+).*completed?"); + } + + public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { + final String value = arg.get("COMPLEMENT" + suffix, 0); + return Failable.<Complement>ok(new Completion(Integer.parseInt(value))); + } +} diff --git a/src/net/sourceforge/plantuml/project3/ComplementDate.java b/src/net/sourceforge/plantuml/project/lang/ComplementDate.java similarity index 94% rename from src/net/sourceforge/plantuml/project3/ComplementDate.java rename to src/net/sourceforge/plantuml/project/lang/ComplementDate.java index 5683fabe8..e4cdb55ee 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementDate.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementDate.java @@ -33,13 +33,17 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; 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.Month; public class ComplementDate implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementDates.java b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/ComplementDates.java rename to src/net/sourceforge/plantuml/project/lang/ComplementDates.java index b09f2fad0..7cbb13e74 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementDates.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java @@ -33,12 +33,16 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; 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.DayAsDate; +import net.sourceforge.plantuml.project.DaysAsDates; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; public class ComplementDates implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java similarity index 90% rename from src/net/sourceforge/plantuml/project3/ComplementDayOfWeek.java rename to src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java index ce2a97577..416352281 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementDayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java @@ -33,12 +33,15 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; 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.DayOfWeek; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; public class ComplementDayOfWeek implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementEmpty.java b/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/ComplementEmpty.java rename to src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java index 874804789..ef9a03c4c 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementEmpty.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java @@ -33,11 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; 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; public class ComplementEmpty implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementInColors.java b/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/ComplementInColors.java rename to src/net/sourceforge/plantuml/project/lang/ComplementInColors.java index b8826e5ae..0c9b5b68c 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementInColors.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java @@ -33,12 +33,14 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; public class ComplementInColors implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementInColors2.java b/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/ComplementInColors2.java rename to src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java index 93f6d8a5f..fb1b504c2 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementInColors2.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java @@ -33,12 +33,14 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; public class ComplementInColors2 implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementName.java b/src/net/sourceforge/plantuml/project/lang/ComplementName.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/ComplementName.java rename to src/net/sourceforge/plantuml/project/lang/ComplementName.java index ed0e8ffee..75cf8997d 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementName.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementName.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; public class ComplementName implements Complement { diff --git a/src/net/sourceforge/plantuml/project3/ComplementNamed.java b/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/ComplementNamed.java rename to src/net/sourceforge/plantuml/project/lang/ComplementNamed.java index 0eee95740..55ee6fd6e 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementNamed.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java @@ -33,11 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; 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; public class ComplementNamed implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementOpen.java b/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/ComplementOpen.java rename to src/net/sourceforge/plantuml/project/lang/ComplementOpen.java index 975352f0f..69fd6bec0 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementOpen.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java @@ -33,11 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; 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; public class ComplementOpen implements ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementPattern.java b/src/net/sourceforge/plantuml/project/lang/ComplementPattern.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/ComplementPattern.java rename to src/net/sourceforge/plantuml/project/lang/ComplementPattern.java index 7f429a27f..cf5b0057f 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementPattern.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementPattern.java @@ -33,10 +33,12 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; public interface ComplementPattern { diff --git a/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java b/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java similarity index 89% rename from src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java rename to src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java index 91a1cd021..41a35d4bb 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java @@ -33,12 +33,15 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; 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.Failable; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.Load; public class ComplementSeveralDays implements ComplementPattern { @@ -52,7 +55,7 @@ public class ComplementSeveralDays implements ComplementPattern { final boolean inWeeks = arg.get("COMPLEMENT" + suffix, 1).startsWith("w"); final int factor = inWeeks ? system.daysInWeek() : 1; final int days = Integer.parseInt(number) * factor; - return Failable.<Complement> ok(LoadInDays.inDay(days)); + return Failable.<Complement> ok(Load.inWinks(days)); } } diff --git a/src/net/sourceforge/plantuml/project3/Subject.java b/src/net/sourceforge/plantuml/project/lang/Subject.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/Subject.java rename to src/net/sourceforge/plantuml/project/lang/Subject.java index ef1be6430..fba6a654e 100644 --- a/src/net/sourceforge/plantuml/project3/Subject.java +++ b/src/net/sourceforge/plantuml/project/lang/Subject.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; public interface Subject { diff --git a/src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java b/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java rename to src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java index 27737ac72..55992f2b8 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -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.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; public class SubjectDayAsDate implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/SubjectDayOfWeek.java rename to src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java index 899d5e3cb..5f2ab8192 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectDayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -41,6 +41,8 @@ import java.util.Collection; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayOfWeek; +import net.sourceforge.plantuml.project.GanttDiagram; public class SubjectDayOfWeek implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java b/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java similarity index 95% rename from src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java rename to src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java index ac7d04973..95398e7a5 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -43,6 +43,9 @@ 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.DaysAsDates; +import net.sourceforge.plantuml.project.GanttDiagram; public class SubjectDaysAsDates implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectPattern.java b/src/net/sourceforge/plantuml/project/lang/SubjectPattern.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/SubjectPattern.java rename to src/net/sourceforge/plantuml/project/lang/SubjectPattern.java index 99d39c346..155f4719b 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectPattern.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectPattern.java @@ -33,12 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Collection; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; public interface SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectProject.java b/src/net/sourceforge/plantuml/project/lang/SubjectProject.java similarity index 94% rename from src/net/sourceforge/plantuml/project3/SubjectProject.java rename to src/net/sourceforge/plantuml/project/lang/SubjectProject.java index 49e83f809..88d36c2e4 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectProject.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectProject.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -41,6 +41,7 @@ import java.util.Collection; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; public class SubjectProject implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectResource.java b/src/net/sourceforge/plantuml/project/lang/SubjectResource.java similarity index 95% rename from src/net/sourceforge/plantuml/project3/SubjectResource.java rename to src/net/sourceforge/plantuml/project/lang/SubjectResource.java index 510d074b3..7723325c1 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectResource.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectResource.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -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 SubjectResource implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/SubjectTask.java b/src/net/sourceforge/plantuml/project/lang/SubjectTask.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/SubjectTask.java rename to src/net/sourceforge/plantuml/project/lang/SubjectTask.java index e570b3e77..2b73cb61f 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectTask.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectTask.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -44,6 +44,8 @@ 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.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Task; public class SubjectTask implements SubjectPattern { @@ -51,7 +53,7 @@ public class SubjectTask implements SubjectPattern { return Arrays .<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(), new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored(), - new VerbIsDeleted()); + new VerbIsDeleted(), new VerbIsForTask()); } public IRegex toRegex() { diff --git a/src/net/sourceforge/plantuml/project3/SubjectToday.java b/src/net/sourceforge/plantuml/project/lang/SubjectToday.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/SubjectToday.java rename to src/net/sourceforge/plantuml/project/lang/SubjectToday.java index 595414566..1e58b7d78 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectToday.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectToday.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -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.Today; public class SubjectToday implements SubjectPattern { diff --git a/src/net/sourceforge/plantuml/project3/Verb.java b/src/net/sourceforge/plantuml/project/lang/Verb.java similarity index 96% rename from src/net/sourceforge/plantuml/project3/Verb.java rename to src/net/sourceforge/plantuml/project/lang/Verb.java index cd74b50df..dc46160a2 100644 --- a/src/net/sourceforge/plantuml/project3/Verb.java +++ b/src/net/sourceforge/plantuml/project/lang/Verb.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import net.sourceforge.plantuml.command.CommandExecutionResult; diff --git a/src/net/sourceforge/plantuml/project3/VerbAre.java b/src/net/sourceforge/plantuml/project/lang/VerbAre.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/VerbAre.java rename to src/net/sourceforge/plantuml/project/lang/VerbAre.java index 79ca1ca53..188e25d88 100644 --- a/src/net/sourceforge/plantuml/project3/VerbAre.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbAre.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayOfWeek; +import net.sourceforge.plantuml.project.GanttDiagram; public class VerbAre implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbEnds.java b/src/net/sourceforge/plantuml/project/lang/VerbEnds.java similarity index 87% rename from src/net/sourceforge/plantuml/project3/VerbEnds.java rename to src/net/sourceforge/plantuml/project/lang/VerbEnds.java index 67637111d..37e67b3cf 100644 --- a/src/net/sourceforge/plantuml/project3/VerbEnds.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbEnds.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,11 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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 VerbEnds implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbHappens.java b/src/net/sourceforge/plantuml/project/lang/VerbHappens.java similarity index 88% rename from src/net/sourceforge/plantuml/project3/VerbHappens.java rename to src/net/sourceforge/plantuml/project/lang/VerbHappens.java index ba647d221..c17a697d8 100644 --- a/src/net/sourceforge/plantuml/project3/VerbHappens.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbHappens.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,11 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.Load; +import net.sourceforge.plantuml.project.core.Task; +import net.sourceforge.plantuml.project.core.TaskInstant; public class VerbHappens implements VerbPattern { @@ -57,7 +62,7 @@ public class VerbHappens implements VerbPattern { return new Verb() { public CommandExecutionResult execute(Subject subject, Complement complement) { final Task task = (Task) subject; - task.setLoad(LoadInDays.inDay(1)); + task.setLoad(Load.inWinks(1)); if (complement instanceof DayAsDate) { final DayAsDate start = (DayAsDate) complement; final DayAsDate startingDate = project.getStartingDate(); diff --git a/src/net/sourceforge/plantuml/project3/VerbIsColored.java b/src/net/sourceforge/plantuml/project/lang/VerbIsColored.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/VerbIsColored.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsColored.java index a067a1345..a20d65314 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsColored.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsColored.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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 VerbIsColored implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbIsColoredForToday.java b/src/net/sourceforge/plantuml/project/lang/VerbIsColoredForToday.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/VerbIsColoredForToday.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsColoredForToday.java index fa9d5b39d..db4ba86b4 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsColoredForToday.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsColoredForToday.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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.Today; public class VerbIsColoredForToday implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbIsDeleted.java b/src/net/sourceforge/plantuml/project/lang/VerbIsDeleted.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/VerbIsDeleted.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsDeleted.java index 6b1830d1b..b17519734 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsDeleted.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsDeleted.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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 VerbIsDeleted implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project/lang/VerbIsForTask.java b/src/net/sourceforge/plantuml/project/lang/VerbIsForTask.java new file mode 100644 index 000000000..800473f5e --- /dev/null +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsForTask.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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.lang; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.Completion; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Task; + +public class VerbIsForTask implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern>asList(new ComplementCompleted()); + } + + public IRegex toRegex() { + return new RegexLeaf("is"); + } + + public Verb getVerb(final GanttDiagram project, RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final Task task = (Task) subject; + final Completion completed = (Completion) complement; + task.setCompletion(completed.getCompletion()); + return CommandExecutionResult.ok(); + } + + }; + } +} diff --git a/src/net/sourceforge/plantuml/project3/VerbIsForToday.java b/src/net/sourceforge/plantuml/project/lang/VerbIsForToday.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/VerbIsForToday.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsForToday.java index 61aa0d559..030df6334 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsForToday.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsForToday.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,8 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; public class VerbIsForToday implements VerbPattern { @@ -56,7 +58,7 @@ public class VerbIsForToday implements VerbPattern { public Verb getVerb(final GanttDiagram project, RegexResult arg) { return new Verb() { public CommandExecutionResult execute(Subject subject, Complement complement) { - final Today task = (Today) subject; + // final Today task = (Today) subject; final DayAsDate date = (DayAsDate) complement; return project.setToday(date); } diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOff.java b/src/net/sourceforge/plantuml/project/lang/VerbIsOff.java similarity index 90% rename from src/net/sourceforge/plantuml/project3/VerbIsOff.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsOff.java index 7ce044d75..285ea496a 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsOff.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsOff.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -44,6 +44,11 @@ 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.DayOfWeek; +import net.sourceforge.plantuml.project.DaysAsDates; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Resource; public class VerbIsOff implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOn.java b/src/net/sourceforge/plantuml/project/lang/VerbIsOn.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/VerbIsOn.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsOn.java index 11e468830..44003c446 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsOn.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsOn.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -44,6 +44,10 @@ 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.DaysAsDates; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Resource; public class VerbIsOn implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOrAre.java b/src/net/sourceforge/plantuml/project/lang/VerbIsOrAre.java similarity index 94% rename from src/net/sourceforge/plantuml/project3/VerbIsOrAre.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsOrAre.java index fdc340126..dd639b263 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsOrAre.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsOrAre.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -43,6 +43,9 @@ import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.DaysAsDates; +import net.sourceforge.plantuml.project.GanttDiagram; public class VerbIsOrAre implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java b/src/net/sourceforge/plantuml/project/lang/VerbIsOrAreNamed.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java rename to src/net/sourceforge/plantuml/project/lang/VerbIsOrAreNamed.java index 91dcfd623..01062ee21 100644 --- a/src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbIsOrAreNamed.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,9 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.DaysAsDates; +import net.sourceforge.plantuml.project.GanttDiagram; public class VerbIsOrAreNamed implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbLasts.java b/src/net/sourceforge/plantuml/project/lang/VerbLasts.java similarity index 91% rename from src/net/sourceforge/plantuml/project3/VerbLasts.java rename to src/net/sourceforge/plantuml/project/lang/VerbLasts.java index 2a68a6ab7..71a0705f1 100644 --- a/src/net/sourceforge/plantuml/project3/VerbLasts.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbLasts.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,9 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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.Load; +import net.sourceforge.plantuml.project.core.Task; public class VerbLasts implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbPattern.java b/src/net/sourceforge/plantuml/project/lang/VerbPattern.java similarity index 93% rename from src/net/sourceforge/plantuml/project3/VerbPattern.java rename to src/net/sourceforge/plantuml/project/lang/VerbPattern.java index c810ceffe..8360b4bb1 100644 --- a/src/net/sourceforge/plantuml/project3/VerbPattern.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbPattern.java @@ -33,12 +33,13 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Collection; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.GanttDiagram; public interface VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java b/src/net/sourceforge/plantuml/project/lang/VerbProjectStarts.java similarity index 94% rename from src/net/sourceforge/plantuml/project3/VerbProjectStarts.java rename to src/net/sourceforge/plantuml/project/lang/VerbProjectStarts.java index d9bceb122..2d0b047fc 100644 --- a/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbProjectStarts.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -45,6 +45,8 @@ 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.project.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; public class VerbProjectStarts implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java b/src/net/sourceforge/plantuml/project/lang/VerbTaskEndsAbsolute.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java rename to src/net/sourceforge/plantuml/project/lang/VerbTaskEndsAbsolute.java index 1fb86199e..10d44afd4 100644 --- a/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbTaskEndsAbsolute.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,9 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Task; public class VerbTaskEndsAbsolute implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskStarts.java b/src/net/sourceforge/plantuml/project/lang/VerbTaskStarts.java similarity index 87% rename from src/net/sourceforge/plantuml/project3/VerbTaskStarts.java rename to src/net/sourceforge/plantuml/project/lang/VerbTaskStarts.java index fc1468755..0418b49d4 100644 --- a/src/net/sourceforge/plantuml/project3/VerbTaskStarts.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbTaskStarts.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,11 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; 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 VerbTaskStarts implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java b/src/net/sourceforge/plantuml/project/lang/VerbTaskStartsAbsolute.java similarity index 92% rename from src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java rename to src/net/sourceforge/plantuml/project/lang/VerbTaskStartsAbsolute.java index 5f8b4eca3..22dee2089 100644 --- a/src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java +++ b/src/net/sourceforge/plantuml/project/lang/VerbTaskStartsAbsolute.java @@ -33,7 +33,7 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.lang; import java.util.Arrays; import java.util.Collection; @@ -42,6 +42,9 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.GanttDiagram; +import net.sourceforge.plantuml.project.core.Task; public class VerbTaskStartsAbsolute implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/project3/TimeScale.java b/src/net/sourceforge/plantuml/project/timescale/TimeScale.java similarity index 84% rename from src/net/sourceforge/plantuml/project3/TimeScale.java rename to src/net/sourceforge/plantuml/project/timescale/TimeScale.java index 7644d444b..b5baf4ef6 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScale.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScale.java @@ -33,14 +33,16 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.timescale; + +import net.sourceforge.plantuml.project.core.Wink; public interface TimeScale { - public double getStartingPosition(Instant instant); + public double getStartingPosition(Wink instant); - public double getEndingPosition(Instant instant); + public double getEndingPosition(Wink instant); - public double getWidth(Instant instant); + public double getWidth(Wink instant); } diff --git a/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java new file mode 100644 index 000000000..e8bafb6cb --- /dev/null +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleDaily.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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.timescale; + +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.GCalendar; +import net.sourceforge.plantuml.project.core.Wink; + +public final class TimeScaleDaily implements TimeScale { + + private final TimeScaleWink basic; + private final double delta; + + public TimeScaleDaily(GCalendar calendar, DayAsDate zeroDay) { + this.basic = new TimeScaleWink(); + if (zeroDay == null) { + this.delta = 0; + } else { + this.delta = basic.getStartingPosition(calendar.fromDayAsDate(zeroDay)); + } + + } + + public double getStartingPosition(Wink instant) { + return basic.getStartingPosition(instant) - delta; + } + + public double getEndingPosition(Wink instant) { + return basic.getEndingPosition(instant) - delta; + } + + public double getWidth(Wink instant) { + return basic.getWidth(instant); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/LoadInDays.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleWeekly.java similarity index 65% rename from src/net/sourceforge/plantuml/project3/LoadInDays.java rename to src/net/sourceforge/plantuml/project/timescale/TimeScaleWeekly.java index 7ef804869..c06dc0780 100644 --- a/src/net/sourceforge/plantuml/project3/LoadInDays.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleWeekly.java @@ -33,28 +33,30 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.timescale; -public class LoadInDays implements Load { +import net.sourceforge.plantuml.project.GCalendar; +import net.sourceforge.plantuml.project.core.Wink; - private final int days; - private final int loadPerDay; +public class TimeScaleWeekly implements TimeScale { - private LoadInDays(int days, int loadPerDay) { - this.days = days; - this.loadPerDay = loadPerDay; + private static final int COMPRESS = 4; + private final TimeScale daily; + + public TimeScaleWeekly(GCalendar calendar) { + this.daily = new TimeScaleDaily(calendar, null); } - public static LoadInDays inDay(int days) { - return new LoadInDays(days, 100); + public double getStartingPosition(Wink instant) { + return daily.getStartingPosition(instant) / COMPRESS; } - public int getFullLoad() { - return days * loadPerDay; + public double getEndingPosition(Wink instant) { + return daily.getEndingPosition(instant) / COMPRESS; } - public int getLoadAt(Instant instant) { - return loadPerDay; + public double getWidth(Wink instant) { + return daily.getWidth(instant) / COMPRESS; } } diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleWink.java similarity index 79% rename from src/net/sourceforge/plantuml/project3/TimeScaleBasic.java rename to src/net/sourceforge/plantuml/project/timescale/TimeScaleWink.java index 85d5d9f3a..118642613 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleWink.java @@ -33,22 +33,24 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.timescale; -public class TimeScaleBasic implements TimeScale { +import net.sourceforge.plantuml.project.core.Wink; + +public class TimeScaleWink implements TimeScale { private final double scale = 16.0; - public double getStartingPosition(Instant instant) { - final int day = ((InstantDay) instant).getNumDay(); - return day * scale; + public double getStartingPosition(Wink instant) { + final int wink = instant.getWink(); + return wink * scale; } - public double getEndingPosition(Instant instant) { + public double getEndingPosition(Wink instant) { return getStartingPosition(instant) + getWidth(instant); } - public double getWidth(Instant instant) { + public double getWidth(Wink instant) { return scale; } diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java b/src/net/sourceforge/plantuml/project/timescale/UnusedTimeScaleWithoutWeekEnd.java similarity index 72% rename from src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java rename to src/net/sourceforge/plantuml/project/timescale/UnusedTimeScaleWithoutWeekEnd.java index 9ef521c4c..da6e677e5 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java +++ b/src/net/sourceforge/plantuml/project/timescale/UnusedTimeScaleWithoutWeekEnd.java @@ -33,32 +33,37 @@ * * */ -package net.sourceforge.plantuml.project3; +package net.sourceforge.plantuml.project.timescale; -public class TimeScaleWithoutWeekEnd implements TimeScale { +import net.sourceforge.plantuml.project.DayAsDate; +import net.sourceforge.plantuml.project.DayOfWeek; +import net.sourceforge.plantuml.project.GCalendar; +import net.sourceforge.plantuml.project.core.Wink; + +public class UnusedTimeScaleWithoutWeekEnd implements TimeScale { private final double scale = 16.0; private final GCalendar calendar; - public TimeScaleWithoutWeekEnd(GCalendar calendar) { + public UnusedTimeScaleWithoutWeekEnd(GCalendar calendar) { if (calendar == null) { throw new IllegalArgumentException(); } this.calendar = calendar; } - public double getStartingPosition(Instant instant) { + public double getStartingPosition(Wink instant) { double result = 0; - InstantDay current = (InstantDay) instant; - while (current.getNumDay() > 0) { + Wink current = (Wink) instant; + while (current.getWink() > 0) { current = current.decrement(); result += getWidth(current); } return result; } - public double getWidth(Instant instant) { - final DayAsDate day = calendar.toDayAsDate((InstantDay) instant); + public double getWidth(Wink instant) { + final DayAsDate day = calendar.toDayAsDate((Wink) instant); final DayOfWeek dayOfWeek = day.getDayOfWeek(); if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) { return 1; @@ -66,7 +71,7 @@ public class TimeScaleWithoutWeekEnd implements TimeScale { return scale; } - public double getEndingPosition(Instant instant) { + public double getEndingPosition(Wink instant) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java b/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java deleted file mode 100644 index 5341ef0a1..000000000 --- a/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java +++ /dev/null @@ -1,79 +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.project3; - -import java.util.Map; -import java.util.TreeMap; - -public class TimeScaleBasic2 implements TimeScale { - - private final GCalendar calendar; - private final GCalendar calendarAllOpen; - private final TimeScaleBasic basic = new TimeScaleBasic(); - private final Map<Instant, Instant> cache = new TreeMap<Instant, Instant>(); - - public TimeScaleBasic2(GCalendarSimple calendar) { - this.calendar = calendar; - this.calendarAllOpen = calendar; - } - - private Instant changeInstantSlow(Instant instant) { - final DayAsDate day = calendar.toDayAsDate((InstantDay) instant); - return calendarAllOpen.fromDayAsDate(day); - } - - private Instant changeInstant(Instant instant) { - Instant result = cache.get(instant); - if (result == null) { - result = changeInstantSlow(instant); - cache.put(instant, result); - } - return result; - } - - public double getStartingPosition(Instant instant) { - return basic.getStartingPosition(changeInstant(instant)); - } - - public double getEndingPosition(Instant instant) { - return basic.getEndingPosition(changeInstant(instant)); - } - - public double getWidth(Instant instant) { - return basic.getWidth(changeInstant(instant)); - } - -} diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index e7fc050b6..9ade106b7 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -54,7 +54,7 @@ import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.command.BlocLines; import net.sourceforge.plantuml.command.Command; import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.FactorySpriteCommand; +import net.sourceforge.plantuml.command.CommandFactorySprite; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.graphic.HtmlColorUtils; @@ -143,8 +143,7 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite { private List<String> manageSprite() { - final FactorySpriteCommand factorySpriteCommand = new FactorySpriteCommand(); - Command<WithSprite> cmd = factorySpriteCommand.createMultiLine(false); + final Command<WithSprite> cmd = new CommandFactorySprite().createMultiLine(false); final List<String> result = new ArrayList<String>(); for (Iterator<String> it = data.iterator(); it.hasNext();) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java index f76166c40..5c9ea175d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java @@ -166,7 +166,7 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker { diagram.getSkinParam()); } else { compTitle = TextBlockUtils.withMargin(TextBlockUtils.title( - new FontConfiguration(drawableSet.getSkinParam(), FontParam.SEQUENCE_TITLE, null), + new FontConfiguration(drawableSet.getSkinParam(), FontParam.TITLE, null), page.getTitle(), drawableSet.getSkinParam()), 7, 7); } final Dimension2D dimTitle = compTitle.calculateDimension(stringBounder); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java index 4a1825953..f6dbe4135 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java @@ -229,7 +229,7 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker { .getIHtmlColorSet(), diagram.getSkinParam()); return compTitle; } else { - compTitle = TextBlockUtils.title(new FontConfiguration(getSkinParam(), FontParam.SEQUENCE_TITLE, null), + compTitle = TextBlockUtils.title(new FontConfiguration(getSkinParam(), FontParam.TITLE, null), diagram.getTitle().getDisplay(), getSkinParam()); return TextBlockUtils.withMargin(compTitle, 7, 7); } diff --git a/src/net/sourceforge/plantuml/sprite/CommandStdlib.java b/src/net/sourceforge/plantuml/sprite/CommandStdlib.java new file mode 100644 index 000000000..3f862c965 --- /dev/null +++ b/src/net/sourceforge/plantuml/sprite/CommandStdlib.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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.sprite; + +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.RegexResult; + +public class CommandStdlib extends SingleLineCommand2<StdlibDiagram> { + + public CommandStdlib() { + super(getRegexConcat()); + } + + private static IRegex getRegexConcat() { + return RegexConcat.build(CommandStdlib.class.getName(), RegexLeaf.start(), // + new RegexLeaf("stdlib"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("NAME", "([-\\w]+)"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(StdlibDiagram system, LineLocation location, RegexResult arg) { + final String name = arg.get("NAME", 0); + system.setStdlibName(name); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sprite/StdlibDiagram.java b/src/net/sourceforge/plantuml/sprite/StdlibDiagram.java new file mode 100644 index 000000000..0edd374b0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sprite/StdlibDiagram.java @@ -0,0 +1,164 @@ +/* ======================================================================== + * 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.sprite; + +import java.awt.geom.Dimension2D; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.WithSprite; +import net.sourceforge.plantuml.command.BlocLines; +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.CommandFactorySprite; +import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.preproc.Stdlib; +import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class StdlibDiagram extends UmlDiagram { + + private static final int WIDTH = 1800; + private String name; + + public StdlibDiagram(ISkinSimple skinParam) { + super(skinParam); + } + + public DiagramDescription getDescription() { + return new DiagramDescription("(Sprites)"); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.HELP; + } + + @Override + protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption) + throws IOException { + + final TextBlock result = getTable(); + final double margin = 10; + final double dpiFactor = 1; + + final ImageBuilder imageBuilder = new ImageBuilder(getSkinParam(), dpiFactor, + fileFormatOption.isWithMetadata() ? getMetadata() : null, getWarningOrError(), margin, margin, + getAnimation()); + imageBuilder.setUDrawable(result); + + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed(), os); + } + + private TextBlock getTable() { + return new AbstractTextBlock() { + + public void drawU(UGraphic ug) { + try { + drawInternal(ug); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return new Dimension2DDouble(WIDTH, 4096); + } + }; + } + + public void setStdlibName(String name) { + this.name = name; + } + + private void drawInternal(UGraphic ug) throws IOException { + double x = 0; + double y = 0; + double rawHeight = 0; + final Stdlib folder = Stdlib.retrieve(name); + + final CommandFactorySprite factorySpriteCommand = new CommandFactorySprite(); + + Command<WithSprite> cmd = factorySpriteCommand.createMultiLine(false); + + final List<String> all = folder.extractAllSprites(); + int nb = 0; + for (String s : all) { + // System.err.println("s="+s); + final BlocLines bloc = BlocLines.fromArray(s.split("\n")); + cmd.execute(this, bloc); +// System.err.println("nb=" + nb); + nb++; + } + + for (String n : getSkinParam().getAllSpriteNames()) { + final Sprite sprite = getSkinParam().getSprite(n); + TextBlock blockName = Display.create(n).create(FontConfiguration.blackBlueTrue(UFont.sansSerif(14)), + HorizontalAlignment.LEFT, getSkinParam()); + TextBlock tb = sprite.asTextBlock(HtmlColorUtils.BLACK, 1.0); + tb = TextBlockUtils.mergeTB(tb, blockName, HorizontalAlignment.CENTER); + tb.drawU(ug.apply(new UTranslate(x, y))); + final Dimension2D dim = tb.calculateDimension(ug.getStringBounder()); + rawHeight = Math.max(rawHeight, dim.getHeight()); + x += dim.getWidth(); + x += 30; + if (x > WIDTH) { + x = 0; + y += rawHeight + 50; + rawHeight = 0; + if (y > 1024) { +// break; + } + } + } + } +} diff --git a/src/net/sourceforge/plantuml/sprite/StdlibDiagramFactory.java b/src/net/sourceforge/plantuml/sprite/StdlibDiagramFactory.java new file mode 100644 index 000000000..b2d427689 --- /dev/null +++ b/src/net/sourceforge/plantuml/sprite/StdlibDiagramFactory.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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.sprite; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.UmlDiagramFactory; + +public class StdlibDiagramFactory extends UmlDiagramFactory { + + private final ISkinSimple skinParam; + + public StdlibDiagramFactory(ISkinSimple skinParam) { + this.skinParam = skinParam; + } + + @Override + protected List<Command> createCommands() { + + final List<Command> cmds = new ArrayList<Command>(); + cmds.add(new CommandStdlib()); + return cmds; + } + + @Override + public StdlibDiagram createEmptyDiagram() { + return new StdlibDiagram(skinParam); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java index 654c05526..0f54ec44b 100644 --- a/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java @@ -47,9 +47,9 @@ 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.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.statediagram.command.CommandAddField; @@ -85,7 +85,7 @@ public class StateDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandAddField()); cmds.add(new CommandConcurrentState()); - final FactoryNoteOnEntityCommand factoryNoteOnEntityCommand = new FactoryNoteOnEntityCommand("state", + final CommandFactoryNoteOnEntity factoryNoteOnEntityCommand = new CommandFactoryNoteOnEntity("state", new RegexOr("ENTITY", new RegexLeaf("[\\p{L}0-9_.]+"), // new RegexLeaf("[%g][^%g]+[%g]") // )); @@ -93,12 +93,12 @@ public class StateDiagramFactory extends UmlDiagramFactory { cmds.add(factoryNoteOnEntityCommand.createMultiLine(false)); cmds.add(factoryNoteOnEntityCommand.createSingleLine()); - final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand(); + final CommandFactoryNoteOnLink factoryNoteOnLinkCommand = new CommandFactoryNoteOnLink(); cmds.add(factoryNoteOnLinkCommand.createSingleLine()); cmds.add(factoryNoteOnLinkCommand.createMultiLine(false)); cmds.add(new CommandUrl()); - final FactoryNoteCommand factoryNoteCommand = new FactoryNoteCommand(); + final CommandFactoryNote factoryNoteCommand = new CommandFactoryNote(); cmds.add(factoryNoteCommand.createSingleLine()); cmds.add(factoryNoteCommand.createMultiLine(false)); diff --git a/src/net/sourceforge/plantuml/svek/Bibliotekon.java b/src/net/sourceforge/plantuml/svek/Bibliotekon.java index 0ddcc33c0..7122bf6ca 100644 --- a/src/net/sourceforge/plantuml/svek/Bibliotekon.java +++ b/src/net/sourceforge/plantuml/svek/Bibliotekon.java @@ -48,24 +48,27 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graphic.StringBounder; public class Bibliotekon { private final List<Cluster> allCluster = new ArrayList<Cluster>(); - private final Map<ILeaf, Shape> shapeMap = new LinkedHashMap<ILeaf, Shape>();; + private final Map<ILeaf, Node> nodeMap = new LinkedHashMap<ILeaf, Node>();; private final List<Line> lines0 = new ArrayList<Line>(); private final List<Line> lines1 = new ArrayList<Line>(); private final List<Line> allLines = new ArrayList<Line>(); - public void putShape(ILeaf ent, Shape shape) { - shapeMap.put(ent, shape); + public Node createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { + final Node node = new Node(ent, image, colorSequence, stringBounder); + nodeMap.put(ent, node); + return node; } public Cluster getCluster(IGroup ent) { for (Cluster cl : allCluster) { - if (cl.getGroup() == ent) { + if (cl.getGroups().contains(ent)) { return cl; } } @@ -105,12 +108,12 @@ public class Bibliotekon { allCluster.add(current); } - public Shape getShape(IEntity ent) { - return shapeMap.get(ent); + public Node getNode(IEntity ent) { + return nodeMap.get(ent); } - public String getShapeUid(ILeaf ent) { - final Shape result = getShape(ent); + public String getNodeUid(ILeaf ent) { + final Node result = getNode(ent); if (result != null) { String uid = result.getUid(); if (result.isShielded()) { @@ -120,9 +123,9 @@ public class Bibliotekon { } assert result == null; if (ent.isGroup()) { - for (IEntity i : shapeMap.keySet()) { + for (IEntity i : nodeMap.keySet()) { if (ent.getCodeGetName().equals(i.getCodeGetName())) { - return getShape(i).getUid(); + return getNode(i).getUid(); } } return Cluster.getSpecialPointId(ent); @@ -132,8 +135,8 @@ public class Bibliotekon { public String getWarningOrError(int warningOrError) { final StringBuilder sb = new StringBuilder(); - for (Map.Entry<ILeaf, Shape> ent : shapeMap.entrySet()) { - final Shape sh = ent.getValue(); + for (Map.Entry<ILeaf, Node> ent : nodeMap.entrySet()) { + final Node sh = ent.getValue(); final double maxX = sh.getMinX() + sh.getWidth(); if (maxX > warningOrError) { final IEntity entity = ent.getKey(); @@ -147,8 +150,8 @@ public class Bibliotekon { public Map<String, Double> getMaxX() { final Map<String, Double> result = new HashMap<String, Double>(); - for (Map.Entry<ILeaf, Shape> ent : shapeMap.entrySet()) { - final Shape sh = ent.getValue(); + for (Map.Entry<ILeaf, Node> ent : nodeMap.entrySet()) { + final Node sh = ent.getValue(); final double maxX = sh.getMinX() + sh.getWidth(); final IEntity entity = ent.getKey(); result.put(entity.getCodeGetName(), maxX); @@ -172,8 +175,8 @@ public class Bibliotekon { return Collections.unmodifiableList(allCluster); } - public Collection<Shape> allShapes() { - return Collections.unmodifiableCollection(shapeMap.values()); + public Collection<Node> allNodes() { + return Collections.unmodifiableCollection(nodeMap.values()); } public List<Line> getAllLineConnectedTo(IEntity leaf) { @@ -205,9 +208,9 @@ public class Bibliotekon { return null; } - public ILeaf getLeaf(Shape shape) { - for (Map.Entry<ILeaf, Shape> ent : shapeMap.entrySet()) { - if (ent.getValue() == shape) { + public ILeaf getLeaf(Node node) { + for (Map.Entry<ILeaf, Node> ent : nodeMap.entrySet()) { + if (ent.getValue() == node) { return ent.getKey(); } } diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java index bec6e4ec4..ab5681e45 100644 --- a/src/net/sourceforge/plantuml/svek/Cluster.java +++ b/src/net/sourceforge/plantuml/svek/Cluster.java @@ -96,9 +96,9 @@ import net.sourceforge.plantuml.utils.UniqueSequence; public class Cluster implements Moveable { - private final Cluster parent; + private final Cluster parentCluster; private final IGroup group; - private final List<Shape> shapes = new ArrayList<Shape>(); + private final List<Node> nodes = new ArrayList<Node>(); private final List<Cluster> children = new ArrayList<Cluster>(); private final int color; private final int colorTitle; @@ -128,7 +128,7 @@ public class Cluster implements Moveable { } private boolean hasEntryOrExitPoint() { - for (Shape sh : shapes) { + for (Node sh : nodes) { if (sh.getEntityPosition() != EntityPosition.NORMAL) { return true; } @@ -137,16 +137,16 @@ public class Cluster implements Moveable { } public Cluster(ColorSequence colorSequence, ISkinParam skinParam, IGroup root) { - this(null, root, colorSequence, skinParam); + this(null, colorSequence, skinParam, root); } private ColorParam border; - private Cluster(Cluster parent, IGroup group, ColorSequence colorSequence, ISkinParam skinParam) { + private Cluster(Cluster parentCluster, ColorSequence colorSequence, ISkinParam skinParam, IGroup group) { if (group == null) { throw new IllegalStateException(); } - this.parent = parent; + this.parentCluster = parentCluster; this.group = group; if (group.getUSymbol() != null) { border = group.getUSymbol().getColorParamBorder(); @@ -161,46 +161,46 @@ public class Cluster implements Moveable { return super.toString() + " " + group; } - public final Cluster getParent() { - return parent; + public final Cluster getParentCluster() { + return parentCluster; } - public void addShape(Shape sh) { - if (sh == null) { + public void addNode(Node node) { + if (node == null) { throw new IllegalArgumentException(); } - this.shapes.add(sh); - sh.setCluster(this); + this.nodes.add(node); + node.setCluster(this); } - public final List<Shape> getShapes() { - return Collections.unmodifiableList(shapes); + public final List<Node> getNodes() { + return Collections.unmodifiableList(nodes); } - private List<Shape> getShapesOrderedTop(Collection<Line> lines) { - final List<Shape> firsts = new ArrayList<Shape>(); + private List<Node> getNodesOrderedTop(Collection<Line> lines) { + final List<Node> firsts = new ArrayList<Node>(); final Set<String> tops = new HashSet<String>(); - final Map<String, Shape> shs = new HashMap<String, Shape>(); + final Map<String, Node> shs = new HashMap<String, Node>(); - for (final Iterator<Shape> it = shapes.iterator(); it.hasNext();) { - final Shape sh = it.next(); - shs.put(sh.getUid(), sh); - if (sh.isTop() && sh.getEntityPosition() == EntityPosition.NORMAL) { - firsts.add(sh); - tops.add(sh.getUid()); + for (final Iterator<Node> it = nodes.iterator(); it.hasNext();) { + final Node node = it.next(); + shs.put(node.getUid(), node); + if (node.isTop() && node.getEntityPosition() == EntityPosition.NORMAL) { + firsts.add(node); + tops.add(node.getUid()); } } for (Line l : lines) { if (tops.contains(l.getStartUidPrefix())) { - final Shape sh = shs.get(l.getEndUidPrefix()); + final Node sh = shs.get(l.getEndUidPrefix()); if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL) { firsts.add(0, sh); } } if (l.isInverted()) { - final Shape sh = shs.get(l.getStartUidPrefix()); + final Node sh = shs.get(l.getStartUidPrefix()); if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL) { firsts.add(0, sh); } @@ -210,11 +210,11 @@ public class Cluster implements Moveable { return firsts; } - private List<Shape> getShapesEntryExit(EnumSet<EntityPosition> positions) { - final List<Shape> result = new ArrayList<Shape>(); + private List<Node> getNodesEntryExit(EnumSet<EntityPosition> positions) { + final List<Node> result = new ArrayList<Node>(); - for (final Iterator<Shape> it = shapes.iterator(); it.hasNext();) { - final Shape sh = it.next(); + for (final Iterator<Node> it = nodes.iterator(); it.hasNext();) { + final Node sh = it.next(); if (positions.contains(sh.getEntityPosition())) { result.add(sh); } @@ -222,13 +222,13 @@ public class Cluster implements Moveable { return result; } - private List<Shape> getShapesOrderedWithoutTop(Collection<Line> lines) { - final List<Shape> all = new ArrayList<Shape>(shapes); + private List<Node> getNodesOrderedWithoutTop(Collection<Line> lines) { + final List<Node> all = new ArrayList<Node>(nodes); final Set<String> tops = new HashSet<String>(); - final Map<String, Shape> shs = new HashMap<String, Shape>(); + final Map<String, Node> shs = new HashMap<String, Node>(); - for (final Iterator<Shape> it = all.iterator(); it.hasNext();) { - final Shape sh = it.next(); + for (final Iterator<Node> it = all.iterator(); it.hasNext();) { + final Node sh = it.next(); if (sh.getEntityPosition() != EntityPosition.NORMAL) { it.remove(); continue; @@ -242,14 +242,14 @@ public class Cluster implements Moveable { for (Line l : lines) { if (tops.contains(l.getStartUidPrefix())) { - final Shape sh = shs.get(l.getEndUidPrefix()); + final Node sh = shs.get(l.getEndUidPrefix()); if (sh != null) { all.remove(sh); } } if (l.isInverted()) { - final Shape sh = shs.get(l.getStartUidPrefix()); + final Node sh = shs.get(l.getStartUidPrefix()); if (sh != null) { all.remove(sh); } @@ -263,9 +263,9 @@ public class Cluster implements Moveable { return Collections.unmodifiableList(children); } - public Cluster createChild(IGroup g, int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title, - TextBlock stereo, ColorSequence colorSequence, ISkinParam skinParam) { - final Cluster child = new Cluster(this, g, colorSequence, skinParam); + public Cluster createChild(int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title, + TextBlock stereo, ColorSequence colorSequence, ISkinParam skinParam, IGroup g) { + final Cluster child = new Cluster(this, colorSequence, skinParam, g); child.titleAndAttributeWidth = titleAndAttributeWidth; child.titleAndAttributeHeight = titleAndAttributeHeight; child.ztitle = title; @@ -274,8 +274,8 @@ public class Cluster implements Moveable { return child; } - public final IGroup getGroup() { - return group; + public final Set<IGroup> getGroups() { + return Collections.singleton(group); } public final int getTitleAndAttributeWidth() { @@ -385,8 +385,8 @@ public class Cluster implements Moveable { HtmlColor backColor = getBackColor(umlDiagramType); backColor = getBackColor(backColor, skinParam2, group.getStereotype()); if (ztitle != null || zstereo != null) { - final double roundCorner = group.getUSymbol() == null ? 0 : group.getUSymbol().getSkinParameter() - .getRoundCorner(skinParam, stereotype); + final double roundCorner = group.getUSymbol() == null ? 0 + : group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, stereotype); final UStroke stroke2 = getStrokeInternal(skinParam2); final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle, @@ -427,7 +427,7 @@ public class Cluster implements Moveable { public void manageEntryExitPoint(StringBounder stringBounder) { final Collection<ClusterPosition> insides = new ArrayList<ClusterPosition>(); final List<Point2D> points = new ArrayList<Point2D>(); - for (Shape sh : shapes) { + for (Node sh : nodes) { if (sh.getEntityPosition() == EntityPosition.NORMAL) { insides.add(sh.getClusterPosition()); } else { @@ -485,8 +485,9 @@ public class Cluster implements Moveable { final HtmlColor background = getColor(skinParam2, ColorParam.background, null); final TextBlockWidth attribute = getTextBlockAttribute(skinParam2); final double attributeHeight = attribute.calculateDimension(ug.getStringBounder()).getHeight(); - final RoundedContainer r = new RoundedContainer(total, suppY, attributeHeight - + (attributeHeight > 0 ? IEntityImage.MARGIN : 0), borderColor, stateBack, background, stroke); + final RoundedContainer r = new RoundedContainer(total, suppY, + attributeHeight + (attributeHeight > 0 ? IEntityImage.MARGIN : 0), borderColor, stateBack, background, + stroke); r.drawU(ug.apply(new UTranslate(minX, minY)), skinParam2.shadowing(group.getStereotype())); if (ztitle != null) { @@ -536,12 +537,12 @@ public class Cluster implements Moveable { } public void printCluster1(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder) { - for (Shape sh : getShapesOrderedTop(lines)) { - sh.appendShape(sb, stringBounder); + for (Node node : getNodesOrderedTop(lines)) { + node.appendShape(sb, stringBounder); } } - private List<IShapePseudo> addProtection(List<Shape> entries, double width) { + private List<IShapePseudo> addProtection(List<Node> entries, double width) { final List<IShapePseudo> result = new ArrayList<IShapePseudo>(); result.add(entries.get(0)); for (int i = 1; i < entries.size(); i++) { @@ -551,10 +552,10 @@ public class Cluster implements Moveable { return result; } - private double getMaxWidthFromLabelForEntryExit(List<Shape> entries, StringBounder stringBounder) { + private double getMaxWidthFromLabelForEntryExit(List<Node> entries, StringBounder stringBounder) { double result = -Double.MAX_VALUE; - for (Shape shape : entries) { - final double w = getMaxWidthFromLabelForEntryExit(shape, stringBounder); + for (Node node : entries) { + final double w = getMaxWidthFromLabelForEntryExit(node, stringBounder); if (w > result) { result = w; } @@ -562,19 +563,19 @@ public class Cluster implements Moveable { return result; } - private double getMaxWidthFromLabelForEntryExit(Shape shape, StringBounder stringBounder) { - return shape.getMaxWidthFromLabelForEntryExit(stringBounder); + private double getMaxWidthFromLabelForEntryExit(Node node, StringBounder stringBounder) { + return node.getMaxWidthFromLabelForEntryExit(stringBounder); } public void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) { - final List<Shape> shapesEntryExitList = getShapesEntryExit(EntityPosition.getInputs()); - final double maxWith = getMaxWidthFromLabelForEntryExit(shapesEntryExitList, stringBounder); + final List<Node> nodesEntryExitList = getNodesEntryExit(EntityPosition.getInputs()); + final double maxWith = getMaxWidthFromLabelForEntryExit(nodesEntryExitList, stringBounder); final double naturalSpace = 70; final List<? extends IShapePseudo> entries; if (maxWith > naturalSpace) { - entries = addProtection(shapesEntryExitList, maxWith - naturalSpace); + entries = addProtection(nodesEntryExitList, maxWith - naturalSpace); } else { - entries = shapesEntryExitList; + entries = nodesEntryExitList; } if (entries.size() > 0) { sb.append("{rank=source;"); @@ -586,26 +587,26 @@ public class Cluster implements Moveable { sh.appendShape(sb, stringBounder); } } - final List<Shape> exits = getShapesEntryExit(EntityPosition.getOutputs()); + final List<Node> exits = getNodesEntryExit(EntityPosition.getOutputs()); if (exits.size() > 0) { sb.append("{rank=sink;"); - for (Shape sh : exits) { + for (Node sh : exits) { sb.append(sh.getUid() + ";"); } sb.append("}"); - for (Shape sh : exits) { + for (Node sh : exits) { sh.appendShape(sb, stringBounder); } } } - public boolean printCluster2(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, - DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) { + public boolean printCluster2(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, DotMode dotMode, + GraphvizVersion graphvizVersion, UmlDiagramType type) { // Log.println("Cluster::printCluster " + this); boolean added = false; - for (Shape sh : getShapesOrderedWithoutTop(lines)) { - sh.appendShape(sb, stringBounder); + for (Node node : getNodesOrderedWithoutTop(lines)) { + node.appendShape(sb, stringBounder); added = true; } @@ -647,7 +648,7 @@ public class Cluster implements Moveable { } public void fillRankMin(Set<String> rankMin) { - for (Shape sh : getShapes()) { + for (Node sh : getNodes()) { if (sh.isTop()) { rankMin.add(sh.getUid()); } @@ -659,8 +660,8 @@ public class Cluster implements Moveable { } private boolean isInCluster(String uid) { - for (Shape sh : shapes) { - if (sh.getUid().equals(uid)) { + for (Node node : nodes) { + if (node.getUid().equals(uid)) { return true; } } @@ -865,16 +866,16 @@ public class Cluster implements Moveable { } final Stereotype stereo = group.getStereotype(); final USymbol sym = group.getUSymbol() == null ? USymbol.PACKAGE : group.getUSymbol(); - final ColorParam backparam = umlDiagramType == UmlDiagramType.ACTIVITY ? ColorParam.partitionBackground : sym - .getColorParamBack(); + final ColorParam backparam = umlDiagramType == UmlDiagramType.ACTIVITY ? ColorParam.partitionBackground + : sym.getColorParamBack(); final HtmlColor c1 = skinParam.getHtmlColor(backparam, stereo, false); if (c1 != null) { return c1; } - if (parent == null) { + if (parentCluster == null) { return null; } - return parent.getBackColor(umlDiagramType); + return parentCluster.getBackColor(umlDiagramType); } public boolean isClusterOf(IEntity ent) { diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java index f649e5bfd..276944096 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java @@ -78,13 +78,15 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { private GeneralImageBuilder createDotDataImageBuilder(DotMode dotMode, StringBounder stringBounder) { final DotData dotData = new DotData(diagram.getEntityFactory().getRootGroup(), getOrderedLinks(), diagram.getLeafsvalues(), diagram.getUmlDiagramType(), diagram.getSkinParam(), diagram, diagram, - diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), - dotMode, diagram.getNamespaceSeparator(), diagram.getPragma()); - return new GeneralImageBuilder(dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), - stringBounder); + diagram.getColorMapper(), diagram.getEntityFactory(), diagram.isHideEmptyDescriptionForState(), dotMode, + diagram.getNamespaceSeparator(), diagram.getPragma()); + final boolean intricated = diagram.mergeIntricated(); + return new GeneralImageBuilder(intricated, dotData, diagram.getEntityFactory(), diagram.getSource(), + diagram.getPragma(), stringBounder); } + private ImageData createFileInternal(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption) throws IOException, InterruptedException { if (diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { diff --git a/src/net/sourceforge/plantuml/svek/DotStringFactory.java b/src/net/sourceforge/plantuml/svek/DotStringFactory.java index f94c68d24..5d1fad9d4 100644 --- a/src/net/sourceforge/plantuml/svek/DotStringFactory.java +++ b/src/net/sourceforge/plantuml/svek/DotStringFactory.java @@ -60,6 +60,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersions; import net.sourceforge.plantuml.cucadiagram.dot.ProcessState; +import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.posimo.Moveable; @@ -104,8 +105,8 @@ public class DotStringFactory implements Moveable { this.current = root; } - public void addShape(Shape shape) { - current.addShape(shape); + public void addNode(Node node) { + current.addNode(node); } private void printMinRanking(StringBuilder sb) { @@ -343,7 +344,8 @@ public class DotStringFactory implements Moveable { return graphviz.getDotExe(); } - public ClusterPosition solve(final String svg) throws IOException, InterruptedException { + public ClusterPosition solve(boolean mergeIntricated, EntityFactory entityFactory, final String svg) + throws IOException, InterruptedException { if (svg.length() == 0) { throw new EmptySvgException(); } @@ -360,18 +362,18 @@ public class DotStringFactory implements Moveable { final Point2DFunction move = new YDelta(fullHeight); final SvgResult svgResult = new SvgResult(svg, move); - for (Shape sh : bibliotekon.allShapes()) { - int idx = svg.indexOf("<title>" + sh.getUid() + "</title>"); - if (sh.getType() == ShapeType.RECTANGLE || sh.getType() == ShapeType.RECTANGLE_HTML_FOR_PORTS - || sh.getType() == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE || sh.getType() == ShapeType.FOLDER - || sh.getType() == ShapeType.DIAMOND) { + for (Node node : bibliotekon.allNodes()) { + int idx = svg.indexOf("<title>" + node.getUid() + "</title>"); + if (node.getType() == ShapeType.RECTANGLE || node.getType() == ShapeType.RECTANGLE_HTML_FOR_PORTS + || node.getType() == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE || node.getType() == ShapeType.FOLDER + || node.getType() == ShapeType.DIAMOND) { final List<Point2D.Double> points = svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS); final double minY = SvekUtils.getMinY(points); - final double overscanX = sh.getOverscanX(stringBounder); + final double overscanX = node.getOverscanX(stringBounder); final double minX = SvekUtils.getMinX(points); corner1.manage(minX - overscanX, minY); - sh.moveSvek(minX, minY); - } else if (sh.getType() == ShapeType.ROUND_RECTANGLE) { + node.moveSvek(minX, minY); + } else if (node.getType() == ShapeType.ROUND_RECTANGLE) { final int idx2 = svg.indexOf("d=\"", idx + 1); idx = svg.indexOf("points=\"", idx + 1); final List<Point2D.Double> points; @@ -388,29 +390,35 @@ public class DotStringFactory implements Moveable { final double minX = SvekUtils.getMinX(points); final double minY = SvekUtils.getMinY(points); corner1.manage(minX, minY); - sh.moveSvek(minX, minY); - } else if (sh.getType() == ShapeType.OCTAGON) { + node.moveSvek(minX, minY); + } else if (node.getType() == ShapeType.OCTAGON) { idx = svg.indexOf("points=\"", idx + 1); final int starting = idx; final List<Point2D.Double> points = svgResult.substring(starting).extractList(SvgResult.POINTS_EQUALS); final double minX = SvekUtils.getMinX(points); final double minY = SvekUtils.getMinY(points); corner1.manage(minX, minY); - sh.moveSvek(minX, minY); - sh.setOctagon(minX, minY, points); - } else if (sh.getType() == ShapeType.CIRCLE || sh.getType() == ShapeType.CIRCLE_IN_RECT - || sh.getType() == ShapeType.OVAL) { + node.moveSvek(minX, minY); + node.setOctagon(minX, minY, points); + } else if (node.getType() == ShapeType.CIRCLE || node.getType() == ShapeType.CIRCLE_IN_RECT + || node.getType() == ShapeType.OVAL) { final double cx = SvekUtils.getValue(svg, idx, "cx"); final double cy = SvekUtils.getValue(svg, idx, "cy") + fullHeight; final double rx = SvekUtils.getValue(svg, idx, "rx"); final double ry = SvekUtils.getValue(svg, idx, "ry"); - sh.moveSvek(cx - rx, cy - ry); + node.moveSvek(cx - rx, cy - ry); } else { - throw new IllegalStateException(sh.getType().toString() + " " + sh.getUid()); + throw new IllegalStateException(node.getType().toString() + " " + node.getUid()); } } for (Cluster cluster : bibliotekon.allCluster()) { + if (mergeIntricated) { + final IGroup group = cluster.getGroups().iterator().next(); + if (entityFactory.isIntricated(group) != null) { + continue; + } + } int idx = getClusterIndex(svg, cluster.getColor()); final int starting = idx; final List<Point2D.Double> points = svgResult.substring(starting).extractList(SvgResult.POINTS_EQUALS); @@ -438,7 +446,7 @@ public class DotStringFactory implements Moveable { } for (Line line : bibliotekon.allLines()) { - line.manageCollision(bibliotekon.allShapes()); + line.manageCollision(bibliotekon.allNodes()); } corner1.manage(0, 0); return new ClusterPosition(corner1.getMinX(), corner1.getMinY(), fullWidth, fullHeight); @@ -459,22 +467,22 @@ public class DotStringFactory implements Moveable { return idx; } - public void openCluster(IGroup g, int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title, - TextBlock stereo) { - this.current = current.createChild(g, titleAndAttributeWidth, titleAndAttributeHeight, title, stereo, - colorSequence, skinParam); + public void openCluster(int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title, TextBlock stereo, + IGroup g) { + this.current = current.createChild(titleAndAttributeWidth, titleAndAttributeHeight, title, stereo, + colorSequence, skinParam, g); bibliotekon.addCluster(this.current); } public void closeCluster() { - if (current.getParent() == null) { + if (current.getParentCluster() == null) { throw new IllegalStateException(); } - this.current = current.getParent(); + this.current = current.getParentCluster(); } public void moveSvek(double deltaX, double deltaY) { - for (Shape sh : bibliotekon.allShapes()) { + for (Node sh : bibliotekon.allNodes()) { sh.moveSvek(deltaX, deltaY); } for (Line line : bibliotekon.allLines()) { diff --git a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java index c04b8dffe..a0025f320 100644 --- a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java +++ b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java @@ -84,6 +84,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.ExeState; import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion; import net.sourceforge.plantuml.cucadiagram.dot.Neighborhood; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; +import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; import net.sourceforge.plantuml.descdiagram.EntityImageDesignedDomain; import net.sourceforge.plantuml.descdiagram.EntityImageDomain; import net.sourceforge.plantuml.descdiagram.EntityImageMachine; @@ -226,8 +227,8 @@ public final class GeneralImageBuilder { if (leaf.getLeafType() == LeafType.EMPTY_PACKAGE) { if (leaf.getUSymbol() != null) { // final HtmlColor black = HtmlColorUtils.BLACK; - final HtmlColor black = SkinParamUtils.getColor(skinParam, leaf.getStereotype(), leaf.getUSymbol() - .getColorParamBorder()); + final HtmlColor black = SkinParamUtils.getColor(skinParam, leaf.getStereotype(), + leaf.getUSymbol().getColorParamBorder()); return new EntityImageDescription(leaf, new SkinParamForecolored(skinParam, black), portionShower, links); } @@ -274,15 +275,17 @@ public final class GeneralImageBuilder { private Map<String, Double> maxX; private final StringBounder stringBounder; + private final boolean mergeIntricated; - public GeneralImageBuilder(DotData dotData, EntityFactory entityFactory, UmlSource source, Pragma pragma, - StringBounder stringBounder) { + public GeneralImageBuilder(boolean mergeIntricated, DotData dotData, EntityFactory entityFactory, UmlSource source, + Pragma pragma, StringBounder stringBounder) { this.dotData = dotData; this.entityFactory = entityFactory; this.source = source; this.pragma = pragma; this.stringBounder = stringBounder; this.strictUmlStyle = dotData.getSkinParam().strictUmlStyle(); + this.mergeIntricated = mergeIntricated; } final public StyleSignature getDefaultStyleDefinitionArrow() { @@ -362,8 +365,8 @@ public final class GeneralImageBuilder { final ISkinParam skinParam = dotData.getSkinParam(); final FontConfiguration labelFont; if (SkinParam.USE_STYLES()) { - final Style style = getDefaultStyleDefinitionArrow().getMergedStyle( - skinParam.getCurrentStyleBuilder()); + final Style style = getDefaultStyleDefinitionArrow() + .getMergedStyle(skinParam.getCurrentStyleBuilder()); labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet()); } else { labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null); @@ -375,17 +378,17 @@ public final class GeneralImageBuilder { dotStringFactory.getBibliotekon().addLine(line); if (isOpalisable(link.getEntity1())) { - final Shape shape = dotStringFactory.getBibliotekon().getShape(link.getEntity1()); - final Shape other = dotStringFactory.getBibliotekon().getShape(link.getEntity2()); + final Node node = dotStringFactory.getBibliotekon().getNode(link.getEntity1()); + final Node other = dotStringFactory.getBibliotekon().getNode(link.getEntity2()); if (other != null) { - ((EntityImageNote) shape.getImage()).setOpaleLine(line, shape, other); + ((EntityImageNote) node.getImage()).setOpaleLine(line, node, other); line.setOpale(true); } } else if (isOpalisable(link.getEntity2())) { - final Shape shape = dotStringFactory.getBibliotekon().getShape(link.getEntity2()); - final Shape other = dotStringFactory.getBibliotekon().getShape(link.getEntity1()); + final Node node = dotStringFactory.getBibliotekon().getNode(link.getEntity2()); + final Node other = dotStringFactory.getBibliotekon().getNode(link.getEntity1()); if (other != null) { - ((EntityImageNote) shape.getImage()).setOpaleLine(line, shape, other); + ((EntityImageNote) node.getImage()).setOpaleLine(line, node, other); line.setOpale(true); } } @@ -413,7 +416,8 @@ public final class GeneralImageBuilder { } final String graphvizVersion = extractGraphvizVersion(svg); try { - final ClusterPosition position = dotStringFactory.solve(svg).delta(10, 10); + final ClusterPosition position = dotStringFactory.solve(mergeIntricated, dotData.getEntityFactory(), svg) + .delta(10, 10); final double minY = position.getMinY(); final double minX = position.getMinX(); if (minX > 0 || minY > 0) { @@ -493,12 +497,8 @@ public final class GeneralImageBuilder { throw new IllegalStateException(); } final IEntityImage image = printEntityInternal(dotStringFactory, 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); - dotStringFactory.getBibliotekon().putShape(ent, shape); + final Node node = dotStringFactory.getBibliotekon().createNode(ent, image, dotStringFactory.getColorSequence(), stringBounder); + dotStringFactory.addNode(node); } private IEntityImage printEntityInternal(DotStringFactory dotStringFactory, ILeaf ent) { @@ -546,29 +546,15 @@ public final class GeneralImageBuilder { } private void printGroups(DotStringFactory dotStringFactory, IGroup parent) { - for (IGroup g : dotData.getGroupHierarchy().getChildrenGroups(parent)) { + final Collection<IGroup> groups = dotData.getGroupHierarchy().getChildrenGroups(parent); + for (IGroup g : groups) { if (g.isRemoved()) { continue; } if (dotData.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) { + final ISkinParam skinParam = dotData.getSkinParam(); entityFactory.thisIsGoingToBeALeaf(g.getIdent()); - final ILeaf folder = entityFactory.createLeaf(g.getIdent(), g.getCode(), g.getDisplay(), - LeafType.EMPTY_PACKAGE, g.getParentContainer(), null, dotData.getNamespaceSeparator()); - final USymbol symbol = g.getUSymbol(); - folder.setUSymbol(symbol); - folder.setStereotype(g.getStereotype()); - if (g.getUrl99() != null) { - folder.addUrl(g.getUrl99()); - } - if (g.getColors(dotData.getSkinParam()).getColor(ColorType.BACK) == null) { - final ColorParam param = symbol == null ? ColorParam.packageBackground : symbol.getColorParamBack(); - final HtmlColor c1 = dotData.getSkinParam().getHtmlColor(param, g.getStereotype(), false); - folder.setSpecificColorTOBEREMOVED(ColorType.BACK, c1 == null ? dotData.getSkinParam() - .getBackgroundColor() : c1); - } else { - folder.setSpecificColorTOBEREMOVED(ColorType.BACK, - g.getColors(dotData.getSkinParam()).getColor(ColorType.BACK)); - } + final ILeaf folder = entityFactory.createLeafForEmptyGroup(g, skinParam); printEntity(dotStringFactory, folder); } else { printGroup(dotStringFactory, g); @@ -580,6 +566,13 @@ public final class GeneralImageBuilder { if (g.getGroupType() == GroupType.CONCURRENT_STATE) { return; } + if (mergeIntricated) { + final IGroup intricated = dotData.getEntityFactory().isIntricated(g); + if (intricated != null) { + printGroup(dotStringFactory, intricated); + return; + } + } int titleAndAttributeWidth = 0; int titleAndAttributeHeight = 0; @@ -605,10 +598,11 @@ public final class GeneralImageBuilder { 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(dotStringFactory, g.getLeafsDirect()); printGroups(dotStringFactory, g); diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java index 3f34446a1..4ac245131 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerActivity.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ISkinParam; @@ -51,6 +52,7 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.cucadiagram.SuperGroup; import net.sourceforge.plantuml.cucadiagram.dot.DotData; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -71,6 +73,18 @@ public final class GroupPngMakerActivity { class InnerGroupHierarchy implements GroupHierarchy { + public Set<SuperGroup> getAllSuperGroups() { + throw new UnsupportedOperationException(); + } + + public IGroup getRootGroup() { + throw new UnsupportedOperationException(); + } + + public SuperGroup getRootSuperGroup() { + throw new UnsupportedOperationException(); + } + public Collection<IGroup> getChildrenGroups(IGroup parent) { if (EntityUtils.groupRoot(parent)) { return diagram.getChildrenGroups(group); @@ -82,6 +96,8 @@ public final class GroupPngMakerActivity { return diagram.isEmpty(g); } + + } public GroupPngMakerActivity(CucaDiagram diagram, IGroup group, StringBounder stringBounder) { @@ -118,18 +134,18 @@ public final class GroupPngMakerActivity { skinParam, new InnerGroupHierarchy(), diagram.getColorMapper(), diagram.getEntityFactory(), false, DotMode.NORMAL, diagram.getNamespaceSeparator(), diagram.getPragma()); - final GeneralImageBuilder svek2 = new GeneralImageBuilder(dotData, diagram.getEntityFactory(), + final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder); if (group.getGroupType() == GroupType.INNER_ACTIVITY) { final Stereotype stereo = group.getStereotype(); final HtmlColor borderColor = getColor(ColorParam.activityBorder, stereo); - final HtmlColor backColor = group.getColors(skinParam).getColor(ColorType.BACK) == null ? getColor( - ColorParam.background, stereo) : group.getColors(skinParam).getColor(ColorType.BACK); + final HtmlColor backColor = group.getColors(skinParam).getColor(ColorType.BACK) == null + ? getColor(ColorParam.background, stereo) + : group.getColors(skinParam).getColor(ColorType.BACK); final double shadowing; if (SkinParam.USE_STYLES()) { - final Style style = getDefaultStyleDefinitionGroup().getMergedStyle( - skinParam.getCurrentStyleBuilder()); + final Style style = getDefaultStyleDefinitionGroup().getMergedStyle(skinParam.getCurrentStyleBuilder()); shadowing = style.value(PName.Shadowing).asDouble(); } else { shadowing = skinParam.shadowing(group.getStereotype()) ? 4 : 0; diff --git a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java index 529f3dcd0..5368d1e04 100644 --- a/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java +++ b/src/net/sourceforge/plantuml/svek/GroupPngMakerState.java @@ -38,6 +38,7 @@ package net.sourceforge.plantuml.svek; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FontParam; @@ -53,6 +54,7 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.cucadiagram.SuperGroup; import net.sourceforge.plantuml.cucadiagram.dot.DotData; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -75,6 +77,18 @@ public final class GroupPngMakerState { class InnerGroupHierarchy implements GroupHierarchy { + public Set<SuperGroup> getAllSuperGroups() { + throw new UnsupportedOperationException(); + } + + public IGroup getRootGroup() { + throw new UnsupportedOperationException(); + } + + public SuperGroup getRootSuperGroup() { + throw new UnsupportedOperationException(); + } + public Collection<IGroup> getChildrenGroups(IGroup parent) { if (EntityUtils.groupRoot(parent)) { return diagram.getChildrenGroups(group); @@ -110,9 +124,8 @@ public final class GroupPngMakerState { public IEntityImage getImage() { final Display display = group.getDisplay(); final ISkinParam skinParam = diagram.getSkinParam(); - final TextBlock title = display.create( - new FontConfiguration(skinParam, FontParam.STATE, group.getStereotype()), HorizontalAlignment.CENTER, - diagram.getSkinParam()); + final TextBlock title = display.create(new FontConfiguration(skinParam, FontParam.STATE, group.getStereotype()), + HorizontalAlignment.CENTER, diagram.getSkinParam()); if (group.size() == 0 && group.getChildren().size() == 0) { return new EntityImageState(group, diagram.getSkinParam()); @@ -124,7 +137,7 @@ public final class GroupPngMakerState { diagram.isHideEmptyDescriptionForState(), DotMode.NORMAL, diagram.getNamespaceSeparator(), diagram.getPragma()); - final GeneralImageBuilder svek2 = new GeneralImageBuilder(dotData, diagram.getEntityFactory(), + final GeneralImageBuilder svek2 = new GeneralImageBuilder(false, dotData, diagram.getEntityFactory(), diagram.getSource(), diagram.getPragma(), stringBounder); if (group.getGroupType() == GroupType.CONCURRENT_STATE) { @@ -141,22 +154,23 @@ public final class GroupPngMakerState { borderColor = getColor(ColorParam.stateBorder, group.getStereotype()); } final Stereotype stereo = group.getStereotype(); - final HtmlColor backColor = group.getColors(skinParam).getColor(ColorType.BACK) == null ? getColor( - ColorParam.stateBackground, stereo) : group.getColors(skinParam).getColor(ColorType.BACK); + final HtmlColor backColor = group.getColors(skinParam).getColor(ColorType.BACK) == null + ? getColor(ColorParam.stateBackground, stereo) + : group.getColors(skinParam).getColor(ColorType.BACK); final TextBlockWidth attribute = getAttributes(skinParam); final Stereotype stereotype = group.getStereotype(); final boolean withSymbol = stereotype != null && stereotype.isWithOOSymbol(); final boolean containsOnlyConcurrentStates = containsOnlyConcurrentStates(dotData); - final IEntityImage image = containsOnlyConcurrentStates ? buildImageForConcurrentState(dotData) : svek2 - .buildImage(null, new String[0]); + final IEntityImage image = containsOnlyConcurrentStates ? buildImageForConcurrentState(dotData) + : svek2.buildImage(null, new String[0]); UStroke stroke = group.getColors(skinParam).getSpecificLineStroke(); if (stroke == null) { stroke = new UStroke(1.5); } - return new InnerStateAutonom(image, title, attribute, borderColor, backColor, skinParam.shadowing(group - .getStereotype()), group.getUrl99(), withSymbol, stroke); + return new InnerStateAutonom(image, title, attribute, borderColor, backColor, + skinParam.shadowing(group.getStereotype()), group.getUrl99(), withSymbol, stroke); } diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index d4fc07a24..9e321e755 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.svek; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; @@ -97,11 +98,13 @@ import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UTranslate; public class Line implements Moveable, Hideable { + private static final Dimension2DDouble CONSTRAINT_SPOT = new Dimension2DDouble(10, 10); private final Cluster ltail; private final Cluster lhead; private final Link link; @@ -142,6 +145,7 @@ public class Line implements Moveable, Hideable { private final boolean useRankSame; private final UStroke defaultThickness; private HtmlColor arrowLollipopColor; + private final ISkinParam skinParam; // private final UmlDiagramType umlType; @@ -212,7 +216,7 @@ public class Line implements Moveable, Hideable { private Cluster getCluster2(Bibliotekon bibliotekon, IEntity entityMutable) { for (Cluster cl : bibliotekon.allCluster()) { - if (entityMutable == cl.getGroup()) { + if (cl.getGroups().contains(entityMutable)) { return cl; } } @@ -225,6 +229,7 @@ public class Line implements Moveable, Hideable { if (link == null) { throw new IllegalArgumentException(); } + this.skinParam = skinParam; // this.umlType = link.getUmlDiagramType(); this.useRankSame = skinParam.useRankSame(); this.startUid = link.getEntityPort1(bibliotekon); @@ -341,7 +346,8 @@ public class Line implements Moveable, Hideable { final VisibilityModifier visibilityModifier = link.getVisibilityModifier(); if (visibilityModifier != null) { final Rose rose = new Rose(); - // final HtmlColor back = visibilityModifier.getBackground() == null ? null : rose.getHtmlColor(skinParam, + // final HtmlColor back = visibilityModifier.getBackground() == null ? null : + // rose.getHtmlColor(skinParam, // visibilityModifier.getBackground()); final HtmlColor fore = rose.getHtmlColor(skinParam, visibilityModifier.getForeground()); TextBlock visibility = visibilityModifier.getUBlock(skinParam.classAttributeIconSize(), fore, null, false); @@ -402,17 +408,17 @@ public class Line implements Moveable, Hideable { sb.append(","); } sb.append("color=\"" + StringUtils.getAsHtml(lineColor) + "\""); - if (labelText != null) { + if (labelText != null || link.getLinkConstraint() != null) { sb.append(","); if (graphvizVersion.useXLabelInsteadOfLabel() || dotMode == DotMode.NO_LEFT_RIGHT_AND_XLABEL) { sb.append("xlabel=<"); } else { sb.append("label=<"); } - appendTable(sb, eventuallyDivideByTwo(labelText.calculateDimension(stringBounder)), noteLabelColor, - graphvizVersion); + final Dimension2D dimNote = labelText == null ? CONSTRAINT_SPOT + : labelText.calculateDimension(stringBounder); + appendTable(sb, eventuallyDivideByTwo(dimNote), noteLabelColor, graphvizVersion); sb.append(">"); - // sb.append(",labelfloat=true"); } if (startTailText != null) { @@ -420,14 +426,12 @@ public class Line implements Moveable, Hideable { sb.append("taillabel=<"); appendTable(sb, startTailText.calculateDimension(stringBounder), startTailColor, graphvizVersion); sb.append(">"); - // sb.append(",labelangle=0"); } if (endHeadText != null) { sb.append(","); sb.append("headlabel=<"); appendTable(sb, endHeadText.calculateDimension(stringBounder), endHeadColor, graphvizVersion); sb.append(">"); - // sb.append(",labelangle=0"); } if (link.isInvis()) { @@ -495,7 +499,7 @@ public class Line implements Moveable, Hideable { } private UDrawable getExtremity(LinkDecor decor, PointListIterator pointListIterator, final Point2D center, - double angle, Cluster cluster, Shape shapeContact) { + double angle, Cluster cluster, Node nodeContact) { final ExtremityFactory extremityFactory = decor.getExtremityFactory(backgroundColor); if (cluster != null) { @@ -518,8 +522,8 @@ public class Line implements Moveable, Hideable { final Point2D p1 = points.get(1); final Point2D p2 = points.get(2); Side side = null; - if (shapeContact != null) { - side = shapeContact.getClusterPosition().getClosestSide(p1); + if (nodeContact != null) { + side = nodeContact.getClusterPosition().getClosestSide(p1); } return extremityFactory.createUDrawable(p0, p1, p2, side); } else if (decor == LinkDecor.NONE) { @@ -565,9 +569,11 @@ public class Line implements Moveable, Hideable { dotPath = new DotPath(path); if (projectionCluster != null) { - // System.err.println("Line::solveLine1 projectionCluster=" + projectionCluster.getClusterPosition()); + // System.err.println("Line::solveLine1 projectionCluster=" + + // projectionCluster.getClusterPosition()); projectionCluster.manageEntryExitPoint(stringBounder); - // System.err.println("Line::solveLine2 projectionCluster=" + projectionCluster.getClusterPosition()); + // System.err.println("Line::solveLine2 projectionCluster=" + + // projectionCluster.getClusterPosition()); // if (lhead != null) // System.err.println("Line::solveLine ltail=" + lhead.getClusterPosition()); // if (ltail != null) @@ -580,15 +586,15 @@ public class Line implements Moveable, Hideable { final LinkType linkType = link.getType(); this.extremity1 = getExtremity(linkType.getDecor2(), pointListIterator, dotPath.getStartPoint(), - dotPath.getStartAngle() + Math.PI, ltail, bibliotekon.getShape(link.getEntity1())); + dotPath.getStartAngle() + Math.PI, ltail, bibliotekon.getNode(link.getEntity1())); this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(), - dotPath.getEndAngle(), lhead, bibliotekon.getShape(link.getEntity2())); + dotPath.getEndAngle(), lhead, bibliotekon.getNode(link.getEntity2())); if (link.getEntity1().getLeafType() == LeafType.LOLLIPOP_HALF) { - bibliotekon.getShape(link.getEntity1()).addImpact(dotPath.getStartAngle() + Math.PI); + bibliotekon.getNode(link.getEntity1()).addImpact(dotPath.getStartAngle() + Math.PI); } if (link.getEntity2().getLeafType() == LeafType.LOLLIPOP_HALF) { - bibliotekon.getShape(link.getEntity2()).addImpact(dotPath.getEndAngle()); + bibliotekon.getNode(link.getEntity2()).addImpact(dotPath.getEndAngle()); } if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) { @@ -603,19 +609,20 @@ public class Line implements Moveable, Hideable { if (dist1start > dist1end && dist2end > dist2start) { pointListIterator = lineSvg.getPointsWithThisColor(lineColor); this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(), - dotPath.getEndAngle(), lhead, bibliotekon.getShape(link.getEntity2())); + dotPath.getEndAngle(), lhead, bibliotekon.getNode(link.getEntity2())); this.extremity1 = getExtremity(linkType.getDecor2(), pointListIterator, dotPath.getStartPoint(), - dotPath.getStartAngle() + Math.PI, ltail, bibliotekon.getShape(link.getEntity1())); + dotPath.getStartAngle() + Math.PI, ltail, bibliotekon.getNode(link.getEntity1())); } } } - if (this.labelText != null) { + if (this.labelText != null || link.getLinkConstraint() != null) { final Point2D pos = getXY(fullSvg, this.noteLabelColor); if (pos != null) { corner1.manage(pos); - this.labelXY = TextBlockUtils.asPositionable(labelText, stringBounder, pos); + this.labelXY = labelText == null ? TextBlockUtils.asPositionable(CONSTRAINT_SPOT, stringBounder, pos) + : TextBlockUtils.asPositionable(labelText, stringBounder, pos); } } @@ -708,8 +715,8 @@ public class Line implements Moveable, Hideable { if (link.getEntity2().isGroup() && link.getEntity2().getUSymbol() instanceof USymbolFolder) { final Cluster endCluster = bibliotekon.getCluster((IGroup) link.getEntity2()); if (endCluster != null) { - final double deltaFolderH = endCluster - .checkFolderPosition(dotPath.getEndPoint(), ug.getStringBounder()); + final double deltaFolderH = endCluster.checkFolderPosition(dotPath.getEndPoint(), + ug.getStringBounder()); todraw = new DotPath(dotPath); todraw.moveEndPoint(0, deltaFolderH); // moveEndY = deltaFolderH; @@ -739,16 +746,17 @@ public class Line implements Moveable, Hideable { if (this.labelText != null && this.labelXY != null && link.getNoteLinkStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED) { - this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX(), y - + this.labelXY.getPosition().getY()))); + this.labelText.drawU(ug.apply( + new UTranslate(x + this.labelXY.getPosition().getX(), y + this.labelXY.getPosition().getY()))); } - if (this.startTailText != null && this.startTailLabelXY != null && this.startTailLabelXY.getPosition() != null) { - this.startTailText.drawU(ug.apply(new UTranslate(x + this.startTailLabelXY.getPosition().getX(), y - + this.startTailLabelXY.getPosition().getY()))); + if (this.startTailText != null && this.startTailLabelXY != null + && this.startTailLabelXY.getPosition() != null) { + this.startTailText.drawU(ug.apply(new UTranslate(x + this.startTailLabelXY.getPosition().getX(), + y + this.startTailLabelXY.getPosition().getY()))); } if (this.endHeadText != null && this.endHeadLabelXY != null && this.endHeadLabelXY.getPosition() != null) { - this.endHeadText.drawU(ug.apply(new UTranslate(x + this.endHeadLabelXY.getPosition().getX(), y - + this.endHeadLabelXY.getPosition().getY()))); + this.endHeadText.drawU(ug.apply(new UTranslate(x + this.endHeadLabelXY.getPosition().getX(), + y + this.endHeadLabelXY.getPosition().getY()))); } if (linkType.getMiddleDecor() != LinkMiddleDecor.NONE) { @@ -763,6 +771,40 @@ public class Line implements Moveable, Hideable { if (url != null) { ug.closeAction(); } + + if (link.getLinkConstraint() != null) { + final double xConstraint = x + this.labelXY.getPosition().getX(); + final double yConstraint = y + this.labelXY.getPosition().getY(); +// ug.apply(new UTranslate(xConstraint, yConstraint)).draw(new URectangle(10, 10)); + final List<Point2D> square = getSquare(xConstraint, yConstraint); + final Set<Point2D> bez = dotPath.sample(); + Point2D minPt = null; + double minDist = Double.MAX_VALUE; + for (Point2D pt : square) { + for (Point2D pt2 : bez) { + final double distance = pt2.distance(pt); + if (minPt == null || distance < minDist) { + minPt = pt; + minDist = distance; + } + } + } + link.getLinkConstraint().setPosition(link, minPt); + link.getLinkConstraint().drawMe(ug, skinParam); + } + } + + private List<Point2D> getSquare(double x, double y) { + final List<Point2D> result = new ArrayList<Point2D>(); + result.add(new Point2D.Double(x, y)); + result.add(new Point2D.Double(x + 5, y)); + result.add(new Point2D.Double(x + 10, y)); + result.add(new Point2D.Double(x, y + 5)); + result.add(new Point2D.Double(x + 10, y + 5)); + result.add(new Point2D.Double(x, y + 10)); + result.add(new Point2D.Double(x + 5, y + 10)); + result.add(new Point2D.Double(x + 10, y + 10)); + return result; } private String uniq(final Set<String> ids, final String comment) { @@ -871,11 +913,12 @@ public class Line implements Moveable, Hideable { return strategy.getResult() + getDecorDzeta(); } - public void manageCollision(Collection<Shape> allShapes) { + public void manageCollision(Collection<Node> allNodes) { - for (Shape sh : allShapes) { + for (Node sh : allNodes) { final Positionable cl = PositionableUtils.addMargin(sh, 8, 8); - if (startTailText != null && startTailLabelXY != null && PositionableUtils.intersect(cl, startTailLabelXY)) { + if (startTailText != null && startTailLabelXY != null + && PositionableUtils.intersect(cl, startTailLabelXY)) { startTailLabelXY = PositionableUtils.moveAwayFrom(cl, startTailLabelXY); } if (endHeadText != null && endHeadLabelXY != null && PositionableUtils.intersect(cl, endHeadLabelXY)) { @@ -903,7 +946,7 @@ public class Line implements Moveable, Hideable { } - private void avoid(Point2D.Double move, Positionable pos, Shape sh) { + private void avoid(Point2D.Double move, Positionable pos, Node sh) { final Oscillator oscillator = new Oscillator(); final Point2D.Double orig = new Point2D.Double(move.x, move.y); while (cut(pos, sh)) { @@ -912,7 +955,7 @@ public class Line implements Moveable, Hideable { } } - private boolean cut(Positionable pos, Shape sh) { + private boolean cut(Positionable pos, Node sh) { return BezierUtils.intersect(pos, sh) || tooClose(pos); } diff --git a/src/net/sourceforge/plantuml/svek/Shape.java b/src/net/sourceforge/plantuml/svek/Node.java similarity index 91% rename from src/net/sourceforge/plantuml/svek/Shape.java rename to src/net/sourceforge/plantuml/svek/Node.java index da602d413..06fc8ec28 100644 --- a/src/net/sourceforge/plantuml/svek/Shape.java +++ b/src/net/sourceforge/plantuml/svek/Node.java @@ -44,6 +44,9 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Hideable; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.cucadiagram.EntityPosition; +import net.sourceforge.plantuml.cucadiagram.IGroup; +import net.sourceforge.plantuml.cucadiagram.ILeaf; +import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.posimo.Positionable; import net.sourceforge.plantuml.svek.image.EntityImageDescription; @@ -52,7 +55,7 @@ import net.sourceforge.plantuml.svek.image.EntityImageStateBorder; import net.sourceforge.plantuml.ugraphic.Shadowable; import net.sourceforge.plantuml.ugraphic.UPolygon; -public class Shape implements Positionable, IShapePseudo, Hideable { +public class Node implements Positionable, IShapePseudo, Hideable { private final ShapeType type; private final double width; @@ -89,21 +92,32 @@ public class Shape implements Positionable, IShapePseudo, Hideable { return super.toString() + " " + image + " " + type; } - public Shape(IEntityImage image, ShapeType type, double width, double height, ColorSequence colorSequence, - boolean top, Margins shield, EntityPosition entityPosition) { - this.entityPosition = entityPosition; + private final ILeaf leaf; + private final IGroup group; + + Node(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { + final Dimension2D dim = image.calculateDimension(stringBounder); + this.entityPosition = ent.getEntityPosition(); this.image = image; - this.top = top; - this.type = type; - this.width = width; - this.height = height; + this.top = ent.isTop(); + this.type = image.getShapeType(); + this.width = dim.getWidth(); + this.height = dim.getHeight(); this.color = colorSequence.getValue(); this.uid = String.format("sh%04d", color); - this.shield = shield; + this.shield = image.getShield(stringBounder); if (shield.isZero() == false && type != ShapeType.RECTANGLE && type != ShapeType.RECTANGLE_HTML_FOR_PORTS && type != ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE) { throw new IllegalArgumentException(); } + + if (((EntityImpl) ent).getOriginalGroup() == null) { + this.group = null; + this.leaf = ent; + } else { + this.group = ((EntityImpl) ent).getOriginalGroup(); + this.leaf = null; + } } public final ShapeType getType() { diff --git a/src/net/sourceforge/plantuml/svek/SvekResult.java b/src/net/sourceforge/plantuml/svek/SvekResult.java index 7d84de7bb..da89ae854 100644 --- a/src/net/sourceforge/plantuml/svek/SvekResult.java +++ b/src/net/sourceforge/plantuml/svek/SvekResult.java @@ -86,11 +86,11 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage, } color = HtmlColorUtils.noGradient(color); - for (Shape shape : dotStringFactory.getBibliotekon().allShapes()) { - final double minX = shape.getMinX(); - final double minY = shape.getMinY(); - final UGraphic ug2 = shape.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; - final IEntityImage image = shape.getImage(); + for (Node node : dotStringFactory.getBibliotekon().allNodes()) { + final double minX = node.getMinX(); + final double minY = node.getMinY(); + final UGraphic ug2 = node.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; + final IEntityImage image = node.getImage(); image.drawU(ug2.apply(new UTranslate(minX, minY))); if (image instanceof Untranslated) { ((Untranslated) image).drawUntranslated(ug.apply(new UChangeColor(color)), minX, minY); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java index 76f29aaa2..3fd49b074 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageActivity.java @@ -58,7 +58,7 @@ import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleSignature; import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.Bibliotekon; -import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.svek.Node; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.Shadowable; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; @@ -122,8 +122,8 @@ public class EntityImageActivity extends AbstractEntityImage { } private UGraphic drawOctagon(UGraphic ug) { - final Shape shape = bibliotekon.getShape(getEntity()); - final Shadowable octagon = shape.getOctagon(); + final Node node = bibliotekon.getNode(getEntity()); + final Shadowable octagon = node.getOctagon(); octagon.setDeltaShadow(shadowing); ug = applyColors(ug); ug.apply(new UStroke(1.5)).draw(octagon); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java index 563b1a929..dfc585561 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye1.java @@ -99,7 +99,7 @@ public class EntityImageLollipopInterfaceEye1 extends AbstractEntityImage { ug.apply(new UStroke(1.5)).apply(new UTranslate(diff, diff)).draw(circle1); ug = ug.apply(new UChangeBackColor(null)); - Point2D pos = bibliotekon.getShape(getEntity()).getPosition(); + Point2D pos = bibliotekon.getNode(getEntity()).getPosition(); final List<Line> lines = bibliotekon.getAllLineConnectedTo(getEntity()); final UTranslate reverse = new UTranslate(pos).reverse(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index d0010698c..6ea5297ea 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -73,7 +73,7 @@ import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleSignature; import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.Line; -import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.svek.Node; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -211,7 +211,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { } else { final StringBounder stringBounder = ug.getStringBounder(); DotPath path = opaleLine.getDotPath(); - path.moveSvek(-shape.getMinX(), -shape.getMinY()); + path.moveSvek(-node.getMinX(), -node.getMinY()); Point2D p1 = path.getStartPoint(); Point2D p2 = path.getEndPoint(); final double textWidth = getTextWidth(stringBounder); @@ -225,9 +225,9 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { final Direction strategy = getOpaleStrategy(textWidth, textHeight, p1); final Point2D pp1 = path.getStartPoint(); final Point2D pp2 = path.getEndPoint(); - final Point2D newRefpp2 = move(pp2, shape.getMinX(), shape.getMinY()); - final Point2D projection = move(other.projection(newRefpp2, stringBounder), -shape.getMinX(), - -shape.getMinY()); + final Point2D newRefpp2 = move(pp2, node.getMinX(), node.getMinY()); + final Point2D projection = move(other.projection(newRefpp2, stringBounder), -node.getMinX(), + -node.getMinY()); final Opale opale = new Opale(shadowing, borderColor, noteBackgroundColor, textBlock, true); opale.setRoundCorner(getRoundCorner()); opale.setOpale(strategy, pp1, projection); @@ -296,15 +296,15 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { } private Line opaleLine; - private Shape shape; - private Shape other; + private Node node; + private Node other; - public void setOpaleLine(Line line, Shape shape, Shape other) { + public void setOpaleLine(Line line, Node node, Node other) { if (other == null) { throw new IllegalArgumentException(); } this.opaleLine = line; - this.shape = shape; + this.node = node; this.other = other; } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java index 840e2d9fc..e9b8fd36c 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageStateBorder.java @@ -55,7 +55,7 @@ import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Cluster; -import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.svek.Node; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; @@ -89,8 +89,8 @@ public class EntityImageStateBorder extends AbstractEntityImage { private boolean upPosition() { final Point2D clusterCenter = stateParent.getClusterPosition().getPointCenter(); - final Shape sh = bibliotekon.getShape(getEntity()); - return sh.getMinY() < clusterCenter.getY(); + final Node node = bibliotekon.getNode(getEntity()); + return node.getMinY() < clusterCenter.getY(); } public Dimension2D calculateDimension(StringBounder stringBounder) { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java index 8825e7267..60d17a2fc 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java @@ -61,7 +61,7 @@ import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.Bibliotekon; -import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.svek.Node; import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -120,17 +120,17 @@ public class EntityImageTips extends AbstractEntityImage { final IEntity other = bibliotekon.getOnlyOther(getEntity()); - final Shape shapeMe = bibliotekon.getShape(getEntity()); - final Shape shapeOther = bibliotekon.getShape(other); - final Point2D positionMe = shapeMe.getPosition(); - final Point2D positionOther = shapeOther.getPosition(); - bibliotekon.getShape(getEntity()); + final Node nodeMe = bibliotekon.getNode(getEntity()); + final Node nodeOther = bibliotekon.getNode(other); + final Point2D positionMe = nodeMe.getPosition(); + final Point2D positionOther = nodeOther.getPosition(); + bibliotekon.getNode(getEntity()); final Position position = getPosition(); Direction direction = position.reverseDirection(); double height = 0; for (Map.Entry<String, Display> ent : getEntity().getTips().entrySet()) { final Display display = ent.getValue(); - final Rectangle2D memberPosition = shapeOther.getImage().getInnerPosition(ent.getKey(), stringBounder, + final Rectangle2D memberPosition = nodeOther.getImage().getInnerPosition(ent.getKey(), stringBounder, InnerStrategy.STRICT); if (memberPosition == null) { return; diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index 7b4c221b9..3ff140f66 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -538,13 +538,13 @@ public class SvgGraphics { private Transformer getTransformer() throws TransformerException { // Get a TransformerFactory object. TransformerFactory xformFactory = null; - try { - final Class<?> factoryClass = Class - .forName("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); - xformFactory = (TransformerFactory) factoryClass.newInstance(); - } catch (Exception e) { +// try { +// final Class<?> factoryClass = Class +// .forName("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); +// xformFactory = (TransformerFactory) factoryClass.newInstance(); +// } catch (Exception e) { xformFactory = TransformerFactory.newInstance(); - } +// } Log.info("TransformerFactory=" + xformFactory.getClass()); // Get an XSL Transformer object. diff --git a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java index a7ce8e804..8898591df 100644 --- a/src/net/sourceforge/plantuml/tikz/TikzGraphics.java +++ b/src/net/sourceforge/plantuml/tikz/TikzGraphics.java @@ -135,8 +135,7 @@ public class TikzGraphics { out(os, " \\p2=(sourcenode.south east),"); out(os, " \\n1={\\x2-\\x1},"); out(os, " \\n2={\\y2-\\y1} in"); - out(os, - " node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\\p1)] {\\href{#1}{\\XeTeXLinkBox{\\phantom{\\rule{\\n1}{\\n2}}}}}"); + out(os, " node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\\p1)] {\\href{#1}{\\XeTeXLinkBox{\\phantom{\\rule{\\n1}{\\n2}}}}}"); out(os, " %xelatex needs \\XeTeXLinkBox, won't create a link unless it"); out(os, " %finds text --- rules don't work without \\XeTeXLinkBox."); out(os, " %Still builds correctly with pdflatex and lualatex"); @@ -151,8 +150,7 @@ public class TikzGraphics { out(os, " \\p2=(sourcenode.south east),"); out(os, " \\n1={\\x2-\\x1},"); out(os, " \\n2={\\y2-\\y1} in"); - out(os, - " node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\\p1)] {\\hyperref [#1]{\\XeTeXLinkBox{\\phantom{\\rule{\\n1}{\\n2}}}}}"); + out(os, " node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\\p1)] {\\hyperref [#1]{\\XeTeXLinkBox{\\phantom{\\rule{\\n1}{\\n2}}}}}"); out(os, " %xelatex needs \\XeTeXLinkBox, won't create a link unless it"); out(os, " %finds text --- rules don't work without \\XeTeXLinkBox."); out(os, " %Still builds correctly with pdflatex and lualatex"); @@ -318,6 +316,9 @@ public class TikzGraphics { } public void appendRaw(double x, double y, String formula) { + if (formula == null) { + throw new IllegalArgumentException(); + } final StringBuilder sb = new StringBuilder("\\node at " + couple(x, y)); sb.append("[below right"); sb.append("]{"); @@ -487,7 +488,8 @@ public class TikzGraphics { } else if (type == USegmentType.SEG_QUADTO) { throw new UnsupportedOperationException(); } else if (type == USegmentType.SEG_CUBICTO) { - // curvetoNoMacro(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y, coord[4] + x, coord[5] + y); + // curvetoNoMacro(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y, + // coord[4] + x, coord[5] + y); sb.append(" ..controls "); sb.append(couple(coord[0] + x, coord[1] + y)); sb.append(" and "); @@ -543,8 +545,8 @@ public class TikzGraphics { } public void drawPathIterator(double x, double y, PathIterator path) { - final StringBuilder sb = new StringBuilder("\\draw[color=" + getColorName(color) + ",fill=" - + getColorName(color) + "] "); + final StringBuilder sb = new StringBuilder( + "\\draw[color=" + getColorName(color) + ",fill=" + getColorName(color) + "] "); final double coord[] = new double[6]; while (path.isDone() == false) { final int code = path.currentSegment(coord); diff --git a/src/net/sourceforge/plantuml/ugraphic/UImage.java b/src/net/sourceforge/plantuml/ugraphic/UImage.java index 569cff812..261855154 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UImage.java +++ b/src/net/sourceforge/plantuml/ugraphic/UImage.java @@ -46,14 +46,24 @@ public class UImage implements UShape { private final BufferedImage image; private final String formula; + private final String rawFileName; - public UImage(BufferedImage image) { - this(image, null); + public String getRawFileName() { + return rawFileName; } - public UImage(BufferedImage image, String formula) { + public UImage(BufferedImage image) { + this(null, image, null); + } + + public UImage(String rawFileName, BufferedImage image) { + this(rawFileName, image, null); + } + + public UImage(String rawFileName, BufferedImage image, String formula) { this.image = image; this.formula = formula; + this.rawFileName = rawFileName; } public UImage scale(double scale) { @@ -74,7 +84,7 @@ public class UImage implements UShape { final AffineTransform at = new AffineTransform(); at.scale(scale, scale); final AffineTransformOp scaleOp = new AffineTransformOp(at, type); - return new UImage(scaleOp.filter(image, after), formula); + return new UImage(rawFileName, scaleOp.filter(image, after), formula); } public final BufferedImage getImage() { @@ -109,7 +119,7 @@ public class UImage implements UShape { } } } - return new UImage(copy, formula); + return new UImage(rawFileName, copy, formula); } public UImage muteTransparentColor(Color newColor) { @@ -127,7 +137,7 @@ public class UImage implements UShape { } } } - return new UImage(copy, formula); + return new UImage(rawFileName, copy, formula); } private int getDarkerRgb() { @@ -135,7 +145,8 @@ public class UImage implements UShape { for (int i = 0; i < image.getWidth(); i++) { for (int j = 0; j < image.getHeight(); j++) { final int color = image.getRGB(i, j); - // System.err.println("i="+i+" j="+j+" "+Integer.toHexString(color)+" "+isTransparent(color)); + // System.err.println("i="+i+" j="+j+" "+Integer.toHexString(color)+" + // "+isTransparent(color)); final int rgb = getRgb(color); final int a = getA(color); if (a != mask_a__) { @@ -171,7 +182,8 @@ public class UImage implements UShape { // return true; // } - // From https://stackoverflow.com/questions/3514158/how-do-you-clone-a-bufferedimage + // From + // https://stackoverflow.com/questions/3514158/how-do-you-clone-a-bufferedimage private static BufferedImage deepCopyOld(BufferedImage bi) { final ColorModel cm = bi.getColorModel(); final boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); @@ -180,7 +192,8 @@ public class UImage implements UShape { } private BufferedImage deepCopy2() { - final BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); + final BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), + BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < this.image.getWidth(); i++) { for (int j = 0; j < this.image.getHeight(); j++) { result.setRGB(i, j, image.getRGB(i, j)); diff --git a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverImageTikz.java b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverImageTikz.java index 0ad98c118..5ee37cedf 100644 --- a/src/net/sourceforge/plantuml/ugraphic/tikz/DriverImageTikz.java +++ b/src/net/sourceforge/plantuml/ugraphic/tikz/DriverImageTikz.java @@ -45,6 +45,15 @@ public class DriverImageTikz implements UDriver<TikzGraphics> { public void draw(UShape ushape, double x, double y, ColorMapper mapper, UParam param, TikzGraphics tikz) { final UImage shape = (UImage) ushape; - tikz.appendRaw(x, y, shape.getFormula()); + final String rawFileName = shape.getRawFileName(); + if (rawFileName != null) { + final String raw = "\\includegraphics{" + rawFileName + "}"; + tikz.appendRaw(x, y, raw); + return; + } + final String formula = shape.getFormula(); + if (formula != null) { + tikz.appendRaw(x, y, formula); + } } } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index f56c78261..b7321e099 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -43,7 +43,7 @@ public class Version { private static final int MAJOR_SEPARATOR = 1000000; public static int version() { - return 1202000; + return 1202001; } public static int versionPatched() { @@ -59,12 +59,11 @@ public class Version { } return dotted(version()); } - + public static String fullDescription() { return "PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")"; } - private static String dotted(int nb) { final String minor = "" + nb % MAJOR_SEPARATOR; final String major = "" + nb / MAJOR_SEPARATOR; @@ -93,7 +92,7 @@ public class Version { } public static long compileTime() { - return 1578745853861L; + return 1581874832922L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/wire/Block.java b/src/net/sourceforge/plantuml/wire/Block.java new file mode 100644 index 000000000..32eb6c3cf --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/Block.java @@ -0,0 +1,208 @@ +/* ======================================================================== + * 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.wire; + +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.AbstractTextBlock; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.MinMax; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class Block extends AbstractTextBlock { + + static class Pos { + final double x; + final double y; + + public Pos(double x, double y) { + this.x = x; + this.y = y; + } + + UGraphic move(UGraphic ug) { + return ug.apply(new UTranslate(x, y)); + } + } + + private final Map<Block, Pos> children = new LinkedHashMap<Block, Pos>(); + private final Display display; + private final Dimension2DDouble fixedDim; + private final ISkinParam skinParam; + + private final List<String> left = new ArrayList<String>(); + private final List<String> right = new ArrayList<String>(); + private final List<String> top = new ArrayList<String>(); + private final List<String> bottom = new ArrayList<String>(); + + private double x = 10; + private double y = 10; + + private MinMax minMax = MinMax.getEmpty(true); + private Block parent; + + public Block(ISkinParam skinParam) { + this(skinParam, Display.empty(), null); + } + + private Block(ISkinParam skinParam, Display display, Dimension2DDouble fixedDim) { + this.skinParam = skinParam; + this.display = display; + this.fixedDim = fixedDim; + + } + + private List<String> getPins(Position position) { + switch (position) { + case LEFT: + return left; + case RIGHT: + return right; + case TOP: + return top; + case BOTTOM: + return bottom; + } + throw new IllegalArgumentException(); + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + if (fixedDim == null) { + return minMax.getDimension(); + } + return fixedDim; + } + + public void drawU(UGraphic ug) { + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK)); + if (children.size() == 0) { + final TextBlock label = display.create(new FontConfiguration(skinParam, FontParam.COMPONENT, null), + HorizontalAlignment.CENTER, skinParam); + label.drawU(ug.apply(new UTranslate(10, 10))); + } else { + for (Entry<Block, Pos> ent : children.entrySet()) { + ent.getKey().drawU(ent.getValue().move(ug)); + } + } + ug.draw(new URectangle(calculateDimension(ug.getStringBounder()))); + + drawPins(Position.BOTTOM, ug); + drawPins(Position.TOP, ug); + drawPins(Position.LEFT, ug); + drawPins(Position.RIGHT, ug); + + } + + private void drawPins(Position pos, UGraphic ug) { + double px = -2; + double py = 10; + if (pos == Position.RIGHT) { + px = calculateDimension(ug.getStringBounder()).getWidth() - 2; + } + if (pos == Position.TOP) { + px = 10; + py = -2; + } + if (pos == Position.BOTTOM) { + px = 10; + py = calculateDimension(ug.getStringBounder()).getHeight() - 2; + } + for (String pin : getPins(pos)) { + ug.apply(new UTranslate(px, py)).draw(new UEllipse(4, 4)); + if (pos == Position.LEFT || pos == Position.RIGHT) { + py += 15; + } else { + px += 15; + } + } + } + + public Block componentEnd() { + parent.minMax = parent.minMax.addPoint(parent.x + this.minMax.getMaxX() + 10, + parent.y + this.minMax.getMaxY() + 10); + parent.x += this.minMax.getMaxX() + 10; + return parent; + } + + public Block addNewBlock(String name, int width, int height) { + final Dimension2DDouble dim = new Dimension2DDouble(width, height); + final Block child = new Block(skinParam, Display.create(name), dim); + children.put(child, new Pos(x, y)); + y += dim.getHeight() + 10; + minMax = minMax.addPoint(x + dim.getWidth() + 10, y); + return child; + } + + public Block createContainer(String name) { + final Block result = new Block(skinParam); + result.parent = this; + children.put(result, new Pos(x, y)); + return result; + } + + public void vspace(int vspace) { + y += vspace - 10; + minMax = minMax.addPoint(x, y); + } + + public void newColumn() { + this.x = minMax.getMaxX(); + this.y = 10; + } + + public void addPin(Position position, String pin) { + getPins(position).add(pin); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandComponent.java b/src/net/sourceforge/plantuml/wire/CommandComponent.java new file mode 100644 index 000000000..a9bf9d4e9 --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandComponent.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandComponent extends SingleLineCommand2<WireDiagram> { + + public CommandComponent() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandComponent.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("TYPE", "component"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("NAME", "([\\w]+)"), // + new RegexOptional(new RegexConcat( // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("\\["), // + new RegexLeaf("WIDTH", "([\\d]+)"), // + new RegexLeaf("[x*]"), // + new RegexLeaf("HEIGHT", "([\\d]+)"), // + new RegexLeaf("\\]")) // + ), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + final String name = arg.get("NAME", 0); + final String width = arg.get("WIDTH", 0); + final String height = arg.get("HEIGHT", 0); + if (width != null) { + return diagram.addComponent(name, Integer.parseInt(width), Integer.parseInt(height)); + } else { + return diagram.addComponent(name); + } + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandContainer.java b/src/net/sourceforge/plantuml/wire/CommandContainer.java new file mode 100644 index 000000000..2c1ce3692 --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandContainer.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandContainer extends SingleLineCommand2<WireDiagram> { + + public CommandContainer() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandContainer.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("TYPE", "component"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("NAME", "([\\w]+)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("\\{"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + final String name = arg.get("NAME", 0); + return diagram.addStartContainer(name); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandContainerEnd.java b/src/net/sourceforge/plantuml/wire/CommandContainerEnd.java new file mode 100644 index 000000000..3fc90ce4f --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandContainerEnd.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandContainerEnd extends SingleLineCommand2<WireDiagram> { + + public CommandContainerEnd() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandContainerEnd.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("\\}"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + return diagram.componentEnd(); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandNewColumn.java b/src/net/sourceforge/plantuml/wire/CommandNewColumn.java new file mode 100644 index 000000000..650e5543c --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandNewColumn.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandNewColumn extends SingleLineCommand2<WireDiagram> { + + public CommandNewColumn() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandNewColumn.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("-+"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + return diagram.newColumn(); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandPin.java b/src/net/sourceforge/plantuml/wire/CommandPin.java new file mode 100644 index 000000000..c346cd8b5 --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandPin.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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.wire; + +import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.command.CommandExecutionResult; +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.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandPin extends SingleLineCommand2<WireDiagram> { + + public CommandPin() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandPin.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexOr("POSITION", // + new RegexLeaf("top"), // + new RegexLeaf("bottom"), // + new RegexLeaf("left"), // + new RegexLeaf("right")), // + new RegexLeaf(":"), // + new RegexLeaf("PINS", "(.*)"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + final Position position = Position.fromString(arg.get("POSITION", 0)); + final String pins = arg.get("PINS", 0); + + for (String s : pins.split(",")) { + diagram.addPin(position, s.trim()); + } + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandPinSpace.java b/src/net/sourceforge/plantuml/wire/CommandPinSpace.java new file mode 100644 index 000000000..ce213ab7c --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandPinSpace.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandPinSpace extends SingleLineCommand2<WireDiagram> { + + public CommandPinSpace() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandPinSpace.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexOr("POSITION", // + new RegexLeaf("top"), // + new RegexLeaf("bottom"), // + new RegexLeaf("left"), // + new RegexLeaf("right")), // + new RegexLeaf(" "), // + new RegexLeaf(".*"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/CommandVspace.java b/src/net/sourceforge/plantuml/wire/CommandVspace.java new file mode 100644 index 000000000..b78fe2e0b --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/CommandVspace.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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.wire; + +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.RegexOptional; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandVspace extends SingleLineCommand2<WireDiagram> { + + public CommandVspace() { + super(false, getRegexConcat()); + } + + static IRegex getRegexConcat() { + return RegexConcat.build(CommandVspace.class.getName(), RegexLeaf.start(), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("TYPE", "vspace"), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("HEIGHT", "([\\d]+)"), // + RegexLeaf.end()); + } + + @Override + protected CommandExecutionResult executeArg(WireDiagram diagram, LineLocation location, RegexResult arg) { + final String height = arg.get("HEIGHT", 0); + return diagram.vspace(Integer.parseInt(height)); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/WireDiagram.java b/src/net/sourceforge/plantuml/wire/WireDiagram.java new file mode 100644 index 000000000..1002bc4ee --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/WireDiagram.java @@ -0,0 +1,163 @@ +/* ======================================================================== + * 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.wire; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.OutputStream; + +import net.sourceforge.plantuml.AnnotatedWorker; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.Scale; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.core.DiagramDescription; +import net.sourceforge.plantuml.core.ImageData; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.InnerStrategy; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.svek.TextBlockBackcolored; +import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.MinMax; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class WireDiagram extends UmlDiagram { + + private final Block root = new Block(getSkinParam()); + private Block current = root; + private Block last; + + public DiagramDescription getDescription() { + return new DiagramDescription("Wire Diagram"); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.WIRE; + } + + @Override + protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption) + throws IOException { + final Scale scale = getScale(); + + final double dpiFactor = scale == null ? getScaleCoef(fileFormatOption) : scale.getScale(100, 100); + final ISkinParam skinParam = getSkinParam(); + final ImageBuilder imageBuilder = new ImageBuilder(skinParam.getColorMapper(), dpiFactor, + skinParam.getBackgroundColor(), fileFormatOption.isWithMetadata() ? getMetadata() : null, "", 10, 10, + null, skinParam.handwritten()); + TextBlock result = getTextBlock(); + + result = new AnnotatedWorker(this, skinParam, fileFormatOption.getDefaultStringBounder()).addAdd(result); + imageBuilder.setUDrawable(result); + + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed(), os); + } + + private TextBlockBackcolored getTextBlock() { + return new TextBlockBackcolored() { + + public void drawU(UGraphic ug) { + drawMe(ug); + } + + public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { + return null; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return getDrawingElement().calculateDimension(stringBounder); + + } + + public MinMax getMinMax(StringBounder stringBounder) { + throw new UnsupportedOperationException(); + } + + public HtmlColor getBackcolor() { + return null; + } + }; + } + + private void drawMe(UGraphic ug) { + getDrawingElement().drawU(ug); + + } + + private TextBlock getDrawingElement() { + return current; + } + + public CommandExecutionResult addComponent(String name) { + return addComponent(name, 100, 100); + } + + public CommandExecutionResult addComponent(String name, int width, int height) { + this.last = current.addNewBlock(name, width, height); + return CommandExecutionResult.ok(); + } + + public CommandExecutionResult vspace(int vspace) { + current.vspace(vspace); + return CommandExecutionResult.ok(); + } + + public CommandExecutionResult newColumn() { + current.newColumn(); + return CommandExecutionResult.ok(); + } + + public CommandExecutionResult addStartContainer(String name) { + current = current.createContainer(name); + return CommandExecutionResult.ok(); + } + + public CommandExecutionResult componentEnd() { + current = current.componentEnd(); + return CommandExecutionResult.ok(); + } + + public void addPin(Position position, String pin) { + last.addPin(position, pin); + } + +} diff --git a/src/net/sourceforge/plantuml/wire/WireDiagramFactory.java b/src/net/sourceforge/plantuml/wire/WireDiagramFactory.java new file mode 100644 index 000000000..e15d2b5c4 --- /dev/null +++ b/src/net/sourceforge/plantuml/wire/WireDiagramFactory.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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.wire; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.UmlDiagramFactory; +import net.sourceforge.plantuml.core.DiagramType; + +public class WireDiagramFactory extends UmlDiagramFactory { + + public WireDiagramFactory() { + super(DiagramType.WIRE); + } + + @Override + protected List<Command> createCommands() { + + final List<Command> cmds = new ArrayList<Command>(); + addCommonCommands1(cmds); + cmds.add(new CommandComponent()); + cmds.add(new CommandContainer()); + cmds.add(new CommandContainerEnd()); + cmds.add(new CommandPin()); + cmds.add(new CommandPinSpace()); + cmds.add(new CommandVspace()); + cmds.add(new CommandNewColumn()); + + return cmds; + } + + @Override + public WireDiagram createEmptyDiagram() { + return new WireDiagram(); + } + +} diff --git a/stdlib/cloudinsight-abx.repx b/stdlib/cloudinsight-abx.repx index 6d6d7832f..b72613854 100644 Binary files a/stdlib/cloudinsight-abx.repx and b/stdlib/cloudinsight-abx.repx differ diff --git a/stdlib/home.repx b/stdlib/home.repx index b09566345..edaba9444 100644 --- a/stdlib/home.repx +++ b/stdlib/home.repx @@ -9,3 +9,4 @@ office c4 osa kubernetes +logos \ No newline at end of file diff --git a/stdlib/logos-abx.repx b/stdlib/logos-abx.repx new file mode 100644 index 000000000..1daaef512 Binary files /dev/null and b/stdlib/logos-abx.repx differ diff --git a/stdlib/logos-dex.repx b/stdlib/logos-dex.repx new file mode 100644 index 000000000..02e926f9e Binary files /dev/null and b/stdlib/logos-dex.repx differ