package de.FeatureModellingTool.GraphicalEditor;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import research.ConnectionFigure;
import research.Drawing;
import research.Figure;
import research.FigureHelper;
import research.connector.Connector;
import research.tool.ConnectionTool;
import research.tool.Tool;
import research.util.Geom;
import de.FeatureModellingTool.FeatureModel.ConstraintModel;
import de.FeatureModellingTool.FeatureModel.FeatureModel;
import de.FeatureModellingTool.FeatureModel.FeatureModelEditor;
import de.FeatureModellingTool.FeatureModel.FeatureRelation;
import de.reuse.GroupMap;
/**
* author: zhangwei
* Date: 2003-6-3
* Time: 21:43:00
*/
class FeatureRelationCreationTool extends ConnectionTool implements ConstantDefinition {
private FeatureModel featureModel = null;
private ConstraintModel constraintModel = null;
private ModelValidation modelValidation = null;
private FeatureModelEditor featureModelEditor = null;
private String relationName = null;
private GroupMap idToFigureMap = null;
/**
* �������������һ��Mouse Down-Drag-Up �����б��浱ǰConnectionFigure������
*/
private transient ConnectionFigure _connection = null;
/**
* ���� ������������һ��Mouse Down-Drag-Up �����б���������һ�ξ�����ͼԪ�Լ���ͼԪ�ڵ�ǰ�����µ���Ч�ԡ�
* ����ҪĿ�����Ż����ܣ�������_connection���ն˱��϶���һ������ͼԪ��ʱ��ֻ�����һ�θ�������Ϊ_connection���ն˵���Ч�ԡ�
* <p/>
* ���Խ�һ���Ľ��ķ��棺�������Ż��ĽǶ�����������������һ�����Ż���
* ������_connection���ն�����������������ͼԪ������Ч�Դ洢���������ٴξ�����ЩͼԪʱ��ֻ��Ҫ��ѯ����Ч�ԾͿ����ˣ���������Ҫ���¼��㡣
*/
private transient Figure _targetFigure = null;
private transient boolean _isValid = false;
@Override
protected void contextChange(PropertyChangeEvent e) {
super.contextChange(e);
String propertyName = e.getPropertyName();
if (FEATURE_MODEL.equals(propertyName)) {
end();
featureModel = (FeatureModel) e.getNewValue();
} else if (CONSTRAINT_MODEL.equals(propertyName)) {
end();
constraintModel = (ConstraintModel) e.getNewValue();
} else if (FEATURE_MODEL_EDITOR.equals(propertyName)) {
end();
featureModelEditor = (FeatureModelEditor) e.getNewValue();
} else if (RELATION_NAME.equals(propertyName)) {
end();
relationName = (String) e.getNewValue();
} else if (ID_TO_FIGURE_MAP.equals(propertyName)) {
idToFigureMap = (GroupMap) e.getNewValue();
} else if (GraphicalEditor.MODEL_VALIDATION.equals(propertyName)) {
end();
modelValidation = (ModelValidation)e.getNewValue();
}
}
@Override
public boolean isEnabled() {
if (!super.isEnabled()) return false;
if (featureModel == null) return false;
if (featureModelEditor == null) return false;
return true;
}
@Override
public void mouseDown(MouseEvent e, int x, int y) {
if (!isEnabled()) return;
//��ʼ����ʱ����
_connection = null;
_targetFigure = null;
_isValid = false;
double scale = drawingView.getScale();
x = (int) (x / scale + 0.5);
y = (int) (y / scale + 0.5);
//�����������������ͼԪΪTargetFigure
setTargetFigure(findConnectionStart(x, y, drawingView.getDrawing()));
_targetFigure = getTargetFigure();
if (_targetFigure != null) {
_isValid = true;
setStartConnector(findConnector(x, y, _targetFigure));
Connector startConnector = getStartConnector();
if (startConnector != null) {
consumeFigure();
setConnection((ConnectionFigure) createdFigure);
_connection = getConnection();
Rectangle rect = startConnector.getDisplayBox();
_connection.startPoint((int) rect.getCenterX(), (int) rect.getCenterY());
_connection.endPoint(x, y);
setAddedFigure(drawingView.add(_connection));
drawingView.setSelection(_connection);
}
}
/**
else {
ConnectionFigure connection = findConnection(x, y, drawingView.getDrawing());
if (connection != null) {
if (!connection.joinSegments(x, y)) {
fSplitPoint = connection.splitSegment(x, y);
fEditedConnection = connection;
} else {
fEditedConnection = null;
}
}
}
**/
}
@Override
public void mouseDrag(MouseEvent e, int x, int y) {
if (_connection == null) return;
double scale = drawingView.getScale();
x = (int) (x / scale + 0.5);
y = (int) (y / scale + 0.5);
//�ı䵱ǰ��괦������ͼԪ���ӵ�Ŀɼ����ԣ����ѵ�ǰ���ӵ�ͨ��setTargetConnector()��������
//�������������Ҫ��������ģ�ͺϷ��Լ��
trackConnectors(e, x, y);
Point p = new Point(x, y);
//������ͼԪ��endPoint����Ϊ��ǰ���ӵ����������
if (getTargetConnector() != null) {
Rectangle realR = getTargetConnector().getDisplayBox();
p = Geom.center(realR);
}
_connection.endPoint(p.x, p.y);
}
public void mouseUp(MouseEvent e, int x, int y) {
double scale = drawingView.getScale();
x = (int) (x / scale + 0.5);
y = (int) (y / scale + 0.5);
Figure c = null;
if (getTargetFigure() != null) { //���ص�ǰ����ͼԪ�����ӵ�Ŀɼ���
FigureHelper.setConnectorVisible(getTargetFigure(), false);
}
if (getStartConnector() != null) {
c = findTarget(x, y, drawingView.getDrawing());
if (c != null) {
if (!isAValidFeature(c)) c = null;
if (c != null) {
String startFeatureId = (String)getStartConnector().owner().getAttribute("id");
String endFeatureId = (String) c.getAttribute("id");
String _relationName = (String) getConnection().getAttribute("type");
if (!modelValidation.canConnect(startFeatureId, endFeatureId, _relationName))
c = null;
}
}
}
if (c != null) {//����������ͼԪ��Ϊ��
setEndConnector(findConnector(x, y, c));
if ((getEndConnector() != null) && !hasExistedBetweenFeatures()) {//�����������Ӳ�Ϊ�գ���������ͼԪ֮��û����ͬ�Ĺ�ϵ����
//ȷ�����ͼԪ
_connection.connectStart(getStartConnector());
_connection.connectEnd(getEndConnector());
_connection.updateConnection();
FeatureRelation relation = featureModelEditor.addRelation(relationName,
(String) _connection.startFigure().getAttribute("id"),
(String) _connection.endFigure().getAttribute("id"));
_connection.setAttribute("id", relation.getID());
//����id��figure��ӳ���
if (idToFigureMap != null) {
idToFigureMap.add(relation.getID(), getConnection());
}
} else if (_connection != null) {
//ɾ��ͼԪ
drawingView.clearSelection();
drawingView.remove(getConnection());
restoreConsumedFigure();
}
} else if (_connection != null) {
//ɾ��ͼԪ
drawingView.clearSelection();
drawingView.remove(getConnection());
restoreConsumedFigure();
}
//�����ʱ����
_connection = null;
_targetFigure = null;
_isValid = false;
setConnection(null);
setStartConnector(null);
setEndConnector(null);
setAddedFigure(null);
getPropertyChangeSupport().firePropertyChange(Tool.TOOL_DONE, false, true);
}
/**
* �����ض�ģ��������Ͽ�����Ϊ��ϵ��ʼ�˵�����ͼԪ.
*
* @param x: ģ������X��ֵ��
* @param y: ģ������Y��ֵ��
* @param drawing: ��ͼ��ģ�ͣ�
* @return: ͼԪ��
* ��Ҫ����
* 1.������ָ�����괦�����ӵ�ͼԪ��
* 2.�жϸ�ͼԪ�Ƿ���һ���Ϸ�������ͼԪ.
*/
@Override
protected Figure findConnectionStart(int x, int y, Drawing drawing) {
Figure target = findConnectableFigure(x, y, drawing);
if (isAValidFeature(target)) {
return target;
} else {
return null;
}
}
//���������֮���Ƿ��Ѿ����ڵ�ǰ�Ĺ�ϵ
protected boolean hasExistedBetweenFeatures() {
String startFID = (String) getStartConnector().owner().getAttribute("id");
String endFID = (String) getEndConnector().owner().getAttribute("id");
return featureModel.contains(relationName, featureModel.getFeature(startFID), featureModel.getFeature(endFID));
}
/**
* ���һ��ͼԪ�Ƿ�Ϊһ���Ϸ�������ͼԪ.
*
* @param f, ����Ĵ����ͼԪ��
* @return f�Ƿ�Ϊһ���Ϸ�������ͼԪ
* ���������ݰ�����
* 1.���������Ϊ�գ�
* 2.ͼԪ����Ϊ"feature"��
* 3.ͼԪ��ID����������ģ���С�
*/
protected boolean isAValidFeature(Figure f) {
if (f == null)
return false;
String type = (String) f.getAttribute("type");
String id = (String) f.getAttribute("id");
if ((type != null) && (type.equals("feature")) && (id != null) && featureModel.containsFeature(id))
return true;
else
return false;
}
/**
* ������ƶ������ʵ�����ͼԪ���Ϸ�ʱ,��ʾ����ͼԪ�����ӵ�.
*
* @param e: ����ж��¼�
* @param x: ����ж��¼���ģ������X��ֵ
* @param y: ����ж��¼���ģ������Y��ֵ
* ��ģ��������Ӧ������ͼ���ꡣ����������IJ�����������ͼ���е�Zoom in/out���������µġ�
*/
@Override
protected void trackConnectors(MouseEvent e, int x, int y) {
Figure c = null;
if (getStartConnector() == null) { //���������Ӧ������ƶ�ʱ�����
c = findConnectionStart(x, y, drawingView.getDrawing());
} else {
c = findTarget(x, y, drawingView.getDrawing());
if (c != null) {
if (!isAValidFeature(c)) c = null;
if (c != null) {
if (c == _targetFigure) {
if (!_isValid) c = null;
} else {
_targetFigure = c;
String targetId = (String) c.getAttribute("id");
String sourceId = (String)getStartConnector().owner().getAttribute("id");
String relationName = (String) getConnection().getAttribute("type");
if (modelValidation.canConnect(sourceId, targetId, relationName))
_isValid = true;
else {
_isValid = false;
c = null;
}
}
}
}
}
// track the figure containing the mouse
Figure targetFigure = getTargetFigure();
if (c != targetFigure) {
if (targetFigure != null) {
FigureHelper.setConnectorVisible(targetFigure, false);
}
setTargetFigure(c);
targetFigure = getTargetFigure();
if (targetFigure != null) {
FigureHelper.setConnectorVisible(targetFigure, true);
}
}
Connector cc = null;
if (c != null) {
cc = findConnector(x, y, c);
}
if (cc != getTargetConnector()) {
setTargetConnector(cc);
}
drawingView.checkDamage();
}
}