1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00

version 1.2020.1

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

View File

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

View File

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

View File

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

View File

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

View File

@ -153,6 +153,8 @@ public class Pipe {
final String s = readOneLine(); final String s = readOneLine();
if (s == null) { if (s == null) {
closed = true; closed = true;
} else if (s.startsWith("@@@format ")) {
manageFormat(s);
} else { } else {
sb.append(s); sb.append(s);
sb.append(BackSlash.NEWLINE); sb.append(BackSlash.NEWLINE);
@ -171,6 +173,14 @@ public class Pipe {
return source; 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 { private String readOneLine() throws IOException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (true) { while (true) {

View File

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

View File

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

View File

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

View File

@ -371,10 +371,10 @@ public class ActivityDiagram3 extends UmlDiagram {
return CommandExecutionResult.error("Cannot find if"); 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(); manageSwimlaneStrategy();
final InstructionRepeat instructionRepeat = new InstructionRepeat(swinlanes.getCurrentSwimlane(), current(), final InstructionRepeat instructionRepeat = new InstructionRepeat(swinlanes.getCurrentSwimlane(), current(),
nextLinkRenderer(), color, label); nextLinkRenderer(), color, label, boxStyleIn, colors);
current().add(instructionRepeat); current().add(instructionRepeat);
setCurrent(instructionRepeat); setCurrent(instructionRepeat);
setNextLinkRendererInternal(LinkRendering.none()); setNextLinkRendererInternal(LinkRendering.none());

View File

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

View File

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

View File

@ -35,8 +35,10 @@
*/ */
package net.sourceforge.plantuml.activitydiagram3.command; package net.sourceforge.plantuml.activitydiagram3.command;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3;
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex; 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.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.color.ColorParser; 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> { public class CommandRepeat3 extends SingleLineCommand2<ActivityDiagram3> {
@ -56,20 +61,39 @@ public class CommandRepeat3 extends SingleLineCommand2<ActivityDiagram3> {
static IRegex getRegexConcat() { static IRegex getRegexConcat() {
return RegexConcat.build(CommandRepeat3.class.getName(), RegexLeaf.start(), // return RegexConcat.build(CommandRepeat3.class.getName(), RegexLeaf.start(), //
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
ColorParser.exp4(), // ColorParser.exp4(), //
new RegexLeaf("repeat"), // new RegexLeaf("repeat"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("LABEL", ":(.*?)")), // new RegexOptional(new RegexLeaf("LABEL", ":(.*?)")), //
new RegexLeaf(";?"), // new RegexOptional(new RegexLeaf("STYLE", CommandActivity3.ENDING_GROUP)), //
// new RegexLeaf(";?"), //
RegexLeaf.end()); RegexLeaf.end());
} }
private static ColorParser color() {
return ColorParser.simpleColor(ColorType.BACK);
}
@Override @Override
protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) { protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) {
final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0)); final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", 0));
final Display label = Display.getWithNewlines(arg.get("LABEL", 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(); return CommandExecutionResult.ok();
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.classdiagram;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Set;
import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.ISkinSimple; 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.Ident;
import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.SuperGroup;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.USymbol; import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram;

View File

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

View File

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

View File

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

View File

@ -100,6 +100,14 @@ public class BlocLines implements Iterable<StringLocated> {
return new BlocLines(result); 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) { public static BlocLines getWithNewlines(String s) {
final List<StringLocated> result = new ArrayList<StringLocated>(); final List<StringLocated> result = new ArrayList<StringLocated>();
for (String cs : BackSlash.getWithNewlines(s)) { for (String cs : BackSlash.getWithNewlines(s)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,13 +38,16 @@ package net.sourceforge.plantuml.core;
import net.sourceforge.plantuml.utils.StartUtils; import net.sourceforge.plantuml.utils.StartUtils;
public enum DiagramType { 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) { static public DiagramType getTypeFromArobaseStart(String s) {
s = s.toLowerCase(); s = s.toLowerCase();
// if (s.startsWith("@startuml2")) { // if (s.startsWith("@startuml2")) {
// return UML2; // return UML2;
// } // }
if (StartUtils.startsWithSymbolAnd("startwire", s)) {
return WIRE;
}
if (StartUtils.startsWithSymbolAnd("startbpm", s)) { if (StartUtils.startsWithSymbolAnd("startbpm", s)) {
return BPM; return BPM;
} }

View File

@ -71,11 +71,13 @@ public class AtomImg extends AbstractAtom implements Atom {
private final BufferedImage image; private final BufferedImage image;
private final double scale; private final double scale;
private final Url url; private final Url url;
private final String rawFileName;
private AtomImg(BufferedImage image, double scale, Url url) {
private AtomImg(BufferedImage image, double scale, Url url, String rawFileName) {
this.image = image; this.image = image;
this.scale = scale; this.scale = scale;
this.url = url; this.url = url;
this.rawFileName = rawFileName;
} }
public static Atom createQrcode(String flash, double scale) { public static Atom createQrcode(String flash, double scale) {
@ -84,7 +86,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (im == null) { if (im == null) {
im = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); 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) { 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) { if (read == null) {
return AtomText.create("(Cannot decode: " + f.getCanonicalPath() + ")", fc); 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) { } catch (IOException e) {
return AtomText.create("ERROR " + e.toString(), fc); return AtomText.create("ERROR " + e.toString(), fc);
} }
@ -130,7 +132,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (read == null) { if (read == null) {
return AtomText.create("(Cannot decode: " + source + ")", fc); 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) 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) { if (read == null) {
return AtomText.create("(Cannot decode: " + text + ")", fc); 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 // Added by Alain Corbiere
@ -178,7 +180,7 @@ public class AtomImg extends AbstractAtom implements Atom {
if (url != null) { if (url != null) {
ug.startUrl(url); ug.startUrl(url);
} }
ug.draw(new UImage(image).scale(scale)); ug.draw(new UImage(rawFileName, image).scale(scale));
if (url != null) { if (url != null) {
ug.closeAction(); ug.closeAction();
} }

View File

@ -99,7 +99,7 @@ public class AtomMath extends AbstractAtom implements Atom {
final SvgString svg = math.getSvg(scale, fore, back); final SvgString svg = math.getSvg(scale, fore, back);
ug.draw(new UImageSvg(svg)); ug.draw(new UImageSvg(svg));
} else { } 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); ug.draw(image);
} }
} }

View File

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

View File

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

View File

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

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.creole.CreoleMode; import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; 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 { 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() { public final boolean V1972() {
if (getPragma().backToLegacyPackage()) {
return false;
}
if (getPragma().useNewPackage()) {
return true;
}
if (G1972)
return true;
return false; 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 horizontalPages = 1;
private int verticalPages = 1; private int verticalPages = 1;
@ -105,13 +132,15 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return this.stacks2.get(stacks2.size() - 1); return this.stacks2.get(stacks2.size() - 1);
} }
private String namespaceSeparator = ".";
final public void setNamespaceSeparator(String namespaceSeparator) { final public void setNamespaceSeparator(String namespaceSeparator) {
this.namespaceSeparatorHasBeenSet = true;
this.namespaceSeparator = namespaceSeparator; this.namespaceSeparator = namespaceSeparator;
} }
final public String getNamespaceSeparator() { final public String getNamespaceSeparator() {
if (namespaceSeparatorHasBeenSet == false) {
return V1972() ? "::" : ".";
}
return namespaceSeparator; return namespaceSeparator;
} }
@ -135,6 +164,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return false; return false;
} }
final public void setLastEntity(ILeaf foo) {
this.lastEntity = foo;
}
final protected ILeaf getOrCreateLeafDefault(Ident idNewLong, Code code, LeafType type, USymbol symbol) { final protected ILeaf getOrCreateLeafDefault(Ident idNewLong, Code code, LeafType type, USymbol symbol) {
checkNotNull(idNewLong); checkNotNull(idNewLong);
if (type == null) { if (type == null) {
@ -182,7 +215,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
} }
final public Ident buildLeafIdent(String id) { final public Ident buildLeafIdent(String id) {
return getLastID().add(id, namespaceSeparator); return getLastID().add(id, getNamespaceSeparator());
} }
final public Ident buildLeafIdentSpecial(String id) { final public Ident buildLeafIdentSpecial(String id) {
@ -196,7 +229,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
} }
final public Ident buildFullyQualified(String id) { 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) { 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); gotoGroupInternalWithNamespace(ident, code, display, code, type, parent);
} else if (strategy == NamespaceStrategy.SINGLE) { } 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); gotoGroupExternal(newIdLong, code, display, null, type, parent);
stacks2.add(newIdLong); stacks2.add(newIdLong);
} else { } else {
@ -363,7 +396,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return; return;
} }
final boolean mutation; final boolean mutation;
if (namespaceSeparator == null) if (getNamespaceSeparator() == null)
mutation = entityFactory.getLeafVerySmart(idNewLong) != null; mutation = entityFactory.getLeafVerySmart(idNewLong) != null;
else else
mutation = entityFactory.getLeafStrict(idNewLong) != null; mutation = entityFactory.getLeafStrict(idNewLong) != null;
@ -491,6 +524,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return entityFactory.getRootGroup(); return entityFactory.getRootGroup();
} }
public SuperGroup getRootSuperGroup() {
return entityFactory.getRootSuperGroup();
}
public final Collection<ILeaf> getLeafsvalues() { public final Collection<ILeaf> getLeafsvalues() {
return entityFactory.leafs2(); return entityFactory.leafs2();
} }
@ -606,6 +643,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
entityFactory.buildSuperGroups();
final CucaDiagramFileMaker maker = this.isUseJDot() final CucaDiagramFileMaker maker = this.isUseJDot()
? new CucaDiagramFileMakerJDot(this, fileFormatOption.getDefaultStringBounder()) ? new CucaDiagramFileMakerJDot(this, fileFormatOption.getDefaultStringBounder())
: new CucaDiagramFileMakerSvek(this); : new CucaDiagramFileMakerSvek(this);
@ -807,6 +846,21 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
return null; 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; private ILeaf lastEntity = null;
final public ILeaf getLastEntity() { final public ILeaf getLastEntity() {
@ -854,4 +908,11 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
entityFactory.incRawLayout(); entityFactory.incRawLayout();
} }
public CommandExecutionResult constraintOnLinks(Link link1, Link link2, Display display) {
final LinkConstraint linkConstraint = new LinkConstraint(link1, link2, display);
link1.setLinkConstraint(linkConstraint);
link2.setLinkConstraint(linkConstraint);
return CommandExecutionResult.ok();
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,13 +38,17 @@ package net.sourceforge.plantuml.cucadiagram.entity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; 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.Bodier;
import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram; 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.Ident;
import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.LeafType;
import net.sourceforge.plantuml.cucadiagram.Link; 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; import net.sourceforge.plantuml.skin.VisibilityModifier;
public final class EntityFactory { public final class EntityFactory {
@ -73,14 +81,104 @@ public final class EntityFactory {
private int rawLayout; private int rawLayout;
private final IGroup rootGroup = new GroupRoot(this); private final IGroup rootGroup = new GroupRoot(this);
private final SuperGroup rootSuperGroup = new SuperGroup(rootGroup);
private final List<HideOrShow2> hides2; private final List<HideOrShow2> hides2;
private final List<HideOrShow2> removed; private final List<HideOrShow2> removed;
/* private */ final public CucaDiagram namespaceSeparator; /* 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) { public EntityFactory(List<HideOrShow2> hides2, List<HideOrShow2> removed, CucaDiagram namespaceSeparator) {
this.hides2 = hides2; this.hides2 = hides2;
this.removed = removed; this.removed = removed;
this.namespaceSeparator = namespaceSeparator; this.namespaceSeparator = namespaceSeparator;
// this.mergeIntricated = namespaceSeparator.mergeIntricated();
// if (OptionFlags.V1972(namespaceSeparator)) { // if (OptionFlags.V1972(namespaceSeparator)) {
// this.leafsByCode = null; // this.leafsByCode = null;
@ -400,9 +498,10 @@ public final class EntityFactory {
if (result != null) { if (result != null) {
return result; return result;
} }
System.err.println("getParentContainer::groups2=" + groups2); // System.err.println("getParentContainer::groups2=" + groups2);
result = createGroup(parent, parent, Display.getWithNewlines(parent.getName()), null, GroupType.PACKAGE, final Display display = Display.getWithNewlines(parent.getName());
null, Collections.<VisibilityModifier>emptySet(), namespaceSeparator.getNamespaceSeparator()); result = createGroup(parent, parent, display, null, GroupType.PACKAGE, null,
Collections.<VisibilityModifier>emptySet(), namespaceSeparator.getNamespaceSeparator());
addGroup(result); addGroup(result);
return result; return result;
} }
@ -412,4 +511,5 @@ public final class EntityFactory {
return parentContainer; return parentContainer;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -106,7 +106,8 @@ public class TextBlockUtils {
return new TextBlockMarged(textBlock, marginX1, marginX2, marginY1, marginY2); 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); return new TextBlockMinWidth(textBlock, minWidth, horizontalAlignment);
} }
@ -125,6 +126,10 @@ public class TextBlockUtils {
return new PositionableImpl(pt, textBlock.calculateDimension(stringBounder)); 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) { public static TextBlock mergeLR(TextBlock b1, TextBlock b2, VerticalAlignment verticallAlignment) {
return new TextBlockHorizontal(b1, b2, verticallAlignment); return new TextBlockHorizontal(b1, b2, verticallAlignment);
} }
@ -133,7 +138,8 @@ public class TextBlockUtils {
return new TextBlockVertical2(b1, b2, horizontalAlignment); return new TextBlockVertical2(b1, b2, horizontalAlignment);
} }
// public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1, TextBlockBackcolored b2, // public static TextBlockBackcolored mergeColoredTB(TextBlockBackcolored b1,
// TextBlockBackcolored b2,
// HorizontalAlignment horizontalAlignment) { // HorizontalAlignment horizontalAlignment) {
// return addBackcolor(mergeTB(b1, b2, horizontalAlignment), b1.getBackcolor()); // return addBackcolor(mergeTB(b1, b2, horizontalAlignment), b1.getBackcolor());
// } // }

View File

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

View File

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

View File

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

View File

@ -56,7 +56,7 @@ public class Stdlib {
} }
} }
private static Stdlib retrieve(final String name) throws IOException { public static Stdlib retrieve(final String name) throws IOException {
Stdlib result = all.get(name); Stdlib result = all.get(name);
if (result == null) { if (result == null) {
final DataInputStream dataStream = getDataStream(name); final DataInputStream dataStream = getDataStream(name);
@ -222,7 +222,7 @@ public class Stdlib {
public static void extractStdLib() throws IOException { public static void extractStdLib() throws IOException {
for (String name : getAll()) { for (String name : getAll()) {
final Stdlib folder = Stdlib.retrieve(name); 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); return Collections.unmodifiableCollection(result);
} }
private void extractMeFull(File dir) throws IOException { private void extractMeFull() throws IOException {
final DataInputStream dataStream = getDataStream(); final DataInputStream dataStream = getDataStream();
if (dataStream == null) { if (dataStream == null) {
return; 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) { public static void addInfoVersion(List<String> strings, boolean details) {
try { try {
for (String name : getAll()) { for (String name : getAll()) {

View File

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

View File

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

View File

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

View File

@ -33,10 +33,15 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project;
import java.util.Date; 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 { public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
private final int year; private final int year;
@ -65,6 +70,10 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
this.month = month; this.month = month;
} }
public int getYear() {
return year;
}
private int internalNumber() { private int internalNumber() {
return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth; return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth;
} }
@ -120,7 +129,7 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
return DayOfWeek.fromH(h); return DayOfWeek.fromH(h);
} }
public InstantDay asInstantDay(DayAsDate reference) { public Wink asInstantDay(DayAsDate reference) {
// if (this.compareTo(reference) < 0) { // if (this.compareTo(reference) < 0) {
// throw new IllegalArgumentException(); // throw new IllegalArgumentException();
// } // }
@ -130,7 +139,39 @@ public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject {
current = current.next(); current = current.next();
cmp++; 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) { public int compareTo(DayAsDate other) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,9 +33,12 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.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 { public class GanttConstraint implements Complement {

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
@ -55,15 +55,11 @@ import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.Scale; import net.sourceforge.plantuml.Scale;
import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.TitledDiagram; import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData; 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.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorSetSimple; import net.sourceforge.plantuml.graphic.HtmlColorSetSimple;
import net.sourceforge.plantuml.graphic.HtmlColorUtils; 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.InnerStrategy;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; 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.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.ImageBuilder; import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.MinMax; 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.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
public class GanttDiagram extends TitledDiagram implements Subject { 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 Map<String, Task> byShortName = new HashMap<String, Task>();
private final List<GanttConstraint> constraints = new ArrayList<GanttConstraint>(); private final List<GanttConstraint> constraints = new ArrayList<GanttConstraint>();
private final IHtmlColorSet colorSet = new HtmlColorSetSimple(); private final IHtmlColorSet colorSet = new HtmlColorSetSimple();
private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class); private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class);
private final Collection<DayAsDate> closedDayAsDate = new HashSet<DayAsDate>(); private final Collection<DayAsDate> closedDayAsDate = new HashSet<DayAsDate>();
private final Collection<DayAsDate> openedDayAsDate = new HashSet<DayAsDate>(); private final Collection<DayAsDate> openedDayAsDate = new HashSet<DayAsDate>();
private GCalendar calendar;
private final Instant min = new InstantDay(0); private final Map<String, Resource> resources = new LinkedHashMap<String, Resource>();
private Instant max; 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() { public DiagramDescription getDescription() {
return new DiagramDescription("(Project)"); return new DiagramDescription("(Project)");
@ -148,16 +172,35 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os);
} }
public void setPrintScale(PrintScale printScale) {
this.printScale = printScale;
}
private TextBlockBackcolored getTextBlock() { private TextBlockBackcolored getTextBlock() {
initMinMax(); if (printStart == null) {
final TimeScale timeScale = getTimeScale(); initMinMax();
initTaskAndResourceDraws(timeScale); } 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() { return new TextBlockBackcolored() {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
drawTimeHeader(ug, timeScale); timeHeader.drawTimeHeader(ug, totalHeight);
drawTasks(ug, timeScale); drawConstraints(ug, timeHeader.getTimeScale());
drawConstraints(ug, timeScale); drawTasksRect(ug);
drawTasksTitle(ug);
drawResources(ug);
} }
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { 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) { public Dimension2D calculateDimension(StringBounder stringBounder) {
final double xmin = timeScale.getStartingPosition(min); final double xmin = timeHeader.getTimeScale().getStartingPosition(min);
final double xmax = timeScale.getEndingPosition(max); final double xmax = timeHeader.getTimeScale().getEndingPosition(max);
return new Dimension2DDouble(xmax - xmin, totalHeight); return new Dimension2DDouble(xmax - xmin, totalHeight);
} }
@ -180,25 +223,43 @@ public class GanttDiagram extends TitledDiagram implements Subject {
}; };
} }
private TimeScale getTimeScale() { private void drawTasksRect(UGraphic ug) {
if (calendar == null) { for (Task task : tasks.values()) {
return new TimeScaleBasic(); 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() { private void drawConstraints(final UGraphic ug, TimeScale timeScale) {
return (GCalendarSimple) calendar; 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() { public final LoadPlanable getDefaultPlan() {
return new LoadPlanable() { return new LoadPlanable() {
public int getLoadAt(Instant instant) { public int getLoadAt(Wink instant) {
if (calendar == null) { if (calendar == null) {
return 100; return 100;
} }
final DayAsDate day = getCalendarSimple().toDayAsDate((InstantDay) instant); final DayAsDate day = calendar.toDayAsDate((Wink) instant);
if (isClosed(day)) { if (isClosed(day)) {
return 0; return 0;
} }
@ -227,152 +288,8 @@ public class GanttDiagram extends TitledDiagram implements Subject {
openedDayAsDate.add(day); openedDayAsDate.add(day);
} }
private void drawConstraints(final UGraphic ug, TimeScale timeScale) { private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight) {
for (GanttConstraint constraint : constraints) { double y = headerHeight;
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();
for (Task task : tasks.values()) { for (Task task : tasks.values()) {
final TaskDraw draw; final TaskDraw draw;
if (task instanceof TaskSeparator) { if (task instanceof TaskSeparator) {
@ -402,8 +319,8 @@ public class GanttDiagram extends TitledDiagram implements Subject {
if (task instanceof TaskSeparator) { if (task instanceof TaskSeparator) {
continue; continue;
} }
final Instant start = task.getStart(); final Wink start = task.getStart();
final Instant end = task.getEnd(); final Wink end = task.getEnd();
// if (min.compareTo(start) > 0) { // if (min.compareTo(start) > 0) {
// min = start; // min = start;
// } // }
@ -414,13 +331,13 @@ public class GanttDiagram extends TitledDiagram implements Subject {
} }
if (calendar != null) { if (calendar != null) {
for (DayAsDate d : colorDays.keySet()) { for (DayAsDate d : colorDays.keySet()) {
final Instant instant = calendar.fromDayAsDate(d); final Wink instant = calendar.fromDayAsDate(d);
if (instant.compareTo(max) > 0) { if (instant.compareTo(max) > 0) {
max = instant; max = instant;
} }
} }
for (DayAsDate d : nameDays.keySet()) { for (DayAsDate d : nameDays.keySet()) {
final Instant instant = calendar.fromDayAsDate(d); final Wink instant = calendar.fromDayAsDate(d);
if (instant.compareTo(max) > 0) { if (instant.compareTo(max) > 0) {
max = instant; max = instant;
} }
@ -443,28 +360,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return result; 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) { public Task getExistingTask(String id) {
if (id == null) { if (id == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
@ -538,7 +433,7 @@ public class GanttDiagram extends TitledDiagram implements Subject {
} }
public void setStartingDate(DayAsDate start) { public void setStartingDate(DayAsDate start) {
this.calendar = new GCalendarSimple(start); this.calendar = new GCalendar(start);
} }
public DayAsDate getStartingDate() { public DayAsDate getStartingDate() {
@ -552,14 +447,14 @@ public class GanttDiagram extends TitledDiagram implements Subject {
if (this.calendar == null) { if (this.calendar == null) {
return null; return null;
} }
return ((GCalendarSimple) this.calendar).toDayAsDate(new InstantDay(nday)); return this.calendar.toDayAsDate(new Wink(nday));
} }
public int daysInWeek() { public int daysInWeek() {
return 7 - closedDayOfWeek.size(); return 7 - closedDayOfWeek.size();
} }
public Instant convert(DayAsDate day) { public Wink convert(DayAsDate day) {
return calendar.fromDayAsDate(day); return calendar.fromDayAsDate(day);
} }
@ -567,8 +462,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return getDefaultPlan().getLoadAt(convert(day)) > 0; return getDefaultPlan().getLoadAt(convert(day)) > 0;
} }
private final Map<String, Resource> resources = new LinkedHashMap<String, Resource>();
public void affectResource(Task result, String description) { public void affectResource(Task result, String description) {
final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?"); final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?");
final Matcher m = p.matcher(description); final Matcher m = p.matcher(description);
@ -586,13 +479,13 @@ public class GanttDiagram extends TitledDiagram implements Subject {
public Resource getResource(String resourceName) { public Resource getResource(String resourceName) {
Resource resource = resources.get(resourceName); Resource resource = resources.get(resourceName);
if (resource == null) { if (resource == null) {
resource = new Resource(resourceName, getDefaultPlan(), getCalendarSimple()); resource = new Resource(resourceName, getDefaultPlan(), calendar);
} }
resources.put(resourceName, resource); resources.put(resourceName, resource);
return resource; return resource;
} }
public int getLoadForResource(Resource res, Instant i) { public int getLoadForResource(Resource res, Wink i) {
int result = 0; int result = 0;
for (Task task : tasks.values()) { for (Task task : tasks.values()) {
if (task instanceof TaskSeparator) { if (task instanceof TaskSeparator) {
@ -604,9 +497,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return result; 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) { public Moment getExistingMoment(String id) {
Moment result = getExistingTask(id); Moment result = getExistingTask(id);
if (result == null) { if (result == null) {
@ -661,8 +551,6 @@ public class GanttDiagram extends TitledDiagram implements Subject {
colorDay(today, colors.getCenter()); colorDay(today, colors.getCenter());
} }
private DayAsDate today;
public CommandExecutionResult setToday(DayAsDate date) { public CommandExecutionResult setToday(DayAsDate date) {
this.today = date; this.today = date;
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
@ -673,4 +561,9 @@ public class GanttDiagram extends TitledDiagram implements Subject {
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }
public void setPrintInterval(DayAsDate start, DayAsDate end) {
this.printStart = start;
this.printEnd = end;
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult; 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.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; 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> { public class CommandGanttArrow extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult; 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.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; 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> { public class CommandGanttArrow2 extends SingleLineCommand2<GanttDiagram> {

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command; 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.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; 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> { public class NaturalCommand extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command; 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.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; 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> { public class NaturalCommandAnd extends SingleLineCommand2<GanttDiagram> {

View File

@ -33,7 +33,7 @@
* *
* *
*/ */
package net.sourceforge.plantuml.project3; package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.Command; 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.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult; 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> { public class NaturalCommandAndAnd extends SingleLineCommand2<GanttDiagram> {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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