From 58e239db9d5caa8c344f83795e3307ed0f758634 Mon Sep 17 00:00:00 2001 From: Phillipus Date: Sat, 26 Oct 2024 10:41:34 +0100 Subject: [PATCH] Support Line Style on diagram objects - TODO: decide on whether Grouping should be OK --- .../factory/CanvasStickyUIProvider.java | 1 + .../canvas/figures/CanvasBlockFigure.java | 2 + com.archimatetool.editor/plugin.xml | 16 +- .../diagram/ArchimateDiagramModelFactory.java | 52 +++--- .../DiagramModelObjectLineStyleCommand.java | 24 +++ .../AbstractDiagramModelObjectFigure.java | 25 +++ .../figures/AbstractFigureDelegate.java | 8 + .../figures/EllipseFigureDelegate.java | 2 + .../figures/RectangleFigureDelegate.java | 2 + .../RoundedRectangleFigureDelegate.java | 2 + .../figures/diagram/DiagramImageFigure.java | 2 + .../diagram/figures/diagram/GroupFigure.java | 2 + .../diagram/figures/diagram/NoteFigure.java | 1 + .../elements/AbstractMotivationFigure.java | 2 + .../figures/elements/GroupingFigure.java | 5 +- .../diagram/sketch/figures/StickyFigure.java | 2 + .../diagram/tools/FormatPainterTool.java | 8 + .../handlers/LineStyleHandler.java | 52 ++++++ .../propertysections/LineOpacitySection.java | 103 ------------ .../editor/propertysections/LineSection2.java | 155 ++++++++++++++++++ .../propertysections/LineStyleComposite.java | 136 +++++++++++++++ .../diagram/DiagramImageUIProvider.java | 3 +- .../factory/sketch/SketchActorUIProvider.java | 3 +- .../model/IDiagramModelObject.java | 17 ++ .../com/archimatetool/model/ModelVersion.java | 13 +- .../model/impl/DiagramModelObject.java | 10 ++ .../model/impl/DiagramModelObjectTests.java | 7 + 27 files changed, 511 insertions(+), 144 deletions(-) create mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/diagram/commands/DiagramModelObjectLineStyleCommand.java create mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/model/compatibility/handlers/LineStyleHandler.java delete mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineOpacitySection.java create mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineSection2.java create mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineStyleComposite.java diff --git a/com.archimatetool.canvas/src/com/archimatetool/canvas/factory/CanvasStickyUIProvider.java b/com.archimatetool.canvas/src/com/archimatetool/canvas/factory/CanvasStickyUIProvider.java index 576c56627..449117a3b 100644 --- a/com.archimatetool.canvas/src/com/archimatetool/canvas/factory/CanvasStickyUIProvider.java +++ b/com.archimatetool.canvas/src/com/archimatetool/canvas/factory/CanvasStickyUIProvider.java @@ -62,6 +62,7 @@ public ImageDescriptor getImageDescriptor() { public boolean shouldExposeFeature(String featureName) { if(featureName == IArchimatePackage.Literals.LINE_OBJECT__LINE_COLOR.getName() || featureName == IArchimatePackage.Literals.LINE_OBJECT__LINE_WIDTH.getName() || + featureName == IDiagramModelObject.FEATURE_LINE_STYLE || featureName == IDiagramModelObject.FEATURE_DERIVE_ELEMENT_LINE_COLOR || featureName == IDiagramModelObject.FEATURE_GRADIENT) { return false; diff --git a/com.archimatetool.canvas/src/com/archimatetool/canvas/figures/CanvasBlockFigure.java b/com.archimatetool.canvas/src/com/archimatetool/canvas/figures/CanvasBlockFigure.java index e2bb77d6e..b1ce6bb87 100644 --- a/com.archimatetool.canvas/src/com/archimatetool/canvas/figures/CanvasBlockFigure.java +++ b/com.archimatetool.canvas/src/com/archimatetool/canvas/figures/CanvasBlockFigure.java @@ -162,6 +162,8 @@ private void drawFigure(Graphics graphics, Color background) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + setLineStyle(graphics); + graphics.setBackgroundColor(background); graphics.fillRectangle(bounds); diff --git a/com.archimatetool.editor/plugin.xml b/com.archimatetool.editor/plugin.xml index 840e8e185..36da242f7 100644 --- a/com.archimatetool.editor/plugin.xml +++ b/com.archimatetool.editor/plugin.xml @@ -431,13 +431,13 @@ + + diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/ArchimateDiagramModelFactory.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/ArchimateDiagramModelFactory.java index 5c5f67f00..556e0be52 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/ArchimateDiagramModelFactory.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/ArchimateDiagramModelFactory.java @@ -29,6 +29,7 @@ import com.archimatetool.model.IProfile; import com.archimatetool.model.ITextAlignment; import com.archimatetool.model.ITextPosition; +import com.archimatetool.model.impl.Grouping; @@ -47,14 +48,17 @@ public class ArchimateDiagramModelFactory implements ICreationFactory { public static IDiagramModelArchimateObject createDiagramModelArchimateObject(IArchimateElement element) { IDiagramModelArchimateObject dmo = IArchimateFactory.eINSTANCE.createDiagramModelArchimateObject(); dmo.setArchimateElement(element); + // Figure Type dmo.setType(ArchiPlugin.PREFERENCES.getInt(IPreferenceConstants.DEFAULT_FIGURE_PREFIX + element.eClass().getName())); - // Add new bounds with a default user size IGraphicalObjectUIProvider provider = (IGraphicalObjectUIProvider)ObjectUIFactory.INSTANCE.getProvider(dmo); + + // Add new bounds with a default user size Dimension size = provider.getDefaultSize(); dmo.setBounds(0, 0, size.width, size.height); + // Text position and alignment dmo.setTextPosition(provider.getDefaultTextPosition()); dmo.setTextAlignment(provider.getDefaultTextAlignment()); @@ -64,6 +68,11 @@ public static IDiagramModelArchimateObject createDiagramModelArchimateObject(IAr // Gradient dmo.setGradient(ArchiPlugin.PREFERENCES.getInt(IPreferenceConstants.DEFAULT_GRADIENT)); + // Line Style for Grouping + if(element instanceof Grouping) { + dmo.setLineStyle(IDiagramModelObject.LINE_STYLE_DASHED); + } + return dmo; } @@ -77,6 +86,8 @@ public static IDiagramModelArchimateConnection createDiagramModelArchimateConnec connection.setArchimateRelationship(relation); IGraphicalObjectUIProvider provider = (IGraphicalObjectUIProvider)ObjectUIFactory.INSTANCE.getProvider(connection); + + // Text alignment connection.setTextAlignment(provider.getDefaultTextAlignment()); // Set user default colors as set in prefs @@ -112,63 +123,58 @@ public Object getNewObject() { return null; } - boolean isSpecialization = fProfile != null && fProfile.getArchimateModel() != null; + boolean isSpecialization = fProfile != null && fProfile.getArchimateModel() != null; EObject object = IArchimateFactory.eINSTANCE.create(fTemplate); // Add Profile to Concept if set - if(object instanceof IArchimateConcept && isSpecialization) { - ((IArchimateConcept)object).getProfiles().add(fProfile); + if(object instanceof IArchimateConcept concept && isSpecialization) { + concept.getProfiles().add(fProfile); } - // Connection created from Relationship Template - if(object instanceof IArchimateRelationship) { - return createDiagramModelArchimateConnection((IArchimateRelationship)object); + // Archimate Connection created from Relationship Template + if(object instanceof IArchimateRelationship relationship) { + return createDiagramModelArchimateConnection(relationship); } // Archimate Diagram Object created from Archimate Element Template - else if(object instanceof IArchimateElement) { - IArchimateElement element = (IArchimateElement)object; + else if(object instanceof IArchimateElement element) { element.setName(isSpecialization ? fProfile.getName() : ArchiLabelProvider.INSTANCE.getDefaultName(fTemplate)); return createDiagramModelArchimateObject(element); } // Group - else if(object instanceof IDiagramModelGroup) { - IDiagramModelGroup group = (IDiagramModelGroup)object; + else if(object instanceof IDiagramModelGroup group) { group.setName(ArchiLabelProvider.INSTANCE.getDefaultName(fTemplate)); ColorFactory.setDefaultColors(group); - // Gradient group.setGradient(ArchiPlugin.PREFERENCES.getInt(IPreferenceConstants.DEFAULT_GRADIENT)); } // Note - else if(object instanceof IDiagramModelNote) { - IDiagramModelNote note = (IDiagramModelNote)object; + else if(object instanceof IDiagramModelNote note) { ColorFactory.setDefaultColors(note); - // Gradient note.setGradient(ArchiPlugin.PREFERENCES.getInt(IPreferenceConstants.DEFAULT_GRADIENT)); } // Connection - else if(object instanceof IDiagramModelConnection) { - ColorFactory.setDefaultColors((IDiagramModelConnection)object); + else if(object instanceof IDiagramModelConnection connection) { + ColorFactory.setDefaultColors(connection); } IGraphicalObjectUIProvider provider = (IGraphicalObjectUIProvider)ObjectUIFactory.INSTANCE.getProvider(object); - if(object instanceof ITextAlignment) { - ((ITextAlignment)object).setTextAlignment(provider.getDefaultTextAlignment()); + if(object instanceof ITextAlignment textAlignment) { + textAlignment.setTextAlignment(provider.getDefaultTextAlignment()); } - if(object instanceof ITextPosition) { - ((ITextPosition)object).setTextPosition(provider.getDefaultTextPosition()); + if(object instanceof ITextPosition textPosition) { + textPosition.setTextPosition(provider.getDefaultTextPosition()); } // Add new bounds with a default user size - if(object instanceof IDiagramModelObject) { + if(object instanceof IDiagramModelObject dmo) { Dimension size = provider.getDefaultSize(); - ((IDiagramModelObject)object).setBounds(0, 0, size.width, size.height); + dmo.setBounds(0, 0, size.width, size.height); } return object; diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/commands/DiagramModelObjectLineStyleCommand.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/commands/DiagramModelObjectLineStyleCommand.java new file mode 100644 index 000000000..44c879036 --- /dev/null +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/commands/DiagramModelObjectLineStyleCommand.java @@ -0,0 +1,24 @@ +/** + * This program and the accompanying materials + * are made available under the terms of the License + * which accompanies this distribution in the file LICENSE.txt + */ +package com.archimatetool.editor.diagram.commands; + +import com.archimatetool.editor.model.commands.FeatureCommand; +import com.archimatetool.model.IDiagramModelObject; + + + +/** + * Line Style Command + * + * @author Phillip Beauvoir + */ +public class DiagramModelObjectLineStyleCommand extends FeatureCommand { + + public DiagramModelObjectLineStyleCommand(IDiagramModelObject object, int style) { + super("Change Line Style", object, + IDiagramModelObject.FEATURE_LINE_STYLE, style, IDiagramModelObject.FEATURE_LINE_STYLE_DEFAULT); + } +} \ No newline at end of file diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractDiagramModelObjectFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractDiagramModelObjectFigure.java index bd6db9993..a1a94d4a9 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractDiagramModelObjectFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractDiagramModelObjectFigure.java @@ -142,6 +142,27 @@ protected void setDisabledState(Graphics graphics) { //graphics.setLineStyle(SWT.LINE_DASH); //graphics.setLineDash(new int[] { 4, 3 }); } + + /** + * Set the line style + * @param graphics + */ + protected void setLineStyle(Graphics graphics) { + double scale = Math.min(FigureUtils.getFigureScale(this), 1.0); // only scale below 1.0 + + switch(getLineStyle()) { + case IDiagramModelObject.LINE_STYLE_SOLID: + default: + graphics.setLineStyle(Graphics.LINE_SOLID); + break; + case IDiagramModelObject.LINE_STYLE_DASHED: + graphics.setLineDash(new float[] { (float)(8 * scale), (float)(4 * scale) }); + break; + case IDiagramModelObject.LINE_STYLE_DOTTED: + graphics.setLineDash(new float[] { (float)(2 * scale), (float)(2 * scale) }); + break; + } + } /** * Set the UI @@ -247,6 +268,10 @@ protected int getLineWidth() { return fDiagramModelObject.getLineWidth(); } + protected int getLineStyle() { + return fDiagramModelObject.getLineStyle(); + } + @Override public void updateIconImage() { if(getIconicDelegate() != null) { diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractFigureDelegate.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractFigureDelegate.java index 90b315c84..96dc34cf4 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractFigureDelegate.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/AbstractFigureDelegate.java @@ -129,6 +129,14 @@ protected void setLineWidth(Graphics graphics, int lineWidth, Rectangle bounds) getOwner().setLineWidth(graphics, lineWidth, bounds); } + /** + * Set line style + * @param graphics + */ + protected void setLineStyle(Graphics graphics) { + getOwner().setLineStyle(graphics); + } + /** * Apply a gradient to the given Graphics instance and bounds using current fill color, alpha and gradient settings */ diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/EllipseFigureDelegate.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/EllipseFigureDelegate.java index 7c7a0c1b3..9c91125ea 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/EllipseFigureDelegate.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/EllipseFigureDelegate.java @@ -34,6 +34,8 @@ public void drawFigure(Graphics graphics) { // Line Width setLineWidth(graphics, bounds); + setLineStyle(graphics); + graphics.setAlpha(getAlpha()); if(!isEnabled()) { diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RectangleFigureDelegate.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RectangleFigureDelegate.java index 48e101ae2..8217407cc 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RectangleFigureDelegate.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RectangleFigureDelegate.java @@ -33,6 +33,8 @@ public void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + + setLineStyle(graphics); graphics.setAlpha(getAlpha()); diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RoundedRectangleFigureDelegate.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RoundedRectangleFigureDelegate.java index 5bfddb925..368276d99 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RoundedRectangleFigureDelegate.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/RoundedRectangleFigureDelegate.java @@ -38,6 +38,8 @@ public void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + + setLineStyle(graphics); graphics.setAlpha(getAlpha()); diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/DiagramImageFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/DiagramImageFigure.java index 5e1671867..ea18e069e 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/DiagramImageFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/DiagramImageFigure.java @@ -105,6 +105,8 @@ protected void paintFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + setLineStyle(graphics); + if(fImage != null) { // Faster but no transparency if(useScaledImage) { diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/GroupFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/GroupFigure.java index 50cfd174c..88d134fdc 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/GroupFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/GroupFigure.java @@ -57,6 +57,8 @@ protected void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + setLineStyle(graphics); + graphics.setAlpha(getAlpha()); if(getDiagramModelObject().getBorderType() == IDiagramModelGroup.BORDER_TABBED) { diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/NoteFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/NoteFigure.java index 56b54e9c0..72a236816 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/NoteFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/diagram/NoteFigure.java @@ -116,6 +116,7 @@ protected void paintFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill if(getDiagramModelObject().getBorderType() != IDiagramModelNote.BORDER_NONE) { setLineWidth(graphics, bounds); + setLineStyle(graphics); } // Fill diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/AbstractMotivationFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/AbstractMotivationFigure.java index cef3eb625..0d7f4071b 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/AbstractMotivationFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/AbstractMotivationFigure.java @@ -44,6 +44,8 @@ protected void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + + setLineStyle(graphics); PointList points = new PointList(); points.addPoint(bounds.x + FLANGE, bounds.y); diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/GroupingFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/GroupingFigure.java index 5e8331980..ebd4c7787 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/GroupingFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/elements/GroupingFigure.java @@ -61,10 +61,7 @@ protected void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); - // Scale line dashes below 1.0 - double scale = Math.min(FigureUtils.getGraphicsScale(graphics), 1.0); - - graphics.setLineDash(new float[] { (float)(8 * scale), (float)(4 * scale) }); + setLineStyle(graphics); graphics.setBackgroundColor(getFillColor()); graphics.setForegroundColor(getLineColor()); diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/sketch/figures/StickyFigure.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/sketch/figures/StickyFigure.java index 2831535ed..66caf75d9 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/sketch/figures/StickyFigure.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/sketch/figures/StickyFigure.java @@ -50,6 +50,8 @@ protected void drawFigure(Graphics graphics) { // Set line width here so that the whole figure is constrained, otherwise SVG graphics will have overspill setLineWidth(graphics, bounds); + + setLineStyle(graphics); graphics.setBackgroundColor(getFillColor()); diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/tools/FormatPainterTool.java b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/tools/FormatPainterTool.java index 9f768a186..a2d7e2b74 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/diagram/tools/FormatPainterTool.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/diagram/tools/FormatPainterTool.java @@ -212,6 +212,14 @@ CompoundCommand createCommand(IDiagramModelComponent targetComponent) { result.add(cmd); } + // Line Style + if(targetUIProvider != null && targetUIProvider.shouldExposeFeature(IDiagramModelObject.FEATURE_LINE_STYLE)) { + cmd = new FeatureCommand("", target, IDiagramModelObject.FEATURE_LINE_STYLE, source.getLineStyle(), IDiagramModelObject.FEATURE_LINE_STYLE_DEFAULT); //$NON-NLS-1$ + if(cmd.canExecute()) { + result.add(cmd); + } + } + // Gradient if(targetUIProvider != null && targetUIProvider.shouldExposeFeature(IDiagramModelObject.FEATURE_GRADIENT)) { cmd = new FeatureCommand("", target, IDiagramModelObject.FEATURE_GRADIENT, source.getGradient(), IDiagramModelObject.FEATURE_GRADIENT_DEFAULT); //$NON-NLS-1$ diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/model/compatibility/handlers/LineStyleHandler.java b/com.archimatetool.editor/src/com/archimatetool/editor/model/compatibility/handlers/LineStyleHandler.java new file mode 100644 index 000000000..6d794cfd5 --- /dev/null +++ b/com.archimatetool.editor/src/com/archimatetool/editor/model/compatibility/handlers/LineStyleHandler.java @@ -0,0 +1,52 @@ +/** + * This program and the accompanying materials + * are made available under the terms of the License + * which accompanies this distribution in the file LICENSE.txt + */ +package com.archimatetool.editor.model.compatibility.handlers; + +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; + +import com.archimatetool.editor.model.compatibility.CompatibilityHandlerException; +import com.archimatetool.editor.model.compatibility.ICompatibilityHandler; +import com.archimatetool.editor.utils.StringUtils; +import com.archimatetool.model.IArchimateModel; +import com.archimatetool.model.IDiagramModelArchimateObject; +import com.archimatetool.model.IDiagramModelObject; +import com.archimatetool.model.IGrouping; + + + +/** + * Convert Grouping line styles to dashed < 5.0.1 + * + * @author Phillip Beauvoir + */ +public class LineStyleHandler implements ICompatibilityHandler { + + @Override + public void fixCompatibility(Resource resource) throws CompatibilityHandlerException { + IArchimateModel model = (IArchimateModel)resource.getContents().get(0); + + if(isVersion(model)) { + setLineStyle(model); + } + } + + private boolean isVersion(IArchimateModel model) { + String version = model.getVersion(); + return version != null && StringUtils.compareVersionNumbers(version, "5.0.1") < 0; //$NON-NLS-1$ + } + + private void setLineStyle(IArchimateModel model) { + for(Iterator iter = model.eAllContents(); iter.hasNext();) { + EObject eObject = iter.next(); + if(eObject instanceof IDiagramModelArchimateObject dmo && dmo.getArchimateConcept() instanceof IGrouping) { + dmo.setLineStyle(IDiagramModelObject.LINE_STYLE_DASHED); + } + } + } +} diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineOpacitySection.java b/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineOpacitySection.java deleted file mode 100644 index ac8fa424c..000000000 --- a/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineOpacitySection.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * This program and the accompanying materials - * are made available under the terms of the License - * which accompanies this distribution in the file LICENSE.txt - */ -package com.archimatetool.editor.propertysections; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.gef.commands.Command; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.PlatformUI; - -import com.archimatetool.editor.diagram.commands.DiagramModelObjectOutlineAlphaCommand; -import com.archimatetool.model.IArchimatePackage; -import com.archimatetool.model.IDiagramModelObject; - - - -/** - * Property Section for Line Opacity - * - * @author Phillip Beauvoir - */ -public class LineOpacitySection extends AbstractECorePropertySection { - - private static final String HELP_ID = "com.archimatetool.help.elementPropertySection"; //$NON-NLS-1$ - - /** - * Filter to show or reject this section depending on input value - */ - public static class Filter extends ObjectFilter { - @Override - public boolean isRequiredType(Object object) { - return object instanceof IDiagramModelObject dmo && shouldExposeFeature(dmo, IDiagramModelObject.FEATURE_LINE_ALPHA); - } - - @Override - public Class getAdaptableType() { - return IDiagramModelObject.class; - } - } - - private OpacityComposite fOpacityComposite; - - @Override - protected void createControls(Composite parent) { - fOpacityComposite = new OpacityComposite(this, parent, Messages.LineOpacitySection_0) { - @Override - Command getCommand(IDiagramModelObject dmo, int newValue) { - return new DiagramModelObjectOutlineAlphaCommand(dmo, newValue); - } - - @Override - int getValue() { - IDiagramModelObject lastSelected = (IDiagramModelObject)getFirstSelectedObject(); - return lastSelected.getLineAlpha(); - } - - @Override - boolean isValidObject(EObject eObject) { - return getFilter().isRequiredType(eObject); - } - }; - - // Help ID - PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, HELP_ID); - } - - @Override - protected void notifyChanged(Notification msg) { - Object feature = msg.getFeature(); - - if(isFeatureNotification(msg, IDiagramModelObject.FEATURE_LINE_ALPHA)) { - if(!fIsExecutingCommand) { - update(); - } - } - else if(feature == IArchimatePackage.Literals.LOCKABLE__LOCKED) { - update(); - } - } - - @Override - protected void update() { - fOpacityComposite.updateControl(); - } - - @Override - protected IObjectFilter getFilter() { - return new Filter(); - } - - @Override - public void dispose() { - super.dispose(); - - if(fOpacityComposite != null) { - fOpacityComposite.dispose(); - fOpacityComposite = null; - } - } -} diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineSection2.java b/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineSection2.java new file mode 100644 index 000000000..72c801bb0 --- /dev/null +++ b/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineSection2.java @@ -0,0 +1,155 @@ +/** + * This program and the accompanying materials + * are made available under the terms of the License + * which accompanies this distribution in the file LICENSE.txt + */ +package com.archimatetool.editor.propertysections; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.commands.Command; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; + +import com.archimatetool.editor.diagram.commands.DiagramModelObjectOutlineAlphaCommand; +import com.archimatetool.model.IArchimatePackage; +import com.archimatetool.model.IDiagramModelObject; + + + +/** + * Property Section for Line Opacity and Line Style + * + * @author Phillip Beauvoir + */ +public class LineSection2 extends AbstractMultiControlSection { + + private static final String HELP_ID = "com.archimatetool.help.elementPropertySection"; //$NON-NLS-1$ + + /** + * Filter to show or reject this section depending on input value + */ + public static class Filter extends ObjectFilter { + @Override + public boolean isRequiredType(Object object) { + return object instanceof IDiagramModelObject dmo && + (shouldExposeFeature(dmo, IDiagramModelObject.FEATURE_LINE_ALPHA) || + shouldExposeFeature(dmo, IDiagramModelObject.FEATURE_LINE_STYLE)); + } + + @Override + public Class getAdaptableType() { + return IDiagramModelObject.class; + } + } + + private OpacityComposite opacityComposite; + private LineStyleComposite linestyleComposite; + + @Override + protected void createControls(Composite parent) { + init(parent, 2); + + // Help ID + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, HELP_ID); + } + + @Override + protected void notifyChanged(Notification msg) { + Object feature = msg.getFeature(); + + if(isFeatureNotification(msg, IDiagramModelObject.FEATURE_LINE_ALPHA)) { + if(!fIsExecutingCommand) { + updateOpacityControl(); + } + } + else if(isFeatureNotification(msg, IDiagramModelObject.FEATURE_LINE_STYLE)) { + updateLineStyleControl(); + } + else if(feature == IArchimatePackage.Literals.LOCKABLE__LOCKED) { + update(); + } + } + + @Override + protected void update() { + updateOpacityControl(); + updateLineStyleControl(); + } + + private void updateOpacityControl() { + boolean show = shouldShowControl(IDiagramModelObject.FEATURE_LINE_ALPHA); + + if(show) { + if(opacityComposite == null) { + opacityComposite = new OpacityComposite(this, parentComposite, Messages.LineOpacitySection_0) { + @Override + Command getCommand(IDiagramModelObject dmo, int newValue) { + return new DiagramModelObjectOutlineAlphaCommand(dmo, newValue); + } + + @Override + int getValue() { + IDiagramModelObject lastSelected = (IDiagramModelObject)getFirstSelectedObject(); + return lastSelected.getLineAlpha(); + } + + @Override + boolean isValidObject(EObject eObject) { + return getFilter().shouldExposeFeature(eObject, IDiagramModelObject.FEATURE_LINE_ALPHA); + } + }; + + // If we're showing the LineStyleComposite move the OpacityComposite above/before it + if(linestyleComposite != null) { + opacityComposite.getComposite().moveAbove(linestyleComposite.getComposite()); + layout(); + } + } + + opacityComposite.updateControl(); + } + else if(opacityComposite != null) { + opacityComposite.dispose(); + opacityComposite = null; + layout(); + } + } + + private void updateLineStyleControl() { + boolean show = shouldShowControl(IDiagramModelObject.FEATURE_LINE_STYLE); + + if(show) { + if(linestyleComposite == null) { + linestyleComposite = new LineStyleComposite(this, parentComposite); + layout(); + } + linestyleComposite.updateControl(); + } + else if(linestyleComposite != null) { + linestyleComposite.dispose(); + linestyleComposite = null; + layout(); + } + } + + @Override + protected IObjectFilter getFilter() { + return new Filter(); + } + + @Override + public void dispose() { + super.dispose(); + + if(opacityComposite != null) { + opacityComposite.dispose(); + opacityComposite = null; + } + + if(linestyleComposite != null) { + linestyleComposite.dispose(); + linestyleComposite = null; + } + } +} diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineStyleComposite.java b/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineStyleComposite.java new file mode 100644 index 000000000..24b38c09b --- /dev/null +++ b/com.archimatetool.editor/src/com/archimatetool/editor/propertysections/LineStyleComposite.java @@ -0,0 +1,136 @@ +/** + * This program and the accompanying materials + * are made available under the terms of the License + * which accompanies this distribution in the file LICENSE.txt + */ +package com.archimatetool.editor.propertysections; + +import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.commands.CompoundCommand; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; + +import com.archimatetool.editor.diagram.commands.DiagramModelObjectLineStyleCommand; +import com.archimatetool.editor.ui.IArchiImages; +import com.archimatetool.model.IDiagramModelObject; + + + +/** + * Diagram Object Line Style Composite + * + * @author Phillip Beauvoir + */ +class LineStyleComposite { + + private Button button; + private AbstractECorePropertySection section; + private Composite composite; + + LineStyleComposite(AbstractECorePropertySection section, Composite parent) { + this.section = section; + composite = section.createComposite(parent, 2, false); + createControls(composite); + } + + Composite getComposite() { + return composite; + } + + private void createControls(Composite parent) { + section.createLabel(parent, "Line Style:", ITabbedLayoutConstants.STANDARD_LABEL_WIDTH, SWT.CENTER); + + button = section.getWidgetFactory().createButton(parent, null, SWT.PUSH); + button.setLayoutData(GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).create()); // a bit more width + + button.addSelectionListener(widgetSelectedAdapter(event -> { + MenuManager menuManager = new MenuManager(); + + menuManager.add(createAction("Solid", IDiagramModelObject.LINE_STYLE_SOLID, IArchiImages.ImageFactory.getImageDescriptor(IArchiImages.LINE_SOLID))); + menuManager.add(createAction("Dashed", IDiagramModelObject.LINE_STYLE_DASHED, IArchiImages.ImageFactory.getImageDescriptor(IArchiImages.LINE_DASHED))); + menuManager.add(createAction("Dotted", IDiagramModelObject.LINE_STYLE_DOTTED, IArchiImages.ImageFactory.getImageDescriptor(IArchiImages.LINE_DOTTED))); + + Menu menu = menuManager.createContextMenu(button.getShell()); + Rectangle buttonBounds = button.getBounds(); + Point p = button.getParent().toDisplay(buttonBounds.x, buttonBounds.y + buttonBounds.height); + menu.setLocation(p); + menu.setVisible(true); + })); + } + + private IAction createAction(String text, final int value, final ImageDescriptor imageDesc) { + IAction action = new Action(text, IAction.AS_RADIO_BUTTON) { + @Override + public void run() { + CompoundCommand result = new CompoundCommand(); + + for(EObject object : section.getEObjects()) { + if(isValidObject(object)) { + Command cmd = new DiagramModelObjectLineStyleCommand((IDiagramModelObject)object, value); + if(cmd.canExecute()) { + result.add(cmd); + } + } + } + + section.executeCommand(result.unwrap()); + } + + @Override + public ImageDescriptor getImageDescriptor() { + return imageDesc; + } + }; + + action.setChecked(((IDiagramModelObject)section.getFirstSelectedObject()).getLineStyle() == value); + + return action; + } + + /** + * In case of multi-selection we should check this + */ + private boolean isValidObject(EObject eObject) { + return section.isAlive(eObject) && + section.getFilter().shouldExposeFeature(eObject, IDiagramModelObject.FEATURE_LINE_STYLE); + } + + void updateControl() { + IDiagramModelObject dmo = (IDiagramModelObject)section.getFirstSelectedObject(); + int lineStyle = dmo.getLineStyle(); + + switch(lineStyle) { + case IDiagramModelObject.LINE_STYLE_SOLID: + default: + button.setImage(IArchiImages.ImageFactory.getImage(IArchiImages.LINE_SOLID)); + break; + case IDiagramModelObject.LINE_STYLE_DASHED: + button.setImage(IArchiImages.ImageFactory.getImage(IArchiImages.LINE_DASHED)); + break; + case IDiagramModelObject.LINE_STYLE_DOTTED: + button.setImage(IArchiImages.ImageFactory.getImage(IArchiImages.LINE_DOTTED)); + break; + } + + button.setEnabled(!section.isLocked(dmo)); + } + + void dispose() { + composite.dispose(); + composite = null; + section = null; + button = null; + } +} diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/diagram/DiagramImageUIProvider.java b/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/diagram/DiagramImageUIProvider.java index b1823924f..c7ac2cda4 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/diagram/DiagramImageUIProvider.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/diagram/DiagramImageUIProvider.java @@ -67,7 +67,8 @@ public boolean shouldExposeFeature(String featureName) { return featureName == IArchimatePackage.Literals.BORDER_OBJECT__BORDER_COLOR.getName() || featureName == IArchimatePackage.Literals.LINE_OBJECT__LINE_WIDTH.getName() || featureName == IArchimatePackage.Literals.DIAGRAM_MODEL_OBJECT__ALPHA.getName() - || featureName == IDiagramModelObject.FEATURE_LINE_ALPHA; + || featureName == IDiagramModelObject.FEATURE_LINE_ALPHA + || featureName == IDiagramModelObject.FEATURE_LINE_STYLE; } } diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/sketch/SketchActorUIProvider.java b/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/sketch/SketchActorUIProvider.java index 0ad30e4d5..b7bbe6cfa 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/sketch/SketchActorUIProvider.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/ui/factory/sketch/SketchActorUIProvider.java @@ -70,7 +70,8 @@ public boolean shouldExposeFeature(String featureName) { featureName == IDiagramModelObject.FEATURE_DERIVE_ELEMENT_LINE_COLOR || featureName == IDiagramModelObject.FEATURE_LINE_ALPHA || featureName == IArchimatePackage.Literals.DIAGRAM_MODEL_OBJECT__ALPHA.getName() || - featureName == IDiagramModelObject.FEATURE_GRADIENT) { + featureName == IDiagramModelObject.FEATURE_GRADIENT || + featureName == IDiagramModelObject.FEATURE_LINE_STYLE) { return false; } diff --git a/com.archimatetool.model/src/com/archimatetool/model/IDiagramModelObject.java b/com.archimatetool.model/src/com/archimatetool/model/IDiagramModelObject.java index f421d000e..4cbdaebdc 100644 --- a/com.archimatetool.model/src/com/archimatetool/model/IDiagramModelObject.java +++ b/com.archimatetool.model/src/com/archimatetool/model/IDiagramModelObject.java @@ -45,6 +45,12 @@ public interface IDiagramModelObject extends IConnectable, IFontAttribute, ILine String FEATURE_DERIVE_ELEMENT_LINE_COLOR = "deriveElementLineColor"; boolean FEATURE_DERIVE_ELEMENT_LINE_COLOR_DEFAULT = true; + String FEATURE_LINE_STYLE = "lineStyle"; + int FEATURE_LINE_STYLE_DEFAULT = 0; + int LINE_STYLE_SOLID = 0; + int LINE_STYLE_DASHED = 1; + int LINE_STYLE_DOTTED = 2; + /** * @return the value of FEATURE_LINE_ALPHA */ @@ -100,6 +106,17 @@ public interface IDiagramModelObject extends IConnectable, IFontAttribute, ILine */ void setDeriveElementLineColor(boolean value); + /** + * @return the value of feature FEATURE_LINE_STYLE + */ + int getLineStyle(); + + /** + * Set the value of feature FEATURE_LINE_STYLE + * @param lineStyle + */ + void setLineStyle(int lineStyle); + /** * Returns the value of the 'Bounds' containment reference. * diff --git a/com.archimatetool.model/src/com/archimatetool/model/ModelVersion.java b/com.archimatetool.model/src/com/archimatetool/model/ModelVersion.java index 47333fb07..1995762c1 100644 --- a/com.archimatetool.model/src/com/archimatetool/model/ModelVersion.java +++ b/com.archimatetool.model/src/com/archimatetool/model/ModelVersion.java @@ -11,13 +11,12 @@ * Use this to determine when loading a different version model if it will bring the whole * show down. Example, folders were introduced in version 1.3 of Archi but won't open in Archi 1.2.

* - * PLEASE NOTE - THIS IS THE VERSION OF THE MODEL, NOT ARCHI. - * As from Archi version 2.6.0 I will try to keep the model version number the same as Archi's version number when the model version is incremented. + * PLEASE NOTE - THIS IS THE VERSION OF THE INTERNAL MODEL, NOT ARCHI. * Only need to change the model version number if there are changes that affect backwards compatibility.

+ *

+ * History:
  * 
- * History:
- * - * 1.0.0 - Archi versions 0.7 - 1.2.0 the version number was not saved to the XMI file
+ * 1.0.0 - Archi versions 0.7 - 1.2.0 the version number was not saved to the XMI file * 1.1.0 - Archi version 1.3.0 introduced sub-folders which are not backwards-compatible * 1.1.1 - Archi version 1.4.0 added sub-folders in the Views folder which are not backwards-compatible * 1.2.0 - Archi version 1.5.0 added the Sketch View which is not backwards-compatible, and text alignment attribute @@ -51,9 +50,11 @@ * - Add images to IDiagramModelArchimateObject * - Refactor IDiagramModelImageProvider, IIconic and more... * 5.0.0 - ArchiMate 3.2 + * 5.0.1 - Line styles on diagram objects. Grouping figure has to be set to dashed lines. * + *
* @author Phillip Beauvoir */ public interface ModelVersion { - String VERSION = "5.0.0"; //$NON-NLS-1$ + String VERSION = "5.0.1"; //$NON-NLS-1$ } diff --git a/com.archimatetool.model/src/com/archimatetool/model/impl/DiagramModelObject.java b/com.archimatetool.model/src/com/archimatetool/model/impl/DiagramModelObject.java index cbf6d6183..c317a0d84 100644 --- a/com.archimatetool.model/src/com/archimatetool/model/impl/DiagramModelObject.java +++ b/com.archimatetool.model/src/com/archimatetool/model/impl/DiagramModelObject.java @@ -261,6 +261,16 @@ public void setDeriveElementLineColor(boolean value) { getFeatures().putBoolean(FEATURE_DERIVE_ELEMENT_LINE_COLOR, value, FEATURE_DERIVE_ELEMENT_LINE_COLOR_DEFAULT); } + @Override + public int getLineStyle() { + return getFeatures().getInt(FEATURE_LINE_STYLE, FEATURE_LINE_STYLE_DEFAULT); + } + + @Override + public void setLineStyle(int lineStyle) { + getFeatures().putInt(FEATURE_LINE_STYLE, lineStyle, FEATURE_LINE_STYLE_DEFAULT); + } + /** * * diff --git a/tests/com.archimatetool.model.tests/src/com/archimatetool/model/impl/DiagramModelObjectTests.java b/tests/com.archimatetool.model.tests/src/com/archimatetool/model/impl/DiagramModelObjectTests.java index 08867a184..3aed579c7 100644 --- a/tests/com.archimatetool.model.tests/src/com/archimatetool/model/impl/DiagramModelObjectTests.java +++ b/tests/com.archimatetool.model.tests/src/com/archimatetool/model/impl/DiagramModelObjectTests.java @@ -159,6 +159,13 @@ public void testGetLineColor() { assertEquals("#ffffff", object.getLineColor()); } + @Test + public void testGetLineStyle() { + assertEquals(0, object.getLineStyle()); + object.setLineStyle(1); + assertEquals(1, object.getLineStyle()); + } + @Test public void testAddConnection_Null_ThrowsException() { assertThrows(IllegalArgumentException.class, () -> {