package de.FeatureModellingTool.GraphicalEditor;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.SwingConstants;
import research.ChangeConnectionHandle;
import research.ConnectionFigure;
import research.Figure;
import research.FigureEnumeration;
import research.Handle;
import research.TextHolder;
import research.connector.Connector;
import research.tool.HandleTracker;
import research.tool.SelectionTool;
import research.util.GlobalFunction;
import de.FeatureModellingTool.FeatureModel.CFRModifier;
import de.FeatureModellingTool.FeatureModel.CFRelation;
import de.FeatureModellingTool.FeatureModel.Constraint;
import de.FeatureModellingTool.FeatureModel.ConstraintModel;
import de.FeatureModellingTool.FeatureModel.ConstraintModelEditor;
import de.FeatureModellingTool.FeatureModel.Feature;
import de.FeatureModellingTool.FeatureModel.FeatureModel;
import de.FeatureModellingTool.FeatureModel.FeatureModelEditor;
import de.FeatureModellingTool.FeatureModel.FeatureRelation;
import de.FeatureModellingTool.FeatureModel.Interaction;
import de.FeatureModellingTool.FeatureModel.InteractionModel;
import de.FeatureModellingTool.FeatureModel.InteractionModelEditor;
import de.reuse.GroupMap;
/**
* author: zhangwei
* Date: 2003-6-4
* Time: 12:59:50
*/
class FeatureModelSelectionTool extends SelectionTool implements ConstantDefinition {
private FeatureModel featureModel = null;
private FeatureModelEditor featureModelEditor = null;
private ConstraintModel constraintModel = null;
private ConstraintModelEditor constraintModelEditor = null;
private InteractionModel interactionModel = null;
private InteractionModelEditor interactionModelEditor = null;
private ModelValidation modelValidation = null;
private GroupMap idToFigureMap = null;
private transient ConnectionFigure focusConnection = null;
private transient Connector oldStartConnector = null;
private transient Figure oldStartFigure = null;
private transient Figure oldEndFigure = null;
//private Vector bufferV = null;
private ArrayList listT = null;
private ArrayList listTConnection = null;
protected boolean shouldChildrenMove = true;
protected void initSubTools() {
super.initSubTools();
dragTracker = new TreeDragTracker();
handleTracker = new HandleTracker(this);
}
protected void contextChange(PropertyChangeEvent e) {
super.contextChange(e);
String propertyName = e.getPropertyName();
if (FEATURE_MODEL.equals(propertyName)) {
end();
featureModel = (FeatureModel) e.getNewValue();
} else if (FEATURE_MODEL_EDITOR.equals(propertyName)) {
end();
featureModelEditor = (FeatureModelEditor) e.getNewValue();
} else if (ID_TO_FIGURE_MAP.equals(propertyName)) {
idToFigureMap = (GroupMap) e.getNewValue();
} else if (CONSTRAINT_MODEL.equals(propertyName)) {
end();
constraintModel = (ConstraintModel) e.getNewValue();
} else if (CONSTRAINT_MODEL_EDITOR.equals(propertyName)) {
end();
constraintModelEditor = (ConstraintModelEditor) e.getNewValue();
} else if (INTERACTION_MODEL.equals(propertyName)) {
end();
interactionModel = (InteractionModel) e.getNewValue();
} else if (INTERACTION_MODEL_EDITOR.equals(propertyName)) {
end();
interactionModelEditor = (InteractionModelEditor) e.getNewValue();
} else if (GraphicalEditor.MODEL_VALIDATION.equals(propertyName)) {
end();
modelValidation = (ModelValidation) e.getNewValue();
}
}
@Override
public void mouseDown(MouseEvent e, int x, int y) {
if (currentTool != null) {
return;
}
Handle handle = drawingView.findHandle(x, y);
if (handle != null) {
handleTracker.setHandle(handle);
currentTool = handleTracker;
if (handle instanceof ChangeConnectionHandle) {
focusConnection = (ConnectionFigure) handle.owner();
String relationName = (String) focusConnection.getAttribute("type");
if (relationName != null) {
if (featureModel.containsFeatureRelations(relationName)
|| relationName.equals(CFRelation.PL_Relation)
|| relationName.equals(Interaction.Interaction)) {
oldStartConnector = focusConnection.getStartConnector();
oldStartFigure = focusConnection.startFigure();
oldEndFigure = focusConnection.endFigure();
} else {
focusConnection = null;
oldStartConnector = null;
oldStartFigure = null;
oldEndFigure = null;
}
} else {
focusConnection = null;
oldStartConnector = null;
oldStartFigure = null;
oldEndFigure = null;
}
}
} else {
double scale = drawingView.getScale();
int realX = (int) (e.getX() / scale + 0.5);
int realY = (int) (e.getY() / scale + 0.5);
FigureEnumeration fe = drawingView.getDrawing().getFiguresReverse();
Figure figure = null;
while (fe.hasMoreElements()) {
figure = fe.nextFigure();
if (!figure.containsPoint(realX, realY)) {
figure = null;
continue;
}
Boolean selectivity = (Boolean) figure.getAttribute("selectivity");
if (selectivity.booleanValue() == false) {
figure = null;
continue;
}
break;
}
if (figure != null) {
dragTracker.setFigure(figure);
dragTracker.getContext().putValue("SHOULD_CHILDREN_MOVE", Boolean.valueOf(shouldChildrenMove));
currentTool = dragTracker;
} else {
if (!e.isShiftDown()) {
drawingView.clearSelection();
}
currentTool = selectAreaTracker;
}
}
currentTool.mouseDown(e, x, y);
}
public void mouseUp(MouseEvent e, int x, int y) {
super.mouseUp(e, x, y);
if (focusConnection != null) {
String relationName = (String) focusConnection.getAttribute("type");
String id = (String) focusConnection.getAttribute("id");
Figure newStartFigure = focusConnection.startFigure();
Figure newEndFigure = focusConnection.endFigure();
String oldSFID = (String) oldStartFigure.getAttribute("id");
String oldEFID = (String) oldEndFigure.getAttribute("id");
String newSFID = (String) newStartFigure.getAttribute("id");
String newEFID = (String) newEndFigure.getAttribute("id");
if (featureModel.containsFeatureRelations(relationName)) {//����ģ���ڵĹ�ϵ�ı䴦��
if (!oldSFID.equals(newSFID) || !oldEFID.equals(newEFID)) {
FeatureRelation relation = featureModel.getFeatureRelation(relationName, oldSFID, oldEFID);
featureModelEditor.removeRelation(relation);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.remove(relation.getID(), focusConnection);
}
if (!featureModel.contains(relationName, newSFID, newEFID)) {
FeatureRelation newRelation = featureModelEditor.addRelation(relationName, id, newSFID, newEFID);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(newRelation.getID(), focusConnection);
}
} else {
drawingView.removeFromSelection(focusConnection);
drawingView.remove(focusConnection);
}
}
} else if (relationName.equals(CFRelation.PL_Relation)) {//Լ��ģ���ڹ�ϵ�ı䴦��
if (!oldEFID.equals(newEFID)) {//��ϵ�������˷����仯
Constraint c = constraintModel.getConstraint(oldSFID);
Feature newF = featureModel.getFeature(newEFID);
String relationID = (String) focusConnection.getAttribute("id");
CFRelation oldR = constraintModel.getCFRelation(relationID);
CFRModifier modifier = oldR.getModifier();
boolean isSource = oldR.isSource();
constraintModelEditor.removeCFRelation(relationID);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.remove(relationID, focusConnection);
}
CFRelation plRelation = plRelation = constraintModelEditor.addCFRelation(relationID, newF, c, isSource, modifier);
if (plRelation != null) {
focusConnection.setAttribute("id", plRelation.getID());
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(plRelation.getID(), focusConnection);
}
}
} else if (!oldSFID.equals(newSFID)) { //��ϵ��Լ���˷����仯
Constraint cNew = constraintModel.getConstraint(newSFID);
Feature newF = featureModel.getFeature(newEFID);
String relationID = (String) focusConnection.getAttribute("id");
CFRModifier modifier = constraintModel.getCFRelation(relationID).getModifier();
constraintModelEditor.removeCFRelation(relationID);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.remove(relationID, focusConnection);
}
ConstraintFigure cf = (ConstraintFigure) newStartFigure;
CFRelation plRelation = null;
if (cf instanceof PLFigure) {
int direction = focusConnection.getStartConnector().getDirection();
if (direction == Connector.WEST_DIRECTION || direction == Connector.NORTH_DIRECTION) {
plRelation = constraintModelEditor.addCFRelation(relationID, newF, cNew, true, modifier);
} else if (direction == Connector.EAST_DIRECTION || direction == Connector.SOUTH_DIRECTION) {
plRelation = constraintModelEditor.addCFRelation(relationID, newF, cNew, false, modifier);
} else {
assert false;
}
} else if (cf instanceof GroupConstraintFigure) {
GroupConstraintFigure gcf = (GroupConstraintFigure) cf;
Integer pp = (Integer) gcf.getAttribute(GroupConstraintFigure.PortPosition);
int value = pp.intValue();
boolean isSource = false;
switch (value) {
case SwingConstants.NORTH:
case SwingConstants.WEST:
isSource = true;
break;
case SwingConstants.EAST:
case SwingConstants.SOUTH:
isSource = false;
break;
default:
assert false;
break;
}
plRelation = constraintModelEditor.addCFRelation(relationID, newF, cNew, isSource, modifier);
} else if (cf instanceof VPConstraintFigure) {
int direction = focusConnection.getStartConnector().getDirection();
if (direction == Connector.WEST_DIRECTION || direction == Connector.NORTH_DIRECTION) {
plRelation = constraintModelEditor.addCFRelation(relationID, newF, cNew, true, modifier);
} else if (direction == Connector.EAST_DIRECTION || direction == Connector.SOUTH_DIRECTION) {
plRelation = constraintModelEditor.addCFRelation(relationID, newF, cNew, false, modifier);
} else {
assert false;
}
} else {
assert false;
}
if (plRelation != null) {
focusConnection.setAttribute("id", plRelation.getID());
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(plRelation.getID(), focusConnection);
}
}
} else
if (oldSFID.equals(newSFID) && (oldStartConnector != focusConnection.getStartConnector())) {//��ϵԼ���˵������ӷ����仯
String relationIDOld = (String) focusConnection.getAttribute("id");
CFRelation plRelationOld = constraintModel.getCFRelation(relationIDOld);
boolean isSource = plRelationOld.isSource();
Feature feature = plRelationOld.getFeature();
Constraint plc = (Constraint) plRelationOld.getConstraint();
CFRModifier modifier = constraintModel.getCFRelation(relationIDOld).getModifier();
constraintModelEditor.removeCFRelation(relationIDOld);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.remove(relationIDOld, focusConnection);
}
CFRelation plRelation = constraintModelEditor.addCFRelation(relationIDOld, feature, plc, !isSource, modifier);
if (plRelation != null) {
focusConnection.setAttribute("id", plRelation.getID());
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(plRelation.getID(), focusConnection);
}
}
}
} else if (relationName.equals(Interaction.Interaction)) {//����ģ���ڹ�ϵ�ı䴦��
if (!oldSFID.equals(newSFID) || !oldEFID.equals(newEFID)) {
Interaction interaction = interactionModel.getInteraction(id);
String type = interaction.getType();
String name = interaction.getName();
interactionModelEditor.removeInteraction(id);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.remove(interaction.getID(), focusConnection);
}
if (!interactionModel.containsInteraction(type, name, newSFID, newEFID)) {
Interaction newInteraction = interactionModelEditor.addInteraction(id, type, name, newSFID, newEFID);
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(newInteraction.getID(), focusConnection);
}
} else {
drawingView.removeFromSelection(focusConnection);
drawingView.remove(focusConnection);
}
}
}
}
focusConnection = null;
oldStartConnector = null;
oldStartFigure = null;
oldEndFigure = null;
}
public void keyDown(KeyEvent evt, int state) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_CONTROL) {
shouldChildrenMove = !shouldChildrenMove;
return;
}
if (evt.getKeyCode() == KeyEvent.VK_DOWN || key == KeyEvent.VK_UP ||
key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
int dx = 0, dy = 0;
int stepX = 1, stepY = 1;
switch (key) {
case KeyEvent.VK_DOWN:
dy = stepY;
break;
case KeyEvent.VK_UP:
dy = -stepY;
break;
case KeyEvent.VK_RIGHT:
dx = stepX;
break;
case KeyEvent.VK_LEFT:
dx = -stepX;
break;
}
moveSelection(dx, dy, shouldChildrenMove, state);
}
}
protected GlobalFunction.Satisfy constraintToConnection = new GlobalFunction.Satisfy() {
public boolean isSatisfied(Figure figure) {
if (figure == null) return false;
if (!(figure instanceof ConnectionFigure)) return false;
Boolean value = (Boolean) figure.getAttribute("hasParentChildSemantic");
if ((value != null) && (!value)) return false;
if (PLConnection.class.isInstance(figure)) {
Connector sc = ((PLConnection) figure).getStartConnector();
Figure fig = sc.owner();
if (VPConstraintFigure.class.isInstance(fig)) {
VPConstraintFigure vpcf = (VPConstraintFigure) fig;
if (vpcf.getStartConnector() == sc) return false;
}
}
return true;
}
};
private void moveSelection(int dx, int dy, boolean shouldChildMove, int state) {
if (state != 0) {
//System.out.println("caculate " + state);
FigureEnumeration figs_tmp = drawingView.selectionElements();
if (listT == null) {
listT = new ArrayList();
} else {
listT.clear();
}
if (listTConnection == null) {
listTConnection = new ArrayList();
} else {
listTConnection.clear();
}
while (figs_tmp.hasMoreElements()) {
Figure fig = figs_tmp.nextFigure();
if (ConnectionFigure.class.isInstance(fig))
continue;
if (!listT.contains(fig)) {
listT.add(fig);
}
if (shouldChildrenMove) {
GlobalFunction.caculateFMOffspringFigures(listT, listT.size() - 1, constraintToConnection);
}
}
/**
if (bufferV == null) {
bufferV = new Vector(listT.size());
} else {
bufferV.removeAllElements();
}
for (int i = 0; i < listT.size(); i++) {
bufferV.add(listT.get(i));
}
**/
Iterator iterator = listT.iterator();
ArrayList connectedTextHolder = null;
while (iterator.hasNext()) {
Figure f = (Figure) iterator.next();
if (f instanceof TextHolder) {
TextHolder th = (TextHolder) f;
if (th.isConnected()) {
Figure cf = th.getConnectedFigure();
if (cf instanceof ConnectionFigure) {
ConnectionFigure rcf = (ConnectionFigure) cf;
Figure st = rcf.getStartConnector().owner();
Figure ed = rcf.getEndConnector().owner();
if (listT.contains(st) || listT.contains(ed)) {
if (connectedTextHolder == null) {
connectedTextHolder = new ArrayList();
}
connectedTextHolder.add(th);
}
}
}
}
}
if (connectedTextHolder != null) {
iterator = connectedTextHolder.iterator();
while (iterator.hasNext()) {
listT.remove(iterator.next());
}
}
/**
*
*/
int size = listT.size();
for (int i = 0; i < size; i++) {
ConnectionFigure[] scFigures = GlobalFunction.getStartConnectedFigures((Figure) listT.get(i));
for (int k = 0; k < scFigures.length; k++) {
ConnectionFigure scf = scFigures[k];
if (listT.contains(scf.endFigure())) {
if (!listTConnection.contains(scf)) {
listTConnection.add(scf);
}
}
}
ConnectionFigure[] ecFigures = GlobalFunction.getEndConnectedFigures((Figure) listT.get(i));
for (int k = 0; k < ecFigures.length; k++) {
ConnectionFigure ecf = ecFigures[k];
if (listT.contains(ecf.startFigure())) {
if (!listTConnection.contains(ecf))
listTConnection.add(ecf);
}
}
}
}
/**
if (bufferV != null) {
int size = bufferV.size();
for (int i = 0; i < size; i++)
((Figure) bufferV.get(i)).moveBy(dx, dy);
}
**/
if (listT != null) {
int size = listT.size();
for (int i = 0; i < size; i++)
((Figure) listT.get(i)).moveBy(dx, dy);
}
if (listTConnection != null) {
int size = listTConnection.size();
for (int i = 0; i < size; i++)
((Figure) listTConnection.get(i)).moveBy(dx, dy);
}
return;
}
public ModelValidation getModelValidation() {
return modelValidation;
}
}