]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
Merge remote branch 'working/user/shadowspar/ttopac-altcleanup' into template-toolkit...
[Evergreen.git] / Open-ILS / web / js / dojo / openils / vandelay / TreeDndSource.js
1 dojo.provide("openils.vandelay.TreeDndSource");
2 dojo.require("dijit._tree.dndSource");
3
4 /* This class specifically serves the eg/vandelay/match_set interface
5  * for editing Vandelay Match Set trees.  It should probably  have a more
6  * specific name that reflects that.
7  */
8 dojo.declare(
9     "openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
10         "_is_replaceable": function(spoint, dpoint, disroot) {
11             /* An OP can replace anything, but non-OPs can only replace other
12              * non-OPs.
13              */
14             if (spoint.bool_op())
15                 return true;
16             else if (!dpoint.bool_op())
17                 return true;
18             return false;
19         },
20         "constructor": function() {
21             /* Given a tree object, there seems to be no way to access its
22              * dndController, which seems to be the only thing that knows
23              * about a tree's selected nodes.  So we register instances
24              * in a global variable in order to find them later. :-(
25              */
26             if (!window._tree_dnd_controllers)
27                 window._tree_dnd_controllers = [];
28
29             window._tree_dnd_controllers.push(this);
30
31             dojo.connect(
32                 this.tree.model.store, "onNew", this,
33                 function() { this.redraw_expression_preview(); }
34             );
35             dojo.connect(
36                 this.tree.model.store, "onDelete", this,
37                 function() { this.redraw_expression_preview(); }
38             );
39         },
40         "redraw_expression_preview": function() {
41             if (typeof(window.redraw_expression_preview) == "function") {
42                 window.redraw_expression_preview();
43             } else {
44                 console.log("no redraw_expression_preview function registered");
45             }
46         },
47         "checkItemAcceptance": function(target, source, position) {
48             if (!source._ready || source == this) return;
49
50             if (this.tree.model.replace_mode) {
51                 var ditem = dijit.getEnclosingWidget(target).item;
52                 return (
53                     position == "over" && this._is_replaceable(
54                         source.getAllNodes()[0].match_point,
55                         this.tree.model.store.getValue(ditem, "match_point"),
56                         ditem === this.tree.model.root
57                     )
58                 );
59             } else {
60                 return (
61                     position != "over" ||
62                     this.tree.model.mayHaveChildren(
63                         dijit.getEnclosingWidget(target).item
64                     )
65                 );
66             }
67             /* code in match_set.js makes sure that source._ready gets set true
68              * only when we want the item to be draggable */
69         },
70         "itemCreator": function(nodes, somethingelse) {
71             var default_items = this.inherited(arguments);
72             for (var i = 0; i < default_items.length; i++)
73                 default_items[i].match_point = nodes[i].match_point;
74             return default_items;
75         },
76         "onDndDrop": function(source, nodes, copy) {
77             if (
78                 !this.tree.model.replace_mode ||
79                 this.containerState != "Over" ||
80                 this.dropPosition == "Before" ||
81                 this.dropPosition == "After" ||
82                 source == this
83             ) {
84                 return this.inherited(arguments);
85             }
86
87             /* This method only comes into play for our "replace mode" */
88
89             var target_widget = dijit.getEnclosingWidget(this.targetAnchor);
90             var new_params = this.itemCreator(nodes, this.targetAnchor)[0];
91
92             /* Here, we morph target_widget.item into the new item */
93
94             var store = this.tree.model.store;
95             var item = target_widget.item;
96             for (var k in new_params) {
97                 if (k == "id") continue;    /* can't use this / don't need it */
98                 store.setValue(item, k, new_params[k]);
99             }
100             if (this.tree.model.root === item) {    /* replacing root node */
101                 if (!new_params.match_point.bool_op()) {
102                     /* If we're here, we've replaced the root node with
103                      * something that isn't a bool op, so we need to nuke
104                      * any children that the item has.
105                      */
106                     store.setValue(item, "children", []);
107                 }
108             }
109             if (typeof(window.render_vmsp_label) == "function") {
110                 store.setValue(
111                     item,
112                     "name",
113                     window.render_vmsp_label(new_params.match_point)
114                 );
115             }
116
117             this.redraw_expression_preview();
118
119             /* just because this is at the end of the default implementation: */
120             this.onDndCancel();
121         }
122     }
123 );