diff options
| author | Camille Letavernier | 2017-08-08 08:42:36 +0000 |
|---|---|---|
| committer | Camille Letavernier | 2017-08-08 14:05:53 +0000 |
| commit | 2837e7e609192950a465e9894267329d9f448276 (patch) | |
| tree | 7c427eaba8934f705c92c3912c78a48d7fa59b9c | |
| parent | 7210a51216943c69261dbf5e34af08c42870823e (diff) | |
| download | org.eclipse.papyrus-2837e7e609192950a465e9894267329d9f448276.tar.gz org.eclipse.papyrus-2837e7e609192950a465e9894267329d9f448276.tar.xz org.eclipse.papyrus-2837e7e609192950a465e9894267329d9f448276.zip | |
Bug 450844: [ClassDiagram] Change property order directly in diagram
https://bugs.eclipse.org/bugs/show_bug.cgi?id=450844
Change-Id: Ib53b438bfe69b914fd1f503793bdc033e3b62963
Signed-off-by: Camille Letavernier <cletavernier@eclipsesource.com>
(cherry picked from commit b14610ecb43b00fd7c7f554b22855ebb91073400)
14 files changed, 523 insertions, 191 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.classpath b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.classpath index 2d1a4302f04..eca7bdba8f0 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.classpath +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.classpath @@ -1,7 +1,7 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/.api_filters b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/.api_filters new file mode 100644 index 00000000000..d9de1851278 --- /dev/null +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/.api_filters @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.papyrus.infra.gmfdiag.dnd" version="2"> + <resource path="src/org/eclipse/papyrus/infra/gmfdiag/dnd/strategy/DropStrategy.java" type="org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy"> + <filter comment="New API with default implementation" id="404000815"> + <message_arguments> + <message_argument value="org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy"/> + <message_argument value="eraseTargetFeedback(Request, EditPart)"/> + </message_arguments> + </filter> + <filter comment="New API with default implementation" id="404000815"> + <message_arguments> + <message_argument value="org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy"/> + <message_argument value="showTargetFeedback(Request, EditPart)"/> + </message_arguments> + </filter> + </resource> +</component> diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/org.eclipse.jdt.core.prefs b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/org.eclipse.jdt.core.prefs index 4759947300a..62a08f4494d 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/META-INF/MANIFEST.MF b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/META-INF/MANIFEST.MF index cbe2a217101..91c70790701 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/META-INF/MANIFEST.MF +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/META-INF/MANIFEST.MF @@ -6,9 +6,9 @@ Require-Bundle: org.eclipse.papyrus.infra.gmfdiag.common;bundle-version="[3.0.0, org.eclipse.papyrus.infra.emf;bundle-version="[3.0.0,4.0.0)"
Bundle-Vendor: Eclipse Modeling Project
Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.3.0.qualifier
Bundle-Name: Customizable Drag and Drop
Bundle-Activator: org.eclipse.papyrus.infra.gmfdiag.dnd.Activator
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.papyrus.infra.gmfdiag.dnd;singleton:=true
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/pom.xml b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/pom.xml index 5a16a050190..6aef04693b7 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/pom.xml +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/pom.xml @@ -8,6 +8,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.gmfdiag.dnd</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>1.3.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/policy/CustomizableDropEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/policy/CustomizableDropEditPolicy.java index 36dffd84eaf..2c1df9d6650 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/policy/CustomizableDropEditPolicy.java +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/policy/CustomizableDropEditPolicy.java @@ -28,6 +28,7 @@ import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; import org.eclipse.gef.commands.Command; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.common.core.command.ICommand; @@ -56,7 +57,7 @@ import org.eclipse.ui.PlatformUI; * An EditPolicy to handle Drop in Papyrus diagrams. * This edit policy can be customized from an extension point. If a customization * is not available, it will delegate the behavior to the default Drop edit policy - * + * * Update: it will enable to manage multiple commands per strategy * * @author Camille Letavernier @@ -105,8 +106,8 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { command = getCustomCommand(request); } } else if (this.understands(request)) { - // Add request - command = getCreationCommand(request); + // Add or Move children request + command = getCustomCommand(request); } else if (defaultCreationEditPolicy != null) { // Creation request if (defaultCreationEditPolicy.understandsRequest(request)) { @@ -137,13 +138,17 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { } protected boolean understands(Request request) { - return org.eclipse.gef.RequestConstants.REQ_ADD.equals(request.getType()); + return org.eclipse.gef.RequestConstants.REQ_ADD.equals(request.getType()) || RequestConstants.REQ_MOVE_CHILDREN.equals(request.getType()); } protected boolean isCustomRequest(Request request) { return !findStrategies(request).isEmpty(); } + /** + * @deprecated Use {@link #getCustomCommand(Request)} + */ + @Deprecated protected Command getCreationCommand(Request request) { return getCustomCommand(request); } @@ -229,10 +234,10 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { * @return */ protected Command getCustomCommand(Request request) { - //extendedMatchingStrategies match Strategy to List of Commands + // extendedMatchingStrategies match Strategy to List of Commands final Map<DropStrategy, List<Command>> extendedMatchingStrategies = findExtendedStrategies(request); - //Reverting to a simple matchingStrategies a strategy to a command + // Reverting to a simple matchingStrategies a strategy to a command final Map<DropStrategy, Command> matchingStrategies = getStrategies(extendedMatchingStrategies); boolean useDefault = true; @@ -250,7 +255,7 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { if (useDefault) { DropStrategy dropStrategy = DropStrategyManager.instance.getDefaultDropStrategy(matchingStrategies.keySet()); if (dropStrategy != null) { - return getValidCommand(dropStrategy, request,extendedMatchingStrategies,matchingStrategies); + return getValidCommand(dropStrategy, request, extendedMatchingStrategies, matchingStrategies); } } @@ -260,6 +265,7 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { DefaultActionHandler handler = new DefaultActionHandler() { + @Override public void defaultActionSelected(Command defaultCommand) { DropStrategy defaultStrategy = findExtendedStrategy(extendedMatchingStrategies, defaultCommand); if (defaultStrategy != null) { @@ -267,34 +273,33 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { } } + @Override public String getLabel() { return "Change the default strategy"; } }; - //Fill the proposalCommands to cover multiple drop strategies and normal drop strategies - List<Command> proposalCommands = new ArrayList<Command>(); - Command initialValidCommand=null; - for(List<Command> cs: extendedMatchingStrategies.values()){ - for(Command c : cs){ + // Fill the proposalCommands to cover multiple drop strategies and normal drop strategies + List<Command> proposalCommands = new ArrayList<>(); + Command initialValidCommand = null; + for (List<Command> cs : extendedMatchingStrategies.values()) { + for (Command c : cs) { if (c != null && c.canExecute()) { - initialValidCommand=c; + initialValidCommand = c; proposalCommands.add(c); } } } - if(proposalCommands.size()==0){ + if (proposalCommands.size() == 0) { // Finally no command return null; - } - else if(proposalCommands.size()==1){ + } else if (proposalCommands.size() == 1) { // Finally one command return initialValidCommand; - } - else if(proposalCommands.size()>1){ + } else if (proposalCommands.size() > 1) { // Finally multiple matching commands - Activator.log.debug("proposalCommands size: "+proposalCommands.size()); - SelectAndExecuteCommand command = new SelectAndExecuteCommand("Select drop", shell, new ArrayList<Command>(proposalCommands), handler); + Activator.log.debug("proposalCommands size: " + proposalCommands.size()); + SelectAndExecuteCommand command = new SelectAndExecuteCommand("Select drop", shell, new ArrayList<>(proposalCommands), handler); return new ICommandProxy(command); } @@ -303,67 +308,70 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { } /** - * @param dropStrategy a dropStrategy - * @param request the request - * @param extendedMatchingStrategies the matching drop strategies with their list of command - * @param matchingStrategies a command in regard of each matching strategy + * @param dropStrategy + * a dropStrategy + * @param request + * the request + * @param extendedMatchingStrategies + * the matching drop strategies with their list of command + * @param matchingStrategies + * a command in regard of each matching strategy * @return */ private Command getValidCommand(DropStrategy dropStrategy, Request request, final Map<DropStrategy, List<Command>> extendedMatchingStrategies, final Map<DropStrategy, Command> matchingStrategies) { - if(dropStrategy instanceof MultipleDropStrategy){ - //the return strategy is a multiple command - List<Command> proposalCommands = new ArrayList<Command>(); - List<Command> cs = ((MultipleDropStrategy)dropStrategy).getCommands(request, getHost()); - Command initialValideCommand=null; - for(Command command : cs){ + if (dropStrategy instanceof MultipleDropStrategy) { + // the return strategy is a multiple command + List<Command> proposalCommands = new ArrayList<>(); + List<Command> cs = ((MultipleDropStrategy) dropStrategy).getCommands(request, getHost()); + Command initialValideCommand = null; + for (Command command : cs) { if (command != null && command.canExecute()) { - initialValideCommand=command; + initialValideCommand = command; proposalCommands.add(command); } } - if(proposalCommands.size()==0){ + if (proposalCommands.size() == 0) { // Finally no matching command return null; - } - else if(proposalCommands.size()==1){ + } else if (proposalCommands.size() == 1) { // Finally one matching command return initialValideCommand; - } - else{ + } else { // Finally more than one matching command Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); DefaultActionHandler handler = new DefaultActionHandler() { + @Override public void defaultActionSelected(Command defaultCommand) { - //At present time, no default command for MultipleDropStrategy + // At present time, no default command for MultipleDropStrategy DropStrategy defaultStrategy = findExtendedStrategy(extendedMatchingStrategies, defaultCommand); if (defaultStrategy != null) { DropStrategyManager.instance.setDefaultDropStrategy(matchingStrategies.keySet(), defaultStrategy); } } + @Override public String getLabel() { return "Change the default strategy"; } }; - Activator.log.debug("proposalCommands size: "+proposalCommands.size()); - SelectAndExecuteCommand command = new SelectAndExecuteCommand("Select drop", shell, new ArrayList<Command>(proposalCommands), handler); + Activator.log.debug("proposalCommands size: " + proposalCommands.size()); + SelectAndExecuteCommand command = new SelectAndExecuteCommand("Select drop", shell, new ArrayList<>(proposalCommands), handler); return new ICommandProxy(command); } - } - else{ - //The return strategy is a simple strategy + } else { + // The return strategy is a simple strategy return matchingStrategies.get(dropStrategy); } } protected static DropStrategy findStrategy(Map<DropStrategy, Command> matchingStrategies, Command command) { for (Map.Entry<DropStrategy, Command> entry : matchingStrategies.entrySet()) { - if (entry.getValue() == command ) { + if (entry.getValue() == command) { return entry.getKey(); } } @@ -383,14 +391,15 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { /** * Returns a map of DropStrategy / Command, from an initial Map that maps DropStrategy to List of commands. The map may be empty. * - * @param Map<DropStrategy, List<Command>> + * @param Map<DropStrategy, + * List<Command>> * @return */ protected Map<DropStrategy, Command> getStrategies(Map<DropStrategy, List<Command>> extendedMatchingStrategies) { - Map<DropStrategy, Command> matchingStrategies = new LinkedHashMap<DropStrategy, Command>(); - for(DropStrategy d : extendedMatchingStrategies.keySet()){ + Map<DropStrategy, Command> matchingStrategies = new LinkedHashMap<>(); + for (DropStrategy d : extendedMatchingStrategies.keySet()) { Iterator<Command> i = extendedMatchingStrategies.get(d).iterator(); - if(i.hasNext()){ + if (i.hasNext()) { matchingStrategies.put(d, i.next()); } } @@ -405,22 +414,21 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { * @return */ protected Map<DropStrategy, Command> findStrategies(Request request) { - Map<DropStrategy, Command> matchingStrategies = new LinkedHashMap<DropStrategy, Command>(); + Map<DropStrategy, Command> matchingStrategies = new LinkedHashMap<>(); for (DropStrategy strategy : DropStrategyManager.instance.getActiveStrategies()) { try { // Strategies are provided through extension points; we can't guarantee they won't crash - if(strategy instanceof MultipleDropStrategy){ - List<Command> commands = ((MultipleDropStrategy)strategy).getCommands(request, getHost()); - if (commands != null && commands.size()>0) { - //take the first one, and fill the map withit - Command command =commands.get(0); + if (strategy instanceof MultipleDropStrategy) { + List<Command> commands = ((MultipleDropStrategy) strategy).getCommands(request, getHost()); + if (commands != null && commands.size() > 0) { + // take the first one, and fill the map withit + Command command = commands.get(0); if (command != null && command.canExecute()) { matchingStrategies.put(strategy, command); } } - } - else{ + } else { Command command = strategy.getCommand(request, getHost()); if (command != null && command.canExecute()) { @@ -449,38 +457,37 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { * @return */ protected Map<DropStrategy, List<Command>> findExtendedStrategies(Request request) { - Map<DropStrategy, List<Command>> matchingStrategies = new LinkedHashMap<DropStrategy, List<Command>>(); + Map<DropStrategy, List<Command>> matchingStrategies = new LinkedHashMap<>(); - //Retrieve strategies + // Retrieve strategies for (DropStrategy strategy : DropStrategyManager.instance.getActiveStrategies()) { - List<Command> selectedCommands = new ArrayList<Command>(); + List<Command> selectedCommands = new ArrayList<>(); - if(strategy instanceof TransactionalCommandsDropStrategy){ - List<Command> cs = ((TransactionalCommandsDropStrategy)strategy).getCommands(request, getHost()); - for(Command command : cs){ + if (strategy instanceof TransactionalCommandsDropStrategy) { + List<Command> cs = ((TransactionalCommandsDropStrategy) strategy).getCommands(request, getHost()); + for (Command command : cs) { if (command != null && command.canExecute()) { selectedCommands.add(command); } } - } - else{ + } else { Command command = strategy.getCommand(request, getHost()); if (command != null && command.canExecute()) { selectedCommands.add(command); } } - if(selectedCommands.size()>0){ + if (selectedCommands.size() > 0) { matchingStrategies.put(strategy, selectedCommands); } } - //Retrieve defaultStrategy + // Retrieve defaultStrategy Command command = defaultDropStrategy.getCommand(request, getHost()); if (command != null && command.canExecute()) { - List<Command> selectedCommands = new ArrayList<Command>(); + List<Command> selectedCommands = new ArrayList<>(); selectedCommands.add(command); matchingStrategies.put(defaultDropStrategy, selectedCommands); } @@ -494,23 +501,44 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { */ @Override public void showTargetFeedback(Request request) { - if (defaultCreationEditPolicy != null && defaultCreationEditPolicy.understandsRequest(request)) { - defaultCreationEditPolicy.showTargetFeedback(request); + + final Map<DropStrategy, List<Command>> matchingStrategies = findExtendedStrategies(request); + + boolean updateFeedback = true; + for (Map.Entry<DropStrategy, List<Command>> dropEntry : matchingStrategies.entrySet()) { + if (dropEntry.getKey().showTargetFeedback(request, getHost())) { + updateFeedback = false; + } } - if (!(getHost() instanceof DiagramEditPart)) { - super.showTargetFeedback(request); + if (updateFeedback) { + + if (defaultCreationEditPolicy != null && defaultCreationEditPolicy.understandsRequest(request)) { + defaultCreationEditPolicy.showTargetFeedback(request); + } + + if (!(getHost() instanceof DiagramEditPart)) { + super.showTargetFeedback(request); + } } } @Override public void eraseTargetFeedback(Request request) { - if (defaultCreationEditPolicy != null) { - defaultCreationEditPolicy.eraseTargetFeedback(request); + boolean updateFeedback = true; + for (DropStrategy strategy : DropStrategyManager.instance.getActiveStrategies()) { + if (strategy.eraseTargetFeedback(request, getHost())) { + updateFeedback = false; + } } - if (!(getHost() instanceof DiagramEditPart)) { - super.eraseTargetFeedback(request); + if (updateFeedback) { + if (defaultCreationEditPolicy != null) { + defaultCreationEditPolicy.eraseTargetFeedback(request); + } + if (!(getHost() instanceof DiagramEditPart)) { + super.eraseTargetFeedback(request); + } } } @@ -528,7 +556,7 @@ public class CustomizableDropEditPolicy extends DragDropEditPolicy { @Override public void eraseSourceFeedback(Request request) { if (defaultCreationEditPolicy != null) { - defaultCreationEditPolicy.showSourceFeedback(request); + defaultCreationEditPolicy.eraseSourceFeedback(request); } if (!(getHost() instanceof DiagramEditPart)) { diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/strategy/DropStrategy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/strategy/DropStrategy.java index 55c3db639f7..54723683436 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/strategy/DropStrategy.java +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.dnd/src/org/eclipse/papyrus/infra/gmfdiag/dnd/strategy/DropStrategy.java @@ -60,7 +60,7 @@ public interface DropStrategy { * @param targetEditPart
* The target edit part
* @return
- * A command, or null if the strategy cannot handle the request
+ * A command, or null if the strategy cannot handle the request
*/
public Command getCommand(Request request, EditPart targetEditPart);
@@ -74,4 +74,38 @@ public interface DropStrategy { @Deprecated
public int getPriority();
+ /**
+ * When this strategy can handle this request, this method can be implemented
+ * to optionally display a visual feedback on the given edit part for this request.
+ *
+ * By default, compartments already support a feedback. Return true to override
+ * the default feedback, false to keep it.
+ *
+ * The feedback should always be erased in {@link #eraseTargetFeedback(Request, EditPart)}
+ *
+ * @param request
+ * @param targetEditPart
+ *
+ * @return true if the default feedback should be overridden, false if it should be preserved
+ *
+ * @since 1.3
+ */
+ public default boolean showTargetFeedback(Request request, EditPart targetEditPart) {
+ return false;
+ }
+
+ /**
+ * Erase any feedback added via {@link #showTargetFeedback(Request, EditPart)}. Note that this method
+ * may be invoked even if {@link #showTargetFeedback(Request, EditPart)} was never called.
+ *
+ * @param request
+ * @param targetEditPart
+ * @return
+ *
+ * @since 1.3
+ */
+ public default boolean eraseTargetFeedback(Request request, EditPart targetEditPart) {
+ return false;
+ }
+
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/figure/node/SubCompartmentLayoutManager.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/figure/node/SubCompartmentLayoutManager.java index 6e857aa5be3..4513ea5fc1b 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/figure/node/SubCompartmentLayoutManager.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/figure/node/SubCompartmentLayoutManager.java @@ -12,103 +12,13 @@ *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.figure.node; -import org.eclipse.draw2d.AbstractLayout; -import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure; - /** * this is the layout manager in charge to place element in compartment element * + * @deprecated since version 3.1 + * Implementation was moved to {@link org.eclipse.papyrus.infra.gmfdiag.common.figure.node.SubCompartmentLayoutManager} */ - -public class SubCompartmentLayoutManager extends AbstractLayout { - - protected final static int MINIMUMCOMPARTMENTSIZE = 15; - - protected final static int MINIMUM_COMPARTMENT_WIDTH = 20; - - protected int preferedHeight = MINIMUMCOMPARTMENTSIZE; - - @Override - protected Dimension calculatePreferredSize(IFigure figure, int wHint, int hHint) { - Dimension dim = new Dimension(10, preferedHeight); - if (!figure.getChildren().isEmpty()) { - Object compartment = figure.getChildren().get(0); - if (compartment instanceof ResizableCompartmentFigure) { - Dimension compartmentPreferredSize = ((ResizableCompartmentFigure) compartment).getPreferredSize(); - dim.height = compartmentPreferredSize.height + 10; - if (dim.height == 0) { - dim.height = 20; - } - dim.width = compartmentPreferredSize.width; - } - } - return dim; - } - - @Override - public Dimension getMinimumSize(IFigure container, int wHint, int hHint) { - return new Dimension(MINIMUM_COMPARTMENT_WIDTH, MINIMUMCOMPARTMENTSIZE); - } - - @Override - public void layout(IFigure container) { - for (int i = 0; i < container.getChildren().size(); i++) { - IFigure child = ((IFigure) container.getChildren().get(i)); - Rectangle bound = new Rectangle(child.getBounds()); - bound.setSize(getPreferedSize(child)); - bound.x = container.getBounds().x; - bound.width = container.getBounds().width; - if (i > 0) { - bound.y = ((IFigure) container.getChildren().get(i - 1)).getBounds().getBottomLeft().y + 1; - } else { - bound.y = container.getBounds().y; - } - child.setBounds(bound); - } - // container - int containersize = container.getChildren().size(); - if (containersize > 0) { - IFigure lastChild = (IFigure) container.getChildren().get(containersize - 1); - Rectangle lastRectangle = lastChild.getBounds(); - lastRectangle.height = container.getBounds().y + container.getBounds().height - lastRectangle.y; - lastRectangle.width = container.getBounds().width; - lastChild.setBounds(lastRectangle); - } - } - - public Dimension getPreferedSize(IFigure figure) { - Dimension dim = new Dimension(10, preferedHeight); - if (figure.getChildren().size() > 0) { - if (figure.getChildren().get(0) instanceof ResizableCompartmentFigure) { - dim.height = ((ResizableCompartmentFigure) figure.getChildren().get(0)).getPreferredSize().height + 10; - if (dim.height == 0) { - dim.height = 20; - } - - } - } - return dim; - } - - /** - * Sets the constraint for the given figure. - * - * @param child - * the child - * @param constraint - * the child's new constraint - */ - @Override - public void setConstraint(IFigure child, Object constraint) { - if (constraint instanceof Rectangle && ((Rectangle) constraint).height > MINIMUMCOMPARTMENTSIZE) { - preferedHeight = ((Rectangle) constraint).height; - } else { - preferedHeight = MINIMUMCOMPARTMENTSIZE; - } - invalidate(child); - } - +@Deprecated +public class SubCompartmentLayoutManager extends org.eclipse.papyrus.infra.gmfdiag.common.figure.node.SubCompartmentLayoutManager { + // Implementation moved to org.eclipse.papyrus.infra.gmfdiag.common.figure.node.SubCompartmentLayoutManager } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.classpath b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.classpath index 098194ca4b7..eca7bdba8f0 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.classpath +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.settings/org.eclipse.jdt.core.prefs b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.settings/org.eclipse.jdt.core.prefs index 9ca8e68231b..62a08f4494d 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/META-INF/MANIFEST.MF b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/META-INF/MANIFEST.MF index 6c799205878..84017435fba 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/META-INF/MANIFEST.MF +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/META-INF/MANIFEST.MF @@ -9,9 +9,9 @@ Require-Bundle: org.eclipse.papyrus.infra.gmfdiag.dnd;bundle-version="[1.2.0,2.0 org.eclipse.papyrus.uml.diagram.clazz;bundle-version="[3.0.0,4.0.0)", org.eclipse.papyrus.uml.diagram.composite;bundle-version="[3.0.0,4.0.0)" Bundle-Vendor: Eclipse Modeling Project -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 1.3.0.qualifier Bundle-Name: UML Drag and Drop Bundle-Activator: org.eclipse.papyrus.uml.diagram.dnd.Activator Bundle-ManifestVersion: 2 diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/plugin.xml b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/plugin.xml index 3797dabcf77..f9de7585a1c 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/plugin.xml +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/plugin.xml @@ -30,5 +30,8 @@ <strategy strategy="org.eclipse.papyrus.uml.diagram.dnd.strategy.PortToTypesPortDropStrategy"> </strategy> + <strategy + strategy="org.eclipse.papyrus.uml.diagram.dnd.strategy.ReorderListItemsStrategy"> + </strategy> </extension> </plugin> diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/pom.xml b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/pom.xml index baa9ec599af..eba05d239f2 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/pom.xml +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/pom.xml @@ -8,6 +8,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.uml.diagram.dnd</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>1.3.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/src/org/eclipse/papyrus/uml/diagram/dnd/strategy/ReorderListItemsStrategy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/src/org/eclipse/papyrus/uml/diagram/dnd/strategy/ReorderListItemsStrategy.java new file mode 100644 index 00000000000..75ddd5dbb07 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.dnd/src/org/eclipse/papyrus/uml/diagram/dnd/strategy/ReorderListItemsStrategy.java @@ -0,0 +1,340 @@ +/***************************************************************************** + * Copyright (c) 2017 EclipseSource and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - Initial API and implementation - Bug 450844 + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.dnd.strategy; + +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.RectangleFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.requests.ChangeBoundsRequest; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.ListCompartmentEditPart; +import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.infra.emf.utils.ResourceUtils; +import org.eclipse.papyrus.infra.gmfdiag.common.helper.NotationHelper; +import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; +import org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.AbstractDropStrategy; +import org.eclipse.papyrus.uml.diagram.common.editparts.UMLCompartmentEditPart; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * Drop strategy to reorder items in a list compartment (e.g. Attributes in a Class) + * + * @since 1.3 + */ +public class ReorderListItemsStrategy extends AbstractDropStrategy { + + private IFigure dropFeedback; + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getLabel() + * + * @return + */ + @Override + public String getLabel() { + return "Reorder list items"; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getDescription() + * + * @return + */ + @Override + public String getDescription() { + return "Reorders items in a list compartment"; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getImage() + * + * @return + */ + @Override + public Image getImage() { + return null; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getID() + * + * @return + */ + @Override + public String getID() { + return "org.eclipse.papyrus.uml.diagram.dnd.strategy.ReorderListItemsStrategy"; + } + + // Drop can happen either on the compartment, or on a child of the compartment (Sibling of the moved element) + // The actual target is always the compartment + private ListCompartmentEditPart getTargetEP(EditPart targetEditPart) { + if (targetEditPart instanceof ListCompartmentEditPart) { + return (ListCompartmentEditPart) targetEditPart; + } else if (targetEditPart.getParent() instanceof ListCompartmentEditPart) { + return (ListCompartmentEditPart) targetEditPart.getParent(); + } + return null; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getCommand(org.eclipse.gef.Request, org.eclipse.gef.EditPart) + * + * @param request + * @param targetEditPart + * @return + */ + @Override + public Command getCommand(Request request, EditPart targetEditPart) { + // We only support diagram-to-diagram drop + if (false == request instanceof ChangeBoundsRequest) { + return null; + } + ListCompartmentEditPart listPart = getTargetEP(targetEditPart); + if (listPart == null) { + return null; + } + + ChangeBoundsRequest dropRequest = (ChangeBoundsRequest) request; + + List<?> objects = dropRequest.getEditParts(); + + List<UMLCompartmentEditPart> editParts = objects.stream() // + .filter(IPrimaryEditPart.class::isInstance) // + .flatMap(selectByType(UMLCompartmentEditPart.class)) // + .filter(p -> p.getParent() == listPart) + .collect(Collectors.toList()); + + if (editParts.isEmpty()) { + return null; + } + + // Some edit parts are not owned by the same parent (e.g. attributes are selected in different classes) + if (editParts.stream().anyMatch(p -> p.getParent() != listPart)) { + return null; + } + + Resource eResource = NotationHelper.findView(listPart).eResource(); + IFile file = ResourceUtils.getFile(eResource); + List<IFile> modifiedResources = file == null ? Collections.emptyList() : Collections.singletonList(file); + + TransactionalEditingDomain editingDomain = (TransactionalEditingDomain) EMFHelper.resolveEditingDomain(listPart); + + return new ICommandProxy(new AbstractTransactionalCommand(editingDomain, "Reorder items", modifiedResources) { + + @Override + protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + EditPart dropBefore = getDropBefore(dropRequest, listPart); + + EditPart primary = listPart; + while (primary != null && false == primary instanceof IPrimaryEditPart) { + primary = primary.getParent(); + } + + if (primary == null) { + return CommandResult.newCancelledCommandResult(); + } + + if (DiagramEditPartsUtil.isCanonical(primary)) { + return reorderSemantic(listPart, dropBefore); + } else { + return reorderGraphical(listPart, dropBefore); + } + } + + private CommandResult reorderGraphical(ListCompartmentEditPart listPart, EditPart dropBefore) { + EList<View> viewChildren = listPart.getNotationView().getPersistedChildren(); + + View dropBeforeView = NotationHelper.findView(dropBefore); + + // Note: Edit parts are dropped in the order they were selected; not in the order they visually appear in the list + // This may lead to surprising reordering during drop. To avoid this, it may be useful to sort the list of selected parts + + for (UMLCompartmentEditPart /* EditPart */ selected : editParts) { + if (selected == dropBefore) { + continue; + } + + View view = selected.getNotationView(); + if (view == null) { + continue; + } + + int targetIndex = dropBeforeView == null ? viewChildren.size() /* End of the list */ : viewChildren.indexOf(dropBeforeView); + int currentIndex = viewChildren.indexOf(view); + + if (targetIndex > currentIndex) { + targetIndex--; + } + + viewChildren.move(targetIndex, view); + } + + return CommandResult.newOKCommandResult(); + } + + private CommandResult reorderSemantic(ListCompartmentEditPart listPart, EditPart dropAfter) { + // The diagram is synchronized, but we don't have detailed access to the strategy used + // to populate the compartment (It seems that the Papyrus Canonical Mode synchronizes the + // entire semantic node, e.g. the class, rather than each individual compartment). + // Additionally, we may not always be able to manipulate semantic children as a single coherent + // list, where ordering would be possible. + + Runnable showInfo = () -> { + MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Reorder not supported", + "Reordering elements from the diagram is not supported when the diagram is synchronized with the model.\n" + + "You can either disable the \"Sync with model\" mode in the Appearance tab of the properties view, or reorder the semantic model directly (e.g. using the Model Explorer)."); + }; + + if (Display.getCurrent() == null) { + Display.getDefault().syncExec(showInfo); + } else { + showInfo.run(); + } + + return CommandResult.newCancelledCommandResult(); + } + + }); + } + + private int getDropIndex(ChangeBoundsRequest dropRequest, ListCompartmentEditPart listPart) { + EditPart dropAfter = getDropBefore(dropRequest, listPart); + return dropAfter == null ? listPart.getChildren().size() : listPart.getChildren().indexOf(dropAfter); + } + + /** + * Find the edit part after which the selected elements should be dropped. If null, elements + * should be dropped at the end of the list + */ + private EditPart getDropBefore(ChangeBoundsRequest dropRequest, ListCompartmentEditPart listPart) { + int target = dropRequest.getLocation().y; + List<EditPart> children = listPart.getChildren(); + + EditPart dropBefore = null; + // Find the first element below the drop target + // Null if all of them are above, i.e. we should drop at the bottom/end of the list + for (EditPart ep : children) { + if (ep instanceof GraphicalEditPart) { + IFigure figure = ((GraphicalEditPart) ep).getFigure(); + if (figure.getBounds().y + figure.getBounds().height / 2 > target) { + dropBefore = ep; + break; + } + } + } + + return dropBefore; + } + + private static <T> Function<Object, Stream<? extends T>> selectByType(Class<T> type) { + return (o -> type.isInstance(o) ? Stream.of(type.cast(o)) : Stream.empty()); + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#getPriority() + * + * @return + * @deprecated + */ + @Deprecated + @Override + public int getPriority() { + return 0; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#showTargetFeedback(org.eclipse.gef.Request, org.eclipse.gef.EditPart) + * + * @param request + * @param targetEditPart + * @return + */ + @Override + public boolean showTargetFeedback(Request request, EditPart targetEditPart) { + if (getCommand(request, targetEditPart) != null) { + ListCompartmentEditPart targetEP = getTargetEP(targetEditPart); + ChangeBoundsRequest dropRequest = (ChangeBoundsRequest) request; + EditPart ep = (EditPart) targetEP.getChildren().get(0); + IFigure sibling = ((GraphicalEditPart) ep).getFigure(); + IFigure figure = sibling.getParent(); + + if (dropFeedback == null) { + RectangleFigure rectangle = new RectangleFigure(); + rectangle.setBounds(new Rectangle(0, 0, 100, 1)); + int border = figure.getBorder().getInsets(figure).getWidth(); + rectangle.getBounds().setWidth(figure.getBounds().width() - border); + // rectangle.setLineWidth(2); + rectangle.setForegroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY)); + rectangle.setBackgroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY)); + rectangle.setVisible(true); + rectangle.setFill(true); + rectangle.setLocation(new Point(30, 300)); + + dropFeedback = rectangle; + figure.add(dropFeedback);// , SubCompartmentLayoutManager.SKIP_LAYOUT); + } + + // Update position + int index = getDropIndex(dropRequest, getTargetEP(targetEditPart)); + figure.add(dropFeedback, index); + return true; + } + return false; + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy#eraseTargetFeedback(org.eclipse.gef.Request, org.eclipse.gef.EditPart) + * + * @param request + * @param targetEditPart + * @return + */ + @Override + public boolean eraseTargetFeedback(Request request, EditPart targetEditPart) { + if (dropFeedback != null && request instanceof ChangeBoundsRequest) { + if (dropFeedback.getParent() != null) { + dropFeedback.getParent().getChildren().remove(dropFeedback); + } + dropFeedback = null; + return true; + } + return false; + } + +} |
