4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
11 Roo.onReady(function(){
\r
13 // seeds for the new node suffix
\r
14 var cseed = 0, oseed = 0;
\r
16 // turn on quick tips
\r
17 Roo.QuickTips.init();
\r
19 var cview = Roo.DomHelper.append('main-ct',
\r
20 {cn:[{id:'main-tb'},{id:'cbody'}]}
\r
24 // create the primary toolbar
\r
25 var tb = new Roo.Toolbar('main-tb');
\r
31 cls:'x-btn-text-icon save',
\r
32 tooltip:'Saves all components to the server'
\r
36 handler:addComponent,
\r
37 cls:'x-btn-text-icon add-cmp',
\r
38 tooltip:'Add a new Component to the dependency builder'
\r
44 cls:'x-btn-text-icon add-opt',
\r
45 tooltip:'Add a new optional dependency to the selected component'
\r
51 cls:'x-btn-text-icon remove',
\r
52 tooltip:'Remove the selected item'
\r
54 // for enabling and disabling
\r
55 var btns = tb.items.map;
\r
59 // create our layout
\r
60 var layout = new Roo.BorderLayout('main-ct', {
\r
67 margins:{left:5,right:0,bottom:5,top:5}
\r
71 margins:{left:0,right:5,bottom:5,top:5}
\r
79 title:'Ext Source Files',
\r
94 // this is the source code tree
\r
95 var stree = new xt.TreePanel('source-files', {
\r
97 loader: new xt.TreeLoader({dataUrl:'dependency.php'}),
\r
99 containerScroll: true
\r
102 new xt.TreeSorter(stree, {folderSort:true});
\r
104 var sroot = new xt.AsyncTreeNode({
\r
109 stree.setRootNode(sroot);
\r
111 sroot.expand(false, false);
\r
114 // the component tree
\r
115 var ctree = new xt.TreePanel('cbody', {
\r
118 containerScroll: true,
\r
121 loader: new Roo.tree.TreeLoader()
\r
124 ctree.el.addKeyListener(Roo.EventObject.DELETE, removeNode);
\r
126 var croot = new xt.AsyncTreeNode({
\r
130 text:'Packages and Components',
\r
132 loader:new Roo.tree.TreeLoader({
\r
133 dataUrl:'dep-tree.json',
\r
134 createNode: readNode
\r
137 ctree.setRootNode(croot);
\r
141 // some functions to determine whether is not the drop is allowed
\r
142 function hasNode(t, n){
\r
143 return (t.attributes.type == 'fileCt' && t.findChild('id', n.id)) ||
\r
144 (t.leaf === true && t.parentNode.findChild('id', n.id));
\r
147 function isSourceCopy(e, n){
\r
148 var a = e.target.attributes;
\r
149 return n.getOwnerTree() == stree && !hasNode(e.target, n) &&
\r
150 ((e.point == 'append' && a.type == 'fileCt') || a.leaf === true);
\r
153 function isReorder(e, n){
\r
154 return n.parentNode == e.target.parentNode && e.point != 'append';
\r
157 // handle drag over and drag drop
\r
158 ctree.on('nodedragover', function(e){
\r
159 var n = e.dropNode;
\r
160 return isSourceCopy(e, n) || isReorder(e, n);
\r
163 ctree.on('beforenodedrop', function(e){
\r
164 var n = e.dropNode;
\r
166 // copy node from source tree
\r
167 if(isSourceCopy(e, n)){
\r
168 var copy = new xt.TreeNode(
\r
169 Roo.apply({allowDelete:true,expanded:true}, n.attributes)
\r
171 copy.loader = undefined;
\r
172 if(e.target.attributes.options){
\r
173 e.target = createOption(e.target, copy.text);
\r
180 return isReorder(e, n);
\r
183 ctree.on('contextmenu', prepareCtx);
\r
185 // track whether save is allowed
\r
186 ctree.on('append', trackSave);
\r
187 ctree.on('remove', trackSave);
\r
188 ctree.el.swallowEvent('contextmenu', true);
\r
189 ctree.el.on('keypress', function(e){
\r
190 if(e.isNavKeyPress()){
\r
194 // when the tree selection changes, enable/disable the toolbar buttons
\r
195 var sm = ctree.getSelectionModel();
\r
196 sm.on('selectionchange', function(){
\r
197 var n = sm.getSelectedNode();
\r
199 btns.remove.disable();
\r
200 btns.option.disable();
\r
203 var a = n.attributes;
\r
204 btns.remove.setDisabled(!a.allowDelete);
\r
205 btns.option.setDisabled(!a.cmpId);
\r
210 // create the editor for the component tree
\r
211 var ge = new xt.TreeEditor(ctree, {
\r
213 blankText:'A name is required',
\r
217 ge.on('beforestartedit', function(){
\r
218 if(!ge.editNode.attributes.allowEdit){
\r
224 // add component handler
\r
225 function addComponent(){
\r
226 var id = guid('c-');
\r
227 var text = 'Component '+(++cseed);
\r
228 var node = createComponent(id, text);
\r
229 node.expand(false, false);
\r
231 node.lastChild.ensureVisible();
\r
232 ge.triggerEdit(node);
\r
235 function createComponent(id, text, cfiles, cdep, coptions){
\r
236 var node = new xt.TreeNode({
\r
246 croot.appendChild(node);
\r
248 var files = new xt.AsyncTreeNode({
\r
256 children:cfiles||[],
\r
260 var dep = new xt.AsyncTreeNode({
\r
261 text: 'Dependencies',
\r
273 var options = new xt.AsyncTreeNode({
\r
274 text: 'Optional Dependencies',
\r
282 children:coptions||[],
\r
287 node.appendChild(files);
\r
288 node.appendChild(dep);
\r
289 node.appendChild(options);
\r
295 function removeNode(){
\r
296 var n = sm.getSelectedNode();
\r
297 if(n && n.attributes.allowDelete){
\r
298 ctree.getSelectionModel().selectPrevious();
\r
299 n.parentNode.removeChild(n);
\r
304 // add option handler
\r
305 function addOption(){
\r
306 var n = sm.getSelectedNode();
\r
308 var node = createOption(n, 'Option'+(++oseed));
\r
310 ge.triggerEdit(node);
\r
314 function createOption(n, text){
\r
315 var cnode = ctree.getNodeById(n.attributes.cmpId);
\r
317 var node = new xt.TreeNode({
\r
326 cnode.childNodes[2].appendChild(node);
\r
327 cnode.childNodes[2].expand(false, false);
\r
332 // semi unique ids across edits
\r
333 function guid(prefix){
\r
334 return prefix+(new Date().getTime());
\r
338 function trackSave(){
\r
339 btns.save.setDisabled(!croot.hasChildNodes());
\r
342 function storeChildren(cmp, n, name){
\r
343 if(n.childrenRendered){
\r
345 n.eachChild(function(f){
\r
346 cmp[name].push(f.attributes);
\r
349 cmp[name] = n.attributes.children || [];
\r
353 // save to the server in a format usable in PHP
\r
356 croot.eachChild(function(c){
\r
363 storeChildren(cmp, c.childNodes[0], 'files');
\r
364 storeChildren(cmp, c.childNodes[1], 'dep');
\r
366 var onode = c.childNodes[2];
\r
367 if(!onode.childrenRendered){
\r
368 cmp.options = onode.attributes.children || [];
\r
370 onode.eachChild(function(o){
\r
371 var opt = Roo.apply({}, o.attributes);
\r
372 storeChildren(opt, o, 'children');
\r
373 cmp.options.push(opt);
\r
379 layout.el.mask('Sending data to server...', 'x-mask-loading');
\r
380 var hide = layout.el.unmask.createDelegate(layout.el);
\r
381 Roo.lib.Ajax.request(
\r
384 {success:hide,failure:hide},
\r
385 'data='+encodeURIComponent(Roo.encode(ch))
\r
389 function readNode(o){
\r
390 createComponent(o.id, o.text, o.files, o.dep, o.options);
\r
395 var ctxMenu = new Roo.menu.Menu({
\r
404 handler:collapseAll,
\r
405 cls:'collapse-all',
\r
406 text:'Collapse All'
\r
409 handler:removeNode,
\r
411 text: 'Remove Item'
\r
415 function prepareCtx(node, e){
\r
417 ctxMenu.items.get('remove')[node.attributes.allowDelete ? 'enable' : 'disable']();
\r
418 ctxMenu.showAt(e.getXY());
\r
421 function collapseAll(){
\r
423 setTimeout(function(){
\r
424 croot.eachChild(function(n){
\r
425 n.collapse(false, false);
\r
430 function expandAll(){
\r
432 setTimeout(function(){
\r
433 croot.eachChild(function(n){
\r
434 n.expand(false, false);
\r