/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * 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: * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.service.palette; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.workspace.AbstractEMFOperation; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; import org.eclipse.gmf.runtime.common.core.util.StringStatics; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil; import org.eclipse.papyrus.commands.wrappers.EMFtoGMFCommandWrapper; import org.eclipse.papyrus.uml.appearance.helper.AppliedStereotypeHelper; import org.eclipse.papyrus.uml.appearance.helper.UMLVisualInformationPapyrusConstant; import org.eclipse.papyrus.uml.diagram.common.Activator; import org.eclipse.papyrus.uml.diagram.common.service.IPapyrusPaletteConstant; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.uml2.uml.Profile; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * Post action that manages the display of applied stereotypes. */ public class ChangeStereotypeDisplayPostAction extends GraphicalPostAction { /** list of stereotypes to display with their names */ protected String displayKind = UMLVisualInformationPapyrusConstant.STEREOTYPE_TEXT_HORIZONTAL_PRESENTATION; /** place where to display stereotypes */ protected String displayPlace = UMLVisualInformationPapyrusConstant.STEREOTYPE_COMPARTMENT_LOCATION; /** combo for configuration of the stereotype display direction */ protected Combo directionCombo; /** combo for configuration of the stereotype display */ protected Combo displayCombo; /** combo for configuration of the stereotype display place */ protected Combo placeCombo; /** text display */ protected static final String TEXT = "text"; /** icon display */ protected static final String ICON = "icon"; /** icon display */ protected static final String SHAPE = "shape"; /** text and icon display */ protected static final String TEXT_AND_ICON = "text and icon"; /** list of available items in the stereotype display combo */ protected static final List<String> DISPLAY_LIST = Arrays.asList(TEXT, ICON, TEXT_AND_ICON, SHAPE); /** horizontal display constant */ private static final String HORIZONTAL = "horizontal"; /** vertical display constant */ private static final String VERTICAL = "vertical"; /** list of available items in the stereotype direction combo */ protected static final List<String> DIRECTION_LIST = Arrays.asList(HORIZONTAL, VERTICAL); /** in comment display constant */ protected static final String COMMENT = "comment"; /** compartment display constant */ protected static final String COMPARTMENT = "compartment"; /** in brace display constant */ protected static final String BRACE = "brace"; /** list of available items in the stereotype place combo */ protected static final List<String> PLACE_LIST = Arrays.asList(COMMENT, COMPARTMENT, BRACE); /** entry proxy "parent" of this action when configuring the action */ protected IPaletteEntryProxy entryProxy; /** list of applied profiles */ protected List<Profile> appliedProfiles; /** * @{inheritDoc */ @Override public void init(Node configurationNode, IAspectActionProvider factory) { super.init(configurationNode, factory); if(configurationNode == null) { return; } Node node = configurationNode.getAttributes().getNamedItem(IPapyrusPaletteConstant.DISPLAY_KIND); if(node != null) { displayKind = node.getNodeValue(); } node = configurationNode.getAttributes().getNamedItem(IPapyrusPaletteConstant.DISPLAY_PLACE); if(node != null) { displayPlace = node.getNodeValue(); } } /** * @{inheritDoc */ @Override public void save(Node configurationNode) { if(configurationNode instanceof Element) { ((Element)configurationNode).setAttribute(IPapyrusPaletteConstant.DISPLAY_KIND, displayKind); ((Element)configurationNode).setAttribute(IPapyrusPaletteConstant.DISPLAY_PLACE, displayPlace); } else { Activator.log.error("configuration node is not an Element", null); } } /** * @{inheritDoc */ @Override public void run(final EditPart editPart) { final CompositeCommand compositeCommand = new CompositeCommand("Modify Stereotype Display"); // View view = (View)editPart.getModel(); final EModelElement view = (EModelElement)((GraphicalEditPart)editPart).getModel(); final TransactionalEditingDomain editingDomain = org.eclipse.papyrus.infra.core.utils.EditorUtils.getTransactionalEditingDomain(); try { editingDomain.runExclusive(new Runnable() { public void run() { Display.getCurrent().asyncExec(new Runnable() { public void run() { String stereotypetoDisplay = AppliedStereotypeHelper.getStereotypesToDisplay(view); final RecordingCommand command = AppliedStereotypeHelper.getAppliedStereotypeToDisplayCommand(editingDomain, view, stereotypetoDisplay, displayKind); compositeCommand.compose(new EMFtoGMFCommandWrapper(command)); compositeCommand.reduce(); if(compositeCommand.canExecute()) { boolean isActivating = true; Map<String, Boolean> options = null; // use the viewer to determine if we are still // initializing the diagram // do not use the DiagramEditPart.isActivating // since ConnectionEditPart's // parent will not be a diagram edit part EditPartViewer viewer = editPart.getViewer(); if(viewer instanceof DiagramGraphicalViewer) { isActivating = ((DiagramGraphicalViewer)viewer).isInitializing(); } if(isActivating || !EditPartUtil.isWriteTransactionInProgress((IGraphicalEditPart)editPart, false, false)) { options = Collections.singletonMap(Transaction.OPTION_UNPROTECTED, Boolean.TRUE); } AbstractEMFOperation operation = new AbstractEMFOperation(((IGraphicalEditPart)editPart).getEditingDomain(), StringStatics.BLANK, options) { @Override protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { editingDomain.getCommandStack().execute(command); return Status.OK_STATUS; } }; try { operation.execute(new NullProgressMonitor(), null); } catch (ExecutionException e) { Activator.log.error(e); } } else { Activator.log.error("Impossible to execute graphical post action " + propertiesToUpdate, null); } } }); } }); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @{inheritDoc */ @Override public Control createConfigurationComposite(Composite parent, IPaletteEntryProxy entryProxy, List<Profile> appliedProfiles) { this.appliedProfiles = appliedProfiles; this.entryProxy = entryProxy; Composite mainComposite = new Composite(parent, SWT.BORDER); GridLayout layout = new GridLayout(2, false); mainComposite.setLayout(layout); Label titleLabel = new Label(mainComposite, SWT.NONE); titleLabel.setText("Customize stereotype display"); GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); titleLabel.setLayoutData(data); Label displayLabel = new Label(mainComposite, SWT.NONE); displayLabel.setText("Stereotype Display:"); displayCombo = new Combo(mainComposite, SWT.READ_ONLY | SWT.BORDER); displayCombo.setItems(DISPLAY_LIST.toArray(new String[]{})); data = new GridData(SWT.FILL, SWT.CENTER, true, false); displayCombo.setLayoutData(data); displayCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updateDisplayKindValue(); } public void widgetDefaultSelected(SelectionEvent e) { // nothing to do } }); Label directionLabel = new Label(mainComposite, SWT.NONE); directionLabel.setText("Text alignement:"); directionCombo = new Combo(mainComposite, SWT.READ_ONLY | SWT.BORDER); directionCombo.setItems(DIRECTION_LIST.toArray(new String[]{})); // data = new GridData(SWT.FILL, SWT.CENTER, true, false); directionCombo.setLayoutData(data); directionCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updateDisplayKindValue(); } public void widgetDefaultSelected(SelectionEvent e) { // nothing to do } }); Label placeLabel = new Label(mainComposite, SWT.NONE); placeLabel.setText("Display place:"); placeCombo = new Combo(mainComposite, SWT.READ_ONLY | SWT.BORDER); placeCombo.add(UMLVisualInformationPapyrusConstant.STEREOTYPE_COMMENT_LOCATION); placeCombo.add(UMLVisualInformationPapyrusConstant.STEREOTYPE_COMPARTMENT_LOCATION); placeCombo.add(UMLVisualInformationPapyrusConstant.STEREOTYPE_BRACE_LOCATION); // data = new GridData(SWT.FILL, SWT.CENTER, true, false); placeCombo.setLayoutData(data); placeCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updateDisplayPlaceValue(); } public void widgetDefaultSelected(SelectionEvent e) { // nothing to do } }); updateCombos(); return mainComposite; } /** * Update the display place value according to the combo selection */ protected void updateDisplayPlaceValue() { int placeIndex = placeCombo.getSelectionIndex(); String place = PLACE_LIST.get((placeIndex >= 0) ? placeIndex : 0); if(BRACE.equals(place)) { displayPlace = UMLVisualInformationPapyrusConstant.STEREOTYPE_BRACE_LOCATION; } else if(COMMENT.equals(place)) { displayPlace = UMLVisualInformationPapyrusConstant.STEREOTYPE_COMMENT_LOCATION; } else { displayPlace = UMLVisualInformationPapyrusConstant.STEREOTYPE_COMPARTMENT_LOCATION; } // be sure display is up to date updateCombos(); } /** * update the display kind value hold by this action, given the combo value */ protected void updateDisplayKindValue() { int displayIndex = displayCombo.getSelectionIndex(); String display = DISPLAY_LIST.get((displayIndex >= 0) ? displayIndex : 0); int directionIndex = directionCombo.getSelectionIndex(); String direction = DIRECTION_LIST.get((directionIndex >= 0) ? directionIndex : 0); if(ICON.equals(display)) { displayKind = UMLVisualInformationPapyrusConstant.ICON_STEREOTYPE_PRESENTATION; } else if(TEXT_AND_ICON.equals(display)) { displayKind = UMLVisualInformationPapyrusConstant.TEXT_ICON_STEREOTYPE_PRESENTATION; } else if(SHAPE.equals(display)) { displayKind = UMLVisualInformationPapyrusConstant.IMAGE_STEREOTYPE_PRESENTATION; } else { if(VERTICAL.equals(direction)) { displayKind = UMLVisualInformationPapyrusConstant.STEREOTYPE_TEXT_VERTICAL_PRESENTATION; } else { displayKind = UMLVisualInformationPapyrusConstant.STEREOTYPE_TEXT_HORIZONTAL_PRESENTATION; } } // be sure display corresponds to the real values updateCombos(); } /** * Updates the combo according to the current values hold by this action */ protected void updateCombos() { // udpate the direction and display combo /* * VisualInformationPapyrusConstants.TEXT_ICON_STEREOTYPE_PRESENTATION, * VisualInformationPapyrusConstants.ICON_STEREOTYPE_PRESENTATION, * VisualInformationPapyrusConstants.IMAGE_STEREOTYPE_PRESENTATION, * VisualInformationPapyrusConstant * .STEREOTYPE_TEXT_HORIZONTAL_PRESENTATION, * VisualInformationPapyrusConstant * .STEREOTYPE_TEXT_VERTICAL_PRESENTATION */ if(UMLVisualInformationPapyrusConstant.TEXT_ICON_STEREOTYPE_PRESENTATION.equals(displayKind)) { displayCombo.select(DISPLAY_LIST.indexOf(TEXT_AND_ICON)); directionCombo.select(DIRECTION_LIST.indexOf(HORIZONTAL)); directionCombo.setEnabled(false); } else if(UMLVisualInformationPapyrusConstant.ICON_STEREOTYPE_PRESENTATION.equals(displayKind)) { displayCombo.select(DISPLAY_LIST.indexOf(ICON)); directionCombo.select(DIRECTION_LIST.indexOf(HORIZONTAL)); directionCombo.setEnabled(false); } else if(UMLVisualInformationPapyrusConstant.IMAGE_STEREOTYPE_PRESENTATION.equals(displayKind)) { displayCombo.select(DISPLAY_LIST.indexOf(SHAPE)); directionCombo.select(DIRECTION_LIST.indexOf(HORIZONTAL)); directionCombo.setEnabled(false); } else if(UMLVisualInformationPapyrusConstant.STEREOTYPE_TEXT_VERTICAL_PRESENTATION.equals(displayKind)) { displayCombo.select(DISPLAY_LIST.indexOf(TEXT)); directionCombo.select(DIRECTION_LIST.indexOf(VERTICAL)); directionCombo.setEnabled(true); } else { displayCombo.select(DISPLAY_LIST.indexOf(TEXT)); directionCombo.select(DIRECTION_LIST.indexOf(HORIZONTAL)); directionCombo.setEnabled(true); } // update the place combo /* * VisualInformationPapyrusConstants.STEREOTYPE_COMMENT_LOCATION * VisualInformationPapyrusConstants.STEREOTYPE_COMPARTMENT_LOCATION * VisualInformationPapyrusConstants.STEREOTYPE_BRACE_LOCATION */ if(UMLVisualInformationPapyrusConstant.STEREOTYPE_COMMENT_LOCATION.equals(displayPlace)) { placeCombo.select(PLACE_LIST.indexOf(COMMENT)); } else if(UMLVisualInformationPapyrusConstant.STEREOTYPE_BRACE_LOCATION.equals(displayPlace)) { placeCombo.select(PLACE_LIST.indexOf(BRACE)); } else { placeCombo.select(PLACE_LIST.indexOf(COMPARTMENT)); } } }