blob: 723d57f283d9f2288cc2b39e86c02d8e41ab7f79 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.commands;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.xwt.IConstants;
import org.eclipse.xwt.metadata.IMetaclass;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.xwt.tools.ui.designer.core.util.StringUtil;
import org.eclipse.xwt.tools.ui.designer.core.util.swt.SWTTools;
import org.eclipse.xwt.tools.ui.designer.parts.ControlEditPart;
import org.eclipse.xwt.tools.ui.designer.utils.OffsetUtil;
import org.eclipse.xwt.tools.ui.designer.utils.XWTModelUtil;
import org.eclipse.xwt.tools.ui.designer.utils.XWTUtility;
import org.eclipse.xwt.tools.ui.xaml.XamlAttribute;
import org.eclipse.xwt.tools.ui.xaml.XamlFactory;
import org.eclipse.xwt.tools.ui.xaml.XamlNode;
/**
* @author jliu (jin.liu@soyatec.com)
*/
public class ChangeConstraintCommand extends Command {
private EditPart editPart;
private XamlNode model;
private Rectangle constraint;
private boolean transform;
private CompoundCommand changeBoundCommand;
public ChangeConstraintCommand(EditPart editPart, Rectangle constraint) {
this(editPart, constraint, false);
}
public ChangeConstraintCommand(EditPart editPart, Rectangle constraint, boolean transform) {
this.editPart = editPart;
this.constraint = constraint;
this.transform = transform;
}
ChangeConstraintCommand(XamlNode model, Rectangle constraint) {
this((EditPart) null, constraint);
this.model = model;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.commands.Command#canExecute()
*/
public boolean canExecute() {
if (editPart != null) {
model = (XamlNode) editPart.getModel();
}
return model != null;
}
private int getXOffset() {
if (editPart == null) {
return 0;
}
/*
* Fixed bug: http://www.soyatec.cn/bugs/view.php?id=813, When the root is not a Shell, the parent host maybe the Diagram directly, we should found the correctly Scrollable Parent to compute the offset value.
*/
if (editPart instanceof ControlEditPart) {
Control control = (Control) ((ControlEditPart) editPart).getWidget();
if (control != null) {
Composite parent = control.getParent();
if (parent instanceof Group) {
return 0;
} else {
return SWTTools.getOffset(parent).x;
}
}
}
return OffsetUtil.getXOffset(editPart.getParent());
}
private int getYOffset() {
if (editPart == null) {
return 0;
}
/*
* Fixed bug: http://www.soyatec.cn/bugs/view.php?id=813, When the root is not a Shell, the parent host maybe the Diagram directly, we should found the correctly Scrollable Parent to compute the offset value.
*/
if (editPart instanceof ControlEditPart) {
Control control = (Control) ((ControlEditPart) editPart).getWidget();
if (control != null) {
Composite parent = control.getParent();
if (parent instanceof Group) {
return 0;
} else {
return SWTTools.getOffset(parent).y;
}
}
}
return OffsetUtil.getYOffset(editPart.getParent());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.commands.Command#execute()
*/
public void execute() {
IMetaclass metaclass = XWTUtility.getMetaclass(model);
if (metaclass == null) {
return;
}
changeBoundCommand = new CompoundCommand("Change Bounds");
XamlAttribute bounds = XWTModelUtil.getChildAttribute(model, "bounds", IConstants.XWT_NAMESPACE);
XamlAttribute location = XWTModelUtil.getChildAttribute(model, "location", IConstants.XWT_NAMESPACE);
XamlAttribute size = XWTModelUtil.getChildAttribute(model, "size", IConstants.XWT_NAMESPACE);
XamlNode boundsParent = null, locationParent = null, sizeParent = null;
Class<?> type = metaclass.getType();
if (Viewer.class.isAssignableFrom(type)) {
XamlNode controlNode = null;
if (bounds != null) {
controlNode = boundsParent = (XamlNode) bounds.eContainer();
}
if (size != null) {
controlNode = sizeParent = (XamlNode) size.eContainer();
}
if (location != null) {
controlNode = locationParent = (XamlNode) location.eContainer();
}
if (controlNode == null) {
controlNode = XamlFactory.eINSTANCE.createAttribute("control", IConstants.XWT_NAMESPACE);
changeBoundCommand.add(new AddNewChildCommand(model, controlNode));
}
if (boundsParent == null) {
boundsParent = controlNode;
}
if (sizeParent == null) {
sizeParent = controlNode;
}
if (locationParent == null) {
locationParent = controlNode;
}
} else {
boundsParent = locationParent = sizeParent = model;
}
Rectangle r = (Rectangle) constraint;
if (transform) {
r.x = r.x - getXOffset();
r.y = r.y - getYOffset();
}
String boundsValue = StringUtil.format(r);
String locationValue = StringUtil.format(r.getLocation());
String sizeValue = StringUtil.format(r.getSize());
Command createBounds = ApplyAttributeSettingCommand.createCommand(boundsParent, "bounds", IConstants.XWT_NAMESPACE, boundsValue);
Command createLocation = ApplyAttributeSettingCommand.createCommand(locationParent, "location", IConstants.XWT_NAMESPACE, locationValue);
Command createSize = ApplyAttributeSettingCommand.createCommand(sizeParent, "size", IConstants.XWT_NAMESPACE, sizeValue);
if (bounds == null) {
if (location == null && size == null) {
changeBoundCommand.add(createBounds);
} else {
changeBoundCommand.add(createSize);
changeBoundCommand.add(createLocation);
}
} else {
changeBoundCommand.add(createBounds);
if (location != null) {
changeBoundCommand.add(createLocation);
}
if (size != null) {
changeBoundCommand.add(createSize);
}
}
if (changeBoundCommand.canExecute()) {
changeBoundCommand.execute();
}
}
/**
* @see org.eclipse.gef.commands.Command#undo()
*/
public void undo() {
changeBoundCommand.undo();
}
/**
* @see org.eclipse.gef.commands.Command#canUndo()
*/
public boolean canUndo() {
return changeBoundCommand != null && changeBoundCommand.canUndo();
}
}