/*****************************************************************************
* Copyright (c) 2010 Atos Origin.
*
*
* 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:
* Atos Origin - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.activity.tabbedproperties.appearance;
import java.io.IOException;
import java.util.List;
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.draw2d.Figure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.properties.sections.AbstractNotationPropertiesSection;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.core.utils.EditorUtils;
import org.eclipse.papyrus.uml.diagram.activity.edit.parts.ForkNodeEditPart;
import org.eclipse.papyrus.uml.diagram.activity.edit.parts.JoinNodeEditPart;
import org.eclipse.papyrus.uml.diagram.activity.part.Messages;
import org.eclipse.papyrus.uml.diagram.activity.part.UMLDiagramEditorPlugin;
import org.eclipse.papyrus.uml.diagram.common.ui.helper.HelpComponentFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
/**
* Section to use in the properties view. This section enables to switch the
* direction of a segment representation (for fork or join).
*/
public class SwitchSegmentDirectionSection extends AbstractNotationPropertiesSection {
/** path to the switch icon */
private static final String ICON_PATH = "icons/switchSegmentOrientation.gif";
/** The switch image. */
public static Image switchImage = null;
/** Load the switch icon once */
static {
try {
switchImage = new Image(Display.getDefault(), UMLDiagramEditorPlugin.getInstance().getBundle().getResource(ICON_PATH).openStream());
} catch (IOException e) {
UMLDiagramEditorPlugin.getInstance().logError(e.getMessage(), e);
}
}
/** current edit part */
protected IGraphicalEditPart editPart;
/**
* Create controls to enable direction switch
*/
@Override
public void initializeControls(Composite parent) {
super.initializeControls(parent);
GridLayout layout = new GridLayout(2, false);
Group switchGroup = getWidgetFactory().createGroup(composite, Messages.ForkJoinSegmentSwitchOrientation_actionLabel);
switchGroup.setLayout(layout);
// create switch button
Button button = new Button(switchGroup, SWT.PUSH);
button.setImage(switchImage);
GridData gd = new GridData(SWT.CENTER, SWT.CENTER, true, true);
button.setLayoutData(gd);
button.addSelectionListener(new SelectionListener() {
/**
* {@inheritDoc}
*/
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
/**
* {@inheritDoc}
*/
public void widgetSelected(SelectionEvent e) {
switchSelectedSegmentsOrientation();
refresh();
}
});
// create help
ImageHyperlink help = HelpComponentFactory.createHelpComponent(switchGroup, getWidgetFactory(), Messages.ForkJoinSegmentSwitchOrientation_helpMessage);
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
help.setLayoutData(gd);
help.setBackground(switchGroup.getBackground());
}
/**
* Switch the orientation of each selected segment figure.
*/
protected void switchSelectedSegmentsOrientation() {
CompositeCommand globalCommand = new CompositeCommand(Messages.ForkJoinSegmentSwitchOrientation_actionLabel);
List<?> editparts = getInput();
for(Object part : editparts) {
Object view = null;
Figure figure = null;
if(part instanceof JoinNodeEditPart) {
view = ((JoinNodeEditPart)part).getModel();
figure = ((JoinNodeEditPart)part).getPrimaryShape();
} else if(part instanceof ForkNodeEditPart) {
view = ((ForkNodeEditPart)part).getModel();
figure = ((ForkNodeEditPart)part).getPrimaryShape();
}
// append a command for selected part only if correct configuration
if(view instanceof View && figure != null) {
TransactionalEditingDomain editingdomain = EditorUtils.getTransactionalEditingDomain();
SwitchSegmentOrientation switchCom = new SwitchSegmentOrientation(editingdomain, figure, (View)view);
globalCommand.add(switchCom);
}
}
// execute the command for all parts
if(!globalCommand.isEmpty() && globalCommand.canExecute()) {
CommandStack stack = (CommandStack)EditorUtils.getMultiDiagramEditor().getAdapter(CommandStack.class);
if(stack != null) {
stack.execute(new ICommandProxy(globalCommand));
}
}
}
/**
* This class is a command which switches the orientation of a figure. The
* figure's width and height are switched, rotating the figure on its
* center. (center location kept)
*/
private class SwitchSegmentOrientation extends AbstractTransactionalCommand {
/** The figure to switch */
private Figure selectedFigure = null;
/** The model view for the figure to switch */
private View selectedView = null;
/**
* Construct a switch orientation command.
*
* @param domain
* transactional editing domain
* @param figure
* the figure to rotate
* @param view
* the view which is the model of the figure
*/
SwitchSegmentOrientation(TransactionalEditingDomain domain, Figure figure, View view) {
super(domain, Messages.ForkJoinSegmentSwitchOrientation_actionLabel, null);
selectedFigure = figure;
selectedView = view;
}
/**
* Execute the command, rotating the figure.
*
* @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
* org.eclipse.core.runtime.IAdaptable)
*
* @param monitor
* progress monitor
* @param info
* adapter for information
* @return the result of the command
* @throws ExecutionException
*/
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
if(selectedFigure == null || selectedView == null) {
return CommandResult.newCancelledCommandResult();
}
Dimension newSize = selectedFigure.getSize().getTransposed();
Point newLocation = selectedFigure.getLocation().getCopy();
newLocation.translate((newSize.height - newSize.width) / 2, (newSize.width - newSize.height) / 2);
ViewUtil.setStructuralFeatureValue(selectedView, NotationPackage.eINSTANCE.getLocation_X(), newLocation.x);
ViewUtil.setStructuralFeatureValue(selectedView, NotationPackage.eINSTANCE.getLocation_Y(), newLocation.y);
ViewUtil.setStructuralFeatureValue(selectedView, NotationPackage.eINSTANCE.getSize_Width(), newSize.width);
ViewUtil.setStructuralFeatureValue(selectedView, NotationPackage.eINSTANCE.getSize_Height(), newSize.height);
return CommandResult.newOKCommandResult();
}
/**
* @see org.eclipse.emf.workspace.AbstractEMFOperation#canUndo()
* @return true if command can undo
*/
@Override
public boolean canUndo() {
return selectedFigure != null && selectedView != null;
}
/**
* @see org.eclipse.emf.workspace.AbstractEMFOperation#canRedo()
* @return true if command can redo
*/
@Override
public boolean canRedo() {
return selectedFigure != null && selectedView != null;
}
/**
* Undo the switch (by switching again)
*
* @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doUndo(org.eclipse.core.runtime.IProgressMonitor,
* org.eclipse.core.runtime.IAdaptable)
*
* @param monitor
* progress monitor
* @param info
* adapter for information
* @return the result of the command
* @throws ExecutionException
*/
@Override
protected IStatus doUndo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
return doExecute(monitor, info);
}
/**
* Redo the switch (by switching again)
*
* @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doRedo(org.eclipse.core.runtime.IProgressMonitor,
* org.eclipse.core.runtime.IAdaptable)
*
* @param monitor
* progress monitor
* @param info
* adapter for information
* @return the result of the command
* @throws ExecutionException
*/
@Override
protected IStatus doRedo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
return doExecute(monitor, info);
}
}
}