diff --git a/src/net/sourceforge/plantuml/abel/LeafType.java b/src/net/sourceforge/plantuml/abel/LeafType.java index ce9b751e1..4c67360de 100644 --- a/src/net/sourceforge/plantuml/abel/LeafType.java +++ b/src/net/sourceforge/plantuml/abel/LeafType.java @@ -62,6 +62,8 @@ public enum LeafType { PORTIN, PORTOUT, + CHEN_ENTITY, CHEN_RELATIONSHIP, CHEN_ATTRIBUTE, + STILL_UNKNOWN; public static LeafType getLeafType(String type) { diff --git a/src/net/sourceforge/plantuml/cheneer/command/CommandCreateAttribute.java b/src/net/sourceforge/plantuml/cheneer/command/CommandCreateAttribute.java index a01dc2c3a..e7a98e8a1 100644 --- a/src/net/sourceforge/plantuml/cheneer/command/CommandCreateAttribute.java +++ b/src/net/sourceforge/plantuml/cheneer/command/CommandCreateAttribute.java @@ -83,7 +83,7 @@ public class CommandCreateAttribute extends SingleLineCommand2 { return CommandExecutionResult.error("Attribute must be inside an entity, relationship or another attribute"); } - final LeafType type = LeafType.USECASE; + final LeafType type = LeafType.CHEN_ATTRIBUTE; final String name = diagram.cleanId(arg.get("NAME", 0).trim()); final String id = owner.getName() + "/" + name; final boolean composite = arg.get("COMPOSITE", 0) != null; diff --git a/src/net/sourceforge/plantuml/cheneer/command/CommandCreateEntity.java b/src/net/sourceforge/plantuml/cheneer/command/CommandCreateEntity.java index 9ca195110..ceb5e7c38 100644 --- a/src/net/sourceforge/plantuml/cheneer/command/CommandCreateEntity.java +++ b/src/net/sourceforge/plantuml/cheneer/command/CommandCreateEntity.java @@ -73,7 +73,18 @@ public class CommandCreateEntity extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ChenEerDiagram diagram, LineLocation location, RegexResult arg) throws NoSuchColorException { - final LeafType type = LeafType.OBJECT; + LeafType type; + switch (arg.get("TYPE", 0)) { + case "entity": + type = LeafType.CHEN_ENTITY; + break; + case "relationship": + type = LeafType.CHEN_RELATIONSHIP; + break; + default: + throw new IllegalStateException(); + } + final String name = diagram.cleanId(arg.get("NAME", 0).trim()); final Quark quark = diagram.quarkInContext(true, name); diff --git a/src/net/sourceforge/plantuml/style/SName.java b/src/net/sourceforge/plantuml/style/SName.java index aa74331bb..451a65036 100644 --- a/src/net/sourceforge/plantuml/style/SName.java +++ b/src/net/sourceforge/plantuml/style/SName.java @@ -63,6 +63,10 @@ public enum SName { component, // composite, // robust, // + chenAttribute, // + chenEerDiagram, // + chenEntity, // + chenRelationship, // concise, // clock, // componentDiagram, // diff --git a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java index 2b76371b5..4a8f317a1 100644 --- a/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java +++ b/src/net/sourceforge/plantuml/svek/GeneralImageBuilder.java @@ -99,6 +99,8 @@ import net.sourceforge.plantuml.svek.image.EntityImageArcCircle; import net.sourceforge.plantuml.svek.image.EntityImageAssociation; import net.sourceforge.plantuml.svek.image.EntityImageAssociationPoint; import net.sourceforge.plantuml.svek.image.EntityImageBranch; +import net.sourceforge.plantuml.svek.image.EntityImageChenAttribute; +import net.sourceforge.plantuml.svek.image.EntityImageChenEntity; import net.sourceforge.plantuml.svek.image.EntityImageCircleEnd; import net.sourceforge.plantuml.svek.image.EntityImageCircleStart; import net.sourceforge.plantuml.svek.image.EntityImageClass; @@ -254,6 +256,16 @@ public final class GeneralImageBuilder { if (leaf.getLeafType() == LeafType.TIPS) return new EntityImageTips(leaf, skinParam, bibliotekon, umlDiagramType); + if (leaf.getLeafType() == LeafType.CHEN_ENTITY) + return new EntityImageChenEntity(leaf, skinParam); + + if (leaf.getLeafType() == LeafType.CHEN_RELATIONSHIP) + // TODO: custom image type + return new EntityImageChenEntity(leaf, skinParam); + + if (leaf.getLeafType() == LeafType.CHEN_ATTRIBUTE) + return new EntityImageChenAttribute(leaf, skinParam); + // TODO Clean if (leaf.getLeafType() == LeafType.DOMAIN && leaf.getStereotype() != null && leaf.getStereotype().isMachineOrSpecification()) diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageChenAttribute.java b/src/net/sourceforge/plantuml/svek/image/EntityImageChenAttribute.java new file mode 100644 index 000000000..609377531 --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageChenAttribute.java @@ -0,0 +1,155 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2024, Arnaud Roques + * + * Project Info: https://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * https://plantuml.com/patreon (only 1$ per month!) + * https://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.svek.image; + +import java.util.Collections; + +import net.sourceforge.plantuml.abel.Entity; +import net.sourceforge.plantuml.klimt.UGroupType; +import net.sourceforge.plantuml.klimt.UShape; +import net.sourceforge.plantuml.klimt.UStroke; +import net.sourceforge.plantuml.klimt.UTranslate; +import net.sourceforge.plantuml.klimt.color.ColorType; +import net.sourceforge.plantuml.klimt.color.Colors; +import net.sourceforge.plantuml.klimt.color.HColor; +import net.sourceforge.plantuml.klimt.creole.CreoleMode; +import net.sourceforge.plantuml.klimt.drawing.UGraphic; +import net.sourceforge.plantuml.klimt.font.FontConfiguration; +import net.sourceforge.plantuml.klimt.font.StringBounder; +import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment; +import net.sourceforge.plantuml.klimt.geom.XDimension2D; +import net.sourceforge.plantuml.klimt.shape.TextBlock; +import net.sourceforge.plantuml.klimt.shape.TextBlockInEllipse; +import net.sourceforge.plantuml.klimt.shape.UEllipse; +import net.sourceforge.plantuml.style.ISkinParam; +import net.sourceforge.plantuml.style.PName; +import net.sourceforge.plantuml.style.SName; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleSignatureBasic; +import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.ShapeType; +import net.sourceforge.plantuml.url.Url; + +public class EntityImageChenAttribute extends AbstractEntityImage { + + final static private int MARGIN = 6; + + final private TextBlock title; + final private Url url; + + public EntityImageChenAttribute(Entity entity, ISkinParam skinParam) { + super(entity, skinParam); + + final FontConfiguration titleFontConfiguration = getStyleTitle(entity, skinParam) + .getFontConfiguration(getSkinParam().getIHtmlColorSet(), entity.getColors()); + + title = entity.getDisplay().create8(titleFontConfiguration, HorizontalAlignment.CENTER, skinParam, CreoleMode.FULL, + getStyle().wrapWidth()); + + url = entity.getUrl99(); + } + + private Style getStyle() { + return getStyle(getEntity(), getSkinParam()); + } + + private static Style getStyle(Entity group, ISkinParam skinParam) { + return StyleSignatureBasic.of(SName.root, SName.element, SName.chenEerDiagram, SName.chenAttribute) + .withTOBECHANGED(group.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder()); + } + + private static Style getStyleTitle(Entity group, ISkinParam skinParam) { + return StyleSignatureBasic.of(SName.root, SName.element, SName.chenEerDiagram, SName.chenAttribute, SName.title) + .withTOBECHANGED(group.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder()); + } + + @Override + public ShapeType getShapeType() { + return ShapeType.OVAL; + } + + @Override + public XDimension2D calculateDimension(StringBounder stringBounder) { + final TextBlockInEllipse ellipse = new TextBlockInEllipse(title, stringBounder); + + return ellipse.calculateDimension(stringBounder); + } + + @Override + public void drawU(UGraphic ug) { + ug.startGroup(Collections.singletonMap(UGroupType.ID, getEntity().getQuark().toStringPoint())); + if (url != null) + ug.startUrl(url); + + final XDimension2D dimTotal = calculateDimension(ug.getStringBounder()); + final XDimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); + + final UStroke stroke = getStyle().getStroke(getEntity().getColors()); + ug = applyColor(ug); + ug = ug.apply(stroke); + ug.draw(getShape(dimTotal)); + + final double xTitle = (dimTotal.getWidth() - dimTitle.getWidth()) / 2; + final double yTitle = MARGIN; + title.drawU(ug.apply(new UTranslate(xTitle, yTitle))); + + if (url != null) + ug.closeUrl(); + + ug.closeGroup(); + } + + final protected UGraphic applyColor(UGraphic ug) { + Colors colors = getEntity().getColors(); + + HColor border = colors.getColor(ColorType.LINE); + if (border == null) + border = getStyle().value(PName.LineColor).asColor(getSkinParam().getIHtmlColorSet()); + ug = ug.apply(border); + + HColor backcolor = colors.getColor(ColorType.BACK); + if (backcolor == null) + backcolor = getStyle().value(PName.BackGroundColor).asColor(getSkinParam().getIHtmlColorSet()); + ug = ug.apply(backcolor.bg()); + + return ug; + } + + private UShape getShape(XDimension2D dimTotal) { + return UEllipse.build(dimTotal.getWidth(), dimTotal.getHeight()); + } + +} diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageChenEntity.java b/src/net/sourceforge/plantuml/svek/image/EntityImageChenEntity.java new file mode 100644 index 000000000..766b6fbab --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageChenEntity.java @@ -0,0 +1,151 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2024, Arnaud Roques + * + * Project Info: https://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * https://plantuml.com/patreon (only 1$ per month!) + * https://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.svek.image; + +import java.util.Collections; + +import net.sourceforge.plantuml.abel.Entity; +import net.sourceforge.plantuml.klimt.UGroupType; +import net.sourceforge.plantuml.klimt.UStroke; +import net.sourceforge.plantuml.klimt.UTranslate; +import net.sourceforge.plantuml.klimt.color.ColorType; +import net.sourceforge.plantuml.klimt.color.Colors; +import net.sourceforge.plantuml.klimt.color.HColor; +import net.sourceforge.plantuml.klimt.creole.CreoleMode; +import net.sourceforge.plantuml.klimt.drawing.UGraphic; +import net.sourceforge.plantuml.klimt.font.FontConfiguration; +import net.sourceforge.plantuml.klimt.font.StringBounder; +import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment; +import net.sourceforge.plantuml.klimt.geom.XDimension2D; +import net.sourceforge.plantuml.klimt.shape.TextBlock; +import net.sourceforge.plantuml.klimt.shape.URectangle; +import net.sourceforge.plantuml.style.ISkinParam; +import net.sourceforge.plantuml.style.PName; +import net.sourceforge.plantuml.style.SName; +import net.sourceforge.plantuml.style.Style; +import net.sourceforge.plantuml.style.StyleSignatureBasic; +import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.ShapeType; +import net.sourceforge.plantuml.url.Url; + +public class EntityImageChenEntity extends AbstractEntityImage { + + final private TextBlock title; + final private Url url; + + public EntityImageChenEntity(Entity entity, ISkinParam skinParam) { + super(entity, skinParam); + + final FontConfiguration titleFontConfiguration = getStyleStateTitle(entity, skinParam) + .getFontConfiguration(getSkinParam().getIHtmlColorSet(), entity.getColors()); + + title = entity.getDisplay().create8(titleFontConfiguration, HorizontalAlignment.CENTER, skinParam, CreoleMode.FULL, + getStyleState().wrapWidth()); + + url = entity.getUrl99(); + } + + private Style getStyleState() { + return getStyleState(getEntity(), getSkinParam()); + } + + private static Style getStyleState(Entity group, ISkinParam skinParam) { + return StyleSignatureBasic.of(SName.root, SName.element, SName.chenEerDiagram, SName.chenEntity) + .withTOBECHANGED(group.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder()); + } + + private static Style getStyleStateTitle(Entity group, ISkinParam skinParam) { + return StyleSignatureBasic.of(SName.root, SName.element, SName.chenEerDiagram, SName.chenEntity, SName.title) + .withTOBECHANGED(group.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder()); + } + + @Override + public ShapeType getShapeType() { + return ShapeType.RECTANGLE; + } + + @Override + public XDimension2D calculateDimension(StringBounder stringBounder) { + final XDimension2D dim = title.calculateDimension(stringBounder); + + return dim.delta(MARGIN * 2 + 2 * MARGIN_LINE); + } + + @Override + public void drawU(UGraphic ug) { + ug.startGroup(Collections.singletonMap(UGroupType.ID, getEntity().getQuark().toStringPoint())); + if (url != null) + ug.startUrl(url); + + final XDimension2D dimTotal = calculateDimension(ug.getStringBounder()); + final XDimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); + + final UStroke stroke = getStyleState().getStroke(getEntity().getColors()); + ug = applyColor(ug); + ug = ug.apply(stroke); + ug.draw(getShape(dimTotal)); + + final double xTitle = (dimTotal.getWidth() - dimTitle.getWidth()) / 2; + final double yTitle = MARGIN + MARGIN_LINE; + title.drawU(ug.apply(new UTranslate(xTitle, yTitle))); + + if (url != null) + ug.closeUrl(); + + ug.closeGroup(); + } + + final protected UGraphic applyColor(UGraphic ug) { + Colors colors = getEntity().getColors(); + + HColor border = colors.getColor(ColorType.LINE); + if (border == null) + border = getStyleState().value(PName.LineColor).asColor(getSkinParam().getIHtmlColorSet()); + ug = ug.apply(border); + + HColor backcolor = colors.getColor(ColorType.BACK); + if (backcolor == null) + backcolor = getStyleState().value(PName.BackGroundColor).asColor(getSkinParam().getIHtmlColorSet()); + ug = ug.apply(backcolor.bg()); + + return ug; + } + + private URectangle getShape(XDimension2D dimTotal) { + return URectangle.build(dimTotal); + } + +}