package com.realpersist.gef.part;
import java.beans.PropertyChangeEvent;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.CommandStackListener;
import com.realpersist.gef.figures.SchemaFigure;
import com.realpersist.gef.figures.TableFigure;
import com.realpersist.gef.layout.DelegatingLayoutManager;
import com.realpersist.gef.layout.GraphAnimation;
import com.realpersist.gef.layout.GraphLayoutManager;
import com.realpersist.gef.model.Schema;
import com.realpersist.gef.model.Table;
import com.realpersist.gef.policy.SchemaContainerEditPolicy;
/**
* Edit part for Schema object, and uses a SchemaDiagram figure as
* the container for all graphical objects
*
* @author Phil Zoio
*/
public class SchemaDiagramPart extends PropertyAwarePart
{
CommandStackListener stackListener = new CommandStackListener()
{
public void commandStackChanged(EventObject event)
{
if (delegatingLayoutManager.getActiveLayoutManager() instanceof GraphLayoutManager)
{
if (!GraphAnimation.captureLayout(getFigure()))
return;
while (GraphAnimation.step())
getFigure().getUpdateManager().performUpdate();
GraphAnimation.end();
}
else
{
getFigure().getUpdateManager().performUpdate();
}
}
};
private DelegatingLayoutManager delegatingLayoutManager;
/**
* Adds this EditPart as a command stack listener, which can be used to call
* performUpdate() when it changes
*/
public void activate()
{
super.activate();
getViewer().getEditDomain().getCommandStack().addCommandStackListener(stackListener);
}
/**
* Removes this EditPart as a command stack listener
*/
public void deactivate()
{
getViewer().getEditDomain().getCommandStack().removeCommandStackListener(stackListener);
super.deactivate();
}
protected IFigure createFigure()
{
Figure f = new SchemaFigure();
delegatingLayoutManager = new DelegatingLayoutManager(this);
f.setLayoutManager(delegatingLayoutManager);
return f;
}
public Schema getSchema()
{
return (Schema) getModel();
}
/**
* @return the children Model objects as a new ArrayList
*/
protected List getModelChildren()
{
return getSchema().getTables();
}
/**
* @see org.eclipse.gef.editparts.AbstractEditPart#isSelectable()
*/
public boolean isSelectable()
{
return false;
}
/**
* Creates EditPolicy objects for the EditPart. The LAYOUT_ROLE policy is
* left to the delegating layout manager
*/
protected void createEditPolicies()
{
installEditPolicy(EditPolicy.CONTAINER_ROLE, new SchemaContainerEditPolicy());
installEditPolicy(EditPolicy.LAYOUT_ROLE, null);
}
/**
* Updates the table bounds in the model so that the same bounds can be
* restored after saving
*
* @return whether the procedure execute successfully without any omissions.
* The latter occurs if any TableFigure has no bounds set for any of
* the Table model objects
*/
public boolean setTableModelBounds()
{
List tableParts = getChildren();
Schema schema = getSchema();
for (Iterator iter = tableParts.iterator(); iter.hasNext();)
{
TablePart tablePart = (TablePart) iter.next();
TableFigure tableFigure = (TableFigure) tablePart.getFigure();
//if we don't find a node for one of the children then we should
// continue
if (tableFigure == null)
continue;
Rectangle bounds = tableFigure.getBounds().getCopy();
Table table = tablePart.getTable();
table.setBounds(bounds);
}
return true;
}
/**
* Updates the bounds of the table figure (without invoking any event
* handling), and sets layout constraint data
*
* @return whether the procedure execute successfully without any omissions.
* The latter occurs if any Table objects have no bounds set or if
* no figure is available for the TablePart
*/
public boolean setTableFigureBounds(boolean updateConstraint)
{
List tableParts = getChildren();
Schema schema = getSchema();
for (Iterator iter = tableParts.iterator(); iter.hasNext();)
{
TablePart tablePart = (TablePart) iter.next();
Table table = tablePart.getTable();
//now check whether we can find an entry in the tableToNodesMap
Rectangle bounds = table.getBounds();
if (bounds == null)
{
//TODO handle this better
return false;
}
else
{
TableFigure tableFigure = (TableFigure) tablePart.getFigure();
if (tableFigure == null)
{
return false;
}
else
{
if (updateConstraint)
{
//pass the constraint information to the xy layout
//setting the width and height so that the preferred size will be applied
delegatingLayoutManager.setXYLayoutConstraint(tableFigure, new Rectangle(bounds.x, bounds.y,
-1, -1));
}
}
}
}
return true;
}
/**
* Passes on to the delegating layout manager that the layout type has
* changed. The delegating layout manager will then decide whether to
* delegate layout to the XY or Graph layout
*/
protected void handleLayoutChange(PropertyChangeEvent evt)
{
Boolean layoutType = (Boolean) evt.getNewValue();
boolean isManualLayoutDesired = layoutType.booleanValue();
getFigure().setLayoutManager(delegatingLayoutManager);
}
/**
* Sets layout constraint only if XYLayout is active
*/
public void setLayoutConstraint(EditPart child, IFigure childFigure, Object constraint)
{
super.setLayoutConstraint(child, childFigure, constraint);
}
/**
* Passes on to the delegating layout manager that the layout type has
* changed. The delegating layout manager will then decide whether to
* delegate layout to the XY or Graph layout
*/
protected void handleChildChange(PropertyChangeEvent evt)
{
super.handleChildChange(evt);
}
}