diff options
Diffstat (limited to 'src/js/view/mxGraphSelectionModel.js')
-rw-r--r-- | src/js/view/mxGraphSelectionModel.js | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/src/js/view/mxGraphSelectionModel.js b/src/js/view/mxGraphSelectionModel.js new file mode 100644 index 0000000..5cd16a8 --- /dev/null +++ b/src/js/view/mxGraphSelectionModel.js @@ -0,0 +1,435 @@ +/** + * $Id: mxGraphSelectionModel.js,v 1.14 2011-11-25 10:16:08 gaudenz Exp $ + * Copyright (c) 2006-2010, JGraph Ltd + */ +/** + * Class: mxGraphSelectionModel + * + * Implements the selection model for a graph. Here is a listener that handles + * all removed selection cells. + * + * (code) + * graph.getSelectionModel().addListener(mxEvent.CHANGE, function(sender, evt) + * { + * var cells = evt.getProperty('added'); + * + * for (var i = 0; i < cells.length; i++) + * { + * // Handle cells[i]... + * } + * }); + * (end) + * + * Event: mxEvent.UNDO + * + * Fires after the selection was changed in <changeSelection>. The + * <code>edit</code> property contains the <mxUndoableEdit> which contains the + * <mxSelectionChange>. + * + * Event: mxEvent.CHANGE + * + * Fires after the selection changes by executing an <mxSelectionChange>. The + * <code>added</code> and <code>removed</code> properties contain arrays of + * cells that have been added to or removed from the selection, respectively. + * + * Constructor: mxGraphSelectionModel + * + * Constructs a new graph selection model for the given <mxGraph>. + * + * Parameters: + * + * graph - Reference to the enclosing <mxGraph>. + */ +function mxGraphSelectionModel(graph) +{ + this.graph = graph; + this.cells = []; +}; + +/** + * Extends mxEventSource. + */ +mxGraphSelectionModel.prototype = new mxEventSource(); +mxGraphSelectionModel.prototype.constructor = mxGraphSelectionModel; + +/** + * Variable: doneResource + * + * Specifies the resource key for the status message after a long operation. + * If the resource for this key does not exist then the value is used as + * the status message. Default is 'done'. + */ +mxGraphSelectionModel.prototype.doneResource = (mxClient.language != 'none') ? 'done' : ''; + +/** + * Variable: updatingSelectionResource + * + * Specifies the resource key for the status message while the selection is + * being updated. If the resource for this key does not exist then the + * value is used as the status message. Default is 'updatingSelection'. + */ +mxGraphSelectionModel.prototype.updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : ''; + +/** + * Variable: graph + * + * Reference to the enclosing <mxGraph>. + */ +mxGraphSelectionModel.prototype.graph = null; + +/** + * Variable: singleSelection + * + * Specifies if only one selected item at a time is allowed. + * Default is false. + */ +mxGraphSelectionModel.prototype.singleSelection = false; + +/** + * Function: isSingleSelection + * + * Returns <singleSelection> as a boolean. + */ +mxGraphSelectionModel.prototype.isSingleSelection = function() +{ + return this.singleSelection; +}; + +/** + * Function: setSingleSelection + * + * Sets the <singleSelection> flag. + * + * Parameters: + * + * singleSelection - Boolean that specifies the new value for + * <singleSelection>. + */ +mxGraphSelectionModel.prototype.setSingleSelection = function(singleSelection) +{ + this.singleSelection = singleSelection; +}; + +/** + * Function: isSelected + * + * Returns true if the given <mxCell> is selected. + */ +mxGraphSelectionModel.prototype.isSelected = function(cell) +{ + if (cell != null) + { + return mxUtils.indexOf(this.cells, cell) >= 0; + } + + return false; +}; + +/** + * Function: isEmpty + * + * Returns true if no cells are currently selected. + */ +mxGraphSelectionModel.prototype.isEmpty = function() +{ + return this.cells.length == 0; +}; + +/** + * Function: clear + * + * Clears the selection and fires a <change> event if the selection was not + * empty. + */ +mxGraphSelectionModel.prototype.clear = function() +{ + this.changeSelection(null, this.cells); +}; + +/** + * Function: setCell + * + * Selects the specified <mxCell> using <setCells>. + * + * Parameters: + * + * cell - <mxCell> to be selected. + */ +mxGraphSelectionModel.prototype.setCell = function(cell) +{ + if (cell != null) + { + this.setCells([cell]); + } +}; + +/** + * Function: setCells + * + * Selects the given array of <mxCells> and fires a <change> event. + * + * Parameters: + * + * cells - Array of <mxCells> to be selected. + */ +mxGraphSelectionModel.prototype.setCells = function(cells) +{ + if (cells != null) + { + if (this.singleSelection) + { + cells = [this.getFirstSelectableCell(cells)]; + } + + var tmp = []; + + for (var i = 0; i < cells.length; i++) + { + if (this.graph.isCellSelectable(cells[i])) + { + tmp.push(cells[i]); + } + } + + this.changeSelection(tmp, this.cells); + } +}; + +/** + * Function: getFirstSelectableCell + * + * Returns the first selectable cell in the given array of cells. + */ +mxGraphSelectionModel.prototype.getFirstSelectableCell = function(cells) +{ + if (cells != null) + { + for (var i = 0; i < cells.length; i++) + { + if (this.graph.isCellSelectable(cells[i])) + { + return cells[i]; + } + } + } + + return null; +}; + +/** + * Function: addCell + * + * Adds the given <mxCell> to the selection and fires a <select> event. + * + * Parameters: + * + * cell - <mxCell> to add to the selection. + */ +mxGraphSelectionModel.prototype.addCell = function(cell) +{ + if (cell != null) + { + this.addCells([cell]); + } +}; + +/** + * Function: addCells + * + * Adds the given array of <mxCells> to the selection and fires a <select> + * event. + * + * Parameters: + * + * cells - Array of <mxCells> to add to the selection. + */ +mxGraphSelectionModel.prototype.addCells = function(cells) +{ + if (cells != null) + { + var remove = null; + + if (this.singleSelection) + { + remove = this.cells; + cells = [this.getFirstSelectableCell(cells)]; + } + + var tmp = []; + + for (var i = 0; i < cells.length; i++) + { + if (!this.isSelected(cells[i]) && + this.graph.isCellSelectable(cells[i])) + { + tmp.push(cells[i]); + } + } + + this.changeSelection(tmp, remove); + } +}; + +/** + * Function: removeCell + * + * Removes the specified <mxCell> from the selection and fires a <select> + * event for the remaining cells. + * + * Parameters: + * + * cell - <mxCell> to remove from the selection. + */ +mxGraphSelectionModel.prototype.removeCell = function(cell) +{ + if (cell != null) + { + this.removeCells([cell]); + } +}; + +/** + * Function: removeCells + */ +mxGraphSelectionModel.prototype.removeCells = function(cells) +{ + if (cells != null) + { + var tmp = []; + + for (var i = 0; i < cells.length; i++) + { + if (this.isSelected(cells[i])) + { + tmp.push(cells[i]); + } + } + + this.changeSelection(null, tmp); + } +}; + +/** + * Function: changeSelection + * + * Inner callback to add the specified <mxCell> to the selection. No event + * is fired in this implementation. + * + * Paramters: + * + * cell - <mxCell> to add to the selection. + */ +mxGraphSelectionModel.prototype.changeSelection = function(added, removed) +{ + if ((added != null && + added.length > 0 && + added[0] != null) || + (removed != null && + removed.length > 0 && + removed[0] != null)) + { + var change = new mxSelectionChange(this, added, removed); + change.execute(); + var edit = new mxUndoableEdit(this, false); + edit.add(change); + this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit)); + } +}; + +/** + * Function: cellAdded + * + * Inner callback to add the specified <mxCell> to the selection. No event + * is fired in this implementation. + * + * Paramters: + * + * cell - <mxCell> to add to the selection. + */ +mxGraphSelectionModel.prototype.cellAdded = function(cell) +{ + if (cell != null && + !this.isSelected(cell)) + { + this.cells.push(cell); + } +}; + +/** + * Function: cellRemoved + * + * Inner callback to remove the specified <mxCell> from the selection. No + * event is fired in this implementation. + * + * Parameters: + * + * cell - <mxCell> to remove from the selection. + */ +mxGraphSelectionModel.prototype.cellRemoved = function(cell) +{ + if (cell != null) + { + var index = mxUtils.indexOf(this.cells, cell); + + if (index >= 0) + { + this.cells.splice(index, 1); + } + } +}; + +/** + * Class: mxSelectionChange + * + * Action to change the current root in a view. + * + * Constructor: mxCurrentRootChange + * + * Constructs a change of the current root in the given view. + */ +function mxSelectionChange(selectionModel, added, removed) +{ + this.selectionModel = selectionModel; + this.added = (added != null) ? added.slice() : null; + this.removed = (removed != null) ? removed.slice() : null; +}; + +/** + * Function: execute + * + * Changes the current root of the view. + */ +mxSelectionChange.prototype.execute = function() +{ + var t0 = mxLog.enter('mxSelectionChange.execute'); + window.status = mxResources.get( + this.selectionModel.updatingSelectionResource) || + this.selectionModel.updatingSelectionResource; + + if (this.removed != null) + { + for (var i = 0; i < this.removed.length; i++) + { + this.selectionModel.cellRemoved(this.removed[i]); + } + } + + if (this.added != null) + { + for (var i = 0; i < this.added.length; i++) + { + this.selectionModel.cellAdded(this.added[i]); + } + } + + var tmp = this.added; + this.added = this.removed; + this.removed = tmp; + + window.status = mxResources.get(this.selectionModel.doneResource) || + this.selectionModel.doneResource; + mxLog.leave('mxSelectionChange.execute', t0); + + this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE, + 'added', this.added, 'removed', this.removed)); +}; |