diff options
Diffstat (limited to 'deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js')
-rw-r--r-- | deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js new file mode 100644 index 0000000..d3d5fc3 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js @@ -0,0 +1,468 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +Ext.ns('Ext.ux.tree'); + +/** + * @class Ext.ux.tree.TreeGrid + * @extends Ext.tree.TreePanel + * + * @xtype treegrid + */ +Ext.ux.tree.TreeGrid = Ext.extend(Ext.tree.TreePanel, { + rootVisible: false, + useArrows: true, + lines: false, + borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell + cls: 'x-treegrid', + + columnResize: true, + enableSort: true, + reserveScrollOffset: true, + enableHdMenu: true, + + columnsText: 'Columns', + + initComponent: function() { + if (!this.root) { + this.root = new Ext.tree.AsyncTreeNode({ text: 'Root' }); + } + + // initialize the loader + var l = this.loader; + if (!l) { + l = new Ext.ux.tree.TreeGridLoader({ + dataUrl: this.dataUrl, + requestMethod: this.requestMethod, + store: this.store, + }); + } else if (Ext.isObject(l) && !l.load) { + l = new Ext.ux.tree.TreeGridLoader(l); + } + this.loader = l; + + Ext.ux.tree.TreeGrid.superclass.initComponent.call(this); + + this.initColumns(); + + if (this.enableSort) { + this.treeGridSorter = new Ext.ux.tree.TreeGridSorter( + this, + this.enableSort + ); + } + + if (this.columnResize) { + this.colResizer = new Ext.tree.ColumnResizer(this.columnResize); + this.colResizer.init(this); + } + + var c = this.columns; + if (!this.internalTpl) { + this.internalTpl = new Ext.XTemplate( + '<div class="x-grid3-header">', + '<div class="x-treegrid-header-inner">', + '<div class="x-grid3-header-offset">', + '<table style="table-layout: fixed;" cellspacing="0" cellpadding="0" border="0"><colgroup><tpl for="columns"><col /></tpl></colgroup>', + '<thead><tr class="x-grid3-hd-row">', + '<tpl for="columns">', + '<td class="x-grid3-hd x-grid3-cell x-treegrid-hd" style="text-align: {align};" id="', + this.id, + '-xlhd-{#}">', + '<div class="x-grid3-hd-inner x-treegrid-hd-inner" unselectable="on">', + this.enableHdMenu + ? '<a class="x-grid3-hd-btn" href="#"></a>' + : '', + '{header}<img class="x-grid3-sort-icon" src="', + Ext.BLANK_IMAGE_URL, + '" />', + '</div>', + '</td></tpl>', + '</tr></thead>', + '</table>', + '</div></div>', + '</div>', + '<div class="x-treegrid-root-node">', + '<table class="x-treegrid-root-table" cellpadding="0" cellspacing="0" style="table-layout: fixed;"></table>', + '</div>' + ); + } + + if (!this.colgroupTpl) { + this.colgroupTpl = new Ext.XTemplate( + '<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>' + ); + } + }, + + initColumns: function() { + var cs = this.columns, + len = cs.length, + columns = [], + i, + c; + + for (i = 0; i < len; i++) { + c = cs[i]; + if (!c.isColumn) { + c.xtype = c.xtype + ? /^tg/.test(c.xtype) + ? c.xtype + : 'tg' + c.xtype + : 'tgcolumn'; + c = Ext.create(c); + } + c.init(this); + columns.push(c); + + if (this.enableSort !== false && c.sortable !== false) { + c.sortable = true; + this.enableSort = true; + } + } + + this.columns = columns; + }, + + onRender: function() { + Ext.tree.TreePanel.superclass.onRender.apply(this, arguments); + + this.el.addClass('x-treegrid'); + + this.outerCt = this.body.createChild({ + cls: + 'x-tree-root-ct x-treegrid-ct ' + + (this.useArrows + ? 'x-tree-arrows' + : this.lines + ? 'x-tree-lines' + : 'x-tree-no-lines'), + }); + + this.internalTpl.overwrite(this.outerCt, { columns: this.columns }); + + this.mainHd = Ext.get(this.outerCt.dom.firstChild); + this.innerHd = Ext.get(this.mainHd.dom.firstChild); + this.innerBody = Ext.get(this.outerCt.dom.lastChild); + this.innerCt = Ext.get(this.innerBody.dom.firstChild); + + this.colgroupTpl.insertFirst(this.innerCt, { columns: this.columns }); + + if (this.hideHeaders) { + this.el.child('.x-grid3-header').setDisplayed('none'); + } else if (this.enableHdMenu !== false) { + this.hmenu = new Ext.menu.Menu({ id: this.id + '-hctx' }); + if (this.enableColumnHide !== false) { + this.colMenu = new Ext.menu.Menu({ + id: this.id + '-hcols-menu', + }); + this.colMenu.on({ + scope: this, + beforeshow: this.beforeColMenuShow, + itemclick: this.handleHdMenuClick, + }); + this.hmenu.add({ + itemId: 'columns', + hideOnClick: false, + text: this.columnsText, + menu: this.colMenu, + iconCls: 'x-cols-icon', + }); + } + this.hmenu.on('itemclick', this.handleHdMenuClick, this); + } + }, + + setRootNode: function(node) { + node.attributes.uiProvider = Ext.ux.tree.TreeGridRootNodeUI; + node = Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this, node); + if (this.innerCt) { + this.colgroupTpl.insertFirst(this.innerCt, { + columns: this.columns, + }); + } + return node; + }, + + clearInnerCt: function() { + if (Ext.isIE) { + var dom = this.innerCt.dom; + while (dom.firstChild) { + dom.removeChild(dom.firstChild); + } + } else { + Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this); + } + }, + + initEvents: function() { + Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this, arguments); + + this.mon(this.innerBody, 'scroll', this.syncScroll, this); + this.mon(this.innerHd, 'click', this.handleHdDown, this); + this.mon(this.mainHd, { + scope: this, + mouseover: this.handleHdOver, + mouseout: this.handleHdOut, + }); + }, + + onResize: function(w, h) { + Ext.ux.tree.TreeGrid.superclass.onResize.apply(this, arguments); + + var bd = this.innerBody.dom; + var hd = this.innerHd.dom; + + if (!bd) { + return; + } + + if (Ext.isNumber(h)) { + bd.style.height = + this.body.getHeight(true) - hd.offsetHeight + 'px'; + } + + if (Ext.isNumber(w)) { + var sw = Ext.num(this.scrollOffset, Ext.getScrollBarWidth()); + if ( + this.reserveScrollOffset || + bd.offsetWidth - bd.clientWidth > 10 + ) { + this.setScrollOffset(sw); + } else { + var me = this; + setTimeout(function() { + me.setScrollOffset( + bd.offsetWidth - bd.clientWidth > 10 ? sw : 0 + ); + }, 10); + } + } + }, + + updateColumnWidths: function() { + var cols = this.columns, + colCount = cols.length, + groups = this.outerCt.query('colgroup'), + groupCount = groups.length, + c, + g, + i, + j; + + for (i = 0; i < colCount; i++) { + c = cols[i]; + for (j = 0; j < groupCount; j++) { + g = groups[j]; + g.childNodes[i].style.width = (c.hidden ? 0 : c.width) + 'px'; + } + } + + for ( + i = 0, groups = this.innerHd.query('td'), len = groups.length; + i < len; + i++ + ) { + c = Ext.fly(groups[i]); + if (cols[i] && cols[i].hidden) { + c.addClass('x-treegrid-hd-hidden'); + } else { + c.removeClass('x-treegrid-hd-hidden'); + } + } + + var tcw = this.getTotalColumnWidth(); + Ext.fly(this.innerHd.dom.firstChild).setWidth( + tcw + (this.scrollOffset || 0) + ); + this.outerCt.select('table').setWidth(tcw); + this.syncHeaderScroll(); + }, + + getVisibleColumns: function() { + var columns = [], + cs = this.columns, + len = cs.length, + i; + + for (i = 0; i < len; i++) { + if (!cs[i].hidden) { + columns.push(cs[i]); + } + } + return columns; + }, + + getTotalColumnWidth: function() { + var total = 0; + for ( + var i = 0, cs = this.getVisibleColumns(), len = cs.length; + i < len; + i++ + ) { + total += cs[i].width; + } + return total; + }, + + setScrollOffset: function(scrollOffset) { + this.scrollOffset = scrollOffset; + this.updateColumnWidths(); + }, + + // private + handleHdDown: function(e, t) { + var hd = e.getTarget('.x-treegrid-hd'); + + if (hd && Ext.fly(t).hasClass('x-grid3-hd-btn')) { + var ms = this.hmenu.items, + cs = this.columns, + index = this.findHeaderIndex(hd), + c = cs[index], + sort = c.sortable; + + e.stopEvent(); + Ext.fly(hd).addClass('x-grid3-hd-menu-open'); + this.hdCtxIndex = index; + + this.fireEvent('headerbuttonclick', ms, c, hd, index); + + this.hmenu.on( + 'hide', + function() { + Ext.fly(hd).removeClass('x-grid3-hd-menu-open'); + }, + this, + { single: true } + ); + + this.hmenu.show(t, 'tl-bl?'); + } else if (hd) { + var index = this.findHeaderIndex(hd); + this.fireEvent('headerclick', this.columns[index], hd, index); + } + }, + + // private + handleHdOver: function(e, t) { + var hd = e.getTarget('.x-treegrid-hd'); + if (hd && !this.headersDisabled) { + index = this.findHeaderIndex(hd); + this.activeHdRef = t; + this.activeHdIndex = index; + var el = Ext.get(hd); + this.activeHdRegion = el.getRegion(); + el.addClass('x-grid3-hd-over'); + this.activeHdBtn = el.child('.x-grid3-hd-btn'); + if (this.activeHdBtn) { + this.activeHdBtn.dom.style.height = + hd.firstChild.offsetHeight - 1 + 'px'; + } + } + }, + + // private + handleHdOut: function(e, t) { + var hd = e.getTarget('.x-treegrid-hd'); + if (hd && (!Ext.isIE || !e.within(hd, true))) { + this.activeHdRef = null; + Ext.fly(hd).removeClass('x-grid3-hd-over'); + hd.style.cursor = ''; + } + }, + + findHeaderIndex: function(hd) { + hd = hd.dom || hd; + var cs = hd.parentNode.childNodes; + for (var i = 0, c; (c = cs[i]); i++) { + if (c == hd) { + return i; + } + } + return -1; + }, + + // private + beforeColMenuShow: function() { + var cols = this.columns, + colCount = cols.length, + i, + c; + this.colMenu.removeAll(); + for (i = 1; i < colCount; i++) { + c = cols[i]; + if (c.hideable !== false) { + this.colMenu.add( + new Ext.menu.CheckItem({ + itemId: 'col-' + i, + text: c.header, + checked: !c.hidden, + hideOnClick: false, + disabled: c.hideable === false, + }) + ); + } + } + }, + + // private + handleHdMenuClick: function(item) { + var index = this.hdCtxIndex, + id = item.getItemId(); + + if ( + this.fireEvent( + 'headermenuclick', + this.columns[index], + id, + index + ) !== false + ) { + index = id.substr(4); + if (index > 0 && this.columns[index]) { + this.setColumnVisible(index, !item.checked); + } + } + + return true; + }, + + setColumnVisible: function(index, visible) { + this.columns[index].hidden = !visible; + this.updateColumnWidths(); + }, + + /** + * Scrolls the grid to the top + */ + scrollToTop: function() { + this.innerBody.dom.scrollTop = 0; + this.innerBody.dom.scrollLeft = 0; + }, + + // private + syncScroll: function() { + this.syncHeaderScroll(); + var mb = this.innerBody.dom; + this.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop); + }, + + // private + syncHeaderScroll: function() { + var mb = this.innerBody.dom; + this.innerHd.dom.scrollLeft = mb.scrollLeft; + this.innerHd.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore) + }, + + registerNode: function(n) { + Ext.ux.tree.TreeGrid.superclass.registerNode.call(this, n); + if (!n.uiProvider && !n.isRoot && !n.ui.isTreeGridNodeUI) { + n.ui = new Ext.ux.tree.TreeGridNodeUI(n); + } + }, +}); + +Ext.reg('treegrid', Ext.ux.tree.TreeGrid); |