mirror of
https://github.com/octoleo/plantuml.git
synced 2024-11-21 20:45:10 +00:00
version 1.2017.19
This commit is contained in:
parent
4b65d2140f
commit
a628cfdb76
8
pom.xml
8
pom.xml
@ -35,7 +35,7 @@
|
||||
|
||||
<groupId>net.sourceforge.plantuml</groupId>
|
||||
<artifactId>plantuml</artifactId>
|
||||
<version>1.2017.19-SNAPSHOT</version>
|
||||
<version>1.2017.20-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PlantUML</name>
|
||||
@ -120,6 +120,12 @@
|
||||
<include>net/sourceforge/plantuml/math/*.js</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${project.basedir}</directory>
|
||||
<includes>
|
||||
<include>stdlib/**/*.puml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -39,7 +39,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -65,8 +64,8 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
|
||||
this.defines = defines;
|
||||
try {
|
||||
reader2 = new UncommentReadLine(new ReadLineReader(reader, desc));
|
||||
includer = new Preprocessor(reader2, charset, defines, newCurrentDir, this);
|
||||
init(includer, config);
|
||||
includer = new Preprocessor(config, reader2, charset, defines, newCurrentDir, this);
|
||||
init(includer);
|
||||
} finally {
|
||||
if (includer != null) {
|
||||
includer.close();
|
||||
@ -79,7 +78,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
|
||||
this(config, charset, defines, reader, null, null);
|
||||
}
|
||||
|
||||
private void init(Preprocessor includer, List<String> config) throws IOException {
|
||||
private void init(Preprocessor includer) throws IOException {
|
||||
CharSequence2 s = null;
|
||||
List<CharSequence2> current2 = null;
|
||||
boolean paused = false;
|
||||
@ -108,21 +107,21 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
|
||||
reader2.setPaused(false);
|
||||
}
|
||||
if (StartUtils.isArobaseEndDiagram(s) && current2 != null) {
|
||||
current2.addAll(1, convert(config, new LineLocationImpl(null, null).oneLineRead()));
|
||||
blocks.add(new BlockUml(current2, startLine - config.size(), defines.cloneMe()));
|
||||
// current2.addAll(1, convert(config, new LineLocationImpl(null, null).oneLineRead()));
|
||||
blocks.add(new BlockUml(current2, startLine/* - config.size() */, defines.cloneMe()));
|
||||
current2 = null;
|
||||
reader2.setPaused(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CharSequence2> convert(List<String> config, LineLocation location) {
|
||||
final List<CharSequence2> result = new ArrayList<CharSequence2>();
|
||||
for (String s : config) {
|
||||
result.add(new CharSequence2Impl(s, location));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// private Collection<CharSequence2> convert(List<String> config, LineLocation location) {
|
||||
// final List<CharSequence2> result = new ArrayList<CharSequence2>();
|
||||
// for (String s : config) {
|
||||
// result.add(new CharSequence2Impl(s, location));
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public List<BlockUml> getBlockUmls() {
|
||||
return Collections.unmodifiableList(blocks);
|
||||
|
@ -282,8 +282,8 @@ public class Option {
|
||||
OptionFlags.getInstance().setGui(true);
|
||||
} else if (s.equalsIgnoreCase("-encodesprite")) {
|
||||
OptionFlags.getInstance().setEncodesprite(true);
|
||||
} else if (s.equalsIgnoreCase("-nosuggestengine")) {
|
||||
OptionFlags.getInstance().setUseSuggestEngine(false);
|
||||
// } else if (s.equalsIgnoreCase("-nosuggestengine")) {
|
||||
// OptionFlags.getInstance().setUseSuggestEngine(false);
|
||||
} else if (s.equalsIgnoreCase("-printfonts")) {
|
||||
OptionFlags.getInstance().setPrintFonts(true);
|
||||
} else if (s.equalsIgnoreCase("-dumphtmlstats")) {
|
||||
|
@ -97,7 +97,7 @@ public class OptionFlags {
|
||||
quiet = false;
|
||||
checkDotError = false;
|
||||
printFonts = false;
|
||||
useSuggestEngine = true;
|
||||
// useSuggestEngine = true;
|
||||
// failOnError = false;
|
||||
encodesprite = false;
|
||||
// PIC_LINE = false;
|
||||
@ -116,7 +116,7 @@ public class OptionFlags {
|
||||
private boolean quiet;
|
||||
private boolean checkDotError;
|
||||
private boolean printFonts;
|
||||
private boolean useSuggestEngine;
|
||||
// private boolean useSuggestEngine;
|
||||
private boolean encodesprite;
|
||||
private boolean dumpHtmlStats;
|
||||
private boolean dumpStats;
|
||||
@ -250,13 +250,17 @@ public class OptionFlags {
|
||||
this.printFonts = printFonts;
|
||||
}
|
||||
|
||||
public final boolean isUseSuggestEngine() {
|
||||
return useSuggestEngine;
|
||||
public final boolean isUseSuggestEngine2() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void setUseSuggestEngine(boolean useSuggestEngine) {
|
||||
this.useSuggestEngine = useSuggestEngine;
|
||||
}
|
||||
// public final boolean isUseSuggestEngine() {
|
||||
// return useSuggestEngine;
|
||||
// }
|
||||
//
|
||||
// public final void setUseSuggestEngine(boolean useSuggestEngine) {
|
||||
// this.useSuggestEngine = useSuggestEngine;
|
||||
// }
|
||||
|
||||
public final boolean isEncodesprite() {
|
||||
return encodesprite;
|
||||
|
@ -119,7 +119,7 @@ public class OptionPrint {
|
||||
System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
|
||||
System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
|
||||
System.out.println(" -language\t\tTo print the list of PlantUML keywords");
|
||||
System.out.println(" -nosuggestengine\tTo disable the suggest engine when errors in diagrams");
|
||||
// System.out.println(" -nosuggestengine\tTo disable the suggest engine when errors in diagrams");
|
||||
System.out.println(" -checkonly\t\tTo check the syntax of files without generating images");
|
||||
System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs");
|
||||
System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster");
|
||||
|
@ -57,6 +57,7 @@ import net.sourceforge.plantuml.descdiagram.DescriptionDiagramFactory;
|
||||
import net.sourceforge.plantuml.directdot.PSystemDotFactory;
|
||||
import net.sourceforge.plantuml.ditaa.PSystemDitaaFactory;
|
||||
import net.sourceforge.plantuml.donors.PSystemDonorsFactory;
|
||||
import net.sourceforge.plantuml.donors.PSystemSkinparameterListFactory;
|
||||
import net.sourceforge.plantuml.eggs.PSystemAppleTwoFactory;
|
||||
import net.sourceforge.plantuml.eggs.PSystemCharlieFactory;
|
||||
import net.sourceforge.plantuml.eggs.PSystemColorsFactory;
|
||||
@ -157,6 +158,7 @@ public class PSystemBuilder {
|
||||
factories.add(new PSystemLicenseFactory());
|
||||
factories.add(new PSystemVersionFactory());
|
||||
factories.add(new PSystemDonorsFactory());
|
||||
factories.add(new PSystemSkinparameterListFactory());
|
||||
factories.add(new PSystemListFontsFactory());
|
||||
factories.add(new PSystemOpenIconicFactory());
|
||||
factories.add(new PSystemListOpenIconicFactory());
|
||||
@ -188,7 +190,8 @@ public class PSystemBuilder {
|
||||
if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) {
|
||||
factories.add(new PSystemXearthFactory());
|
||||
}
|
||||
factories.add(new GanttDiagramFactory());
|
||||
factories.add(new GanttDiagramFactory(DiagramType.GANTT));
|
||||
factories.add(new GanttDiagramFactory(DiagramType.UML));
|
||||
factories.add(new FlowDiagramFactory());
|
||||
factories.add(new PSystemTreeFactory(DiagramType.JUNGLE));
|
||||
factories.add(new PSystemCuteFactory(DiagramType.CUTE));
|
||||
|
@ -65,6 +65,7 @@ import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
|
||||
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
|
||||
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UImage;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
@ -185,6 +186,10 @@ public class PSystemError extends AbstractPSystem {
|
||||
return new Dimension2DDouble(imWidth + 1, imHeight + 1);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return MinMax.fromMax(imWidth + 1, imHeight + 1);
|
||||
}
|
||||
|
||||
public HtmlColor getBackcolor() {
|
||||
return backImage;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ 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.creole.CommandCreoleMonospaced;
|
||||
import net.sourceforge.plantuml.cucadiagram.LinkStyle;
|
||||
import net.sourceforge.plantuml.cucadiagram.Rankdir;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotype;
|
||||
import net.sourceforge.plantuml.cucadiagram.dot.DotSplines;
|
||||
@ -112,7 +113,18 @@ public class SkinParam implements ISkinParam {
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<String> cleanForKey(String key) {
|
||||
private final Map<String, List<String>> cacheCleanForKey = new HashMap<String, List<String>>();
|
||||
|
||||
List<String> cleanForKey(String key) {
|
||||
List<String> result = cacheCleanForKey.get(key);
|
||||
if (result == null) {
|
||||
result = cleanForKeySlow(key);
|
||||
cacheCleanForKey.put(key, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
List<String> cleanForKeySlow(String key) {
|
||||
key = StringUtils.trin(StringUtils.goLowerCase(key));
|
||||
key = key.replaceAll("_|\\.|\\s", "");
|
||||
// key = replaceSmart(key, "partition", "package");
|
||||
@ -134,7 +146,7 @@ public class SkinParam implements ISkinParam {
|
||||
if (result.size() == 0) {
|
||||
result.add(key);
|
||||
}
|
||||
return result;
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
private static String replaceSmart(String s, String src, String target) {
|
||||
@ -200,7 +212,7 @@ public class SkinParam implements ISkinParam {
|
||||
return null;
|
||||
}
|
||||
final boolean acceptTransparent = param == ColorParam.background
|
||||
|| param == ColorParam.sequenceGroupBodyBackground;
|
||||
|| param == ColorParam.sequenceGroupBodyBackground || param == ColorParam.sequenceBoxBackground;
|
||||
return getIHtmlColorSet().getColorIfValid(value, acceptTransparent);
|
||||
}
|
||||
|
||||
@ -643,16 +655,38 @@ public class SkinParam implements ISkinParam {
|
||||
}
|
||||
|
||||
public UStroke getThickness(LineParam param, Stereotype stereotype) {
|
||||
LinkStyle style = null;
|
||||
if (stereotype != null) {
|
||||
checkStereotype(stereotype);
|
||||
|
||||
final String styleValue = getValue(param.name() + "style" + stereotype.getLabel(false));
|
||||
if (styleValue != null) {
|
||||
style = LinkStyle.fromString2(styleValue);
|
||||
}
|
||||
|
||||
final String value2 = getValue(param.name() + "thickness" + stereotype.getLabel(false));
|
||||
if (value2 != null && value2.matches("[\\d.]+")) {
|
||||
return new UStroke(Double.parseDouble(value2));
|
||||
if (style == null) {
|
||||
style = LinkStyle.NORMAL();
|
||||
}
|
||||
return style.goThickness(Double.parseDouble(value2)).getStroke3();
|
||||
}
|
||||
}
|
||||
final String value = getValue(param.name() + "thickness");
|
||||
if (value != null && value.matches("[\\d.]+")) {
|
||||
return new UStroke(Double.parseDouble(value));
|
||||
if (style == null) {
|
||||
style = LinkStyle.NORMAL();
|
||||
}
|
||||
return style.goThickness(Double.parseDouble(value)).getStroke3();
|
||||
}
|
||||
if (style == null) {
|
||||
final String styleValue = getValue(param.name() + "style");
|
||||
if (styleValue != null) {
|
||||
style = LinkStyle.fromString2(styleValue);
|
||||
}
|
||||
}
|
||||
if (style != null && style.isNormal() == false) {
|
||||
return style.getStroke3();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ import net.sourceforge.plantuml.UmlDiagram;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlanes;
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.core.DiagramDescription;
|
||||
@ -59,7 +58,6 @@ import net.sourceforge.plantuml.graphic.Rainbow;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockCompressed;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockRecentred;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.graphic.color.Colors;
|
||||
import net.sourceforge.plantuml.sequencediagram.NotePosition;
|
||||
import net.sourceforge.plantuml.sequencediagram.NoteType;
|
||||
@ -191,8 +189,9 @@ public class ActivityDiagram3 extends UmlDiagram {
|
||||
result = new TextBlockRecentred(result);
|
||||
final ISkinParam skinParam = getSkinParam();
|
||||
result = new AnnotatedWorker(this, skinParam).addAdd(result);
|
||||
final Dimension2D dim = TextBlockUtils.getMinMax(result, fileFormatOption.getDefaultStringBounder())
|
||||
.getDimension();
|
||||
// final Dimension2D dim = TextBlockUtils.getMinMax(result, fileFormatOption.getDefaultStringBounder())
|
||||
// .getDimension();
|
||||
final Dimension2D dim = result.getMinMax(fileFormatOption.getDefaultStringBounder()).getDimension();
|
||||
final double margin = 10;
|
||||
final double dpiFactor = getDpiFactor(fileFormatOption, Dimension2DDouble.delta(dim, 2 * margin, 0));
|
||||
|
||||
|
@ -46,21 +46,15 @@ import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
|
||||
|
||||
private final boolean shadowing;
|
||||
private final ISkinParam skinParam;
|
||||
|
||||
private AbstractFtile(boolean shadowing) {
|
||||
this.shadowing = shadowing;
|
||||
this.skinParam = null;
|
||||
}
|
||||
|
||||
public AbstractFtile(ISkinParam skinParam) {
|
||||
this.shadowing = skinParam.shadowing();
|
||||
this.skinParam = skinParam;
|
||||
}
|
||||
|
||||
@ -101,10 +95,31 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
|
||||
|
||||
public Collection<Ftile> getMyChildren() {
|
||||
throw new UnsupportedOperationException("" + getClass());
|
||||
// return Collections.emptyList();
|
||||
}
|
||||
|
||||
public HorizontalAlignment arrowHorizontalAlignment() {
|
||||
return skinParam.getHorizontalAlignment(AlignParam.ARROW_MESSAGE_ALIGN, null);
|
||||
}
|
||||
|
||||
private FtileGeometry cachedGeometry;
|
||||
|
||||
final public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
if (cachedGeometry == null) {
|
||||
cachedGeometry = calculateDimensionFtile(stringBounder);
|
||||
}
|
||||
return cachedGeometry;
|
||||
}
|
||||
|
||||
abstract protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder);
|
||||
|
||||
@Override
|
||||
final public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
// return getMinMaxFtile(stringBounder);
|
||||
}
|
||||
|
||||
// protected MinMax getMinMaxFtile(StringBounder stringBounder) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -40,8 +40,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
@ -76,7 +78,18 @@ public class FtileAssemblySimple extends AbstractTextBlock implements Ftile {
|
||||
return tile2.getSwimlaneOut();
|
||||
}
|
||||
|
||||
private final Map<Ftile, UTranslate> cachedTranslation = new HashMap<Ftile, UTranslate>();
|
||||
|
||||
public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) {
|
||||
UTranslate result = cachedTranslation.get(child);
|
||||
if (result == null) {
|
||||
result = getTranslateForSlow(child, stringBounder);
|
||||
cachedTranslation.put(child, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private UTranslate getTranslateForSlow(Ftile child, StringBounder stringBounder) {
|
||||
if (child == tile1) {
|
||||
return getTranslated1(stringBounder);
|
||||
}
|
||||
@ -96,8 +109,8 @@ public class FtileAssemblySimple extends AbstractTextBlock implements Ftile {
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
ug.apply(getTranslated1(stringBounder)).draw(tile1);
|
||||
ug.apply(getTranslated2(stringBounder)).draw(tile2);
|
||||
ug.apply(getTranslateFor(tile1, stringBounder)).draw(tile1);
|
||||
ug.apply(getTranslateFor(tile2, stringBounder)).draw(tile2);
|
||||
}
|
||||
|
||||
public LinkRendering getInLinkRendering() {
|
||||
|
@ -58,8 +58,9 @@ public class FtileBreak extends FtileEmpty implements WeldingPoint {
|
||||
return "FtileBreak";
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
return super.calculateDimension(stringBounder).withoutPointOut();
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return calculateDimensionEmpty().withoutPointOut();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,7 +85,12 @@ public class FtileEmpty extends AbstractFtile {
|
||||
public void drawU(UGraphic ug) {
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return calculateDimensionEmpty();
|
||||
}
|
||||
|
||||
final protected FtileGeometry calculateDimensionEmpty() {
|
||||
return new FtileGeometry(width, height, width / 2, 0, height);
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,9 @@ public class FtileGoto extends FtileEmpty {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
return super.calculateDimension(stringBounder).withoutPointOut();
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return calculateDimensionEmpty().withoutPointOut();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -76,7 +76,8 @@ public class FtileHeightFixed extends AbstractFtile {
|
||||
return tile.getSwimlaneOut();
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return tile.calculateDimension(stringBounder).translate(getTranslate(stringBounder)).fixedHeight(fixedHeight);
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,8 @@ public class FtileKilled extends AbstractFtile {
|
||||
return tile.getSwimlaneOut();
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry geo = tile.calculateDimension(stringBounder);
|
||||
return new FtileGeometry(tile.calculateDimension(stringBounder), geo.getLeft(), geo.getInY());
|
||||
}
|
||||
|
@ -85,7 +85,8 @@ public class FtileMarged extends AbstractFtile {
|
||||
return tile.getSwimlaneOut();
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry orig = tile.calculateDimension(stringBounder);
|
||||
return new FtileGeometry(orig.getWidth() + margin1 + margin2, orig.getHeight(), orig.getLeft() + margin1,
|
||||
orig.getInY(), orig.getOutY());
|
||||
|
@ -74,7 +74,8 @@ public class FtileMargedRight extends AbstractFtile {
|
||||
return tile.getSwimlaneOut();
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry orig = tile.calculateDimension(stringBounder);
|
||||
if (orig.getWidth() > maxX) {
|
||||
throw new IllegalStateException();
|
||||
|
@ -58,7 +58,16 @@ public class FtileMargedVertically extends FtileDecorate {
|
||||
ug.draw(getFtileDelegated());
|
||||
}
|
||||
|
||||
private FtileGeometry cached;
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
if (cached == null) {
|
||||
this.cached = calculateDimensionSlow(stringBounder);
|
||||
}
|
||||
return this.cached;
|
||||
}
|
||||
|
||||
private FtileGeometry calculateDimensionSlow(StringBounder stringBounder) {
|
||||
final FtileGeometry orig = getFtileDelegated().calculateDimension(stringBounder);
|
||||
return new FtileGeometry(orig.getWidth(), orig.getHeight() + margin1 + margin2, orig.getLeft(), orig.getInY()
|
||||
+ margin1, orig.hasPointOut() ? orig.getOutY() + margin1 : orig.getOutY());
|
||||
|
@ -64,7 +64,6 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.graphic.UGraphicDelegator;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorType;
|
||||
import net.sourceforge.plantuml.skin.rose.Rose;
|
||||
@ -113,7 +112,8 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
|
||||
factory = new FtileFactoryDelegatorWhile(factory);
|
||||
factory = new FtileFactoryDelegatorRepeat(factory);
|
||||
factory = new FtileFactoryDelegatorCreateParallel(factory);
|
||||
// factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new FtileFactoryDelegatorCreateParallel1(factory));
|
||||
// factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new
|
||||
// FtileFactoryDelegatorCreateParallel1(factory));
|
||||
factory = new FtileFactoryDelegatorAddNote(factory);
|
||||
factory = new FtileFactoryDelegatorCreateGroup(factory);
|
||||
return factory;
|
||||
@ -173,16 +173,20 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
|
||||
}
|
||||
|
||||
static private final double separationMargin = 10;
|
||||
private TextBlock full;
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final FtileFactory factory = getFtileFactory(ug.getStringBounder());
|
||||
TextBlock full = root.createFtile(factory);
|
||||
if (full == null) {
|
||||
final FtileFactory factory = getFtileFactory(ug.getStringBounder());
|
||||
full = root.createFtile(factory);
|
||||
if (swimlanes.size() <= 1) {
|
||||
// BUG42
|
||||
full = new TextBlockInterceptorUDrawable(full);
|
||||
}
|
||||
}
|
||||
|
||||
ug = new UGraphicForSnake(ug);
|
||||
if (swimlanes.size() <= 1) {
|
||||
full = new TextBlockInterceptorUDrawable(full);
|
||||
// BUG42
|
||||
// full.drawU(ug);
|
||||
full.drawU(ug);
|
||||
ug.flushUg();
|
||||
return;
|
||||
@ -383,10 +387,21 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
|
||||
ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height));
|
||||
}
|
||||
|
||||
// private Dimension2D cachedDimension;
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return TextBlockUtils.getMinMax(this, stringBounder).getDimension();
|
||||
return getMinMax(stringBounder).getDimension();
|
||||
// if (cachedDimension == null) {
|
||||
// cachedDimension = calculateDimensionSlow(stringBounder);
|
||||
// }
|
||||
// return cachedDimension;
|
||||
}
|
||||
|
||||
// private Dimension2D calculateDimensionSlow(StringBounder stringBounder) {
|
||||
// final Dimension2D result = TextBlockUtils.getMinMax(this, stringBounder).getDimension();
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public Instruction getCurrent() {
|
||||
return currentInstruction;
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ import java.util.HashMap;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
@ -59,7 +58,8 @@ public class TextBlockInterceptorUDrawable extends AbstractTextBlock implements
|
||||
}
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return TextBlockUtils.getMinMax(this, stringBounder).getDimension();
|
||||
// return TextBlockUtils.getMinMax(this, stringBounder).getDimension();
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -93,7 +93,8 @@ class FtileForkInner extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
double height = 0;
|
||||
double width = 0;
|
||||
for (Ftile ftile : forks) {
|
||||
|
@ -93,7 +93,8 @@ class FtileForkInnerOverlapped extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
double height = 0;
|
||||
double width = 0;
|
||||
for (Ftile ftile : forks) {
|
||||
|
@ -130,12 +130,12 @@ public class FtileGroup extends AbstractFtile {
|
||||
return new UTranslate(suppWidth / 2, diffHeightTitle(stringBounder) + headerNoteHeight(stringBounder));
|
||||
}
|
||||
|
||||
private static MinMax getMinMax(TextBlock tb, StringBounder stringBounder) {
|
||||
private MinMax getInnerMinMax(StringBounder stringBounder) {
|
||||
final LimitFinder limitFinder = new LimitFinder(stringBounder, false);
|
||||
final UGraphicForSnake interceptor = new UGraphicForSnake(limitFinder);
|
||||
final UGraphicInterceptorUDrawable interceptor2 = new UGraphicInterceptorUDrawable(interceptor);
|
||||
|
||||
tb.drawU(interceptor2);
|
||||
inner.drawU(interceptor2);
|
||||
interceptor2.flushUg();
|
||||
return limitFinder.getMinMax();
|
||||
}
|
||||
@ -149,9 +149,19 @@ public class FtileGroup extends AbstractFtile {
|
||||
return suppWidth;
|
||||
}
|
||||
|
||||
private FtileGeometry cachedInnerDimension;
|
||||
|
||||
private FtileGeometry getInnerDimension(StringBounder stringBounder) {
|
||||
if (cachedInnerDimension == null) {
|
||||
cachedInnerDimension = getInnerDimensionSlow(stringBounder);
|
||||
}
|
||||
return cachedInnerDimension;
|
||||
|
||||
}
|
||||
|
||||
private FtileGeometry getInnerDimensionSlow(StringBounder stringBounder) {
|
||||
final FtileGeometry orig = inner.calculateDimension(stringBounder);
|
||||
final MinMax minMax = getMinMax(inner, stringBounder);
|
||||
final MinMax minMax = getInnerMinMax(stringBounder);
|
||||
final double missingWidth = minMax.getMaxX() - orig.getWidth();
|
||||
if (missingWidth > 0) {
|
||||
return orig.addDim(missingWidth + 5, 0);
|
||||
@ -159,7 +169,8 @@ public class FtileGroup extends AbstractFtile {
|
||||
return orig;
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry orig = getInnerDimension(stringBounder);
|
||||
final double suppWidth = suppWidth(stringBounder);
|
||||
final double width = orig.getWidth() + suppWidth;
|
||||
|
@ -271,7 +271,8 @@ class FtileIfAndStop extends AbstractFtile {
|
||||
ug.apply(getTranslateStop(stringBounder)).draw(stop2);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimStop2 = stop2.calculateDimension(stringBounder);
|
||||
final FtileGeometry dim1 = tile1.calculateDimension(stringBounder).addDim(0,
|
||||
getDiamondStopDistance() + dimStop2.getWidth());
|
||||
|
@ -341,7 +341,8 @@ public class FtileIfDown extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder);
|
||||
final FtileGeometry geoThen = thenBlock.calculateDimension(stringBounder);
|
||||
final FtileGeometry geoDiamond2 = diamond2.calculateDimension(stringBounder);
|
||||
|
@ -38,7 +38,6 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -561,7 +560,8 @@ class FtileIfLongHorizontal extends AbstractFtile {
|
||||
return new FtileGeometry(result, result.getWidth() / 2, 0);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
|
||||
final List<Ftile> all = new ArrayList<Ftile>(tiles);
|
||||
|
@ -571,7 +571,8 @@ class FtileIfLongVertical extends AbstractFtile {
|
||||
return width;
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
|
||||
final List<Ftile> all = new ArrayList<Ftile>(tiles);
|
||||
|
@ -113,7 +113,8 @@ public class FtileNoteAlone extends AbstractFtile implements Stencil {
|
||||
opale.drawU(ug);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
if (withOutPoint) {
|
||||
return new FtileGeometry(dimTotal, dimTotal.getWidth() / 2, 0, dimTotal.getHeight());
|
||||
|
@ -490,7 +490,8 @@ class FtileRepeat extends AbstractFtile {
|
||||
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
return new FtileGeometry(dimTotal, getLeft(stringBounder), 0, dimTotal.getHeight());
|
||||
}
|
||||
|
@ -91,7 +91,8 @@ class FtileSplit1 extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
double height = 0;
|
||||
double width = 0;
|
||||
for (Ftile ftile : forks) {
|
||||
|
@ -454,7 +454,8 @@ class FtileWhile extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry geoDiamond1 = diamond1.calculateDimension(stringBounder);
|
||||
FtileGeometry geoWhile = whileBlock.calculateDimension(stringBounder);
|
||||
final double diff = -geoWhile.getWidth();
|
||||
|
@ -199,7 +199,8 @@ public class FtileWithNoteOpale extends AbstractFtile implements Stencil {
|
||||
ug.apply(getTranslate(stringBounder)).draw(tile);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
final FtileGeometry orig = tile.calculateDimension(stringBounder);
|
||||
final UTranslate translate = getTranslate(stringBounder);
|
||||
|
@ -173,7 +173,8 @@ public class FtileWithNotes extends AbstractFtile {
|
||||
ug.apply(getTranslate(stringBounder)).draw(tile);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dimTotal = calculateDimensionInternal(stringBounder);
|
||||
final FtileGeometry orig = tile.calculateDimension(stringBounder);
|
||||
final UTranslate translate = getTranslate(stringBounder);
|
||||
|
@ -128,7 +128,8 @@ public class FtileIfNude extends FtileDimensionMemoize {
|
||||
ug.apply(getTranslate2(stringBounder)).draw(tile2);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry dimTotal = calculateDimensionInternal(stringBounder);
|
||||
if (tile1.calculateDimension(stringBounder).hasPointOut()
|
||||
|| tile2.calculateDimension(stringBounder).hasPointOut()) {
|
||||
|
@ -81,7 +81,8 @@ public class FtileBlackBlock extends AbstractFtile {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
double supp = label.calculateDimension(stringBounder).getWidth();
|
||||
if (supp > 0) {
|
||||
supp += labelMargin;
|
||||
|
@ -151,7 +151,8 @@ public class FtileBox extends AbstractFtile {
|
||||
tb.drawU(ug.apply(new UTranslate(MARGIN, MARGIN)));
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dim = tb.calculateDimension(stringBounder);
|
||||
return new FtileGeometry(Dimension2DDouble.delta(dim, 2 * MARGIN, 2 * MARGIN), dim.getWidth() / 2 + MARGIN, 0,
|
||||
dim.getHeight() + 2 * MARGIN);
|
||||
|
@ -111,7 +111,8 @@ public class FtileCircleEnd extends AbstractFtile {
|
||||
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0);
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,8 @@ public class FtileCircleStart extends AbstractFtile {
|
||||
ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(backColor)).draw(circle);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0, SIZE);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,8 @@ public class FtileCircleStop extends AbstractFtile {
|
||||
.draw(circleSmall);
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return new FtileGeometry(SIZE, SIZE, SIZE / 2, 0);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,8 @@ public class FtileDiamond extends AbstractFtile {
|
||||
+ Diamond.diamondHalfSize)));
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final double suppY1 = north.calculateDimension(stringBounder).getHeight();
|
||||
final Dimension2D dim = new Dimension2DDouble(Diamond.diamondHalfSize * 2, Diamond.diamondHalfSize * 2 + suppY1);
|
||||
return new FtileGeometry(dim, dim.getWidth() / 2, suppY1, dim.getHeight());
|
||||
|
@ -130,7 +130,8 @@ public class FtileDiamondFoo1 extends AbstractFtile {
|
||||
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D dim = calculateDimensionInternal(stringBounder);
|
||||
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
|
||||
}
|
||||
|
@ -161,7 +161,8 @@ public class FtileDiamondInside extends AbstractFtile {
|
||||
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final FtileGeometry dimDiamonAlone = calculateDimensionAlone(stringBounder);
|
||||
final Dimension2D dimWest = west.calculateDimension(stringBounder);
|
||||
final Dimension2D dimEast = east.calculateDimension(stringBounder);
|
||||
|
@ -150,7 +150,8 @@ public class FtileDiamondInside2 extends AbstractFtile {
|
||||
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D diamond = calculateDimensionAlone(stringBounder);
|
||||
final Dimension2D north = this.north.calculateDimension(stringBounder);
|
||||
final double height = diamond.getHeight() + north.getHeight();
|
||||
|
@ -152,7 +152,8 @@ public class FtileDiamondInside3 extends AbstractFtile implements FtileOverpassi
|
||||
return new FtileGeometry(dim, dim.getWidth() / 2, 0, dim.getHeight());
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
final Dimension2D diamond = calculateDimensionAlone(stringBounder);
|
||||
final Dimension2D north = this.north.calculateDimension(stringBounder);
|
||||
final double height = diamond.getHeight() + north.getHeight();
|
||||
|
@ -44,7 +44,6 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
@ -73,7 +72,8 @@ public class FtileThinSplit extends AbstractFtile {
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
public FtileGeometry calculateDimension(StringBounder stringBounder) {
|
||||
@Override
|
||||
protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) {
|
||||
return new FtileGeometry(width, height, width / 2, 0, height);
|
||||
}
|
||||
|
||||
|
@ -362,10 +362,10 @@ public class PlantUmlTask extends Task {
|
||||
setNbThread(s);
|
||||
}
|
||||
|
||||
public void setSuggestEngine(String s) {
|
||||
OptionFlags.getInstance().setUseSuggestEngine(
|
||||
"true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s));
|
||||
}
|
||||
// public void setSuggestEngine(String s) {
|
||||
// OptionFlags.getInstance().setUseSuggestEngine(
|
||||
// "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s));
|
||||
// }
|
||||
|
||||
public void setFailFast(String s) {
|
||||
final boolean flag = "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s) || "on".equalsIgnoreCase(s);
|
||||
|
@ -52,6 +52,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.InnerStrategy;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
@ -111,6 +112,10 @@ public class BpmElement extends AbstractConnectorPuzzle implements ConnectorPuzz
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return raw.calculateDimension(stringBounder);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return raw.getMinMax(stringBounder);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.InnerStrategy;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
@ -116,6 +117,11 @@ public class ConnectorPuzzleEmpty extends AbstractConnectorPuzzle implements Pla
|
||||
return new Dimension2DDouble(20, 20);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
return null;
|
||||
}
|
||||
|
@ -58,16 +58,14 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
|
||||
|
||||
public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
|
||||
private String namespaceSeparator = ".";
|
||||
|
||||
@Override
|
||||
public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) {
|
||||
if (namespaceSeparator != null) {
|
||||
code = code.withSeparator(namespaceSeparator);
|
||||
if (getNamespaceSeparator() != null) {
|
||||
code = code.withSeparator(getNamespaceSeparator());
|
||||
}
|
||||
if (type == null) {
|
||||
code = code.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
|
||||
if (namespaceSeparator == null) {
|
||||
if (getNamespaceSeparator() == null) {
|
||||
return getOrCreateLeafDefault(code, LeafType.CLASS, symbol);
|
||||
}
|
||||
code = code.getFullyQualifiedCode(getCurrentGroup());
|
||||
@ -77,7 +75,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())),
|
||||
LeafType.CLASS, symbol);
|
||||
}
|
||||
if (namespaceSeparator == null) {
|
||||
if (getNamespaceSeparator() == null) {
|
||||
return getOrCreateLeafDefault(code, LeafType.CLASS, symbol);
|
||||
}
|
||||
code = code.getFullyQualifiedCode(getCurrentGroup());
|
||||
@ -87,42 +85,18 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
return createEntityWithNamespace(code, Display.getWithNewlines(code.getShortName(getLeafs())), type, symbol);
|
||||
}
|
||||
|
||||
public IGroup getOrCreateNamespace(Code namespace, Display display, GroupType type, IGroup parent) {
|
||||
if (namespaceSeparator != null) {
|
||||
namespace = namespace.withSeparator(namespaceSeparator).getFullyQualifiedCode(getCurrentGroup());
|
||||
}
|
||||
final IGroup g = getOrCreateNamespaceInternal(namespace, display, type, parent);
|
||||
currentGroup = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
private IGroup getOrCreateNamespaceInternal(Code namespace, Display display, GroupType type, IGroup parent) {
|
||||
IGroup result = entityFactory.getGroups().get(namespace);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
if (entityFactory.getLeafs().containsKey(namespace)) {
|
||||
result = entityFactory.muteToGroup(namespace, namespace, type, parent);
|
||||
result.setDisplay(display);
|
||||
} else {
|
||||
result = entityFactory.createGroup(namespace, display, namespace, type, parent, getHides(),
|
||||
getNamespaceSeparator());
|
||||
}
|
||||
entityFactory.addGroup(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILeaf createLeaf(Code code, Display display, LeafType type, USymbol symbol) {
|
||||
if (namespaceSeparator != null) {
|
||||
code = code.withSeparator(namespaceSeparator);
|
||||
if (getNamespaceSeparator() != null) {
|
||||
code = code.withSeparator(getNamespaceSeparator());
|
||||
}
|
||||
if (type != LeafType.ABSTRACT_CLASS && type != LeafType.ANNOTATION && type != LeafType.CLASS
|
||||
&& type != LeafType.INTERFACE && type != LeafType.ENUM && type != LeafType.LOLLIPOP
|
||||
&& type != LeafType.NOTE) {
|
||||
return super.createLeaf(code, display, type, symbol);
|
||||
}
|
||||
if (namespaceSeparator == null) {
|
||||
if (getNamespaceSeparator() == null) {
|
||||
return super.createLeaf(code, display, type, symbol);
|
||||
}
|
||||
code = code.getFullyQualifiedCode(getCurrentGroup());
|
||||
@ -150,21 +124,21 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
private final String getNamespace(Code fullyCode) {
|
||||
String name = fullyCode.getFullName();
|
||||
do {
|
||||
final int x = name.lastIndexOf(namespaceSeparator);
|
||||
final int x = name.lastIndexOf(getNamespaceSeparator());
|
||||
if (x == -1) {
|
||||
return null;
|
||||
}
|
||||
name = name.substring(0, x);
|
||||
} while (getLeafs().containsKey(Code.of(name, namespaceSeparator)));
|
||||
} while (getLeafs().containsKey(Code.of(name, getNamespaceSeparator())));
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean leafExist(Code code) {
|
||||
if (namespaceSeparator == null) {
|
||||
if (getNamespaceSeparator() == null) {
|
||||
return super.leafExist(code);
|
||||
}
|
||||
code = code.withSeparator(namespaceSeparator);
|
||||
code = code.withSeparator(getNamespaceSeparator());
|
||||
return super.leafExist(code.getFullyQualifiedCode(getCurrentGroup()));
|
||||
}
|
||||
|
||||
@ -173,14 +147,6 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
return UmlDiagramType.CLASS;
|
||||
}
|
||||
|
||||
public void setNamespaceSeparator(String namespaceSeparator) {
|
||||
this.namespaceSeparator = namespaceSeparator;
|
||||
}
|
||||
|
||||
public String getNamespaceSeparator() {
|
||||
return namespaceSeparator;
|
||||
}
|
||||
|
||||
private boolean allowMixing;
|
||||
|
||||
public void setAllowMixing(boolean allowMixing) {
|
||||
|
@ -118,7 +118,7 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory {
|
||||
if (commandControl == CommandControl.NOT_OK) {
|
||||
final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", /* it.currentNum(), */it.peek()
|
||||
.getLocation());
|
||||
if (OptionFlags.getInstance().isUseSuggestEngine()) {
|
||||
if (OptionFlags.getInstance().isUseSuggestEngine2()) {
|
||||
final SuggestEngine engine = new SuggestEngine(source, this);
|
||||
final SuggestEngineResult result = engine.tryToSuggest(sys);
|
||||
if (result.getStatus() == SuggestEngineStatus.ONE_SUGGESTION) {
|
||||
|
@ -38,7 +38,7 @@ package net.sourceforge.plantuml.core;
|
||||
import net.sourceforge.plantuml.utils.StartUtils;
|
||||
|
||||
public enum DiagramType {
|
||||
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, UNKNOWN;
|
||||
UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, JUNGLE, CUTE, MATH, LATEX, DEFINITION, GANTT, UNKNOWN;
|
||||
|
||||
static public DiagramType getTypeFromArobaseStart(String s) {
|
||||
s = s.toLowerCase();
|
||||
@ -87,6 +87,9 @@ public enum DiagramType {
|
||||
if (StartUtils.startsWithSymbolAnd("startdef", s)) {
|
||||
return DEFINITION;
|
||||
}
|
||||
if (StartUtils.startsWithSymbolAnd("startgantt", s)) {
|
||||
return GANTT;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -80,10 +80,20 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
|
||||
|
||||
public abstract IEntity getOrCreateLeaf(Code code, LeafType type, USymbol symbol);
|
||||
|
||||
public String getNamespaceSeparator() {
|
||||
return null;
|
||||
private String namespaceSeparator = ".";
|
||||
|
||||
final public void setNamespaceSeparator(String namespaceSeparator) {
|
||||
this.namespaceSeparator = namespaceSeparator;
|
||||
}
|
||||
|
||||
final public String getNamespaceSeparator() {
|
||||
return namespaceSeparator;
|
||||
}
|
||||
|
||||
// public String getNamespaceSeparator() {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean hasUrl() {
|
||||
for (IEntity entity : getGroups(true)) {
|
||||
@ -158,12 +168,40 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
|
||||
return Collections.unmodifiableCollection(result);
|
||||
}
|
||||
|
||||
final public IGroup getOrCreateNamespace(Code namespace, Display display, GroupType type, IGroup parent) {
|
||||
if (getNamespaceSeparator() != null) {
|
||||
namespace = namespace.withSeparator(getNamespaceSeparator()).getFullyQualifiedCode(getCurrentGroup());
|
||||
}
|
||||
final IGroup g = getOrCreateNamespaceInternal(namespace, display, type, parent);
|
||||
currentGroup = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
final public IGroup getOrCreateGroup(Code code, Display display, GroupType type, IGroup parent) {
|
||||
final IGroup g = getOrCreateGroupInternal(code, display, null, type, parent);
|
||||
currentGroup = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
|
||||
final protected IGroup getOrCreateNamespaceInternal(Code namespace, Display display, GroupType type, IGroup parent) {
|
||||
IGroup result = entityFactory.getGroups().get(namespace);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
if (entityFactory.getLeafs().containsKey(namespace)) {
|
||||
result = entityFactory.muteToGroup(namespace, namespace, type, parent);
|
||||
result.setDisplay(display);
|
||||
} else {
|
||||
result = entityFactory.createGroup(namespace, display, namespace, type, parent, getHides(),
|
||||
getNamespaceSeparator());
|
||||
}
|
||||
entityFactory.addGroup(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private IGroup getOrCreateGroupInternal(Code code, Display display, Code namespace2, GroupType type, IGroup parent) {
|
||||
IGroup result = entityFactory.getGroups().get(code);
|
||||
if (result != null) {
|
||||
|
@ -206,6 +206,19 @@ public class Display implements Iterable<CharSequence> {
|
||||
return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode);
|
||||
}
|
||||
|
||||
public Display withPage(int page, int lastpage) {
|
||||
if (display == null) {
|
||||
return this;
|
||||
}
|
||||
final List<CharSequence> result = new ArrayList<CharSequence>();
|
||||
for (CharSequence line : display) {
|
||||
line = line.toString().replace("%page%", "" + page);
|
||||
line = line.toString().replace("%lastpage%", "" + lastpage);
|
||||
result.add(line);
|
||||
}
|
||||
return new Display(result, this.naturalHorizontalAlignment, this.isNull, this.defaultCreoleMode);
|
||||
}
|
||||
|
||||
public Display underlined() {
|
||||
final List<CharSequence> result = new ArrayList<CharSequence>();
|
||||
for (CharSequence line : display) {
|
||||
|
@ -121,7 +121,15 @@ public class LinkStyle {
|
||||
return thickness;
|
||||
}
|
||||
|
||||
public static LinkStyle fromString(String s) {
|
||||
public static LinkStyle fromString1(String s) {
|
||||
final LinkStyle result = fromString2(s);
|
||||
if (result == null) {
|
||||
return LinkStyle.NORMAL();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static LinkStyle fromString2(String s) {
|
||||
if ("dashed".equalsIgnoreCase(s)) {
|
||||
return DASHED();
|
||||
}
|
||||
@ -134,12 +142,7 @@ public class LinkStyle {
|
||||
if ("hidden".equalsIgnoreCase(s)) {
|
||||
return INVISIBLE();
|
||||
}
|
||||
return LinkStyle.NORMAL();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static LinkStyle valueOf(String s) {
|
||||
return fromString(s);
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isThicknessOverrided() {
|
||||
|
@ -45,14 +45,12 @@ import net.sourceforge.plantuml.graphic.USymbol;
|
||||
|
||||
public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
|
||||
private String namespaceSeparator = null;
|
||||
|
||||
@Override
|
||||
public ILeaf getOrCreateLeaf(Code code, LeafType type, USymbol symbol) {
|
||||
if (namespaceSeparator != null) {
|
||||
code = code.withSeparator(namespaceSeparator);
|
||||
if (getNamespaceSeparator() != null) {
|
||||
code = code.withSeparator(getNamespaceSeparator());
|
||||
}
|
||||
if (namespaceSeparator != null && code.getFullName().contains(namespaceSeparator)) {
|
||||
if (getNamespaceSeparator() != null && code.getFullName().contains(getNamespaceSeparator())) {
|
||||
// System.err.println("code=" + code);
|
||||
final Code fullyCode = code;
|
||||
// final String namespace = fullyCode.getNamespace(getLeafs());
|
||||
@ -138,12 +136,4 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
return UmlDiagramType.DESCRIPTION;
|
||||
}
|
||||
|
||||
public void setNamespaceSeparator(String namespaceSeparator) {
|
||||
this.namespaceSeparator = namespaceSeparator;
|
||||
}
|
||||
|
||||
public String getNamespaceSeparator() {
|
||||
return namespaceSeparator;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ import net.sourceforge.plantuml.graphic.color.Colors;
|
||||
|
||||
public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiagram> {
|
||||
|
||||
public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle";
|
||||
public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle|collections";
|
||||
|
||||
public CommandCreateElementFull() {
|
||||
super(getRegexConcat());
|
||||
@ -205,7 +205,8 @@ public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiag
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
public static boolean existsWithBadType(AbstractEntityDiagram diagram, final Code code, LeafType type, USymbol usymbol) {
|
||||
public static boolean existsWithBadType(AbstractEntityDiagram diagram, final Code code, LeafType type,
|
||||
USymbol usymbol) {
|
||||
if (diagram.leafExist(code) == false) {
|
||||
return false;
|
||||
}
|
||||
@ -213,7 +214,7 @@ public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiag
|
||||
if (other.getLeafType() != type) {
|
||||
return true;
|
||||
}
|
||||
if (other.getUSymbol() != usymbol) {
|
||||
if (usymbol != null && other.getUSymbol() != usymbol) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -77,7 +77,7 @@ public class PSystemDonors extends AbstractPSystem {
|
||||
+ "VHC7Wx0p1ovU3ReAoyPmPtB36bh8p5kG0R6JrqsbaLqTW8wKWlfJ_H2ahn_g7z1BEzOksNZ5yZ08h6Ol"
|
||||
+ "d9iEd26PzTfIAMOouyQDyD-fCiSrAZ4jdMAFr5_gXwVx-dlpbAW_ru_rp_hnwGF_xldJDpYpL8angeoT"
|
||||
+ "THxskf4hiLvFIJM7EcWRloA3gHX5F2IxB5XWr_HoA4M5uhdHKibXSKZeSgW_rb-F9M5Wx3cVvyei9SFe"
|
||||
+ "eyr2dx88J6VmAHwXNeLhxcfOkAtF-PyPyzpDFxMzjnO0";
|
||||
+ "eyr2dx88J6VmAHwXNeLhxcfOkAtF-PyPyzpDgyhFkpzUfhdf";
|
||||
|
||||
@Override
|
||||
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)
|
||||
|
@ -0,0 +1,111 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.donors;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.AbstractPSystem;
|
||||
import net.sourceforge.plantuml.FileFormatOption;
|
||||
import net.sourceforge.plantuml.SkinParam;
|
||||
import net.sourceforge.plantuml.core.DiagramDescription;
|
||||
import net.sourceforge.plantuml.core.ImageData;
|
||||
import net.sourceforge.plantuml.graphic.GraphicStrings;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
|
||||
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class PSystemSkinparameterList extends AbstractPSystem {
|
||||
|
||||
@Override
|
||||
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)
|
||||
throws IOException {
|
||||
final UDrawable result = getGraphicStrings();
|
||||
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
|
||||
getMetadata(), null, 0, 0, null, false);
|
||||
imageBuilder.setUDrawable(result);
|
||||
return imageBuilder.writeImageTOBEMOVED(fileFormat, seed, os);
|
||||
}
|
||||
|
||||
private UDrawable getGraphicStrings() throws IOException {
|
||||
final List<TextBlock> cols = getCols(getDonors(), 5);
|
||||
return new UDrawable() {
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
for (TextBlock tb : cols) {
|
||||
final Dimension2D dim = tb.calculateDimension(stringBounder);
|
||||
tb.drawU(ug.apply(new UTranslate(x, 0)));
|
||||
x += dim.getWidth() + 10;
|
||||
y = Math.max(y, dim.getHeight());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static List<TextBlock> getCols(List<String> lines, final int nbCol) throws IOException {
|
||||
final List<TextBlock> result = new ArrayList<TextBlock>();
|
||||
final int maxLine = (lines.size() + (nbCol - 1)) / nbCol;
|
||||
for (int i = 0; i < lines.size(); i += maxLine) {
|
||||
final List<String> current = lines.subList(i, Math.min(lines.size(), i + maxLine));
|
||||
result.add(GraphicStrings.createBlackOnWhite(current));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> getDonors() throws IOException {
|
||||
final List<String> lines = new ArrayList<String>(SkinParam.getPossibleValues());
|
||||
return lines;
|
||||
}
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescription("(Parameters)");
|
||||
}
|
||||
|
||||
public static PSystemSkinparameterList create() {
|
||||
return new PSystemSkinparameterList();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.donors;
|
||||
|
||||
import net.sourceforge.plantuml.AbstractPSystem;
|
||||
import net.sourceforge.plantuml.command.PSystemSingleLineFactory;
|
||||
|
||||
public class PSystemSkinparameterListFactory extends PSystemSingleLineFactory {
|
||||
|
||||
@Override
|
||||
protected AbstractPSystem executeLine(String line) {
|
||||
if (line.matches("(?i)^(skinparameters)\\s*$")) {
|
||||
return PSystemSkinparameterList.create();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -62,6 +62,7 @@ import net.sourceforge.plantuml.graphic.InnerStrategy;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UEllipse;
|
||||
@ -209,4 +210,9 @@ public class FlowDiagram extends UmlDiagram implements TextBlock {
|
||||
final MinMaxGolem minMax = getMinMax();
|
||||
return new Dimension2DDouble(minMax.getWidth() * SINGLE_SIZE_X, minMax.getHeight() * SINGLE_SIZE_Y);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,9 +37,15 @@ package net.sourceforge.plantuml.graphic;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
|
||||
public abstract class AbstractTextBlock implements TextBlock {
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
throw new UnsupportedOperationException("member=" + member + " " + getClass().toString());
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException(getClass().toString());
|
||||
}
|
||||
}
|
@ -88,7 +88,7 @@ public class HtmlColorAndStyle {
|
||||
LinkStyle style = LinkStyle.NORMAL();
|
||||
final IHtmlColorSet set = skinParam.getIHtmlColorSet();
|
||||
for (String s : definition.split(",")) {
|
||||
final LinkStyle tmpStyle = LinkStyle.fromString(s);
|
||||
final LinkStyle tmpStyle = LinkStyle.fromString1(s);
|
||||
if (tmpStyle.isNormal() == false) {
|
||||
style = tmpStyle;
|
||||
continue;
|
||||
|
@ -243,7 +243,10 @@ public class QuoteUtils {
|
||||
"P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.",
|
||||
"Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.",
|
||||
"Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag",
|
||||
"Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf");
|
||||
"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.");
|
||||
|
||||
private QuoteUtils() {
|
||||
}
|
||||
|
@ -92,6 +92,9 @@ public class SkinParameter {
|
||||
public static final SkinParameter RECTANGLE = new SkinParameter("RECTANGLE", ColorParam.rectangleBackground,
|
||||
ColorParam.rectangleBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
|
||||
|
||||
public static final SkinParameter COLLECTIONS = new SkinParameter("COLLECTIONS", ColorParam.collectionsBackground,
|
||||
ColorParam.collectionsBorder, FontParam.RECTANGLE, FontParam.RECTANGLE_STEREOTYPE);
|
||||
|
||||
public static final SkinParameter ACTOR = new SkinParameter("ACTOR", ColorParam.actorBackground,
|
||||
ColorParam.actorBorder, FontParam.ACTOR, FontParam.ACTOR_STEREOTYPE);
|
||||
|
||||
|
@ -68,17 +68,28 @@ public class SymbolContext {
|
||||
}
|
||||
|
||||
final public UGraphic apply(UGraphic ug) {
|
||||
return applyStroke(applyColors(ug));
|
||||
ug = applyColors(ug);
|
||||
ug = applyStroke(ug);
|
||||
return ug;
|
||||
}
|
||||
|
||||
public UGraphic applyColors(UGraphic ug) {
|
||||
return ug.apply(new UChangeColor(foreColor)).apply(new UChangeBackColor(backColor));
|
||||
ug = ug.apply(new UChangeColor(foreColor));
|
||||
ug = ug.apply(new UChangeBackColor(backColor));
|
||||
return ug;
|
||||
}
|
||||
|
||||
public UGraphic applyStroke(UGraphic ug) {
|
||||
return ug.apply(stroke);
|
||||
}
|
||||
|
||||
public SymbolContext transparentBackColorToNull() {
|
||||
if (backColor instanceof HtmlColorTransparent) {
|
||||
return new SymbolContext(null, foreColor, stroke, shadowing, deltaShadow, roundCorner);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SymbolContext(HtmlColor backColor, HtmlColor foreColor) {
|
||||
this(backColor, foreColor, new UStroke(), false, 0, 0);
|
||||
}
|
||||
|
@ -38,13 +38,15 @@ package net.sourceforge.plantuml.graphic;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UShape;
|
||||
|
||||
public interface TextBlock extends UDrawable, UShape {
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder);
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder);
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy);
|
||||
|
||||
|
||||
}
|
@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.ugraphic.CompressionTransform;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.SlotFinder;
|
||||
import net.sourceforge.plantuml.ugraphic.SlotSet;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
@ -58,7 +59,26 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
|
||||
textBlock.drawU(new UGraphicCompress(ug, compressionTransform));
|
||||
}
|
||||
|
||||
private MinMax cachedMinMax;
|
||||
|
||||
@Override
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
if (cachedMinMax == null) {
|
||||
cachedMinMax = TextBlockUtils.getMinMax(this, stringBounder);
|
||||
}
|
||||
return cachedMinMax;
|
||||
}
|
||||
|
||||
private CompressionTransform cachedCompressionTransform;
|
||||
|
||||
private CompressionTransform getCompressionTransform(final StringBounder stringBounder) {
|
||||
if (cachedCompressionTransform == null) {
|
||||
cachedCompressionTransform = getCompressionTransformSlow(stringBounder);
|
||||
}
|
||||
return cachedCompressionTransform;
|
||||
}
|
||||
|
||||
private CompressionTransform getCompressionTransformSlow(final StringBounder stringBounder) {
|
||||
final SlotFinder slotFinder = new SlotFinder(stringBounder);
|
||||
textBlock.drawU(slotFinder);
|
||||
final SlotSet ysSlotSet = slotFinder.getYSlotSet().reverse().smaller(5.0);
|
||||
|
@ -37,6 +37,7 @@ package net.sourceforge.plantuml.graphic;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
@ -51,12 +52,29 @@ public class TextBlockRecentred extends AbstractTextBlock implements TextBlockBa
|
||||
}
|
||||
|
||||
public void drawU(final UGraphic ug) {
|
||||
final MinMax minMax = TextBlockUtils.getMinMax(textBlock, ug.getStringBounder());
|
||||
StringBounder stringBounder = ug.getStringBounder();
|
||||
final MinMax minMax = getMinMax(stringBounder);
|
||||
textBlock.drawU(ug.apply(new UTranslate(-minMax.getMinX(), -minMax.getMinY())));
|
||||
}
|
||||
|
||||
// private MinMax cachedMinMax;
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return textBlock.getMinMax(stringBounder);
|
||||
// if (cachedMinMax == null) {
|
||||
// cachedMinMax = getMinMaxSlow(stringBounder);
|
||||
// }
|
||||
// // assert cachedMinMax.toString().equals(getMinMaxSlow(stringBounder).toString());
|
||||
// return cachedMinMax;
|
||||
}
|
||||
|
||||
// private MinMax getMinMaxSlow(StringBounder stringBounder) {
|
||||
// final MinMax result = TextBlockUtils.getMinMax(textBlock, stringBounder);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
final MinMax minMax = TextBlockUtils.getMinMax(textBlock, stringBounder);
|
||||
final MinMax minMax = getMinMax(stringBounder);
|
||||
return minMax.getDimension();
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ import net.sourceforge.plantuml.ISkinSimple;
|
||||
import net.sourceforge.plantuml.LineBreakStrategy;
|
||||
import net.sourceforge.plantuml.creole.CreoleMode;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
@ -71,6 +72,10 @@ public class TextBlockTitle implements TextBlock {
|
||||
return new Dimension2DDouble(width, height);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
return null;
|
||||
}
|
||||
|
@ -165,6 +165,10 @@ public class TextBlockUtils {
|
||||
return bloc.calculateDimension(stringBounder);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return bloc.getMinMax(stringBounder);
|
||||
}
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
if (strategy.check(display, member)) {
|
||||
final Dimension2D dim = calculateDimension(stringBounder);
|
||||
|
@ -39,6 +39,7 @@ import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
|
||||
public class TextBlockWithUrl implements TextBlock {
|
||||
@ -69,6 +70,10 @@ public class TextBlockWithUrl implements TextBlock {
|
||||
return block.calculateDimension(stringBounder);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return block.getMinMax(stringBounder);
|
||||
}
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
return block.getInnerPosition(member, stringBounder, strategy);
|
||||
}
|
||||
|
@ -62,6 +62,8 @@ public abstract class USymbol {
|
||||
public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile());
|
||||
public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect(
|
||||
SkinParameter.RECTANGLE, HorizontalAlignment.CENTER));
|
||||
public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS, new USymbolCollections(
|
||||
SkinParameter.RECTANGLE, HorizontalAlignment.CENTER));
|
||||
public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT,
|
||||
HorizontalAlignment.CENTER));
|
||||
public final static USymbol ACTOR = record("ACTOR", SkinParameter.ACTOR, new USymbolActor());
|
||||
@ -197,6 +199,8 @@ public abstract class USymbol {
|
||||
usymbol = USymbol.PACKAGE;
|
||||
} else if (symbol.equalsIgnoreCase("rectangle")) {
|
||||
usymbol = USymbol.RECTANGLE;
|
||||
} else if (symbol.equalsIgnoreCase("collections")) {
|
||||
usymbol = USymbol.COLLECTIONS;
|
||||
} else if (symbol.equalsIgnoreCase("node")) {
|
||||
usymbol = USymbol.NODE;
|
||||
} else if (symbol.equalsIgnoreCase("frame")) {
|
||||
|
145
src/net/sourceforge/plantuml/graphic/USymbolCollections.java
Normal file
145
src/net/sourceforge/plantuml/graphic/USymbolCollections.java
Normal file
@ -0,0 +1,145 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.graphic;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
class USymbolCollections extends USymbol {
|
||||
|
||||
private final SkinParameter skinParameter;
|
||||
private final HorizontalAlignment stereotypeAlignement;
|
||||
|
||||
public USymbolCollections(SkinParameter skinParameter, HorizontalAlignment stereotypeAlignement) {
|
||||
this.skinParameter = skinParameter;
|
||||
this.stereotypeAlignement = stereotypeAlignement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public USymbol withStereoAlignment(HorizontalAlignment alignment) {
|
||||
return new USymbolCollections(skinParameter, alignment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkinParameter getSkinParameter() {
|
||||
return skinParameter;
|
||||
}
|
||||
|
||||
private void drawCollections(UGraphic ug, double width, double height, boolean shadowing, double roundCorner) {
|
||||
final URectangle small = new URectangle(width - getDeltaCollection(), height - getDeltaCollection(),
|
||||
roundCorner, roundCorner);
|
||||
if (shadowing) {
|
||||
small.setDeltaShadow(3.0);
|
||||
}
|
||||
ug.apply(new UTranslate(getDeltaCollection(), getDeltaCollection())).draw(small);
|
||||
small.setDeltaShadow(0);
|
||||
ug.apply(new UTranslate(0, 0)).draw(small);
|
||||
}
|
||||
|
||||
private Margin getMargin() {
|
||||
return new Margin(10, 10, 10, 10);
|
||||
}
|
||||
|
||||
private double getDeltaCollection() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
|
||||
final SymbolContext symbolContext) {
|
||||
return new AbstractTextBlock() {
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final Dimension2D dim = calculateDimension(ug.getStringBounder());
|
||||
ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke());
|
||||
ug = symbolContext.apply(ug);
|
||||
drawCollections(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(),
|
||||
symbolContext.getRoundCorner());
|
||||
final Margin margin = getMargin();
|
||||
final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereotypeAlignement);
|
||||
tb.drawU(ug.apply(new UTranslate(margin.getX1() - getDeltaCollection() / 2, margin.getY1()
|
||||
- getDeltaCollection() / 2)));
|
||||
}
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
final Dimension2D dimLabel = label.calculateDimension(stringBounder);
|
||||
final Dimension2D dimStereo = stereotype.calculateDimension(stringBounder);
|
||||
return getMargin().addDimension(Dimension2DDouble.mergeTB(dimStereo, dimLabel));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public TextBlock asBig(final TextBlock title, final TextBlock stereotype, final double width, final double height,
|
||||
final SymbolContext symbolContext) {
|
||||
return new AbstractTextBlock() {
|
||||
public void drawU(UGraphic ug) {
|
||||
final Dimension2D dim = calculateDimension(ug.getStringBounder());
|
||||
ug = symbolContext.apply(ug);
|
||||
drawCollections(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(),
|
||||
symbolContext.getRoundCorner());
|
||||
final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder());
|
||||
final double posStereoX;
|
||||
final double posStereoY;
|
||||
if (stereotypeAlignement == HorizontalAlignment.RIGHT) {
|
||||
posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2;
|
||||
posStereoY = getMargin().getY1() / 2;
|
||||
} else {
|
||||
posStereoX = (width - dimStereo.getWidth()) / 2;
|
||||
posStereoY = 2;
|
||||
}
|
||||
stereotype.drawU(ug.apply(new UTranslate(posStereoX, posStereoY)));
|
||||
final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder());
|
||||
final double posTitle = (width - dimTitle.getWidth()) / 2;
|
||||
title.drawU(ug.apply(new UTranslate(posTitle, 2 + dimStereo.getHeight())));
|
||||
}
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
return new Dimension2DDouble(width, height);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean manageHorizontalLine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -170,7 +170,7 @@ public class Colors {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final Colors result = copy();
|
||||
result.lineStyle = LinkStyle.valueOf(StringUtils.goUpperCase(s));
|
||||
result.lineStyle = LinkStyle.fromString1(StringUtils.goUpperCase(s));
|
||||
return result;
|
||||
|
||||
}
|
||||
|
@ -66,16 +66,35 @@ public class Preprocessor implements ReadLine {
|
||||
private final Defines defines;
|
||||
private final PreprocessorInclude rawSource;
|
||||
private final ReadLineInsertable source;
|
||||
private final SubPreprocessor subPreprocessor;
|
||||
|
||||
public Preprocessor(ReadLine reader, String charset, Defines defines, File newCurrentDir,
|
||||
public Sub getSub(String blocname) {
|
||||
return subPreprocessor.getSub(blocname);
|
||||
}
|
||||
|
||||
public Preprocessor(List<String> config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
|
||||
DefinitionsContainer definitionsContainer) {
|
||||
this.defines = defines;
|
||||
this.defines.saveState();
|
||||
this.rawSource = new PreprocessorInclude(reader, defines, charset, newCurrentDir, definitionsContainer);
|
||||
this.rawSource = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
|
||||
this.source = new ReadLineInsertable(new IfManager(rawSource, defines));
|
||||
this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, new ReadLine() {
|
||||
|
||||
public void close() throws IOException {
|
||||
Preprocessor.this.close();
|
||||
}
|
||||
|
||||
public CharSequence2 readLine() throws IOException {
|
||||
return readLineInternal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CharSequence2 readLine() throws IOException {
|
||||
return subPreprocessor.readLine();
|
||||
}
|
||||
|
||||
private CharSequence2 readLineInternal() throws IOException {
|
||||
final CharSequence2 s = source.readLine();
|
||||
if (s == null) {
|
||||
return null;
|
||||
|
@ -44,6 +44,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -72,6 +73,7 @@ public class PreprocessorInclude implements ReadLine {
|
||||
private final ReadLine reader2;
|
||||
private final String charset;
|
||||
private final Defines defines;
|
||||
private final List<String> config;
|
||||
private final DefinitionsContainer definitionsContainer;
|
||||
|
||||
private int numLine = 0;
|
||||
@ -82,19 +84,20 @@ public class PreprocessorInclude implements ReadLine {
|
||||
private final Set<FileWithSuffix> filesUsedCurrent;
|
||||
private final Set<FileWithSuffix> filesUsedGlobal;
|
||||
|
||||
public PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir,
|
||||
DefinitionsContainer definitionsContainer) {
|
||||
this(reader, defines, charset, newCurrentDir, new HashSet<FileWithSuffix>(), new HashSet<FileWithSuffix>(),
|
||||
definitionsContainer);
|
||||
public PreprocessorInclude(List<String> config, ReadLine reader, Defines defines, String charset,
|
||||
File newCurrentDir, DefinitionsContainer definitionsContainer) {
|
||||
this(config, reader, defines, charset, newCurrentDir, new HashSet<FileWithSuffix>(),
|
||||
new HashSet<FileWithSuffix>(), definitionsContainer);
|
||||
}
|
||||
|
||||
public Set<FileWithSuffix> getFilesUsedGlobal() {
|
||||
return Collections.unmodifiableSet(filesUsedGlobal);
|
||||
}
|
||||
|
||||
private PreprocessorInclude(ReadLine reader, Defines defines, String charset, File newCurrentDir,
|
||||
Set<FileWithSuffix> filesUsedCurrent, Set<FileWithSuffix> filesUsedGlobal,
|
||||
private PreprocessorInclude(List<String> config, ReadLine reader, Defines defines, String charset,
|
||||
File newCurrentDir, Set<FileWithSuffix> filesUsedCurrent, Set<FileWithSuffix> filesUsedGlobal,
|
||||
DefinitionsContainer definitionsContainer) {
|
||||
this.config = config;
|
||||
this.defines = defines;
|
||||
this.charset = charset;
|
||||
this.reader2 = reader;
|
||||
@ -117,6 +120,11 @@ public class PreprocessorInclude implements ReadLine {
|
||||
|
||||
public CharSequence2 readLine() throws IOException {
|
||||
final CharSequence2 result = readLineInternal();
|
||||
if (result != null && StartUtils.isArobaseStartDiagram(result) && config.size() > 0) {
|
||||
final List<String> empty = new ArrayList<String>();
|
||||
included = new PreprocessorInclude(empty, new ReadLineList(config, result.getLocation()), defines, charset,
|
||||
null, filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
}
|
||||
if (result != null && (StartUtils.isArobaseEndDiagram(result) || StartUtils.isArobaseStartDiagram(result))) {
|
||||
// http://plantuml.sourceforge.net/qa/?qa=3389/error-generating-when-same-file-included-different-diagram
|
||||
filesUsedCurrent.clear();
|
||||
@ -173,8 +181,8 @@ public class PreprocessorInclude implements ReadLine {
|
||||
}
|
||||
try {
|
||||
final URL url = new URL(urlString);
|
||||
included = new PreprocessorInclude(getReaderInclude(s, url, suf), defines, charset, null, filesUsedCurrent,
|
||||
filesUsedGlobal, definitionsContainer);
|
||||
included = new PreprocessorInclude(config, getReaderInclude(s, url, suf), defines, charset, null,
|
||||
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
} catch (MalformedURLException e) {
|
||||
return s.withErrorPreprocessor("Cannot include url " + urlString);
|
||||
}
|
||||
@ -184,8 +192,8 @@ public class PreprocessorInclude implements ReadLine {
|
||||
private CharSequence2 manageDefinitionInclude(CharSequence2 s, Matcher2 matcher) throws IOException {
|
||||
final String definitionName = matcher.group(1);
|
||||
final List<? extends CharSequence> definition = definitionsContainer.getDefinition(definitionName);
|
||||
included = new PreprocessorInclude(new ReadLineList(definition, s.getLocation()), defines, charset, null,
|
||||
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
included = new PreprocessorInclude(config, new ReadLineList(definition, s.getLocation()), defines, charset,
|
||||
null, filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
return this.readLine();
|
||||
}
|
||||
|
||||
@ -197,8 +205,8 @@ public class PreprocessorInclude implements ReadLine {
|
||||
if (strlibReader == null) {
|
||||
return s.withErrorPreprocessor("Cannot include " + fileName);
|
||||
}
|
||||
included = new PreprocessorInclude(strlibReader, defines, charset, null, filesUsedCurrent, filesUsedGlobal,
|
||||
definitionsContainer);
|
||||
included = new PreprocessorInclude(config, strlibReader, defines, charset, null, filesUsedCurrent,
|
||||
filesUsedGlobal, definitionsContainer);
|
||||
return this.readLine();
|
||||
}
|
||||
final int idx = fileName.lastIndexOf('!');
|
||||
@ -214,12 +222,11 @@ public class PreprocessorInclude implements ReadLine {
|
||||
} else if (allowMany == false && filesUsedCurrent.contains(f2)) {
|
||||
// return CharSequence2Impl.errorPreprocessor("File already included " + f.getAbsolutePath(), lineLocation);
|
||||
return this.readLine();
|
||||
} else {
|
||||
filesUsedCurrent.add(f2);
|
||||
filesUsedGlobal.add(f2);
|
||||
included = new PreprocessorInclude(getReaderInclude(s, f, suf), defines, charset, f.getParentFile(),
|
||||
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
}
|
||||
filesUsedCurrent.add(f2);
|
||||
filesUsedGlobal.add(f2);
|
||||
included = new PreprocessorInclude(config, getReaderInclude(s, f, suf), defines, charset, f.getParentFile(),
|
||||
filesUsedCurrent, filesUsedGlobal, definitionsContainer);
|
||||
return this.readLine();
|
||||
}
|
||||
|
||||
|
72
src/net/sourceforge/plantuml/preproc/ReadLineConcat.java
Normal file
72
src/net/sourceforge/plantuml/preproc/ReadLineConcat.java
Normal file
@ -0,0 +1,72 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.preproc;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.sourceforge.plantuml.CharSequence2;
|
||||
|
||||
public class ReadLineConcat implements ReadLine {
|
||||
|
||||
private ReadLine file1;
|
||||
final private ReadLine file2;
|
||||
|
||||
public ReadLineConcat(ReadLine file1, ReadLine file2) {
|
||||
this.file1 = file1;
|
||||
this.file2 = file2;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (file1 != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
file2.close();
|
||||
}
|
||||
|
||||
public CharSequence2 readLine() throws IOException {
|
||||
CharSequence2 result = null;
|
||||
if (file1 != null) {
|
||||
result = file1.readLine();
|
||||
if (result == null) {
|
||||
file1.close();
|
||||
file1 = null;
|
||||
}
|
||||
return readLine();
|
||||
}
|
||||
return file2.readLine();
|
||||
}
|
||||
|
||||
}
|
61
src/net/sourceforge/plantuml/preproc/Sub.java
Normal file
61
src/net/sourceforge/plantuml/preproc/Sub.java
Normal file
@ -0,0 +1,61 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.preproc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.CharSequence2;
|
||||
import net.sourceforge.plantuml.LineLocation;
|
||||
|
||||
public class Sub {
|
||||
|
||||
private final String name;
|
||||
private final List<CharSequence2> lines = new ArrayList<CharSequence2>();
|
||||
|
||||
public Sub(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void add(CharSequence2 s) {
|
||||
this.lines.add(s);
|
||||
}
|
||||
|
||||
public ReadLine getReadLine(LineLocation lineLocation) {
|
||||
return new ReadLineList(lines, lineLocation);
|
||||
}
|
||||
|
||||
}
|
183
src/net/sourceforge/plantuml/preproc/SubPreprocessor.java
Normal file
183
src/net/sourceforge/plantuml/preproc/SubPreprocessor.java
Normal file
@ -0,0 +1,183 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, 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.preproc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.plantuml.CharSequence2;
|
||||
import net.sourceforge.plantuml.DefinitionsContainer;
|
||||
import net.sourceforge.plantuml.FileSystem;
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.command.regex.Matcher2;
|
||||
import net.sourceforge.plantuml.command.regex.MyPattern;
|
||||
import net.sourceforge.plantuml.command.regex.Pattern2;
|
||||
|
||||
public class SubPreprocessor implements ReadLine {
|
||||
|
||||
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
|
||||
|
||||
private static final Pattern2 includeSubPattern = MyPattern.cmpile("^[%s]*!includesub[%s]+[%g]?([^%g]+)[%g]?$");
|
||||
|
||||
private static final Pattern2 startsub = MyPattern.cmpile("^[%s]*!startsub[%s]+(" + ID + ")");
|
||||
private static final Pattern2 endsub = MyPattern.cmpile("^[%s]*!endsub[%s]*");
|
||||
|
||||
private final ReadLine source;
|
||||
private final Defines defines;
|
||||
private final DefinitionsContainer definitionsContainer;
|
||||
private final String charset;
|
||||
private final Map<String, Sub> subs = new HashMap<String, Sub>();
|
||||
private final List<String> config;
|
||||
private Sub learningSub;
|
||||
private ReadLine includedSub;
|
||||
|
||||
public SubPreprocessor(List<String> config, String charset, Defines defines,
|
||||
DefinitionsContainer definitionsContainer, ReadLine source) {
|
||||
this.config = config;
|
||||
this.source = source;
|
||||
this.charset = charset;
|
||||
this.defines = defines;
|
||||
this.definitionsContainer = definitionsContainer;
|
||||
}
|
||||
|
||||
public CharSequence2 readLine() throws IOException {
|
||||
if (includedSub != null) {
|
||||
final CharSequence2 s = includedSub.readLine();
|
||||
if (s != null) {
|
||||
eventuallyLearn(s);
|
||||
return s;
|
||||
}
|
||||
includedSub = null;
|
||||
}
|
||||
|
||||
final CharSequence2 s = source.readLine();
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Matcher2 m1 = includeSubPattern.matcher(s);
|
||||
if (m1.find()) {
|
||||
return manageIncludeSub(s, m1);
|
||||
}
|
||||
|
||||
Matcher2 m = startsub.matcher(s);
|
||||
if (m.find()) {
|
||||
return manageStartsub(m);
|
||||
}
|
||||
|
||||
m = endsub.matcher(s);
|
||||
if (m.find()) {
|
||||
return manageEndsub(m);
|
||||
}
|
||||
eventuallyLearn(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private void eventuallyLearn(final CharSequence2 s) {
|
||||
if (learningSub != null) {
|
||||
learningSub.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
private CharSequence2 manageIncludeSub(CharSequence2 s, Matcher2 m) throws IOException {
|
||||
final String name = m.group(1);
|
||||
final int idx = name.indexOf('!');
|
||||
if (idx != -1) {
|
||||
final String filename = name.substring(0, idx);
|
||||
final String blocname = name.substring(idx + 1);
|
||||
final File f = FileSystem.getInstance().getFile(PreprocessorInclude.withEnvironmentVariable(filename));
|
||||
if (f.exists() == false || f.isDirectory()) {
|
||||
return s.withErrorPreprocessor("Cannot include " + f.getAbsolutePath());
|
||||
}
|
||||
final Preprocessor data = new Preprocessor(config, getReaderInclude(s, f), charset, defines, null,
|
||||
definitionsContainer);
|
||||
while (data.readLine() != null) {
|
||||
// Read file
|
||||
}
|
||||
data.close();
|
||||
this.includedSub = data.getSub(blocname).getReadLine(s.getLocation());
|
||||
} else {
|
||||
this.includedSub = getSub(name).getReadLine(s.getLocation());
|
||||
}
|
||||
return this.readLine();
|
||||
}
|
||||
|
||||
private ReadLine getReaderInclude(CharSequence2 s, final File f) {
|
||||
try {
|
||||
if (charset == null) {
|
||||
Log.info("Using default charset");
|
||||
return new ReadLineReader(new FileReader(f), f.getAbsolutePath(), s.getLocation());
|
||||
}
|
||||
Log.info("Using charset " + charset);
|
||||
return new ReadLineReader(new InputStreamReader(new FileInputStream(f), charset), f.getAbsolutePath(),
|
||||
s.getLocation());
|
||||
} catch (IOException e) {
|
||||
return new ReadLineSimple(s, e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CharSequence2 manageStartsub(Matcher2 m) throws IOException {
|
||||
final String name = m.group(1);
|
||||
this.learningSub = getSub(name);
|
||||
return this.readLine();
|
||||
}
|
||||
|
||||
private CharSequence2 manageEndsub(Matcher2 m) throws IOException {
|
||||
this.learningSub = null;
|
||||
return this.readLine();
|
||||
}
|
||||
|
||||
Sub getSub(String name) {
|
||||
Sub result = subs.get(name);
|
||||
if (result == null) {
|
||||
result = new Sub(name);
|
||||
subs.put(name, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
source.close();
|
||||
}
|
||||
|
||||
}
|
83
src/net/sourceforge/plantuml/project3/CommandGanttArrow.java
Normal file
83
src/net/sourceforge/plantuml/project3/CommandGanttArrow.java
Normal file
@ -0,0 +1,83 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.project3;
|
||||
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.SingleLineCommand2;
|
||||
import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandGanttArrow extends SingleLineCommand2<GanttDiagram> {
|
||||
|
||||
public CommandGanttArrow() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("CODE1", "([\\p{L}0-9_.]+)"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("ARROW", "(-+)\\>"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("CODE2", "([\\p{L}0-9_.]+)"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("$"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) {
|
||||
|
||||
final String code1 = arg.get("CODE1", 0);
|
||||
final String code2 = arg.get("CODE2", 0);
|
||||
final Task task1 = diagram.getExistingTask(code1);
|
||||
if (task1 == null) {
|
||||
return CommandExecutionResult.error("No such task " + code1);
|
||||
}
|
||||
final Task task2 = diagram.getExistingTask(code2);
|
||||
if (task2 == null) {
|
||||
return CommandExecutionResult.error("No such task " + code2);
|
||||
}
|
||||
|
||||
final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END);
|
||||
|
||||
task2.setStart(end1.getInstantPrecise());
|
||||
diagram.addContraint(new GanttConstraint(end1, new TaskInstant(task2, TaskAttribute.START)));
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.project3;
|
||||
|
||||
public class DayAsDate implements Complement {
|
||||
public class DayAsDate implements Complement, Comparable<DayAsDate> {
|
||||
|
||||
private final int year;
|
||||
private final int dayOfMonth;
|
||||
@ -55,6 +55,10 @@ public class DayAsDate implements Complement {
|
||||
this.month = month;
|
||||
}
|
||||
|
||||
private int internalNumber() {
|
||||
return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + year + "/" + month + "/" + dayOfMonth;
|
||||
@ -94,4 +98,21 @@ public class DayAsDate implements Complement {
|
||||
final int h = ((q + 13 * (m + 1) / 5) + k + k / 4 + j / 4 + 5 * j) % 7;
|
||||
return DayOfWeek.fromH(h);
|
||||
}
|
||||
|
||||
public InstantDay asInstantDay(DayAsDate reference) {
|
||||
// if (this.compareTo(reference) < 0) {
|
||||
// throw new IllegalArgumentException();
|
||||
// }
|
||||
int cmp = 0;
|
||||
DayAsDate current = reference;
|
||||
while (current.compareTo(this) < 0) {
|
||||
current = current.next();
|
||||
cmp++;
|
||||
}
|
||||
return new InstantDay(cmp);
|
||||
}
|
||||
|
||||
public int compareTo(DayAsDate other) {
|
||||
return this.internalNumber() - other.internalNumber();
|
||||
}
|
||||
}
|
||||
|
@ -41,4 +41,6 @@ public interface GCalendar {
|
||||
|
||||
public DayAsDate toDayAsDate(InstantDay day);
|
||||
|
||||
public DayAsDate getStartingDate();
|
||||
|
||||
}
|
||||
|
@ -51,4 +51,8 @@ public class GCalendarSimple implements GCalendar {
|
||||
return result;
|
||||
}
|
||||
|
||||
public DayAsDate getStartingDate() {
|
||||
return start;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
|
||||
private final IHtmlColorSet colorSet = new HtmlColorSetSimple();
|
||||
private GCalendar calendar;
|
||||
|
||||
private Instant min;
|
||||
private final Instant min = new InstantDay(0);
|
||||
private Instant max;
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
@ -95,7 +95,8 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
|
||||
|
||||
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, "", "", 0, 0, null,
|
||||
false);
|
||||
imageBuilder.setUDrawable(getUDrawable());
|
||||
final UDrawable result = getUDrawable();
|
||||
imageBuilder.setUDrawable(result);
|
||||
|
||||
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os);
|
||||
}
|
||||
@ -226,14 +227,14 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
|
||||
}
|
||||
|
||||
private void initMinMax() {
|
||||
min = tasks.values().iterator().next().getStart();
|
||||
// min = tasks.values().iterator().next().getStart();
|
||||
max = tasks.values().iterator().next().getEnd();
|
||||
for (Task task : tasks.values()) {
|
||||
final Instant start = task.getStart();
|
||||
final Instant end = task.getEnd();
|
||||
if (min.compareTo(start) > 0) {
|
||||
min = start;
|
||||
}
|
||||
// if (min.compareTo(start) > 0) {
|
||||
// min = start;
|
||||
// }
|
||||
if (max.compareTo(end) < 0) {
|
||||
max = end;
|
||||
}
|
||||
@ -320,4 +321,8 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
|
||||
this.calendar = new GCalendarSimple(start);
|
||||
}
|
||||
|
||||
public DayAsDate getStartingDate() {
|
||||
return this.calendar.getStartingDate();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,20 +54,21 @@ public class GanttDiagramFactory extends UmlDiagramFactory {
|
||||
return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek());
|
||||
}
|
||||
|
||||
public GanttDiagramFactory() {
|
||||
super(DiagramType.UML);
|
||||
public GanttDiagramFactory(DiagramType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Command> createCommands() {
|
||||
final List<Command> cmds = new ArrayList<Command>();
|
||||
//addCommonCommands(cmds);
|
||||
cmds.add(new CommandNope());
|
||||
cmds.add(new CommandComment());
|
||||
cmds.add(new CommandMultilinesComment());
|
||||
|
||||
for (Command cmd : getLanguageCommands()) {
|
||||
cmds.add(cmd);
|
||||
}
|
||||
cmds.add(new CommandGanttArrow());
|
||||
return cmds;
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,8 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
public class SubjectTask implements SubjectPattern {
|
||||
|
||||
public Collection<VerbPattern> getVerbs() {
|
||||
return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbStarts(), new VerbHappens(), new VerbEnds(),
|
||||
new VerbIsColored());
|
||||
return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
|
||||
new VerbHappens(), new VerbEnds(), new VerbIsColored());
|
||||
}
|
||||
|
||||
public IRegex toRegex() {
|
||||
|
@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.IRegex;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class VerbStarts implements VerbPattern {
|
||||
public class VerbTaskStarts implements VerbPattern {
|
||||
|
||||
public Collection<ComplementPattern> getComplements() {
|
||||
return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
|
@ -0,0 +1,67 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.project3;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.regex.IRegex;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class VerbTaskStartsAbsolute implements VerbPattern {
|
||||
|
||||
public Collection<ComplementPattern> getComplements() {
|
||||
return Arrays.<ComplementPattern> asList(new ComplementDate());
|
||||
}
|
||||
|
||||
public IRegex toRegex() {
|
||||
return new RegexLeaf("starts[%s]*(the[%s]*|on[%s]*)*");
|
||||
}
|
||||
|
||||
public Verb getVerb(final GanttDiagram project, RegexResult arg) {
|
||||
return new Verb() {
|
||||
public CommandExecutionResult execute(Subject subject, Complement complement) {
|
||||
final Task task = (Task) subject;
|
||||
final DayAsDate start = (DayAsDate) complement;
|
||||
task.setStart(start.asInstantDay(project.getStartingDate()));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
@ -158,8 +158,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
final Dimension2D dimTitle = compTitle.calculateDimension(stringBounder);
|
||||
area.setTitleArea(dimTitle.getWidth(), dimTitle.getHeight());
|
||||
}
|
||||
area.initFooter(getPngTitler(FontParam.FOOTER), stringBounder);
|
||||
area.initHeader(getPngTitler(FontParam.HEADER), stringBounder);
|
||||
area.initFooter(getPngTitler(FontParam.FOOTER, index), stringBounder);
|
||||
area.initHeader(getPngTitler(FontParam.HEADER, index), stringBounder);
|
||||
|
||||
final DisplayPositionned legend = diagram.getLegend();
|
||||
final TextBlock legendBlock;
|
||||
@ -178,8 +178,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
|
||||
final String metadata = fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null;
|
||||
|
||||
final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam(), oneOf(scale, dpiFactor), metadata, null, 3,
|
||||
10, diagram.getAnimation());
|
||||
final ImageBuilder imageBuilder = new ImageBuilder(diagram.getSkinParam(), oneOf(scale, dpiFactor), metadata,
|
||||
null, 3, 10, diagram.getAnimation());
|
||||
|
||||
imageBuilder.setUDrawable(new UDrawable() {
|
||||
public void drawU(UGraphic ug) {
|
||||
@ -213,8 +213,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
drawableSet.drawU22(ug.apply(new UTranslate(area.getSequenceAreaX() + delta1 / 2, sequenceAreaY)),
|
||||
delta, fullDimension.getWidth(), page, diagram.isShowFootbox());
|
||||
|
||||
drawHeader(area, ug);
|
||||
drawFooter(area, ug);
|
||||
drawHeader(area, ug, index);
|
||||
drawFooter(area, ug, index);
|
||||
|
||||
if (DisplayPositionned.isNull(legend) == false) {
|
||||
final double delta2;
|
||||
@ -234,8 +234,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, diagram.seed(), os);
|
||||
}
|
||||
|
||||
private void drawFooter(SequenceDiagramArea area, UGraphic ug) {
|
||||
final PngTitler pngTitler = getPngTitler(FontParam.FOOTER);
|
||||
private void drawFooter(SequenceDiagramArea area, UGraphic ug, int page) {
|
||||
final PngTitler pngTitler = getPngTitler(FontParam.FOOTER, page);
|
||||
final TextBlock text = pngTitler.getTextBlock();
|
||||
if (text == null) {
|
||||
return;
|
||||
@ -244,8 +244,8 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
.getFooterY())));
|
||||
}
|
||||
|
||||
private void drawHeader(SequenceDiagramArea area, UGraphic ug) {
|
||||
final PngTitler pngTitler = getPngTitler(FontParam.HEADER);
|
||||
private void drawHeader(SequenceDiagramArea area, UGraphic ug, int page) {
|
||||
final PngTitler pngTitler = getPngTitler(FontParam.HEADER, page);
|
||||
final TextBlock text = pngTitler.getTextBlock();
|
||||
if (text == null) {
|
||||
return;
|
||||
@ -281,14 +281,14 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker {
|
||||
return diagram.getScale().getScale(width, height);
|
||||
}
|
||||
|
||||
private PngTitler getPngTitler(final FontParam fontParam) {
|
||||
private PngTitler getPngTitler(final FontParam fontParam, int page) {
|
||||
final HtmlColor hyperlinkColor = diagram.getSkinParam().getHyperlinkColor();
|
||||
final HtmlColor titleColor = diagram.getSkinParam().getFontHtmlColor(null, fontParam);
|
||||
final String fontFamily = diagram.getSkinParam().getFont(null, false, fontParam).getFamily(null);
|
||||
final int fontSize = diagram.getSkinParam().getFont(null, false, fontParam).getSize();
|
||||
return new PngTitler(titleColor, diagram.getFooterOrHeaderTeoz(fontParam).getDisplay(), fontSize, fontFamily,
|
||||
diagram.getFooterOrHeaderTeoz(fontParam).getHorizontalAlignment(), hyperlinkColor, diagram
|
||||
.getSkinParam().useUnderlineForHyperlink());
|
||||
final Display display = diagram.getFooterOrHeaderTeoz(fontParam).getDisplay().withPage(page + 1, pages.size());
|
||||
return new PngTitler(titleColor, display, fontSize, fontFamily, diagram.getFooterOrHeaderTeoz(fontParam)
|
||||
.getHorizontalAlignment(), hyperlinkColor, diagram.getSkinParam().useUnderlineForHyperlink());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,15 +54,17 @@ public class ComponentRoseEnglober extends AbstractTextualComponent {
|
||||
|
||||
private final SymbolContext symbolContext;
|
||||
|
||||
public ComponentRoseEnglober(SymbolContext symbolContext, Display strings, FontConfiguration font, ISkinSimple spriteContainer) {
|
||||
super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.CENTER, 3, 3, 1, spriteContainer, false, null, null);
|
||||
public ComponentRoseEnglober(SymbolContext symbolContext, Display strings, FontConfiguration font,
|
||||
ISkinSimple spriteContainer) {
|
||||
super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.CENTER, 3, 3, 1, spriteContainer, false, null,
|
||||
null);
|
||||
this.symbolContext = symbolContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackgroundInternalU(UGraphic ug, Area area) {
|
||||
final Dimension2D dimensionToUse = area.getDimensionToUse();
|
||||
ug = symbolContext.apply(ug);
|
||||
ug = symbolContext.transparentBackColorToNull().apply(ug);
|
||||
ug.draw(new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight()));
|
||||
final double xpos = (dimensionToUse.getWidth() - getPureTextWidth(ug.getStringBounder())) / 2;
|
||||
getTextBlock().drawU(ug.apply(new UTranslate(xpos, 0)));
|
||||
|
@ -44,6 +44,7 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.VerticalAlignment;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
@ -141,6 +142,11 @@ public class DecorateEntityImage extends AbstractTextBlock implements TextBlockB
|
||||
return Dimension2DDouble.mergeTB(dimOriginal, dimText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
return MinMax.fromDim(calculateDimension(stringBounder));
|
||||
}
|
||||
|
||||
public final double getDeltaX() {
|
||||
if (original instanceof DecorateEntityImage) {
|
||||
return deltaX + ((DecorateEntityImage) original).deltaX;
|
||||
|
@ -47,4 +47,10 @@ public class ExtremityFactoryCrowfoot extends AbstractExtremityFactory implement
|
||||
final double ortho = atan2(p0, p2);
|
||||
return new ExtremityCrowfoot(p1, ortho, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UDrawable createUDrawable(Point2D p0, double angle, Side side) {
|
||||
throw new UnsupportedOperationException(getClass().toString());
|
||||
}
|
||||
|
||||
}
|
@ -145,7 +145,6 @@ public class ImageHelper {
|
||||
* dimensions of the area the image is to be drawn in.
|
||||
*/
|
||||
public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
|
||||
|
||||
final int originalWidth = imgSize.width;
|
||||
final int originaHeight = imgSize.height;
|
||||
final int boundWidth = boundary.width;
|
||||
@ -172,6 +171,25 @@ public class ImageHelper {
|
||||
return new Dimension(newWidth, newHeight);
|
||||
}
|
||||
|
||||
public static Dimension getScaledDimensionWidthFit(Dimension imgSize, Dimension boundary) {
|
||||
final int originalWidth = imgSize.width;
|
||||
final int originaHeight = imgSize.height;
|
||||
final int boundWidth = boundary.width;
|
||||
final int boundHeight = boundary.height;
|
||||
int newWidth = originalWidth;
|
||||
int newHeight = originaHeight;
|
||||
|
||||
// first check if we need to scale width
|
||||
if (originalWidth != boundWidth) {
|
||||
// scale width to fit
|
||||
newWidth = boundWidth;
|
||||
// scale height to maintain aspect ratio
|
||||
newHeight = (newWidth * originaHeight) / originalWidth;
|
||||
}
|
||||
|
||||
return new Dimension(newWidth, newHeight);
|
||||
}
|
||||
|
||||
public static Dimension getScaledDimension(Dimension dim, double zoom) {
|
||||
return new Dimension((int) (dim.getWidth() * zoom), (int) (dim.getHeight() * zoom));
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ class ImageWindow2 extends JFrame {
|
||||
|
||||
private final static Preferences prefs = Preferences.userNodeForPackage(ImageWindow2.class);
|
||||
private final static String KEY_ZOOM_FIT = "zoomfit";
|
||||
private final static String KEY_WIDTH_FIT = "widthfit";
|
||||
|
||||
private SimpleLine2 simpleLine2;
|
||||
private final JScrollPane scrollPane;
|
||||
@ -92,6 +93,7 @@ class ImageWindow2 extends JFrame {
|
||||
private final JButton copy = new JButton("Copy");
|
||||
private final JButton previous = new JButton("Previous");
|
||||
private final JCheckBox zoomFitButt = new JCheckBox("Zoom fit");
|
||||
private final JCheckBox widthFitButt = new JCheckBox("Width fit");
|
||||
private final JButton zoomMore = new JButton("+");
|
||||
private final JButton zoomLess = new JButton("-");
|
||||
private final MainWindow2 main;
|
||||
@ -101,7 +103,7 @@ class ImageWindow2 extends JFrame {
|
||||
private int zoomFactor = 0;
|
||||
|
||||
private enum SizeMode {
|
||||
FULL_SIZE, ZOOM_FIT
|
||||
FULL_SIZE, ZOOM_FIT, WIDTH_FIT
|
||||
};
|
||||
|
||||
private SizeMode sizeMode = SizeMode.FULL_SIZE;
|
||||
@ -121,6 +123,7 @@ class ImageWindow2 extends JFrame {
|
||||
north.add(copy);
|
||||
north.add(next);
|
||||
north.add(zoomFitButt);
|
||||
north.add(widthFitButt);
|
||||
north.add(zoomMore);
|
||||
north.add(zoomLess);
|
||||
copy.setFocusable(false);
|
||||
@ -144,6 +147,14 @@ class ImageWindow2 extends JFrame {
|
||||
zoomFitButt.setFocusable(false);
|
||||
zoomFitButt.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
widthFitButt.setSelected(false);
|
||||
zoomFit();
|
||||
}
|
||||
});
|
||||
widthFitButt.setFocusable(false);
|
||||
widthFitButt.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
zoomFitButt.setSelected(false);
|
||||
zoomFit();
|
||||
}
|
||||
});
|
||||
@ -189,6 +200,11 @@ class ImageWindow2 extends JFrame {
|
||||
if (zoomChecked) {
|
||||
sizeMode = SizeMode.ZOOM_FIT;
|
||||
}
|
||||
final boolean widthZoomChecked = prefs.getBoolean(KEY_WIDTH_FIT, false);
|
||||
widthFitButt.setSelected(widthZoomChecked);
|
||||
if (widthZoomChecked) {
|
||||
sizeMode = SizeMode.WIDTH_FIT;
|
||||
}
|
||||
|
||||
this.setFocusable(true);
|
||||
this.addKeyListener(new KeyAdapter() {
|
||||
@ -251,11 +267,15 @@ class ImageWindow2 extends JFrame {
|
||||
}
|
||||
|
||||
private void zoomFit() {
|
||||
final boolean selected = zoomFitButt.isSelected();
|
||||
prefs.putBoolean(KEY_ZOOM_FIT, selected);
|
||||
final boolean selectedZoom = zoomFitButt.isSelected();
|
||||
final boolean selectedWidth = widthFitButt.isSelected();
|
||||
prefs.putBoolean(KEY_ZOOM_FIT, selectedZoom);
|
||||
prefs.putBoolean(KEY_WIDTH_FIT, selectedWidth);
|
||||
zoomFactor = 0;
|
||||
if (selected) {
|
||||
if (selectedZoom) {
|
||||
sizeMode = SizeMode.ZOOM_FIT;
|
||||
} else if (selectedWidth) {
|
||||
sizeMode = SizeMode.WIDTH_FIT;
|
||||
} else {
|
||||
sizeMode = SizeMode.FULL_SIZE;
|
||||
}
|
||||
@ -297,6 +317,11 @@ class ImageWindow2 extends JFrame {
|
||||
final Dimension newImgDim = ImageHelper
|
||||
.getScaledDimension(imageDim, scrollPane.getViewport().getSize());
|
||||
image = ImageHelper.getScaledInstance(image, newImgDim, getHints(), true);
|
||||
} else if (sizeMode == SizeMode.WIDTH_FIT) {
|
||||
final Dimension imageDim = new Dimension(image.getWidth(), image.getHeight());
|
||||
final Dimension newImgDim = ImageHelper.getScaledDimensionWidthFit(imageDim, scrollPane.getViewport()
|
||||
.getSize());
|
||||
image = ImageHelper.getScaledInstance(image, newImgDim, getHints(), false);
|
||||
} else if (zoomFactor != 0) {
|
||||
final Dimension imageDim = new Dimension(image.getWidth(), image.getHeight());
|
||||
final Dimension newImgDim = ImageHelper.getScaledDimension(imageDim, getZoom());
|
||||
|
@ -289,7 +289,6 @@ public class MainWindow2 extends JFrame {
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
chooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
|
||||
chooser.setDialogTitle("Directory to watch:");
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
final String currentPath = prefs.get(KEY_DIR, ".");
|
||||
chooser.setCurrentDirectory(new File(currentPath));
|
||||
@ -298,7 +297,11 @@ public class MainWindow2 extends JFrame {
|
||||
Log.info("Closing OpenDialog");
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
final File dir = chooser.getSelectedFile();
|
||||
changeDir(dir);
|
||||
if (dir.isDirectory()) {
|
||||
changeDir(dir);
|
||||
} else {
|
||||
changeDir(dir.getParentFile());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,11 +40,14 @@ import java.awt.geom.PathIterator;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.SignatureUtils;
|
||||
import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.eps.EpsGraphics;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
@ -75,6 +78,29 @@ public class TikzGraphics {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
private final Map<String, Integer> styles = new LinkedHashMap<String, Integer>();
|
||||
private final Map<String, String> stylesID = new HashMap<String, String>();
|
||||
|
||||
private void addCommand(final StringBuilder sb) {
|
||||
final String s = sb.toString();
|
||||
cmd.add(s);
|
||||
if (s.startsWith("\\draw[") || s.startsWith("\\shade[")) {
|
||||
final int end = s.indexOf(']');
|
||||
if (end != -1) {
|
||||
final int start = s.indexOf('[');
|
||||
final String style = s.substring(start + 1, end);
|
||||
Integer count = styles.get(style);
|
||||
if (count == null) {
|
||||
count = 1;
|
||||
stylesID.put(style, "pstyle" + stylesID.size());
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
styles.put(style, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getColorName(Color c) {
|
||||
if (c.equals(Color.WHITE)) {
|
||||
return "white";
|
||||
@ -142,9 +168,14 @@ public class TikzGraphics {
|
||||
if (scale != 1) {
|
||||
out(os, "\\scalebox{" + format(scale) + "}{");
|
||||
}
|
||||
out(os, "\\begin{tikzpicture}[yscale=-1]");
|
||||
out(os, "\\begin{tikzpicture}[yscale=-1");
|
||||
purgeStyles();
|
||||
for (String style : styles.keySet()) {
|
||||
out(os, "," + stylesID.get(style) + "/.style={" + style + "}");
|
||||
}
|
||||
out(os, "]");
|
||||
for (String s : cmd) {
|
||||
out(os, s);
|
||||
out(os, useStyle(s));
|
||||
}
|
||||
out(os, "\\end{tikzpicture}");
|
||||
if (scale != 1) {
|
||||
@ -155,6 +186,31 @@ public class TikzGraphics {
|
||||
}
|
||||
}
|
||||
|
||||
private String useStyle(String s) {
|
||||
for (String style : styles.keySet()) {
|
||||
final String start1 = "\\draw[" + style + "]";
|
||||
if (s.startsWith(start1)) {
|
||||
final String newStart = "\\draw[" + stylesID.get(style) + "]";
|
||||
return newStart + s.substring(start1.length());
|
||||
}
|
||||
final String start2 = "\\shade[" + style + "]";
|
||||
if (s.startsWith(start2)) {
|
||||
final String newStart = "\\shade[" + stylesID.get(style) + "]";
|
||||
return newStart + s.substring(start2.length());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private void purgeStyles() {
|
||||
for (Iterator<Map.Entry<String, Integer>> it = styles.entrySet().iterator(); it.hasNext();) {
|
||||
final Map.Entry<String, Integer> ent = it.next();
|
||||
if (ent.getValue().intValue() == 1) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String definecolor(String name, Color color) {
|
||||
return "\\definecolor{" + name + "}{RGB}{" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
|
||||
+ "}";
|
||||
@ -162,23 +218,8 @@ public class TikzGraphics {
|
||||
|
||||
public void rectangle(double x, double y, double width, double height) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final boolean gradient = this.fillcolorGradient2 != null;
|
||||
if (pendingUrl == null) {
|
||||
sb.append(gradient ? "\\shade[" : "\\draw[");
|
||||
if (color != null) {
|
||||
sb.append(gradient ? "draw=" : "color=");
|
||||
sb.append(getColorName(color) + ",");
|
||||
}
|
||||
if (gradient) {
|
||||
sb.append("top color=" + getColorName(fillcolor) + ",");
|
||||
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
|
||||
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
|
||||
} else if (fillcolor != null) {
|
||||
sb.append("fill=" + getColorName(fillcolor) + ",");
|
||||
if (color == null) {
|
||||
sb.append("color=" + getColorName(fillcolor) + ",");
|
||||
}
|
||||
}
|
||||
appendShadeOrDraw(sb);
|
||||
sb.append("line width=" + thickness + "pt] ");
|
||||
sb.append(couple(x, y) + " rectangle " + couple(x + width, y + height));
|
||||
sb.append(";");
|
||||
@ -207,7 +248,7 @@ public class TikzGraphics {
|
||||
sb.append(" {};");
|
||||
urlIgnoreText = true;
|
||||
}
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
private String getAngleFromGradientPolicy() {
|
||||
@ -235,11 +276,11 @@ public class TikzGraphics {
|
||||
}
|
||||
|
||||
private void out(OutputStream os, String s) throws IOException {
|
||||
os.write(s.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
os.write(s.getBytes("UTF-8"));
|
||||
os.write("\n".getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
public void text(double x, double y, String text) {
|
||||
public void text(double x, double y, String text, boolean underline, boolean italic, boolean bold) {
|
||||
final StringBuilder sb = new StringBuilder("\\node at " + couple(x, y));
|
||||
sb.append("[below right");
|
||||
if (color != null) {
|
||||
@ -248,7 +289,25 @@ public class TikzGraphics {
|
||||
}
|
||||
sb.append("]{");
|
||||
if (pendingUrl == null || urlIgnoreText) {
|
||||
if (underline) {
|
||||
sb.append("\\underline{");
|
||||
}
|
||||
if (italic) {
|
||||
sb.append("\\textit{");
|
||||
}
|
||||
if (bold) {
|
||||
sb.append("\\textbf{");
|
||||
}
|
||||
sb.append(protectText(text));
|
||||
if (bold) {
|
||||
sb.append("}");
|
||||
}
|
||||
if (italic) {
|
||||
sb.append("}");
|
||||
}
|
||||
if (underline) {
|
||||
sb.append("}");
|
||||
}
|
||||
} else {
|
||||
appendPendingUrl(sb);
|
||||
sb.append("{");
|
||||
@ -256,7 +315,7 @@ public class TikzGraphics {
|
||||
sb.append("}");
|
||||
}
|
||||
sb.append("};");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
private void appendPendingUrl(final StringBuilder sb) {
|
||||
@ -279,11 +338,14 @@ public class TikzGraphics {
|
||||
}
|
||||
|
||||
private String protectText(String text) {
|
||||
text = text.replaceAll("\\\\", "\\\\\\\\");
|
||||
text = text.replaceAll("_", "\\\\_");
|
||||
text = text.replaceAll("\u00AB", "\\\\guillemotleft ");
|
||||
text = text.replaceAll("\u00BB", "\\\\guillemotright ");
|
||||
text = text.replaceAll("<", "\\\\textless ");
|
||||
text = text.replaceAll(">", "\\\\textgreater ");
|
||||
text = text.replaceAll("&", "\\\\&");
|
||||
text = text.replaceAll("~", "\\\\~{}");
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -302,17 +364,13 @@ public class TikzGraphics {
|
||||
sb.append(" -- ");
|
||||
sb.append(couple(x2, y2));
|
||||
sb.append(";");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
public void polygon(double[] points) {
|
||||
final StringBuilder sb = new StringBuilder("\\draw[");
|
||||
if (color != null) {
|
||||
sb.append("color=" + getColorName(color) + ",");
|
||||
}
|
||||
if (fillcolor != null) {
|
||||
sb.append("fill=" + getColorName(fillcolor) + ",");
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
appendShadeOrDraw(sb);
|
||||
sb.append("line width=" + thickness + "pt]");
|
||||
sb.append(" ");
|
||||
for (int i = 0; i < points.length; i += 2) {
|
||||
@ -320,17 +378,12 @@ public class TikzGraphics {
|
||||
sb.append(" -- ");
|
||||
}
|
||||
sb.append("cycle;");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
private void round(double r, double[] points) {
|
||||
final StringBuilder sb = new StringBuilder("\\draw[");
|
||||
if (color != null) {
|
||||
sb.append("color=" + getColorName(color) + ",");
|
||||
}
|
||||
if (fillcolor != null) {
|
||||
sb.append("fill=" + getColorName(fillcolor) + ",");
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
appendShadeOrDraw(sb);
|
||||
sb.append("line width=" + thickness + "pt]");
|
||||
sb.append(" ");
|
||||
int i = 0;
|
||||
@ -351,7 +404,26 @@ public class TikzGraphics {
|
||||
sb.append(couple(points[i++], points[i++]));
|
||||
sb.append(" -- ");
|
||||
sb.append("cycle;");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
private void appendShadeOrDraw(final StringBuilder sb) {
|
||||
final boolean gradient = this.fillcolorGradient2 != null;
|
||||
sb.append(gradient ? "\\shade[" : "\\draw[");
|
||||
if (color != null) {
|
||||
sb.append(gradient ? "draw=" : "color=");
|
||||
sb.append(getColorName(color) + ",");
|
||||
}
|
||||
if (gradient) {
|
||||
sb.append("top color=" + getColorName(fillcolor) + ",");
|
||||
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
|
||||
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
|
||||
} else if (fillcolor != null) {
|
||||
sb.append("fill=" + getColorName(fillcolor) + ",");
|
||||
if (color == null) {
|
||||
sb.append("color=" + getColorName(fillcolor) + ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rectangleRound(double x, double y, double width, double height, double r) {
|
||||
@ -381,23 +453,12 @@ public class TikzGraphics {
|
||||
|
||||
public void upath(double x, double y, UPath path) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final boolean gradient = this.fillcolorGradient2 != null;
|
||||
sb.append(gradient ? "\\shade[" : "\\draw[");
|
||||
if (color != null) {
|
||||
sb.append(gradient ? "draw=" : "color=");
|
||||
sb.append(getColorName(color) + ",");
|
||||
appendShadeOrDraw(sb);
|
||||
sb.append("line width=" + thickness + "pt");
|
||||
if (dash != null) {
|
||||
sb.append(",dash pattern=" + dash);
|
||||
}
|
||||
if (gradient) {
|
||||
sb.append("top color=" + getColorName(fillcolor) + ",");
|
||||
sb.append("bottom color=" + getColorName(fillcolorGradient2) + ",");
|
||||
sb.append("shading=axis,shading angle=" + getAngleFromGradientPolicy() + ",");
|
||||
} else if (fillcolor != null) {
|
||||
sb.append("fill=" + getColorName(fillcolor) + ",");
|
||||
if (color == null) {
|
||||
sb.append("color=" + getColorName(fillcolor) + ",");
|
||||
}
|
||||
}
|
||||
sb.append("line width=" + thickness + "pt] ");
|
||||
sb.append("] ");
|
||||
for (USegment seg : path) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
@ -423,7 +484,7 @@ public class TikzGraphics {
|
||||
}
|
||||
}
|
||||
sb.append(";");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
public void ellipse(double x, double y, double width, double height) {
|
||||
@ -437,7 +498,7 @@ public class TikzGraphics {
|
||||
}
|
||||
sb.append("line width=" + thickness + "pt] " + couple(x, y) + " ellipse (" + format(width) + "pt and "
|
||||
+ format(height) + "pt);");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
public void drawSingleCharacter(double x, double y, char c) {
|
||||
@ -445,7 +506,7 @@ public class TikzGraphics {
|
||||
sb.append("\\node at ");
|
||||
sb.append(couple(x, y));
|
||||
sb.append("[]{\\textbf{\\Large " + c + "}};");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
}
|
||||
|
||||
public void drawPathIterator(double x, double y, PathIterator path) {
|
||||
@ -461,7 +522,7 @@ public class TikzGraphics {
|
||||
sb.append(couple(coord[0] + x, coord[1] + y));
|
||||
} else if (code == PathIterator.SEG_CLOSE) {
|
||||
sb.append(";");
|
||||
cmd.add(sb.toString());
|
||||
addCommand(sb);
|
||||
sb.setLength(0);
|
||||
sb.append("\\draw ");
|
||||
} else if (code == PathIterator.SEG_CUBICTO) {
|
||||
|
@ -66,7 +66,13 @@ public class CommandTimeMessage extends SingleLineCommand2<TimingDiagram> {
|
||||
@Override
|
||||
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
|
||||
final Player player1 = diagram.getPlayer(arg.get("PART1", 0));
|
||||
if (player1 == null) {
|
||||
return CommandExecutionResult.error("No such element: " + arg.get("PART1", 0));
|
||||
}
|
||||
final Player player2 = diagram.getPlayer(arg.get("PART2", 0));
|
||||
if (player2 == null) {
|
||||
return CommandExecutionResult.error("No such element: " + arg.get("PART2", 0));
|
||||
}
|
||||
final TimeTick tick1 = TimeTickBuilder.parseTimeTick("TIME1", arg, diagram);
|
||||
final TimeTick tick2 = TimeTickBuilder.parseTimeTick("TIME2", arg, diagram);
|
||||
diagram.createTimeMessage(player1, tick1, player2, tick2, arg.get("MESSAGE", 0));
|
||||
|
@ -55,6 +55,7 @@ import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.color.Colors;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
@ -254,6 +255,10 @@ public class Histogram implements TimeDrawing {
|
||||
return new Dimension2DDouble(width, getFullDeltaY());
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
|
||||
return null;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ import net.sourceforge.plantuml.graphic.InnerStrategy;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.color.Colors;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
@ -161,6 +162,11 @@ public class Player implements TextBlock, TimeProjected {
|
||||
return new Dimension2DDouble(width, title.calculateDimension(stringBounder).getHeight() * 2 + zoneHeight);
|
||||
}
|
||||
|
||||
public MinMax getMinMax(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
private double getZoneHeight() {
|
||||
return getTimeDrawing().getHeight();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user