/*
* Copyright 2014 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
/**
* This plugin is a Ext.tree.plugin.TreeViewDragDrop plugin that is compatible with the Ametys relation system.
*
* That means that any dragged node can be drop on any Ametys relation zone and will use the Ametys.relation.RelationManager to connect the results.
* That means that any Ametys object can be drop here.
*
* If you want to be able to drag objects using the relation system, it is required to implement #setAmetysDragInfos and use the default "ametys" dragGroup.
* If you want to be able to drop objects using the relation system, it is required to implement #setAmetysDropZoneInfos and use the default "ametys" dropGroup.
*/
Ext.define('Ametys.relation.dd.AmetysTreeViewDragDrop', {
extend: 'Ext.tree.plugin.TreeViewDragDrop',
alias: 'plugin.ametystreeviewdragdrop',
/**
* @ignore
* @cfg {String} ddGroup
*/
config: {
/**
* @cfg {String} [defaultRelation="null"] A constant in Ametys.relation.Relation to define the default relation during a drag'n'drop operation. Can be null to take the default relation of the Ametys.relation.RelationHandler
*/
defaultRelation: null,
/**
* @cfg {String} [ctrlRelation="Ametys.relation.Relation.COPY"] A constant in Ametys.relation.Relation to define the relation during a drag'n'drop operation when CTRL key is used. Can be null to take the default relation of the Ametys.relation.RelationHandler
*/
ctrlRelation: Ametys.relation.Relation.COPY,
/**
* @cfg {String} [shiftRelation="Ametys.relation.Relation.MOVE"] A constant in Ametys.relation.Relation to define the relation during a drag'n'drop operation when SHIFT key is used. Can be null to take the default relation of the Ametys.relation.RelationHandler
*/
shiftRelation: Ametys.relation.Relation.MOVE
},
/**
* @cfg {Function} setAmetysDragInfos (required) Implements this method called by the getDragData method to create the Ametys.relation.RelationPoint of the drag operation.
* @cfg {Object} setAmetysDragInfos.item The default drag data that will be transmitted. You have to add a 'source' item in it:
* @cfg {Object} setAmetysDragInfos.item.source The source (in the relation way) of the drag operation. A Ametys.relation.RelationPoint config.
*/
/**
* @cfg {Function} setAmetysDropZoneInfos (required) Implements this method called before the beforeDrop event to create the Ametys.relation.RelationPoint of the drop operation.
* @cfg {Ext.data.Model[]} setAmetysDropZoneInfos.targetRecords The target records of the drop operation.
* @cfg {Object} setAmetysDropZoneInfos.item The default drag data that will be transmitted. You have to add a 'target' item in it:
* @cfg {Object} setAmetysDropZoneInfos.item.target The target (in the relation way) of the drop operation. A Ametys.relation.RelationPoint config.
* @cfg {String} setAmetysDropZoneInfos.dropPosition "before", "after" or "append" depending whether the dragged object (in item.target) should be inserted before, after the targetRecords, or appended to it.
*/
onViewRender : function(view)
{
var me = this,
scrollEl;
if (me.enableDrag)
{
if (me.containerScroll)
{
scrollEl = view.getEl();
}
view.copy = true;
me.dragZone = new Ametys.relation.dd.AmetysTreeViewDragZone({
view: view,
ddGroup: me.dragGroup || "ametys",
dragText: me.dragText,
displayField: me.displayField,
repairHighlightColor: me.nodeHighlightColor,
repairHighlight: me.nodeHighlightOnRepair,
scrollEl: scrollEl,
setAmetysDragInfos: me.setAmetysDragInfos
});
}
if (me.enableDrop)
{
me.dropZone = new Ametys.relation.dd.AmetysTreeViewDropZone({
view: view,
ddGroup: me.dropGroup || "ametys",
allowContainerDrops: me.allowContainerDrops,
appendOnly: me.appendOnly,
allowParentInserts: me.allowParentInserts,
expandDelay: me.expandDelay,
dropHighlightColor: me.nodeHighlightColor,
dropHighlight: me.nodeHighlightOnDrop,
sortOnDrop: me.sortOnDrop,
containerScroll: me.containerScroll,
setAmetysDropZoneInfos: me.setAmetysDropZoneInfos
});
view.addListener('beforedrop', this._onBeforeDrop, this);
}
},
/**
* @private
* This function is called when a drop gesture has been triggered in a valid drop position in the tree.
* @param {HTMLElement} nodeEl The TreeView node
* @param {Object} data The data object gathered at mousedown time
* @param {Ext.data.Model} overModel The Model over which the drop gesture took place.
* @param {String} dropPosition "before", "after" or "append" depending on whether the mouse is above or below the midline of the node, or the node is a branch node which accepts new child nodes.
* @param {Object} dropHandlers This parameter allows to control when the drop action takes place.
*/
_onBeforeDrop: function (nodeEl, data, overModel, dropPosition, dropHandlers)
{
if (data.source && data.target)
{
dropHandlers.wait = true; // Defer the handling
// FIXME handle the CTRL / SHIFT / ALT d'n'd and fill the below vars
var relationType = this.defaultRelation;
var forceUserChoice = false;
var bindedDropHandled = Ext.bind(this._onDropHandled, this, [data, dropHandlers], true);
if (!overModel.isExpanded())
{
overModel.expand (false, Ext.bind (Ametys.relation.RelationManager.link, Ametys.relation.RelationManager, [data.source, data.target, bindedDropHandled, relationType, forceUserChoice], false));
}
else
{
Ametys.relation.RelationManager.link(data.source, data.target, bindedDropHandled, relationType, forceUserChoice);
}
}
else
{
return false;
}
},
/**
* @private
* Callback when the Ametys.relation.RelationManager ended.
* @param {Boolean/String} success Has the operation been successful? The success. False is a problem occurred, a Ametys.relation.Relation constant else determining which operation was done
* @param {Object} data The drag data
* @param {Object} dropHandlers This parameter allows to control when the drop action takes place.
*/
_onDropHandled: function(success, data, dropHandlers)
{
// Are source and target from the same tree model ?
if (success)
{
var treeStore = Ext.isFunction(data.records[0].getTreeStore) ? data.records[0].getTreeStore() : null;
if (treeStore && treeStore.getModel().getName() == this.getCmp().getStore().getModel().getName())
{
// Same tree model, let's extjs do the graphical magic
switch (success)
{
case Ametys.relation.Relation.MOVE:
data.copy = false;
break;
case Ametys.relation.Relation.COPY:
data.copy = true;
break;
case Ametys.relation.Relation.REFERENCE:
data.copy = true;
break;
}
dropHandlers.processDrop();
return;
}
}
// Different models, ExtJS cannot do the graphical magic, let's cancel the drop: the RelationHandler should have sent a message bus that will be interpreted by source and target components
dropHandlers.cancelDrop();
}
});