From f3da9169652b6c9378bb0bafcd4718e9a348da13 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 7 Jul 2012 11:52:23 -0300 Subject: [PATCH] Fix several errors removing a node ... --- .../src/main/javascript/ConnectionLine.js | 415 +++++++++--------- mindplot/src/main/javascript/Designer.js | 29 +- .../src/main/javascript/DesignerKeyboard.js | 72 ++- mindplot/src/main/javascript/Relationship.js | 20 +- .../main/javascript/commands/DeleteCommand.js | 36 +- .../main/javascript/layout/BalancedSorter.js | 62 +-- .../main/javascript/layout/OriginalLayout.js | 68 +-- mindplot/src/main/javascript/model/Mindmap.js | 47 +- .../src/main/javascript/model/NodeModel.js | 401 +++++++++-------- .../persistence/XMLSerializer_Pela.js | 23 +- 10 files changed, 616 insertions(+), 557 deletions(-) diff --git a/mindplot/src/main/javascript/ConnectionLine.js b/mindplot/src/main/javascript/ConnectionLine.js index 08c38cf1..c8869fb4 100644 --- a/mindplot/src/main/javascript/ConnectionLine.js +++ b/mindplot/src/main/javascript/ConnectionLine.js @@ -1,207 +1,210 @@ -/* - * Copyright [2011] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -mindplot.ConnectionLine = new Class({ - initialize:function(sourceNode, targetNode, lineType) { - $assert(targetNode, 'parentNode node can not be null'); - $assert(sourceNode, 'childNode node can not be null'); - $assert(sourceNode != targetNode, 'Cilcular connection'); - - this._targetTopic = targetNode; - this._sourceTopic = sourceNode; - - var line; - var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode); - if (targetNode.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) { - line = this._createLine(lineType, mindplot.ConnectionLine.CURVED); - if (line.getType() == "CurvedLine") { - line.setSrcControlPoint(ctrlPoints[0]); - line.setDestControlPoint(ctrlPoints[1]); - } - } else { - line = this._createLine(lineType, mindplot.ConnectionLine.SIMPLE_CURVED); - if (line.getType() == "CurvedLine") { - line.setSrcControlPoint(ctrlPoints[0]); - line.setDestControlPoint(ctrlPoints[1]); - } - } - // Set line styles ... - var strokeColor = mindplot.ConnectionLine.getStrokeColor(); - line.setStroke(1, 'solid', strokeColor, 1); - line.setFill(strokeColor, 1); - - this._line2d = line; - }, - - _getCtrlPoints : function(sourceNode, targetNode) { - var srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition()); - var destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition()); - var deltaX = (srcPos.x - destPos.x) / 3; - return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)]; - }, - - _createLine : function(lineType, defaultStyle) { - if (!$defined(lineType)) { - lineType = defaultStyle; - } - lineType = parseInt(lineType); - this._lineType = lineType; - var line = null; - switch (lineType) { - case mindplot.ConnectionLine.POLYLINE: - line = new web2d.PolyLine(); - break; - case mindplot.ConnectionLine.CURVED: - line = new web2d.CurvedLine(); - break; - case mindplot.ConnectionLine.SIMPLE_CURVED: - line = new web2d.CurvedLine(); - line.setStyle(web2d.CurvedLine.SIMPLE_LINE); - break; - default: - line = new web2d.Line(); - break; - } - return line; - }, - - setVisibility : function(value) { - this._line2d.setVisibility(value); - }, - - isVisible : function() { - return this._line2d.isVisible(); - }, - - setOpacity : function(opacity) { - this._line2d.setOpacity(opacity); - }, - - redraw : function() { - var line2d = this._line2d; - var sourceTopic = this._sourceTopic; - var sourcePosition = sourceTopic.getPosition(); - - var targetTopic = this._targetTopic; - var targetPosition = targetTopic.getPosition(); - - var sPos,tPos; - sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition); - tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition); - - line2d.setFrom(tPos.x, tPos.y); - line2d.setTo(sPos.x, sPos.y); - - if (line2d.getType() == "CurvedLine") { - var ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic); - line2d.setSrcControlPoint(ctrlPoints[0]); - line2d.setDestControlPoint(ctrlPoints[1]); - } - - // Add connector ... - this._positionateConnector(targetTopic); - - }, - - _positionateConnector : function(targetTopic) { - var targetPosition = targetTopic.getPosition(); - var offset = mindplot.Topic.CONNECTOR_WIDTH / 2; - var targetTopicSize = targetTopic.getSize(); - var y; - if (targetTopic.getShapeType() == mindplot.model.TopicShape.LINE) { - y = targetTopicSize.height; - } else { - y = targetTopicSize.height / 2; - } - y = y - offset; - - var connector = targetTopic.getShrinkConnector(); - if ($defined(connector)) { - if (Math.sign(targetPosition.x) > 0) { - var x = targetTopicSize.width; - connector.setPosition(x, y); - } - else { - var x = -mindplot.Topic.CONNECTOR_WIDTH; - connector.setPosition(x, y); - } - } - }, - - setStroke : function(color, style, opacity) { - this._line2d.setStroke(null, null, color, opacity); - }, - - addToWorkspace : function(workspace) { - workspace.appendChild(this._line2d); - this._line2d.moveToBack(); - }, - - removeFromWorkspace : function(workspace) { - workspace.removeChild(this._line2d); - }, - - getTargetTopic : function() { - return this._targetTopic; - }, - - getSourceTopic : function() { - return this._sourceTopic; - }, - - getLineType : function() { - return this._lineType; - }, - - getLine : function() { - return this._line2d; - }, - - getModel : function() { - return this._model; - }, - - setModel : function(model) { - this._model = model; - }, - - getType : function() { - return "ConnectionLine"; - }, - - getId : function() { - return this._model.getId(); - }, - - moveToBack : function() { - this._line2d.moveToBack(); - }, - - moveToFront : function() { - this._line2d.moveToFront(); - } -}); - -mindplot.ConnectionLine.getStrokeColor = function() { - return '#495879'; -}; - -mindplot.ConnectionLine.SIMPLE = 0; -mindplot.ConnectionLine.POLYLINE = 1; -mindplot.ConnectionLine.CURVED = 2; +/* + * Copyright [2011] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +mindplot.ConnectionLine = new Class({ + initialize:function (sourceNode, targetNode, lineType) { + $assert(targetNode, 'parentNode node can not be null'); + $assert(sourceNode, 'childNode node can not be null'); + $assert(sourceNode != targetNode, 'Cilcular connection'); + + this._targetTopic = targetNode; + this._sourceTopic = sourceNode; + + var line; + var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode); + if (targetNode.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) { + line = this._createLine(lineType, mindplot.ConnectionLine.CURVED); + if (line.getType() == "CurvedLine") { + line.setSrcControlPoint(ctrlPoints[0]); + line.setDestControlPoint(ctrlPoints[1]); + } + } else { + line = this._createLine(lineType, mindplot.ConnectionLine.SIMPLE_CURVED); + if (line.getType() == "CurvedLine") { + line.setSrcControlPoint(ctrlPoints[0]); + line.setDestControlPoint(ctrlPoints[1]); + } + } + // Set line styles ... + var strokeColor = mindplot.ConnectionLine.getStrokeColor(); + line.setStroke(1, 'solid', strokeColor, 1); + line.setFill(strokeColor, 1); + + this._line2d = line; + }, + + _getCtrlPoints:function (sourceNode, targetNode) { + var srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition()); + var destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition()); + var deltaX = (srcPos.x - destPos.x) / 3; + return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)]; + }, + + _createLine:function (lineType, defaultStyle) { + if (!$defined(lineType)) { + lineType = defaultStyle; + } + lineType = parseInt(lineType); + this._lineType = lineType; + var line = null; + switch (lineType) { + case mindplot.ConnectionLine.POLYLINE: + line = new web2d.PolyLine(); + break; + case mindplot.ConnectionLine.CURVED: + line = new web2d.CurvedLine(); + break; + case mindplot.ConnectionLine.SIMPLE_CURVED: + line = new web2d.CurvedLine(); + line.setStyle(web2d.CurvedLine.SIMPLE_LINE); + break; + default: + line = new web2d.Line(); + break; + } + return line; + }, + + setVisibility:function (value) { + this._line2d.setVisibility(value); + }, + + isVisible:function () { + return this._line2d.isVisible(); + }, + + setOpacity:function (opacity) { + this._line2d.setOpacity(opacity); + }, + + redraw:function () { + var line2d = this._line2d; + var sourceTopic = this._sourceTopic; + var sourcePosition = sourceTopic.getPosition(); + + var targetTopic = this._targetTopic; + var targetPosition = targetTopic.getPosition(); + + var sPos, tPos; + sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition); + tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition); + + line2d.setFrom(tPos.x, tPos.y); + line2d.setTo(sPos.x, sPos.y); + + if (line2d.getType() == "CurvedLine") { + var ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic); + line2d.setSrcControlPoint(ctrlPoints[0]); + line2d.setDestControlPoint(ctrlPoints[1]); + } + + // Add connector ... + this._positionateConnector(targetTopic); + + }, + + _positionateConnector:function (targetTopic) { + var targetPosition = targetTopic.getPosition(); + var offset = mindplot.Topic.CONNECTOR_WIDTH / 2; + var targetTopicSize = targetTopic.getSize(); + var y, x; + if (targetTopic.getShapeType() == mindplot.model.TopicShape.LINE) { + y = targetTopicSize.height; + } else { + y = targetTopicSize.height / 2; + } + y = y - offset; + + var connector = targetTopic.getShrinkConnector(); + if ($defined(connector)) { + if (Math.sign(targetPosition.x) > 0) { + x = targetTopicSize.width; + connector.setPosition(x, y); + } + else { + x = -mindplot.Topic.CONNECTOR_WIDTH; + } + console.log("conector:" + x + ", " + y); + connector.setPosition(x, y); + + } + + }, + + setStroke:function (color, style, opacity) { + this._line2d.setStroke(null, null, color, opacity); + }, + + addToWorkspace:function (workspace) { + workspace.appendChild(this._line2d); + this._line2d.moveToBack(); + }, + + removeFromWorkspace:function (workspace) { + workspace.removeChild(this._line2d); + }, + + getTargetTopic:function () { + return this._targetTopic; + }, + + getSourceTopic:function () { + return this._sourceTopic; + }, + + getLineType:function () { + return this._lineType; + }, + + getLine:function () { + return this._line2d; + }, + + getModel:function () { + return this._model; + }, + + setModel:function (model) { + this._model = model; + }, + + getType:function () { + return "ConnectionLine"; + }, + + getId:function () { + return this._model.getId(); + }, + + moveToBack:function () { + this._line2d.moveToBack(); + }, + + moveToFront:function () { + this._line2d.moveToFront(); + } +}); + +mindplot.ConnectionLine.getStrokeColor = function () { + return '#495879'; +}; + +mindplot.ConnectionLine.SIMPLE = 0; +mindplot.ConnectionLine.POLYLINE = 1; +mindplot.ConnectionLine.CURVED = 2; mindplot.ConnectionLine.SIMPLE_CURVED = 3; \ No newline at end of file diff --git a/mindplot/src/main/javascript/Designer.js b/mindplot/src/main/javascript/Designer.js index 6bb3010e..a55a0145 100644 --- a/mindplot/src/main/javascript/Designer.js +++ b/mindplot/src/main/javascript/Designer.js @@ -506,7 +506,6 @@ mindplot.Designer = new Class({ $assert(mindmapModel, "mindmapModel can not be null"); this._mindmap = mindmapModel; -// try { // Init layout manager ... var size = {width:25, height:25}; var layoutManager = new mindplot.layout.LayoutManager(mindmapModel.getCentralTopic().getId(), size); @@ -543,9 +542,6 @@ mindplot.Designer = new Class({ mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.DoLayout); this.fireEvent('loadSuccess'); -// } catch(e) { -// this.fireEvent('loadError', e); -// } }, getMindmap:function () { @@ -591,7 +587,7 @@ mindplot.Designer = new Class({ _relationshipModelToRelationship:function (model) { $assert(model, "Node model can not be null"); - var result = this._buildRelationship(model); + var result = this._buildRelationshipShape(model); var sourceTopic = result.getSourceTopic(); sourceTopic.addRelationship(result); @@ -602,7 +598,6 @@ mindplot.Designer = new Class({ result.setVisibility(sourceTopic.isVisible() && targetTopic.isVisible()); this._workspace.appendChild(result); - result.redraw(); return result; }, @@ -623,7 +618,7 @@ mindplot.Designer = new Class({ this.getModel().removeRelationship(relationship); }, - _buildRelationship:function (model) { + _buildRelationshipShape:function (model) { var dmodel = this.getModel(); var sourceTopicId = model.getFromNode(); @@ -674,16 +669,20 @@ mindplot.Designer = new Class({ // If there are more than one node selected, $notify($msg('ENTITIES_COULD_NOT_BE_DELETED')); return; + } else if (topics.length == 1 && topics[0].getTopicType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) { + $notify($msg('CENTRAL_TOPIC_CAN_NOT_BE_DELETED')); + return; } - // Filter the lists ... - var validateFunc = function (object) { - return object.getType() == mindplot.Relationship.type || object.getTopicType() != mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE - }; - var validateError = $msg('CENTRAL_TOPIC_CAN_NOT_BE_DELETED'); - var model = this.getModel(); - var topicIds = model.filterTopicsIds(validateFunc, validateError); - var relIds = model.filterSelectedRelationships().map(function (rel) { + // If the central topic has been selected, I must filter ir + var topicIds = topics.filter(function (topic) { + return topic.getTopicType() != mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE + }).map(function (topic) { + return topic.getId() + }); + + + var relIds = topics.map(function (rel) { return rel.getId(); }); diff --git a/mindplot/src/main/javascript/DesignerKeyboard.js b/mindplot/src/main/javascript/DesignerKeyboard.js index d3ffed21..01a616ec 100644 --- a/mindplot/src/main/javascript/DesignerKeyboard.js +++ b/mindplot/src/main/javascript/DesignerKeyboard.js @@ -42,11 +42,11 @@ mindplot.DesignerKeyboard = new Class({ var model = designer.getModel(); var keyboardEvents = { 'backspace':function (event) { - designer.deleteSelectedEntities(); - event.preventDefault(); event.stopPropagation(); + designer.deleteSelectedEntities(); + }.bind(this), 'space':function () { @@ -73,129 +73,123 @@ mindplot.DesignerKeyboard = new Class({ }.bind(this), 'meta+enter':function (event) { - designer.createChildForSelectedNode(); - event.preventDefault(); event.stopPropagation(); + designer.createChildForSelectedNode(); }.bind(this), 'ctrl+z':function () { - designer.undo(); - event.preventDefault(event); event.stopPropagation(); - + designer.undo(); }.bind(this), 'meta+z':function (event) { - designer.undo(); - event.preventDefault(); event.stopPropagation(); + designer.undo(); + }.bind(this), 'ctrl+z+shift':function (event) { - designer.redo(); - event.preventDefault(); event.stopPropagation(); + + designer.redo(); }.bind(this), 'meta+z+shift':function (event) { - designer.redo(); - event.preventDefault(); event.stopPropagation(); + + designer.redo(); }.bind(this), 'ctrl+y':function (event) { - designer.redo(); - event.preventDefault(); event.stopPropagation(); + designer.redo(); + }.bind(this), 'meta+y':function (event) { - designer.redo(); - event.preventDefault(); event.stopPropagation(); + designer.redo(); + }.bind(this), 'ctrl+a':function (event) { - designer.selectAll(); - event.preventDefault(); event.stopPropagation(); + + designer.selectAll(); }, 'ctrl+b':function (event) { - designer.changeFontWeight(); - event.preventDefault(); event.stopPropagation(); + + designer.changeFontWeight(); }, 'meta+b':function (event) { - designer.changeFontWeight(); - event.preventDefault(); event.stopPropagation(); + + designer.changeFontWeight(); }, 'ctrl+s':function (event) { - event.preventDefault(); - $('save').fireEvent('click'); - event.preventDefault(); event.stopPropagation(); + $('save').fireEvent('click'); }, 'meta+s':function (event) { - event.preventDefault(); - $('save').fireEvent('click'); - event.preventDefault(); event.stopPropagation(); + + $('save').fireEvent('click'); }, 'ctrl+i':function (event) { - designer.changeFontStyle(); - event.preventDefault(); event.stopPropagation(); + + designer.changeFontStyle(); }, 'meta+i':function (event) { - designer.changeFontStyle(); - event.preventDefault(); event.stopPropagation(); + + designer.changeFontStyle(); }, 'meta+shift+a':function (event) { - designer.deselectAll(); - event.preventDefault(); event.stopPropagation(); + + designer.deselectAll(); }, 'ctrl+shift+a':function (event) { - designer.deselectAll(); - event.preventDefault(); event.stopPropagation(); + + designer.deselectAll(); }, 'meta+a':function (event) { - designer.selectAll(); - event.preventDefault(); event.stopPropagation(); + + designer.selectAll(); }, 'right':function () { diff --git a/mindplot/src/main/javascript/Relationship.js b/mindplot/src/main/javascript/Relationship.js index b18f5af7..bf6770e8 100644 --- a/mindplot/src/main/javascript/Relationship.js +++ b/mindplot/src/main/javascript/Relationship.js @@ -17,9 +17,15 @@ */ mindplot.Relationship = new Class({ Extends:mindplot.ConnectionLine, + Static:{ + getStrokeColor:function () { + return '#9b74e6'; + }, + type: "Relationship" + }, initialize:function (sourceNode, targetNode, model) { - $assert(sourceNode,"sourceNode can not be null"); - $assert(targetNode,"targetNode can not be null"); + $assert(sourceNode, "sourceNode can not be null"); + $assert(targetNode, "targetNode can not be null"); this.parent(sourceNode, targetNode, model.getLineType()); this.setModel(model); @@ -161,6 +167,8 @@ mindplot.Relationship = new Class({ this.parent(workspace); this._positionArrows(); + this.redraw(); + }, _initializeControlPointController:function () { @@ -306,13 +314,7 @@ mindplot.Relationship = new Class({ this._line2d.setIsDestControlPointCustom(isCustom); }, - getId: function(){ + getId:function () { return this._model.getId(); } }); - - -mindplot.Relationship.type = "Relationship"; -mindplot.Relationship.getStrokeColor = function () { - return '#9b74e6'; -}; diff --git a/mindplot/src/main/javascript/commands/DeleteCommand.js b/mindplot/src/main/javascript/commands/DeleteCommand.js index 4720f883..785e4a52 100644 --- a/mindplot/src/main/javascript/commands/DeleteCommand.js +++ b/mindplot/src/main/javascript/commands/DeleteCommand.js @@ -30,10 +30,14 @@ mindplot.commands.DeleteCommand = new Class({ }, execute:function (commandContext) { - var topics = commandContext.findTopics(this._topicIds); + + // If a parent has been selected for deletion, the children must be excluded from the delete ... + var topics = this._filterChildren(this._topicIds, commandContext); + + if (topics.length > 0) { topics.forEach( - function (topic, index) { + function (topic) { var model = topic.getModel(); // Delete relationships @@ -45,9 +49,8 @@ mindplot.commands.DeleteCommand = new Class({ commandContext.deleteRelationship(relationship); } + // Delete the node itself ... this._deletedTopicModels.push(model); - - // Is connected?. var outTopic = topic.getOutgoingConnectedTopic(); var outTopicId = null; if (outTopic != null) { @@ -72,9 +75,7 @@ mindplot.commands.DeleteCommand = new Class({ undoExecute:function (commandContext) { - var topics = commandContext.findTopics(this._topicIds); var parent = commandContext.findTopics(this._parentTopicIds); - this._deletedTopicModels.forEach( function (model, index) { var topic = commandContext.createTopic(model); @@ -95,5 +96,28 @@ mindplot.commands.DeleteCommand = new Class({ this._deletedTopicModels = []; this._parentTopicIds = []; this._deletedRelModel = []; + }, + + _filterChildren:function (topicIds, commandContext) { + var topics = commandContext.findTopics(topicIds); + + var result = []; + topics.forEach(function (topic) { + var parent = topic.getParent(); + var found = false; + while (parent != null && !found) { + found = topicIds.contains(parent.getId()); + if (found) { + break; + } + parent = parent.getParent(); + } + + if (!found) { + result.push(topic); + } + }); + + return result; } }); \ No newline at end of file diff --git a/mindplot/src/main/javascript/layout/BalancedSorter.js b/mindplot/src/main/javascript/layout/BalancedSorter.js index f7d70ced..40d5043e 100644 --- a/mindplot/src/main/javascript/layout/BalancedSorter.js +++ b/mindplot/src/main/javascript/layout/BalancedSorter.js @@ -16,13 +16,13 @@ * limitations under the License. */ mindplot.layout.BalancedSorter = new Class({ - Extends: mindplot.layout.AbstractBasicSorter, + Extends:mindplot.layout.AbstractBasicSorter, - initialize: function() { + initialize:function () { }, - predict : function(graph, parent, node, position, free) { + predict:function (graph, parent, node, position, free) { // If its a free node... if (free) { $assert($defined(position), "position cannot be null for predict in free positioning"); @@ -31,13 +31,13 @@ mindplot.layout.BalancedSorter = new Class({ var rootNode = graph.getRootNode(parent); var direction = this._getRelativeDirection(rootNode.getPosition(), node.getPosition()); - var limitXPos = parent.getPosition().x + direction * (parent.getSize().width/2 + node.getSize().width/2 + mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING); + var limitXPos = parent.getPosition().x + direction * (parent.getSize().width / 2 + node.getSize().width / 2 + mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING); var xPos = direction > 0 ? (position.x >= limitXPos ? position.x : limitXPos) : - (position.x <= limitXPos ? position.x : limitXPos) ; + (position.x <= limitXPos ? position.x : limitXPos); - return [0, {x: xPos, y:position.y}]; + return [0, {x:xPos, y:position.y}]; } var rootNode = graph.getRootNode(parent); @@ -61,10 +61,10 @@ mindplot.layout.BalancedSorter = new Class({ } // Filter nodes on one side.. var order = position ? (position.x > rootNode.getPosition().x ? 0 : 1) : ((right.length - left.length) > 0 ? 1 : 0); - var direction = order%2 == 0 ? 1 : -1; + var direction = order % 2 == 0 ? 1 : -1; // Exclude the dragged node (if set) - var children = this._getChildrenForOrder(parent, graph, order).filter(function(child) { + var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) { return child != node; }); @@ -76,14 +76,14 @@ mindplot.layout.BalancedSorter = new Class({ // Try to fit within ... var result = null; var last = children.getLast(); - position = position || {x: last.getPosition().x, y:last.getPosition().y + 1}; - children.each(function(child, index) { + position = position || {x:last.getPosition().x, y:last.getPosition().y + 1}; + children.each(function (child, index) { var cpos = child.getPosition(); if (position.y > cpos.y) { yOffset = child == last ? child.getSize().height + mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING * 2 : (children[index + 1].getPosition().y - child.getPosition().y) / 2; - result = [child.getOrder() + 2,{x:cpos.x, y:cpos.y + yOffset}]; + result = [child.getOrder() + 2, {x:cpos.x, y:cpos.y + yOffset}]; } }); @@ -99,7 +99,7 @@ mindplot.layout.BalancedSorter = new Class({ return result; }, - insert: function(treeSet, parent, child, order) { + insert:function (treeSet, parent, child, order) { var children = this._getChildrenForOrder(parent, treeSet, order); // If no children, return 0 or 1 depending on the side @@ -124,12 +124,12 @@ mindplot.layout.BalancedSorter = new Class({ child.setOrder(newOrder); }, - detach:function(treeSet, node) { + detach:function (treeSet, node) { var parent = treeSet.getParent(node); // Filter nodes on one side.. var children = this._getChildrenForOrder(parent, treeSet, node.getOrder()); - children.each(function(child, index) { + children.each(function (child, index) { if (child.getOrder() > node.getOrder()) { child.setOrder(child.getOrder() - 2); } @@ -137,7 +137,7 @@ mindplot.layout.BalancedSorter = new Class({ node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1); }, - computeOffsets:function(treeSet, node) { + computeOffsets:function (treeSet, node) { $assert(treeSet, "treeSet can no be null."); $assert(node, "node can no be null."); @@ -145,8 +145,8 @@ mindplot.layout.BalancedSorter = new Class({ // Compute heights ... var heights = children.map( - function(child) { - return {id:child.getId(), order:child.getOrder(), width: child.getSize().width, height:this._computeChildrenHeight(treeSet, child)}; + function (child) { + return {id:child.getId(), order:child.getOrder(), width:child.getSize().width, height:this._computeChildrenHeight(treeSet, child)}; }, this).reverse(); @@ -154,7 +154,7 @@ mindplot.layout.BalancedSorter = new Class({ var totalPHeight = 0; var totalNHeight = 0; - heights.forEach(function(elem) { + heights.forEach(function (elem) { if (elem.order % 2 == 0) { totalPHeight += elem.height; } else { @@ -179,17 +179,17 @@ mindplot.layout.BalancedSorter = new Class({ } var yOffset = ysum + heights[i].height / 2; - var xOffset = direction * (node.getSize().width / 2 + heights[i].width / 2 + + mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING); + var xOffset = direction * (node.getSize().width / 2 + heights[i].width / 2 + +mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING); $assert(!isNaN(xOffset), "xOffset can not be null"); $assert(!isNaN(yOffset), "yOffset can not be null"); - result[heights[i].id] = {x:xOffset,y:yOffset}; + result[heights[i].id] = {x:xOffset, y:yOffset}; } return result; }, - verify:function(treeSet, node) { + verify:function (treeSet, node) { // Check that all is consistent ... var children = this._getChildrenForOrder(node, treeSet, node.getOrder()); @@ -198,37 +198,37 @@ mindplot.layout.BalancedSorter = new Class({ var factor = node.getOrder() % 2 == 0 ? 2 : 1; for (var i = 0; i < children.length; i++) { var order = i == 0 && factor == 1 ? 1 : (factor * i); - $assert(children[i].getOrder() == order, "Missing order elements. Missing order: " + (i * factor)); + $assert(children[i].getOrder() == order, "Missing order elements. Missing order: " + (i * factor) + ". Parent:" + node.getId() + ",Node:" + children[i].getId()); } }, - getDirection: function(treeSet, node) { + getDirection:function (treeSet, node) { return node.getOrder() % 2 == 0 ? 1 : -1; }, - toString:function() { + toString:function () { return "Balanced Sorter"; }, - _getOrderForPosition: function(rootNode, position) { + _getOrderForPosition:function (rootNode, position) { return position.x > rootNode.getPosition().x ? 0 : 1; }, - _getChildrenForSide: function(parent, graph, position) { - position = position || {x: parent.getPosition().x + 1, y:parent.getPosition().y + 1}; + _getChildrenForSide:function (parent, graph, position) { + position = position || {x:parent.getPosition().x + 1, y:parent.getPosition().y + 1}; var rootPosition = graph.getRootNode(parent).getPosition(); - return graph.getChildren(parent).filter(function(child) { + return graph.getChildren(parent).filter(function (child) { return position.x > rootPosition.x ? child.getPosition().x > rootPosition.x : child.getPosition().x < rootPosition.x; }); }, - _getChildrenForOrder: function (parent, graph, order) { - return this._getSortedChildren(graph, parent).filter(function(child) { + _getChildrenForOrder:function (parent, graph, order) { + return this._getSortedChildren(graph, parent).filter(function (child) { return child.getOrder() % 2 == order % 2; }); }, - _getVerticalPadding: function() { + _getVerticalPadding:function () { return mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING; } }); diff --git a/mindplot/src/main/javascript/layout/OriginalLayout.js b/mindplot/src/main/javascript/layout/OriginalLayout.js index 717eb5ad..2347cc93 100644 --- a/mindplot/src/main/javascript/layout/OriginalLayout.js +++ b/mindplot/src/main/javascript/layout/OriginalLayout.js @@ -16,11 +16,11 @@ * limitations under the License. */ mindplot.layout.OriginalLayout = new Class({ - initialize: function(treeSet) { + initialize:function (treeSet) { this._treeSet = treeSet; }, - createNode:function(id, size, position, type) { + createNode:function (id, size, position, type) { $assert($defined(id), "id can not be null"); $assert(size, "size can not be null"); $assert(position, "position can not be null"); @@ -32,7 +32,7 @@ mindplot.layout.OriginalLayout = new Class({ return new mindplot.layout.Node(id, size, position, strategy); }, - connectNode: function(parentId, childId, order) { + connectNode:function (parentId, childId, order) { var parent = this._treeSet.find(parentId); var child = this._treeSet.find(childId); @@ -48,7 +48,7 @@ mindplot.layout.OriginalLayout = new Class({ sorter.verify(this._treeSet, parent); }, - disconnectNode: function(nodeId) { + disconnectNode:function (nodeId) { var node = this._treeSet.find(nodeId); var parent = this._treeSet.getParent(node); $assert(parent, "Node already disconnected"); @@ -65,12 +65,12 @@ mindplot.layout.OriginalLayout = new Class({ this._treeSet.disconnect(nodeId); // Fire a basic validation ... - sorter.verify(this._treeSet, node); + parent.getSorter().verify(this._treeSet, parent); }, - layout: function() { + layout:function () { var roots = this._treeSet.getTreeRoots(); - roots.forEach(function(node) { + roots.forEach(function (node) { // Calculate all node heights ... var sorter = node.getSorter(); @@ -83,13 +83,17 @@ mindplot.layout.OriginalLayout = new Class({ }, this); }, - _layoutChildren: function(node, heightById) { + _layoutChildren:function (node, heightById) { var nodeId = node.getId(); var children = this._treeSet.getChildren(node); var parent = this._treeSet.getParent(node); - var childrenOrderMoved = children.some(function(child) { return child.hasOrderChanged(); }); - var childrenSizeChanged = children.some(function(child) { return child.hasSizeChanged(); }); + var childrenOrderMoved = children.some(function (child) { + return child.hasOrderChanged(); + }); + var childrenSizeChanged = children.some(function (child) { + return child.hasSizeChanged(); + }); // If ether any of the nodes has been changed of position or the height of the children is not // the same, children nodes must be repositioned .... @@ -104,7 +108,7 @@ mindplot.layout.OriginalLayout = new Class({ var offsetById = sorter.computeOffsets(this._treeSet, node); var parentPosition = node.getPosition(); - children.forEach(function(child) { + children.forEach(function (child) { var offset = offsetById[child.getId()]; var childFreeDisplacement = child.getFreeDisplacement(); @@ -112,7 +116,7 @@ mindplot.layout.OriginalLayout = new Class({ if ((direction > 0 && childFreeDisplacement.x < 0) || (direction < 0 && childFreeDisplacement.x > 0)) { child.resetFreeDisplacement(); - child.setFreeDisplacement({x: -childFreeDisplacement.x, y:childFreeDisplacement.y}); + child.setFreeDisplacement({x:-childFreeDisplacement.x, y:childFreeDisplacement.y}); } offset.x += child.getFreeDisplacement().x; @@ -129,12 +133,12 @@ mindplot.layout.OriginalLayout = new Class({ } // Continue reordering the children nodes ... - children.forEach(function(child) { + children.forEach(function (child) { this._layoutChildren(child, heightById); }, this); }, - _calculateAlignOffset: function(node, child, heightById) { + _calculateAlignOffset:function (node, child, heightById) { if (child.isFree()) { return 0; } @@ -146,15 +150,15 @@ mindplot.layout.OriginalLayout = new Class({ if (this._treeSet.isStartOfSubBranch(child) && this._branchIsTaller(child, heightById)) { if (this._treeSet.hasSinglePathToSingleLeaf(child)) { - offset = heightById[child.getId()]/2 - (childHeight + child.getSorter()._getVerticalPadding()*2)/2; + offset = heightById[child.getId()] / 2 - (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2; } else { - offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight)/2; + offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2; } } else if (nodeHeight > childHeight) { if (this._treeSet.getSiblings(child).length > 0) { offset = 0; } else { - offset = nodeHeight/2 - childHeight/2; + offset = nodeHeight / 2 - childHeight / 2; } } else if (childHeight > nodeHeight) { @@ -168,29 +172,29 @@ mindplot.layout.OriginalLayout = new Class({ return offset; }, - _branchIsTaller: function(node, heightById) { - return heightById[node.getId()] > (node.getSize().height + node.getSorter()._getVerticalPadding()*2); + _branchIsTaller:function (node, heightById) { + return heightById[node.getId()] > (node.getSize().height + node.getSorter()._getVerticalPadding() * 2); }, - _fixOverlapping: function(node, heightById) { + _fixOverlapping:function (node, heightById) { var children = this._treeSet.getChildren(node); if (node.isFree()) { this._shiftBranches(node, heightById); } - children.forEach(function(child) { + children.forEach(function (child) { this._fixOverlapping(child, heightById); }, this); }, - _shiftBranches: function(node, heightById) { + _shiftBranches:function (node, heightById) { var shiftedBranches = [node]; var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(node, node.getFreeDisplacement().y); var last = node; - siblingsToShift.forEach(function(sibling) { - var overlappingOccurs = shiftedBranches.some(function(shiftedBranch) { + siblingsToShift.forEach(function (sibling) { + var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) { return this._branchesOverlap(shiftedBranch, sibling, heightById); }, this); @@ -201,28 +205,28 @@ mindplot.layout.OriginalLayout = new Class({ } }, this); - var branchesToShift = this._treeSet.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y).filter(function(branch) { + var branchesToShift = this._treeSet.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y).filter(function (branch) { return !shiftedBranches.contains(branch); }); - branchesToShift.forEach(function(branch) { + branchesToShift.forEach(function (branch) { var bAmount = node.getFreeDisplacement().y; this._treeSet.shiftBranchPosition(branch, 0, bAmount); shiftedBranches.push(branch); last = branch; - },this); + }, this); }, - _branchesOverlap: function(branchA, branchB, heightById) { + _branchesOverlap:function (branchA, branchB, heightById) { // a branch doesn't really overlap with itself if (branchA == branchB) { return false; } - var topA = branchA.getPosition().y - heightById[branchA.getId()]/2; - var bottomA = branchA.getPosition().y + heightById[branchA.getId()]/2; - var topB = branchB.getPosition().y - heightById[branchB.getId()]/2; - var bottomB = branchB.getPosition().y + heightById[branchB.getId()]/2; + var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2; + var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2; + var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2; + var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2; return !(topA >= bottomB || bottomA <= topB); } diff --git a/mindplot/src/main/javascript/model/Mindmap.js b/mindplot/src/main/javascript/model/Mindmap.js index 983eb46f..086fb17e 100644 --- a/mindplot/src/main/javascript/model/Mindmap.js +++ b/mindplot/src/main/javascript/model/Mindmap.js @@ -16,8 +16,8 @@ * limitations under the License. */ mindplot.model.Mindmap = new Class({ - Extends: mindplot.model.IMindmap, - initialize : function(id, version) { + Extends:mindplot.model.IMindmap, + initialize:function (id, version) { $assert(id, "Id can not be null"); this._branches = []; this._description = null; @@ -26,32 +26,32 @@ mindplot.model.Mindmap = new Class({ this._id = id; }, - getDescription : function() { + getDescription:function () { return this._description; }, - setDescription : function(value) { + setDescription:function (value) { this._description = value; }, - getId : function() { + getId:function () { return this._id; }, - setId : function(id) { + setId:function (id) { this._id = id; }, - getVersion : function() { + getVersion:function () { return this._version; }, - setVersion : function(version) { + setVersion:function (version) { this._version = version; }, - addBranch : function(nodeModel) { + addBranch:function (nodeModel) { $assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects'); var branches = this.getBranches(); if (branches.length == 0) { @@ -64,20 +64,20 @@ mindplot.model.Mindmap = new Class({ this._branches.push(nodeModel); }, - removeBranch : function(nodeModel) { + removeBranch:function (nodeModel) { $assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects'); return this._branches.erase(nodeModel); }, - getBranches : function() { + getBranches:function () { return this._branches; }, - getRelationships : function() { + getRelationships:function () { return this._relationships; }, - hasAlreadyAdded : function(node) { + hasAlreadyAdded:function (node) { var result = false; // Check in not connected nodes. @@ -90,29 +90,40 @@ mindplot.model.Mindmap = new Class({ } }, - createNode : function(type, id) { + createNode:function (type, id) { type = !$defined(type) ? mindplot.model.INodeModel.MAIN_TOPIC_TYPE : type; return new mindplot.model.NodeModel(type, this, id); }, - createRelationship : function(sourceNodeId, targetNodeId) { + createRelationship:function (sourceNodeId, targetNodeId) { $assert($defined(sourceNodeId), 'from node cannot be null'); $assert($defined(targetNodeId), 'to node cannot be null'); return new mindplot.model.RelationshipModel(sourceNodeId, targetNodeId); }, - addRelationship : function(relationship) { + addRelationship:function (relationship) { this._relationships.push(relationship); }, - deleteRelationship : function(relationship) { + deleteRelationship:function (relationship) { this._relationships.erase(relationship); + }, + + findNodeById:function (id) { + var result; + for (var i = 0; i < this._branches; i++) { + var branch = this._branches[i]; + result = branch.findNodeById(id) + if (result) { + break; + } + } } } ); -mindplot.model.Mindmap.buildEmpty = function(mapId) { +mindplot.model.Mindmap.buildEmpty = function (mapId) { var result = new mindplot.model.Mindmap(mapId); var node = result.createNode(mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE, 0); result.addBranch(node); diff --git a/mindplot/src/main/javascript/model/NodeModel.js b/mindplot/src/main/javascript/model/NodeModel.js index 96ddfaf6..7031e5c1 100644 --- a/mindplot/src/main/javascript/model/NodeModel.js +++ b/mindplot/src/main/javascript/model/NodeModel.js @@ -1,193 +1,210 @@ -/* - * Copyright [2011] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -mindplot.model.NodeModel = new Class({ - Extends: mindplot.model.INodeModel, - initialize:function(type, mindmap, id) { - $assert(type, 'Node type can not be null'); - $assert(mindmap, 'mindmap can not be null'); - this._properties = {}; - - this.parent(mindmap); - this.setId(id); - this.setType(type); - this.areChildrenShrunken(false); - - this._children = []; - this._feature = []; - }, - - createFeature: function(type, attributes) { - return mindplot.TopicFeature.createModel(type, this, attributes); - }, - - addFeature: function(feature) { - $assert(feature, 'feature can not be null'); - this._feature.push(feature); - }, - - getFeatures: function() { - return this._feature; - }, - - removeFeature: function(feature) { - $assert(feature, 'feature can not be null'); - this._feature.erase(feature); - }, - - findFeatureByType : function(type) { - $assert(type, 'type can not be null'); - return this._feature.filter(function(feature) { - return feature.getType() == type; - }); - }, - - findFeatureById : function(id) { - $assert($defined(id), 'id can not be null'); - return this._feature.filter(function(feature) { - return feature.getId() == id; - })[0]; - }, - - getPropertiesKeys : function() { - return Object.keys(this._properties); - }, - - putProperty : function(key, value) { - $defined(key, 'key can not be null'); - this._properties[key] = value; - }, - - - getProperties: function() { - return this._properties; - }, - - getProperty : function(key) { - $defined(key, 'key can not be null'); - var result = this._properties[key]; - return !$defined(result) ? null : result; - }, - - clone : function() { - var result = new mindplot.model.NodeModel(this.getType(), this._mindmap); - result._children = this._children.each(function(node) { - var cnode = node.clone(); - cnode._parent = result; - return cnode; - }); - - result._properties = Object.clone(this._properties); - result._feature = this._feature.clone(); - return result; - }, - - appendChild : function(child) { - $assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object'); - this._children.push(child); - child._parent = this; - }, - - removeChild : function(child) { - $assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.'); - this._children.erase(child); - child._parent = null; - }, - - getChildren : function() { - return this._children; - }, - - getParent : function() { - return this._parent; - }, - - setParent : function(parent) { - $assert(parent != this, 'The same node can not be parent and child if itself.'); - this._parent = parent; - }, - - canBeConnected : function(sourceModel, sourcePosition, targetTopicHeight,targetTopicSize) { - $assert(sourceModel != this, 'The same node can not be parent and child if itself.'); - $assert(sourcePosition, 'childPosition can not be null.'); - $assert(targetTopicHeight, 'childrenWidth can not be null.'); - $assert(targetTopicSize, 'targetTopicSize can not be null.'); - - - // Only can be connected if the node is in the left or rigth. - var targetModel = this; - var mindmap = targetModel.getMindmap(); - var targetPosition = targetModel.getPosition(); - var result = false; - - if (sourceModel.getType() == mindplot.model.INodeModel.MAIN_TOPIC_TYPE) { - // Finally, check current node position ... - var yDistance = Math.abs(sourcePosition.y - targetPosition.y); - var gap = 35 + targetTopicHeight / 2; - if (targetModel.getChildren().length > 0) { - gap += Math.abs(targetPosition.y - targetModel.getChildren()[0].getPosition().y); - } - - if (yDistance <= gap) { - // Circular connection ? - if (!sourceModel._isChildNode(this)) { - var toleranceDistance = (targetTopicSize.width / 2) + targetTopicHeight; - - var xDistance = sourcePosition.x - targetPosition.x; - var isTargetAtRightFromCentral = targetPosition.x >= 0; - - if (isTargetAtRightFromCentral) { - if (xDistance >= -targetTopicSize.width / 2 && xDistance <= mindplot.model.INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE / 2 + (targetTopicSize.width / 2)) { - result = true; - } - - } else { - if (xDistance <= targetTopicSize.width / 2 && Math.abs(xDistance) <= mindplot.model.INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE / 2 + (targetTopicSize.width / 2)) { - result = true; - } - } - } - } - } else { - throw "No implemented yet"; - } - return result; - }, - - _isChildNode : function(node) { - var result = false; - if (node == this) { - result = true; - } else { - var children = this.getChildren(); - for (var i = 0; i < children.length; i++) { - var child = children[i]; - result = child._isChildNode(node); - if (result) { - break; - } - } - } - return result; - - }, - - inspect : function() { - return '(type:' + this.getType() + ' , id: ' + this.getId() + ')'; - } +/* + * Copyright [2011] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +mindplot.model.NodeModel = new Class({ + Extends: mindplot.model.INodeModel, + initialize:function(type, mindmap, id) { + $assert(type, 'Node type can not be null'); + $assert(mindmap, 'mindmap can not be null'); + this._properties = {}; + + this.parent(mindmap); + this.setId(id); + this.setType(type); + this.areChildrenShrunken(false); + + this._children = []; + this._feature = []; + }, + + createFeature: function(type, attributes) { + return mindplot.TopicFeature.createModel(type, this, attributes); + }, + + addFeature: function(feature) { + $assert(feature, 'feature can not be null'); + this._feature.push(feature); + }, + + getFeatures: function() { + return this._feature; + }, + + removeFeature: function(feature) { + $assert(feature, 'feature can not be null'); + this._feature.erase(feature); + }, + + findFeatureByType : function(type) { + $assert(type, 'type can not be null'); + return this._feature.filter(function(feature) { + return feature.getType() == type; + }); + }, + + findFeatureById : function(id) { + $assert($defined(id), 'id can not be null'); + return this._feature.filter(function(feature) { + return feature.getId() == id; + })[0]; + }, + + getPropertiesKeys : function() { + return Object.keys(this._properties); + }, + + putProperty : function(key, value) { + $defined(key, 'key can not be null'); + this._properties[key] = value; + }, + + + getProperties: function() { + return this._properties; + }, + + getProperty : function(key) { + $defined(key, 'key can not be null'); + var result = this._properties[key]; + return !$defined(result) ? null : result; + }, + + clone : function() { + var result = new mindplot.model.NodeModel(this.getType(), this._mindmap); + result._children = this._children.each(function(node) { + var cnode = node.clone(); + cnode._parent = result; + return cnode; + }); + + result._properties = Object.clone(this._properties); + result._feature = this._feature.clone(); + return result; + }, + + appendChild : function(child) { + $assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object'); + this._children.push(child); + child._parent = this; + }, + + removeChild : function(child) { + $assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.'); + this._children.erase(child); + child._parent = null; + }, + + getChildren : function() { + return this._children; + }, + + getParent : function() { + return this._parent; + }, + + setParent : function(parent) { + $assert(parent != this, 'The same node can not be parent and child if itself.'); + this._parent = parent; + }, + + canBeConnected : function(sourceModel, sourcePosition, targetTopicHeight,targetTopicSize) { + $assert(sourceModel != this, 'The same node can not be parent and child if itself.'); + $assert(sourcePosition, 'childPosition can not be null.'); + $assert(targetTopicHeight, 'childrenWidth can not be null.'); + $assert(targetTopicSize, 'targetTopicSize can not be null.'); + + + // Only can be connected if the node is in the left or rigth. + var targetModel = this; + var mindmap = targetModel.getMindmap(); + var targetPosition = targetModel.getPosition(); + var result = false; + + if (sourceModel.getType() == mindplot.model.INodeModel.MAIN_TOPIC_TYPE) { + // Finally, check current node position ... + var yDistance = Math.abs(sourcePosition.y - targetPosition.y); + var gap = 35 + targetTopicHeight / 2; + if (targetModel.getChildren().length > 0) { + gap += Math.abs(targetPosition.y - targetModel.getChildren()[0].getPosition().y); + } + + if (yDistance <= gap) { + // Circular connection ? + if (!sourceModel._isChildNode(this)) { + var toleranceDistance = (targetTopicSize.width / 2) + targetTopicHeight; + + var xDistance = sourcePosition.x - targetPosition.x; + var isTargetAtRightFromCentral = targetPosition.x >= 0; + + if (isTargetAtRightFromCentral) { + if (xDistance >= -targetTopicSize.width / 2 && xDistance <= mindplot.model.INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE / 2 + (targetTopicSize.width / 2)) { + result = true; + } + + } else { + if (xDistance <= targetTopicSize.width / 2 && Math.abs(xDistance) <= mindplot.model.INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE / 2 + (targetTopicSize.width / 2)) { + result = true; + } + } + } + } + } else { + throw "No implemented yet"; + } + return result; + }, + + _isChildNode : function(node) { + var result = false; + if (node == this) { + result = true; + } else { + var children = this.getChildren(); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + result = child._isChildNode(node); + if (result) { + break; + } + } + } + return result; + }, + + findNodeById : function(id) { + var result = null; + if (this.getId() == id) { + return this; + } else { + var children = this.getChildren(); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + result = child.findNodeById(id); + if (result) { + break; + } + } + } + return result; + }, + + + inspect : function() { + return '(type:' + this.getType() + ' , id: ' + this.getId() + ')'; + } }); \ No newline at end of file diff --git a/mindplot/src/main/javascript/persistence/XMLSerializer_Pela.js b/mindplot/src/main/javascript/persistence/XMLSerializer_Pela.js index d2b07e3f..ece2f9c2 100644 --- a/mindplot/src/main/javascript/persistence/XMLSerializer_Pela.js +++ b/mindplot/src/main/javascript/persistence/XMLSerializer_Pela.js @@ -18,7 +18,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ - toXML : function(mindmap) { + toXML:function (mindmap) { $assert(mindmap, "Can not save a null mindmap"); var document = core.Utils.createDocument(); @@ -56,7 +56,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return document; }, - _topicToXML : function(document, topic) { + _topicToXML:function (document, topic) { var parentTopic = document.createElement("topic"); // Set topic attributes... @@ -164,7 +164,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return parentTopic; }, - _noteTextToXML : function(document, elem, text) { + _noteTextToXML:function (document, elem, text) { if (text.indexOf('\n') == -1) { elem.setAttribute('text', text); } else { @@ -175,7 +175,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ } }, - _relationshipToXML : function(document, relationship) { + _relationshipToXML:function (document, relationship) { var result = document.createElement("relationship"); result.setAttribute("srcTopicId", relationship.getFromNode()); result.setAttribute("destTopicId", relationship.getToNode()); @@ -197,7 +197,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return result; }, - loadFromDom : function(dom, mapId) { + loadFromDom:function (dom, mapId) { $assert(dom, "dom can not be null"); $assert(mapId, "mapId can not be null"); @@ -233,7 +233,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return mindmap; }, - _deserializeNode : function(domElem, mindmap) { + _deserializeNode:function (domElem, mindmap) { var type = (domElem.getAttribute('central') != null) ? mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE : mindplot.model.INodeModel.MAIN_TOPIC_TYPE; // Load attributes... @@ -363,7 +363,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return topic; }, - _deserializeTextAttr : function(domElem) { + _deserializeTextAttr:function (domElem) { var value = domElem.getAttribute("text"); if (!$defined(value)) { var children = domElem.childNodes; @@ -386,7 +386,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return value; }, - _deserializeNodeText: function(domElem) { + _deserializeNodeText:function (domElem) { var children = domElem.childNodes; var value = null; for (var i = 0; i < children.length; i++) { @@ -398,7 +398,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ return value; }, - _deserializeRelationship : function(domElement, mindmap) { + _deserializeRelationship:function (domElement, mindmap) { var srcId = domElement.getAttribute("srcTopicId"); var destId = domElement.getAttribute("destTopicId"); var lineType = domElement.getAttribute("lineType"); @@ -410,6 +410,11 @@ mindplot.persistence.XMLSerializer_Pela = new Class({ if (srcId == destId) { return null; } + // Is the connections points valid ?. If it's not, do not load the relationship ... + if (mindmap.findNodeById(srcId) == null || mindmap.findNodeById(destId)) { + return null; + } + var model = mindmap.createRelationship(srcId, destId); model.setLineType(lineType); if ($defined(srcCtrlPoint) && srcCtrlPoint != "") {