From 2e2851dc13d73352530dd4495c7e05603b2e520d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 23:38:38 +0200 Subject: Adding upstream version 2.1.2~dev0+20240219. Signed-off-by: Daniel Baumann --- deluge/ui/web/js/deluge-all/.order | 2 + deluge/ui/web/js/deluge-all/AboutWindow.js | 128 + deluge/ui/web/js/deluge-all/AddConnectionWindow.js | 117 + deluge/ui/web/js/deluge-all/AddTrackerWindow.js | 86 + deluge/ui/web/js/deluge-all/Client.js | 199 + deluge/ui/web/js/deluge-all/ConnectionManager.js | 442 + deluge/ui/web/js/deluge-all/CopyMagnetWindow.js | 73 + deluge/ui/web/js/deluge-all/Deluge.js | 179 + .../ui/web/js/deluge-all/EditConnectionWindow.js | 128 + deluge/ui/web/js/deluge-all/EditTrackerWindow.js | 74 + deluge/ui/web/js/deluge-all/EditTrackersWindow.js | 234 + deluge/ui/web/js/deluge-all/EventsManager.js | 118 + deluge/ui/web/js/deluge-all/FileBrowser.js | 43 + deluge/ui/web/js/deluge-all/FilterPanel.js | 175 + deluge/ui/web/js/deluge-all/Formatters.js | 206 + deluge/ui/web/js/deluge-all/Keys.js | 138 + deluge/ui/web/js/deluge-all/LoginWindow.js | 134 + deluge/ui/web/js/deluge-all/Menus.js | 398 + deluge/ui/web/js/deluge-all/MoveStorage.js | 85 + deluge/ui/web/js/deluge-all/MultiOptionsManager.js | 218 + deluge/ui/web/js/deluge-all/OptionsManager.js | 279 + deluge/ui/web/js/deluge-all/OtherLimitWindow.js | 79 + deluge/ui/web/js/deluge-all/Plugin.js | 106 + deluge/ui/web/js/deluge-all/RemoveWindow.js | 77 + deluge/ui/web/js/deluge-all/Sidebar.js | 146 + deluge/ui/web/js/deluge-all/Statusbar.js | 362 + deluge/ui/web/js/deluge-all/StatusbarMenu.js | 79 + deluge/ui/web/js/deluge-all/Toolbar.js | 206 + deluge/ui/web/js/deluge-all/TorrentGrid.js | 516 + deluge/ui/web/js/deluge-all/UI.js | 311 + deluge/ui/web/js/deluge-all/add/.order | 1 + deluge/ui/web/js/deluge-all/add/AddWindow.js | 332 + deluge/ui/web/js/deluge-all/add/FilesTab.js | 100 + deluge/ui/web/js/deluge-all/add/Infohash.js | 10 + deluge/ui/web/js/deluge-all/add/OptionsPanel.js | 145 + deluge/ui/web/js/deluge-all/add/OptionsTab.js | 217 + deluge/ui/web/js/deluge-all/add/UrlWindow.js | 112 + deluge/ui/web/js/deluge-all/add/Window.js | 29 + deluge/ui/web/js/deluge-all/data/.order | 1 + deluge/ui/web/js/deluge-all/data/PeerRecord.js | 53 + deluge/ui/web/js/deluge-all/data/SortTypes.js | 37 + deluge/ui/web/js/deluge-all/data/TorrentRecord.js | 121 + .../ui/web/js/deluge-all/details/DetailsPanel.js | 81 + deluge/ui/web/js/deluge-all/details/DetailsTab.js | 100 + deluge/ui/web/js/deluge-all/details/FilesTab.js | 236 + deluge/ui/web/js/deluge-all/details/OptionsTab.js | 417 + deluge/ui/web/js/deluge-all/details/PeersTab.js | 166 + deluge/ui/web/js/deluge-all/details/StatusTab.js | 155 + .../web/js/deluge-all/preferences/BandwidthPage.js | 202 + .../ui/web/js/deluge-all/preferences/CachePage.js | 61 + .../ui/web/js/deluge-all/preferences/DaemonPage.js | 85 + .../web/js/deluge-all/preferences/DownloadsPage.js | 124 + .../js/deluge-all/preferences/EncryptionPage.js | 99 + .../deluge-all/preferences/InstallPluginWindow.js | 83 + .../web/js/deluge-all/preferences/InterfacePage.js | 358 + .../web/js/deluge-all/preferences/NetworkPage.js | 257 + .../ui/web/js/deluge-all/preferences/OtherPage.js | 100 + .../web/js/deluge-all/preferences/PluginsPage.js | 277 + .../js/deluge-all/preferences/PreferencesWindow.js | 245 + .../ui/web/js/deluge-all/preferences/ProxyField.js | 225 + .../ui/web/js/deluge-all/preferences/ProxyPage.js | 62 + .../ui/web/js/deluge-all/preferences/QueuePage.js | 234 + deluge/ui/web/js/extjs/ext-all-debug.js | 52270 +++++++++++++++++++ deluge/ui/web/js/extjs/ext-all.js | 21 + deluge/ui/web/js/extjs/ext-base-debug.js | 3352 ++ deluge/ui/web/js/extjs/ext-base.js | 21 + deluge/ui/web/js/extjs/ext-extensions/JSLoader.js | 40 + deluge/ui/web/js/extjs/ext-extensions/Spinner.js | 474 + deluge/ui/web/js/extjs/ext-extensions/StatusBar.js | 422 + .../extjs/ext-extensions/form/FileUploadField.js | 208 + .../js/extjs/ext-extensions/form/RadioGroupFix.js | 50 + .../js/extjs/ext-extensions/form/SpinnerField.js | 68 + .../extjs/ext-extensions/form/SpinnerFieldFix.js | 13 + .../js/extjs/ext-extensions/form/SpinnerGroup.js | 205 + .../js/extjs/ext-extensions/form/ToggleField.js | 72 + .../web/js/extjs/ext-extensions/grid/BufferView.js | 270 + .../extjs/ext-extensions/layout/FormLayoutFix.js | 39 + .../ext-extensions/tree/MultiSelectionModelFix.js | 68 + .../web/js/extjs/ext-extensions/tree/TreeGrid.js | 468 + .../ext-extensions/tree/TreeGridColumnResizer.js | 123 + .../extjs/ext-extensions/tree/TreeGridColumns.js | 40 + .../js/extjs/ext-extensions/tree/TreeGridLoader.js | 18 + .../js/extjs/ext-extensions/tree/TreeGridNodeUI.js | 149 + .../extjs/ext-extensions/tree/TreeGridNodeUIFix.js | 33 + .../ext-extensions/tree/TreeGridRenderColumn.js | 9 + .../js/extjs/ext-extensions/tree/TreeGridSorter.js | 158 + 86 files changed, 68654 insertions(+) create mode 100644 deluge/ui/web/js/deluge-all/.order create mode 100644 deluge/ui/web/js/deluge-all/AboutWindow.js create mode 100644 deluge/ui/web/js/deluge-all/AddConnectionWindow.js create mode 100644 deluge/ui/web/js/deluge-all/AddTrackerWindow.js create mode 100644 deluge/ui/web/js/deluge-all/Client.js create mode 100644 deluge/ui/web/js/deluge-all/ConnectionManager.js create mode 100644 deluge/ui/web/js/deluge-all/CopyMagnetWindow.js create mode 100644 deluge/ui/web/js/deluge-all/Deluge.js create mode 100644 deluge/ui/web/js/deluge-all/EditConnectionWindow.js create mode 100644 deluge/ui/web/js/deluge-all/EditTrackerWindow.js create mode 100644 deluge/ui/web/js/deluge-all/EditTrackersWindow.js create mode 100644 deluge/ui/web/js/deluge-all/EventsManager.js create mode 100644 deluge/ui/web/js/deluge-all/FileBrowser.js create mode 100644 deluge/ui/web/js/deluge-all/FilterPanel.js create mode 100644 deluge/ui/web/js/deluge-all/Formatters.js create mode 100644 deluge/ui/web/js/deluge-all/Keys.js create mode 100644 deluge/ui/web/js/deluge-all/LoginWindow.js create mode 100644 deluge/ui/web/js/deluge-all/Menus.js create mode 100644 deluge/ui/web/js/deluge-all/MoveStorage.js create mode 100644 deluge/ui/web/js/deluge-all/MultiOptionsManager.js create mode 100644 deluge/ui/web/js/deluge-all/OptionsManager.js create mode 100644 deluge/ui/web/js/deluge-all/OtherLimitWindow.js create mode 100644 deluge/ui/web/js/deluge-all/Plugin.js create mode 100644 deluge/ui/web/js/deluge-all/RemoveWindow.js create mode 100644 deluge/ui/web/js/deluge-all/Sidebar.js create mode 100644 deluge/ui/web/js/deluge-all/Statusbar.js create mode 100644 deluge/ui/web/js/deluge-all/StatusbarMenu.js create mode 100644 deluge/ui/web/js/deluge-all/Toolbar.js create mode 100644 deluge/ui/web/js/deluge-all/TorrentGrid.js create mode 100644 deluge/ui/web/js/deluge-all/UI.js create mode 100644 deluge/ui/web/js/deluge-all/add/.order create mode 100644 deluge/ui/web/js/deluge-all/add/AddWindow.js create mode 100644 deluge/ui/web/js/deluge-all/add/FilesTab.js create mode 100644 deluge/ui/web/js/deluge-all/add/Infohash.js create mode 100644 deluge/ui/web/js/deluge-all/add/OptionsPanel.js create mode 100644 deluge/ui/web/js/deluge-all/add/OptionsTab.js create mode 100644 deluge/ui/web/js/deluge-all/add/UrlWindow.js create mode 100644 deluge/ui/web/js/deluge-all/add/Window.js create mode 100644 deluge/ui/web/js/deluge-all/data/.order create mode 100644 deluge/ui/web/js/deluge-all/data/PeerRecord.js create mode 100644 deluge/ui/web/js/deluge-all/data/SortTypes.js create mode 100644 deluge/ui/web/js/deluge-all/data/TorrentRecord.js create mode 100644 deluge/ui/web/js/deluge-all/details/DetailsPanel.js create mode 100644 deluge/ui/web/js/deluge-all/details/DetailsTab.js create mode 100644 deluge/ui/web/js/deluge-all/details/FilesTab.js create mode 100644 deluge/ui/web/js/deluge-all/details/OptionsTab.js create mode 100644 deluge/ui/web/js/deluge-all/details/PeersTab.js create mode 100644 deluge/ui/web/js/deluge-all/details/StatusTab.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/CachePage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/DaemonPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/InterfacePage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/NetworkPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/OtherPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/PluginsPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/ProxyField.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/ProxyPage.js create mode 100644 deluge/ui/web/js/deluge-all/preferences/QueuePage.js create mode 100644 deluge/ui/web/js/extjs/ext-all-debug.js create mode 100644 deluge/ui/web/js/extjs/ext-all.js create mode 100644 deluge/ui/web/js/extjs/ext-base-debug.js create mode 100644 deluge/ui/web/js/extjs/ext-base.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/JSLoader.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/Spinner.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/StatusBar.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js create mode 100644 deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js (limited to 'deluge/ui/web/js') diff --git a/deluge/ui/web/js/deluge-all/.order b/deluge/ui/web/js/deluge-all/.order new file mode 100644 index 0000000..4b6be43 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/.order @@ -0,0 +1,2 @@ ++ OptionsManager.js ++ StatusbarMenu.js diff --git a/deluge/ui/web/js/deluge-all/AboutWindow.js b/deluge/ui/web/js/deluge-all/AboutWindow.js new file mode 100644 index 0000000..cfae7a8 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/AboutWindow.js @@ -0,0 +1,128 @@ +/** + * Deluge.AboutWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.namespace('Deluge.about'); + +/** + * @class Deluge.about.AboutWindow + * @extends Ext.Window + */ +Deluge.about.AboutWindow = Ext.extend(Ext.Window, { + id: 'AboutWindow', + title: _('About Deluge'), + height: 330, + width: 270, + iconCls: 'x-deluge-main-panel', + resizable: false, + plain: true, + layout: { + type: 'vbox', + align: 'center', + }, + buttonAlign: 'center', + + initComponent: function () { + Deluge.about.AboutWindow.superclass.initComponent.call(this); + this.addEvents({ + build_ready: true, + }); + + var self = this; + var libtorrent = function () { + deluge.client.core.get_libtorrent_version({ + success: function (lt_version) { + comment += '
' + _('libtorrent:') + ' ' + lt_version; + Ext.getCmp('about_comment').setText(comment, false); + self.fireEvent('build_ready'); + }, + }); + }; + + var client_version = deluge.version; + + var comment = + _( + 'A peer-to-peer file sharing program\nutilizing the BitTorrent protocol.' + ).replace('\n', '
') + + '

' + + _('Client:') + + ' ' + + client_version + + '
'; + deluge.client.web.connected({ + success: function (connected) { + if (connected) { + deluge.client.daemon.get_version({ + success: function (server_version) { + comment += + _('Server:') + ' ' + server_version + '
'; + libtorrent(); + }, + }); + } else { + this.fireEvent('build_ready'); + } + }, + failure: function () { + this.fireEvent('build_ready'); + }, + scope: this, + }); + + this.add([ + { + xtype: 'box', + style: 'padding-top: 5px', + height: 80, + width: 240, + cls: 'x-deluge-logo', + hideLabel: true, + }, + { + xtype: 'label', + style: 'padding-top: 10px; font-weight: bold; font-size: 16px;', + text: _('Deluge') + ' ' + client_version, + }, + { + xtype: 'label', + id: 'about_comment', + style: 'padding-top: 10px; text-align:center; font-size: 12px;', + html: comment, + }, + { + xtype: 'label', + style: 'padding-top: 10px; font-size: 10px;', + text: _('Copyright 2007-2018 Deluge Team'), + }, + { + xtype: 'label', + style: 'padding-top: 5px; font-size: 12px;', + html: 'deluge-torrent.org', + }, + ]); + this.addButton(_('Close'), this.onCloseClick, this); + }, + + show: function () { + this.on('build_ready', function () { + Deluge.about.AboutWindow.superclass.show.call(this); + }); + }, + + onCloseClick: function () { + this.close(); + }, +}); + +Ext.namespace('Deluge'); + +Deluge.About = function () { + new Deluge.about.AboutWindow().show(); +}; diff --git a/deluge/ui/web/js/deluge-all/AddConnectionWindow.js b/deluge/ui/web/js/deluge-all/AddConnectionWindow.js new file mode 100644 index 0000000..4d821f2 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/AddConnectionWindow.js @@ -0,0 +1,117 @@ +/** + * Deluge.AddConnectionWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.AddConnectionWindow + * @extends Ext.Window + */ +Deluge.AddConnectionWindow = Ext.extend(Ext.Window, { + title: _('Add Connection'), + iconCls: 'x-deluge-add-window-icon', + + layout: 'fit', + width: 300, + height: 195, + constrainHeader: true, + bodyStyle: 'padding: 10px 5px;', + closeAction: 'hide', + + initComponent: function () { + Deluge.AddConnectionWindow.superclass.initComponent.call(this); + + this.addEvents('hostadded'); + + this.addButton(_('Close'), this.hide, this); + this.addButton(_('Add'), this.onAddClick, this); + + this.on('hide', this.onHide, this); + + this.form = this.add({ + xtype: 'form', + defaultType: 'textfield', + baseCls: 'x-plain', + labelWidth: 60, + items: [ + { + fieldLabel: _('Host:'), + labelSeparator: '', + name: 'host', + anchor: '75%', + value: '', + }, + { + xtype: 'spinnerfield', + fieldLabel: _('Port:'), + labelSeparator: '', + name: 'port', + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: -1, + maxValue: 65535, + }, + value: '58846', + anchor: '40%', + }, + { + fieldLabel: _('Username:'), + labelSeparator: '', + name: 'username', + anchor: '75%', + value: '', + }, + { + fieldLabel: _('Password:'), + labelSeparator: '', + anchor: '75%', + name: 'password', + inputType: 'password', + value: '', + }, + ], + }); + }, + + onAddClick: function () { + var values = this.form.getForm().getValues(); + deluge.client.web.add_host( + values.host, + Number(values.port), + values.username, + values.password, + { + success: function (result) { + if (!result[0]) { + Ext.MessageBox.show({ + title: _('Error'), + msg: String.format( + _('Unable to add host: {0}'), + result[1] + ), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + } else { + this.fireEvent('hostadded'); + } + this.hide(); + }, + scope: this, + } + ); + }, + + onHide: function () { + this.form.getForm().reset(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/AddTrackerWindow.js b/deluge/ui/web/js/deluge-all/AddTrackerWindow.js new file mode 100644 index 0000000..aaf4a3f --- /dev/null +++ b/deluge/ui/web/js/deluge-all/AddTrackerWindow.js @@ -0,0 +1,86 @@ +/** + * Deluge.AddTrackerWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +// Custom VType validator for tracker urls +var trackerUrlTest = + /(((^https?)|(^udp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i; +Ext.apply(Ext.form.VTypes, { + trackerUrl: function (val, field) { + return trackerUrlTest.test(val); + }, + trackerUrlText: 'Not a valid tracker url', +}); + +/** + * @class Deluge.AddTrackerWindow + * @extends Ext.Window + */ +Deluge.AddTrackerWindow = Ext.extend(Ext.Window, { + title: _('Add Tracker'), + layout: 'fit', + width: 375, + height: 150, + plain: true, + closable: true, + resizable: false, + constrainHeader: true, + bodyStyle: 'padding: 5px', + buttonAlign: 'right', + closeAction: 'hide', + iconCls: 'x-deluge-edit-trackers', + + initComponent: function () { + Deluge.AddTrackerWindow.superclass.initComponent.call(this); + + this.addButton(_('Cancel'), this.onCancelClick, this); + this.addButton(_('Add'), this.onAddClick, this); + this.addEvents('add'); + + this.form = this.add({ + xtype: 'form', + defaultType: 'textarea', + baseCls: 'x-plain', + labelWidth: 55, + items: [ + { + fieldLabel: _('Trackers:'), + labelSeparator: '', + name: 'trackers', + anchor: '100%', + }, + ], + }); + }, + + onAddClick: function () { + var trackers = this.form.getForm().findField('trackers').getValue(); + trackers = trackers.split('\n'); + + var cleaned = []; + Ext.each( + trackers, + function (tracker) { + if (Ext.form.VTypes.trackerUrl(tracker)) { + cleaned.push(tracker); + } + }, + this + ); + this.fireEvent('add', cleaned); + this.hide(); + this.form.getForm().findField('trackers').setValue(''); + }, + + onCancelClick: function () { + this.form.getForm().findField('trackers').setValue(''); + this.hide(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/Client.js b/deluge/ui/web/js/deluge-all/Client.js new file mode 100644 index 0000000..a06e863 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Client.js @@ -0,0 +1,199 @@ +/** + * Deluge.Client.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Ext.ux.util'); + +/** + * A class that connects to a json-rpc resource and adds the available + * methods as functions to the class instance. + * @class Ext.ux.util.RpcClient + * @namespace Ext.ux.util + */ +Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, { + _components: [], + + _methods: [], + + _requests: {}, + + _url: null, + + _optionKeys: ['scope', 'success', 'failure'], + + /** + * @event connected + * Fires when the client has retrieved the list of methods from the server. + * @param {Ext.ux.util.RpcClient} this + */ + constructor: function (config) { + Ext.ux.util.RpcClient.superclass.constructor.call(this, config); + this._url = config.url || null; + this._id = 0; + + this.addEvents( + // raw events + 'connected', + 'error' + ); + this.reloadMethods(); + }, + + reloadMethods: function () { + this._execute('system.listMethods', { + success: this._setMethods, + scope: this, + }); + }, + + _execute: function (method, options) { + options = options || {}; + options.params = options.params || []; + options.id = this._id; + + var request = Ext.encode({ + method: method, + params: options.params, + id: options.id, + }); + this._id++; + + return Ext.Ajax.request({ + url: this._url, + method: 'POST', + success: this._onSuccess, + failure: this._onFailure, + scope: this, + jsonData: request, + options: options, + }); + }, + + _onFailure: function (response, requestOptions) { + var options = requestOptions.options; + errorObj = { + id: options.id, + result: null, + error: { + msg: 'HTTP: ' + response.status + ' ' + response.statusText, + code: 255, + }, + }; + + this.fireEvent('error', errorObj, response, requestOptions); + + if (Ext.type(options.failure) != 'function') return; + if (options.scope) { + options.failure.call( + options.scope, + errorObj, + response, + requestOptions + ); + } else { + options.failure(errorObj, response, requestOptions); + } + }, + + _onSuccess: function (response, requestOptions) { + var responseObj = Ext.decode(response.responseText); + var options = requestOptions.options; + if (responseObj.error) { + this.fireEvent('error', responseObj, response, requestOptions); + + if (Ext.type(options.failure) != 'function') return; + if (options.scope) { + options.failure.call( + options.scope, + responseObj, + response, + requestOptions + ); + } else { + options.failure(responseObj, response, requestOptions); + } + } else { + if (Ext.type(options.success) != 'function') return; + if (options.scope) { + options.success.call( + options.scope, + responseObj.result, + responseObj, + response, + requestOptions + ); + } else { + options.success( + responseObj.result, + responseObj, + response, + requestOptions + ); + } + } + }, + + _parseArgs: function (args) { + var params = []; + Ext.each(args, function (arg) { + params.push(arg); + }); + + var options = params[params.length - 1]; + if (Ext.type(options) == 'object') { + var keys = Ext.keys(options), + isOption = false; + + Ext.each(this._optionKeys, function (key) { + if (keys.indexOf(key) > -1) isOption = true; + }); + + if (isOption) { + params.remove(options); + } else { + options = {}; + } + } else { + options = {}; + } + options.params = params; + return options; + }, + + _setMethods: function (methods) { + var components = {}, + self = this; + + Ext.each(methods, function (method) { + var parts = method.split('.'); + var component = components[parts[0]] || {}; + + var fn = function () { + var options = self._parseArgs(arguments); + return self._execute(method, options); + }; + component[parts[1]] = fn; + components[parts[0]] = component; + }); + + for (var name in components) { + self[name] = components[name]; + } + Ext.each( + this._components, + function (component) { + if (!component in components) { + delete this[component]; + } + }, + this + ); + this._components = Ext.keys(components); + this.fireEvent('connected', this); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/ConnectionManager.js b/deluge/ui/web/js/deluge-all/ConnectionManager.js new file mode 100644 index 0000000..2e61e22 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/ConnectionManager.js @@ -0,0 +1,442 @@ +/** + * Deluge.ConnectionManager.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Deluge.ConnectionManager = Ext.extend(Ext.Window, { + layout: 'fit', + width: 300, + height: 220, + bodyStyle: 'padding: 10px 5px;', + buttonAlign: 'right', + closeAction: 'hide', + closable: true, + plain: true, + constrainHeader: true, + title: _('Connection Manager'), + iconCls: 'x-deluge-connect-window-icon', + + initComponent: function () { + Deluge.ConnectionManager.superclass.initComponent.call(this); + this.on('hide', this.onHide, this); + this.on('show', this.onShow, this); + + deluge.events.on('login', this.onLogin, this); + deluge.events.on('logout', this.onLogout, this); + + this.addButton(_('Close'), this.onClose, this); + this.addButton(_('Connect'), this.onConnect, this); + + this.list = new Ext.list.ListView({ + store: new Ext.data.ArrayStore({ + fields: [ + { name: 'status', mapping: 4 }, + { name: 'host', mapping: 1 }, + { name: 'port', mapping: 2 }, + { name: 'user', mapping: 3 }, + { name: 'version', mapping: 5 }, + ], + id: 0, + }), + columns: [ + { + header: _('Status'), + width: 0.24, + sortable: true, + tpl: new Ext.XTemplate( + '', + _('Online'), + '', + '', + _('Offline'), + '', + '', + _('Connected'), + '' + ), + dataIndex: 'status', + }, + { + id: 'host', + header: _('Host'), + width: 0.51, + sortable: true, + tpl: '{user}@{host}:{port}', + dataIndex: 'host', + }, + { + header: _('Version'), + width: 0.25, + sortable: true, + tpl: '{version}', + dataIndex: 'version', + }, + ], + singleSelect: true, + listeners: { + selectionchange: { fn: this.onSelectionChanged, scope: this }, + }, + }); + + this.panel = this.add({ + autoScroll: true, + items: [this.list], + bbar: new Ext.Toolbar({ + buttons: [ + { + id: 'cm-add', + cls: 'x-btn-text-icon', + text: _('Add'), + iconCls: 'icon-add', + handler: this.onAddClick, + scope: this, + }, + { + id: 'cm-edit', + cls: 'x-btn-text-icon', + text: _('Edit'), + iconCls: 'icon-edit', + handler: this.onEditClick, + scope: this, + }, + { + id: 'cm-remove', + cls: 'x-btn-text-icon', + text: _('Remove'), + iconCls: 'icon-remove', + handler: this.onRemoveClick, + disabled: true, + scope: this, + }, + '->', + { + id: 'cm-stop', + cls: 'x-btn-text-icon', + text: _('Stop Daemon'), + iconCls: 'icon-error', + handler: this.onStopClick, + disabled: true, + scope: this, + }, + ], + }), + }); + this.update = this.update.createDelegate(this); + }, + + /** + * Check to see if the the web interface is currently connected + * to a Deluge Daemon and show the Connection Manager if not. + */ + checkConnected: function () { + deluge.client.web.connected({ + success: function (connected) { + if (connected) { + deluge.events.fire('connect'); + } else { + this.show(); + } + }, + scope: this, + }); + }, + + disconnect: function (show) { + deluge.events.fire('disconnect'); + if (show) { + if (this.isVisible()) return; + this.show(); + } + }, + + loadHosts: function () { + deluge.client.web.get_hosts({ + success: this.onGetHosts, + scope: this, + }); + }, + + update: function () { + this.updating = setTimeout(this.update, 2000); + this.list.getStore().each(function (r) { + deluge.client.web.get_host_status(r.id, { + success: this.onUpdate, + scope: this, + }); + }, this); + }, + onUpdate: function (host) { + if (!this.isVisible()) return; + this.onGetHostStatus(host); + + if (this.updating) { + clearTimeout(this.updating); + } + this.updating = setTimeout(this.update, 2000); + }, + + /** + * Updates the buttons in the Connection Manager UI according to the + * passed in records host state. + * @param {Ext.data.Record} record The hosts record to update the UI for + */ + updateButtons: function (record) { + var button = this.buttons[1], + status = record.get('status'); + + // Update the Connect/Disconnect button + button.enable(); + if (status.toLowerCase() == 'connected') { + button.setText(_('Disconnect')); + } else { + button.setText(_('Connect')); + if (status.toLowerCase() != 'online') button.disable(); + } + + // Update the Stop/Start Daemon button + if ( + status.toLowerCase() == 'connected' || + status.toLowerCase() == 'online' + ) { + this.stopHostButton.enable(); + this.stopHostButton.setText(_('Stop Daemon')); + } else { + if ( + record.get('host') == '127.0.0.1' || + record.get('host') == 'localhost' + ) { + this.stopHostButton.enable(); + this.stopHostButton.setText(_('Start Daemon')); + } else { + this.stopHostButton.disable(); + } + } + }, + + // private + onAddClick: function (button, e) { + if (!this.addWindow) { + this.addWindow = new Deluge.AddConnectionWindow(); + this.addWindow.on('hostadded', this.onHostChange, this); + } + this.addWindow.show(); + }, + + // private + onEditClick: function (button, e) { + var connection = this.list.getSelectedRecords()[0]; + if (!connection) return; + + if (!this.editWindow) { + this.editWindow = new Deluge.EditConnectionWindow(); + this.editWindow.on('hostedited', this.onHostChange, this); + } + this.editWindow.show(connection); + }, + + // private + onHostChange: function () { + this.loadHosts(); + }, + + // private + onClose: function (e) { + this.hide(); + }, + + // private + onConnect: function (e) { + var selected = this.list.getSelectedRecords()[0]; + if (!selected) return; + + var me = this; + var disconnect = function () { + deluge.client.web.disconnect({ + success: function (result) { + this.update(this); + deluge.events.fire('disconnect'); + }, + scope: me, + }); + }; + + if (selected.get('status').toLowerCase() == 'connected') { + disconnect(); + } else { + if ( + this.list + .getStore() + .find('status', 'Connected', 0, false, false) > -1 + ) { + disconnect(); + } + + var id = selected.id; + deluge.client.web.connect(id, { + success: function (methods) { + deluge.client.reloadMethods(); + deluge.client.on( + 'connected', + function (e) { + deluge.events.fire('connect'); + }, + this, + { single: true } + ); + }, + }); + this.hide(); + } + }, + + // private + onGetHosts: function (hosts) { + this.list.getStore().loadData(hosts); + Ext.each( + hosts, + function (host) { + deluge.client.web.get_host_status(host[0], { + success: this.onGetHostStatus, + scope: this, + }); + }, + this + ); + }, + + // private + onGetHostStatus: function (host) { + var record = this.list.getStore().getById(host[0]); + record.set('status', host[1]); + record.set('version', host[2]); + record.commit(); + var selected = this.list.getSelectedRecords()[0]; + if (!selected) return; + if (selected == record) this.updateButtons(record); + }, + + // private + onHide: function () { + if (this.updating) { + window.clearTimeout(this.updating); + this.updating = undefined; + } + }, + + // private + onLogin: function () { + if (deluge.config.first_login) { + Ext.MessageBox.confirm( + _('Change Default Password'), + _( + 'We recommend changing the default password.

Would you like to change it now?' + ), + function (res) { + this.checkConnected(); + if (res == 'yes') { + deluge.preferences.show(); + deluge.preferences.selectPage('Interface'); + } + deluge.client.web.set_config({ first_login: false }); + }, + this + ); + } else { + this.checkConnected(); + } + }, + + // private + onLogout: function () { + this.disconnect(); + if (!this.hidden && this.rendered) { + this.hide(); + } + }, + + // private + onRemoveClick: function (button) { + var connection = this.list.getSelectedRecords()[0]; + if (!connection) return; + + deluge.client.web.remove_host(connection.id, { + success: function (result) { + if (!result) { + Ext.MessageBox.show({ + title: _('Error'), + msg: result[1], + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + } else { + this.list.getStore().remove(connection); + } + }, + scope: this, + }); + }, + + // private + onSelectionChanged: function (list, selections) { + if (selections[0]) { + this.editHostButton.enable(); + this.removeHostButton.enable(); + this.stopHostButton.enable(); + this.stopHostButton.setText(_('Stop Daemon')); + this.updateButtons(this.list.getRecord(selections[0])); + } else { + this.editHostButton.disable(); + this.removeHostButton.disable(); + this.stopHostButton.disable(); + } + }, + + // FIXME: Find out why this is being fired twice + // private + onShow: function () { + if (!this.addHostButton) { + var bbar = this.panel.getBottomToolbar(); + this.addHostButton = bbar.items.get('cm-add'); + this.editHostButton = bbar.items.get('cm-edit'); + this.removeHostButton = bbar.items.get('cm-remove'); + this.stopHostButton = bbar.items.get('cm-stop'); + } + this.loadHosts(); + if (this.updating) return; + this.updating = window.setTimeout(this.update, 2000); + }, + + // private + onStopClick: function (button, e) { + var connection = this.list.getSelectedRecords()[0]; + if (!connection) return; + + if (connection.get('status') == 'Offline') { + // This means we need to start the daemon + deluge.client.web.start_daemon(connection.get('port')); + } else { + // This means we need to stop the daemon + deluge.client.web.stop_daemon(connection.id, { + success: function (result) { + if (!result[0]) { + Ext.MessageBox.show({ + title: _('Error'), + msg: result[1], + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + } + }, + }); + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/CopyMagnetWindow.js b/deluge/ui/web/js/deluge-all/CopyMagnetWindow.js new file mode 100644 index 0000000..ddcd4ab --- /dev/null +++ b/deluge/ui/web/js/deluge-all/CopyMagnetWindow.js @@ -0,0 +1,73 @@ +/* + * Deluge.CopyMagnet.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the OpenSSL + * library. + * You must obey the GNU General Public License in all respects for all of + * the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete + * this exception statement from your version. If you delete this exception + * statement from all source files in the program, then also delete it here. + */ +Deluge.CopyMagnet = Ext.extend(Ext.Window, { + title: _('Copy Magnet URI'), + width: 375, + closeAction: 'hide', + iconCls: 'icon-magnet-copy', + + initComponent: function () { + Deluge.CopyMagnet.superclass.initComponent.call(this); + form = this.add({ + xtype: 'form', + defaultType: 'textfield', + hideLabels: true, + }); + this.magnetURI = form.add({ + name: 'URI', + anchor: '100%', + }); + this.addButton(_('Close'), this.onClose, this); + this.addButton(_('Copy'), this.onCopy, this); + }, + show: function (a) { + Deluge.CopyMagnet.superclass.show.call(this); + var torrent = deluge.torrents.getSelected(); + deluge.client.core.get_magnet_uri(torrent.id, { + success: this.onRequestComplete, + scope: this, + }); + }, + onRequestComplete: function (uri) { + this.magnetURI.setValue(uri); + }, + onCopy: function () { + this.magnetURI.focus(); + this.magnetURI.el.dom.select(); + document.execCommand('copy'); + }, + onClose: function () { + this.hide(); + }, +}); + +deluge.copyMagnetWindow = new Deluge.CopyMagnet(); diff --git a/deluge/ui/web/js/deluge-all/Deluge.js b/deluge/ui/web/js/deluge-all/Deluge.js new file mode 100644 index 0000000..260ad97 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Deluge.js @@ -0,0 +1,179 @@ +/** + * Deluge.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +// Setup the state manager +Ext.state.Manager.setProvider( + new Ext.state.CookieProvider({ + /** + * By default, cookies will expire after 7 days. Provide + * an expiry date 10 years in the future to approximate + * a cookie that does not expire. + */ + expires: new Date( + new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 10 + ), + }) +); + +// Add some additional functions to ext and setup some of the +// configurable parameters +Ext.apply(Ext, { + isObjectEmpty: function (obj) { + for (var i in obj) { + return false; + } + return true; + }, + + areObjectsEqual: function (obj1, obj2) { + var equal = true; + if (!obj1 || !obj2) return false; + for (var i in obj1) { + if (obj1[i] != obj2[i]) { + equal = false; + } + } + return equal; + }, + + keys: function (obj) { + var keys = []; + for (var i in obj) + if (obj.hasOwnProperty(i)) { + keys.push(i); + } + return keys; + }, + + values: function (obj) { + var values = []; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + values.push(obj[i]); + } + } + return values; + }, + + splat: function (obj) { + var type = Ext.type(obj); + return type ? (type != 'array' ? [obj] : obj) : []; + }, +}); +Ext.getKeys = Ext.keys; +Ext.BLANK_IMAGE_URL = deluge.config.base + 'images/s.gif'; +Ext.USE_NATIVE_JSON = true; + +// Create the Deluge namespace +Ext.apply(Deluge, { + // private + pluginStore: {}, + + // private + progressTpl: + '
' + + '
' + + '
' + + '
' + + '
{0}
' + + '
' + + '
' + + '
' + + '
{0}
' + + '
' + + '
' + + '
', + + /** + * A method to create a progress bar that can be used by renderers + * to display a bar within a grid or tree. + * @param {Number} progress The bars progress + * @param {Number} width The width of the bar + * @param {String} text The text to display on the bar + * @param {Number} modified Amount to subtract from the width allowing for fixes + */ + progressBar: function (progress, width, text, modifier) { + modifier = Ext.value(modifier, 10); + var progressWidth = ((width / 100.0) * progress).toFixed(0); + var barWidth = progressWidth - 1; + var textWidth = + progressWidth - modifier > 0 ? progressWidth - modifier : 0; + return String.format( + Deluge.progressTpl, + text, + width, + barWidth, + textWidth + ); + }, + + /** + * Constructs a new instance of the specified plugin. + * @param {String} name The plugin name to create + */ + createPlugin: function (name) { + return new Deluge.pluginStore[name](); + }, + + /** + * Check to see if a plugin has been registered. + * @param {String} name The plugin name to check + */ + hasPlugin: function (name) { + return Deluge.pluginStore[name] ? true : false; + }, + + /** + * Register a plugin with the Deluge interface. + * @param {String} name The plugin name to register + * @param {Plugin} plugin The plugin to register + */ + registerPlugin: function (name, plugin) { + Deluge.pluginStore[name] = plugin; + }, +}); + +// Setup a space for plugins to insert themselves +deluge.plugins = {}; + +// Hinting for gettext_gen.py +// _('Skip') +// _('Low') +// _('Normal') +// _('High') +// _('Mixed') +FILE_PRIORITY = { + 0: 'Skip', + 1: 'Low', + 2: 'Low', + 3: 'Low', + 4: 'Normal', + 5: 'High', + 6: 'High', + 7: 'High', + 9: 'Mixed', + Skip: 0, + Low: 1, + Normal: 4, + High: 7, + Mixed: 9, +}; + +FILE_PRIORITY_CSS = { + 0: 'x-no-download', + 1: 'x-low-download', + 2: 'x-low-download', + 3: 'x-low-download', + 4: 'x-normal-download', + 5: 'x-high-download', + 6: 'x-high-download', + 7: 'x-high-download', + 9: 'x-mixed-download', +}; diff --git a/deluge/ui/web/js/deluge-all/EditConnectionWindow.js b/deluge/ui/web/js/deluge-all/EditConnectionWindow.js new file mode 100644 index 0000000..bfeb38f --- /dev/null +++ b/deluge/ui/web/js/deluge-all/EditConnectionWindow.js @@ -0,0 +1,128 @@ +/** + * Deluge.EditConnectionWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.EditConnectionWindow + * @extends Ext.Window + */ +Deluge.EditConnectionWindow = Ext.extend(Ext.Window, { + title: _('Edit Connection'), + iconCls: 'x-deluge-add-window-icon', + + layout: 'fit', + width: 300, + height: 195, + constrainHeader: true, + bodyStyle: 'padding: 10px 5px;', + closeAction: 'hide', + + initComponent: function () { + Deluge.EditConnectionWindow.superclass.initComponent.call(this); + + this.addEvents('hostedited'); + + this.addButton(_('Close'), this.hide, this); + this.addButton(_('Edit'), this.onEditClick, this); + + this.on('hide', this.onHide, this); + + this.form = this.add({ + xtype: 'form', + defaultType: 'textfield', + baseCls: 'x-plain', + labelWidth: 60, + items: [ + { + fieldLabel: _('Host:'), + labelSeparator: '', + name: 'host', + anchor: '75%', + value: '', + }, + { + xtype: 'spinnerfield', + fieldLabel: _('Port:'), + labelSeparator: '', + name: 'port', + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: 0, + maxValue: 65535, + }, + anchor: '40%', + value: 58846, + }, + { + fieldLabel: _('Username:'), + labelSeparator: '', + name: 'username', + anchor: '75%', + value: '', + }, + { + fieldLabel: _('Password:'), + labelSeparator: '', + anchor: '75%', + name: 'password', + inputType: 'password', + value: '', + }, + ], + }); + }, + + show: function (connection) { + Deluge.EditConnectionWindow.superclass.show.call(this); + + this.form.getForm().findField('host').setValue(connection.get('host')); + this.form.getForm().findField('port').setValue(connection.get('port')); + this.form + .getForm() + .findField('username') + .setValue(connection.get('user')); + this.host_id = connection.id; + }, + + onEditClick: function () { + var values = this.form.getForm().getValues(); + deluge.client.web.edit_host( + this.host_id, + values.host, + Number(values.port), + values.username, + values.password, + { + success: function (result) { + if (!result) { + console.log(result); + Ext.MessageBox.show({ + title: _('Error'), + msg: String.format(_('Unable to edit host')), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + } else { + this.fireEvent('hostedited'); + } + this.hide(); + }, + scope: this, + } + ); + }, + + onHide: function () { + this.form.getForm().reset(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/EditTrackerWindow.js b/deluge/ui/web/js/deluge-all/EditTrackerWindow.js new file mode 100644 index 0000000..646b8de --- /dev/null +++ b/deluge/ui/web/js/deluge-all/EditTrackerWindow.js @@ -0,0 +1,74 @@ +/** + * Deluge.EditTrackerWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.EditTrackerWindow + * @extends Ext.Window + */ +Deluge.EditTrackerWindow = Ext.extend(Ext.Window, { + title: _('Edit Tracker'), + layout: 'fit', + width: 375, + height: 110, + plain: true, + closable: true, + resizable: false, + constrainHeader: true, + bodyStyle: 'padding: 5px', + buttonAlign: 'right', + closeAction: 'hide', + iconCls: 'x-deluge-edit-trackers', + + initComponent: function () { + Deluge.EditTrackerWindow.superclass.initComponent.call(this); + + this.addButton(_('Cancel'), this.onCancelClick, this); + this.addButton(_('Save'), this.onSaveClick, this); + this.on('hide', this.onHide, this); + + this.form = this.add({ + xtype: 'form', + defaultType: 'textfield', + baseCls: 'x-plain', + labelWidth: 55, + items: [ + { + fieldLabel: _('Tracker:'), + labelSeparator: '', + name: 'tracker', + anchor: '100%', + }, + ], + }); + }, + + show: function (record) { + Deluge.EditTrackerWindow.superclass.show.call(this); + + this.record = record; + this.form.getForm().findField('tracker').setValue(record.data['url']); + }, + + onCancelClick: function () { + this.hide(); + }, + + onHide: function () { + this.form.getForm().findField('tracker').setValue(''); + }, + + onSaveClick: function () { + var url = this.form.getForm().findField('tracker').getValue(); + this.record.set('url', url); + this.record.commit(); + this.hide(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/EditTrackersWindow.js b/deluge/ui/web/js/deluge-all/EditTrackersWindow.js new file mode 100644 index 0000000..178fd58 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/EditTrackersWindow.js @@ -0,0 +1,234 @@ +/** + * Deluge.EditTrackers.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.EditTrackersWindow + * @extends Ext.Window + */ +Deluge.EditTrackersWindow = Ext.extend(Ext.Window, { + title: _('Edit Trackers'), + layout: 'fit', + width: 350, + height: 220, + plain: true, + closable: true, + resizable: true, + constrainHeader: true, + + bodyStyle: 'padding: 5px', + buttonAlign: 'right', + closeAction: 'hide', + iconCls: 'x-deluge-edit-trackers', + + initComponent: function () { + Deluge.EditTrackersWindow.superclass.initComponent.call(this); + + this.addButton(_('Cancel'), this.onCancelClick, this); + this.addButton(_('OK'), this.onOkClick, this); + this.addEvents('save'); + + this.on('show', this.onShow, this); + this.on('save', this.onSave, this); + + this.addWindow = new Deluge.AddTrackerWindow(); + this.addWindow.on('add', this.onAddTrackers, this); + this.editWindow = new Deluge.EditTrackerWindow(); + + this.list = new Ext.list.ListView({ + store: new Ext.data.JsonStore({ + root: 'trackers', + fields: ['tier', 'url'], + }), + columns: [ + { + header: _('Tier'), + width: 0.1, + dataIndex: 'tier', + }, + { + header: _('Tracker'), + width: 0.9, + dataIndex: 'url', + tpl: new Ext.XTemplate('{url:htmlEncode}'), + }, + ], + columnSort: { + sortClasses: ['', ''], + }, + stripeRows: true, + singleSelect: true, + listeners: { + dblclick: { fn: this.onListNodeDblClicked, scope: this }, + selectionchange: { fn: this.onSelect, scope: this }, + }, + }); + + this.panel = this.add({ + items: [this.list], + autoScroll: true, + bbar: new Ext.Toolbar({ + items: [ + { + text: _('Up'), + iconCls: 'icon-up', + handler: this.onUpClick, + scope: this, + }, + { + text: _('Down'), + iconCls: 'icon-down', + handler: this.onDownClick, + scope: this, + }, + '->', + { + text: _('Add'), + iconCls: 'icon-add', + handler: this.onAddClick, + scope: this, + }, + { + text: _('Edit'), + iconCls: 'icon-edit-trackers', + handler: this.onEditClick, + scope: this, + }, + { + text: _('Remove'), + iconCls: 'icon-remove', + handler: this.onRemoveClick, + scope: this, + }, + ], + }), + }); + }, + + onAddClick: function () { + this.addWindow.show(); + }, + + onAddTrackers: function (trackers) { + var store = this.list.getStore(); + Ext.each( + trackers, + function (tracker) { + var duplicate = false, + heightestTier = -1; + store.each(function (record) { + if (record.get('tier') > heightestTier) { + heightestTier = record.get('tier'); + } + if (tracker == record.get('tracker')) { + duplicate = true; + return false; + } + }, this); + if (duplicate) return; + store.add( + new store.recordType({ + tier: heightestTier + 1, + url: tracker, + }) + ); + }, + this + ); + }, + + onCancelClick: function () { + this.hide(); + }, + + onEditClick: function () { + var selected = this.list.getSelectedRecords()[0]; + if (!selected) return; + this.editWindow.show(selected); + }, + + onHide: function () { + this.list.getStore().removeAll(); + }, + + onListNodeDblClicked: function (list, index, node, e) { + this.editWindow.show(this.list.getRecord(node)); + }, + + onOkClick: function () { + var trackers = []; + this.list.getStore().each(function (record) { + trackers.push({ + tier: record.get('tier'), + url: record.get('url'), + }); + }, this); + + deluge.client.core.set_torrent_trackers(this.torrentId, trackers, { + failure: this.onSaveFail, + scope: this, + }); + + this.hide(); + }, + + onRemoveClick: function () { + // Remove from the grid + var selected = this.list.getSelectedRecords()[0]; + if (!selected) return; + this.list.getStore().remove(selected); + }, + + onRequestComplete: function (status) { + this.list.getStore().loadData(status); + this.list.getStore().sort('tier', 'ASC'); + }, + + onSaveFail: function () {}, + + onSelect: function (list) { + if (list.getSelectionCount()) { + this.panel.getBottomToolbar().items.get(4).enable(); + } + }, + + onShow: function () { + this.panel.getBottomToolbar().items.get(4).disable(); + var r = deluge.torrents.getSelected(); + this.torrentId = r.id; + deluge.client.core.get_torrent_status(r.id, ['trackers'], { + success: this.onRequestComplete, + scope: this, + }); + }, + + onDownClick: function () { + var r = this.list.getSelectedRecords()[0]; + if (!r) return; + + r.set('tier', r.get('tier') + 1); + r.store.sort('tier', 'ASC'); + r.store.commitChanges(); + + this.list.select(r.store.indexOf(r)); + }, + + onUpClick: function () { + var r = this.list.getSelectedRecords()[0]; + if (!r) return; + + if (r.get('tier') == 0) return; + r.set('tier', r.get('tier') - 1); + r.store.sort('tier', 'ASC'); + r.store.commitChanges(); + + this.list.select(r.store.indexOf(r)); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/EventsManager.js b/deluge/ui/web/js/deluge-all/EventsManager.js new file mode 100644 index 0000000..89d8980 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/EventsManager.js @@ -0,0 +1,118 @@ +/** + * Deluge.EventsManager.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * @class Deluge.EventsManager + * @extends Ext.util.Observable + *

Deluge.EventsManager is instantated as deluge.events and can be used by components of the UI to fire global events

+ * Class for holding global events that occur within the UI. + */ +Deluge.EventsManager = Ext.extend(Ext.util.Observable, { + constructor: function () { + this.toRegister = []; + this.on('login', this.onLogin, this); + Deluge.EventsManager.superclass.constructor.call(this); + }, + + /** + * Append an event handler to this object. + */ + addListener: function (eventName, fn, scope, o) { + this.addEvents(eventName); + if (/[A-Z]/.test(eventName.substring(0, 1))) { + if (!deluge.client) { + this.toRegister.push(eventName); + } else { + deluge.client.web.register_event_listener(eventName); + } + } + Deluge.EventsManager.superclass.addListener.call( + this, + eventName, + fn, + scope, + o + ); + }, + + getEvents: function () { + deluge.client.web.get_events({ + success: this.onGetEventsSuccess, + failure: this.onGetEventsFailure, + scope: this, + }); + }, + + /** + * Starts the EventsManagerManager checking for events. + */ + start: function () { + Ext.each(this.toRegister, function (eventName) { + deluge.client.web.register_event_listener(eventName); + }); + this.running = true; + this.errorCount = 0; + this.getEvents(); + }, + + /** + * Stops the EventsManagerManager checking for events. + */ + stop: function () { + this.running = false; + }, + + // private + onLogin: function () { + this.start(); + }, + + onGetEventsSuccess: function (events) { + if (!this.running) return; + if (events) { + Ext.each( + events, + function (event) { + var name = event[0], + args = event[1]; + args.splice(0, 0, name); + this.fireEvent.apply(this, args); + }, + this + ); + } + this.getEvents(); + }, + + // private + onGetEventsFailure: function (result, error) { + // the request timed out or we had a communication failure + if (!this.running) return; + if (!error.isTimeout && this.errorCount++ >= 3) { + this.stop(); + return; + } + this.getEvents(); + }, +}); + +/** + * Appends an event handler to this object (shorthand for {@link #addListener}) + * @method + */ +Deluge.EventsManager.prototype.on = Deluge.EventsManager.prototype.addListener; + +/** + * Fires the specified event with the passed parameters (minus the + * event name). + * @method + */ +Deluge.EventsManager.prototype.fire = Deluge.EventsManager.prototype.fireEvent; +deluge.events = new Deluge.EventsManager(); diff --git a/deluge/ui/web/js/deluge-all/FileBrowser.js b/deluge/ui/web/js/deluge-all/FileBrowser.js new file mode 100644 index 0000000..2afe1b1 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/FileBrowser.js @@ -0,0 +1,43 @@ +/** + * Deluge.FileBrowser.js + * + * Copyright (c) Damien Churchill 2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.namespace('Deluge'); +Deluge.FileBrowser = Ext.extend(Ext.Window, { + title: _('File Browser'), + + width: 500, + height: 400, + + initComponent: function () { + Deluge.FileBrowser.superclass.initComponent.call(this); + + this.add({ + xtype: 'toolbar', + items: [ + { + text: _('Back'), + iconCls: 'icon-back', + }, + { + text: _('Forward'), + iconCls: 'icon-forward', + }, + { + text: _('Up'), + iconCls: 'icon-up', + }, + { + text: _('Home'), + iconCls: 'icon-home', + }, + ], + }); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/FilterPanel.js b/deluge/ui/web/js/deluge-all/FilterPanel.js new file mode 100644 index 0000000..f1fade1 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/FilterPanel.js @@ -0,0 +1,175 @@ +/** + * Deluge.FilterPanel.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.FilterPanel + * @extends Ext.list.ListView + */ +Deluge.FilterPanel = Ext.extend(Ext.Panel, { + autoScroll: true, + + border: false, + + show_zero: null, + + initComponent: function () { + Deluge.FilterPanel.superclass.initComponent.call(this); + this.filterType = this.initialConfig.filter; + var title = ''; + if (this.filterType == 'state') { + title = _('States'); + } else if (this.filterType == 'tracker_host') { + title = _('Trackers'); + } else if (this.filterType == 'owner') { + title = _('Owner'); + } else if (this.filterType == 'label') { + title = _('Labels'); + } else { + (title = this.filterType.replace('_', ' ')), + (parts = title.split(' ')), + (title = ''); + Ext.each(parts, function (p) { + fl = p.substring(0, 1).toUpperCase(); + title += fl + p.substring(1) + ' '; + }); + } + this.setTitle(_(title)); + + if (Deluge.FilterPanel.templates[this.filterType]) { + var tpl = Deluge.FilterPanel.templates[this.filterType]; + } else { + var tpl = + '
{filter} ({count})
'; + } + + this.list = this.add({ + xtype: 'listview', + singleSelect: true, + hideHeaders: true, + reserveScrollOffset: true, + store: new Ext.data.ArrayStore({ + idIndex: 0, + fields: ['filter', 'count'], + }), + columns: [ + { + id: 'filter', + sortable: false, + tpl: tpl, + dataIndex: 'filter', + }, + ], + }); + this.relayEvents(this.list, ['selectionchange']); + }, + + /** + * Return the currently selected filter state + * @returns {String} the current filter state + */ + getState: function () { + if (!this.list.getSelectionCount()) return; + + var state = this.list.getSelectedRecords()[0]; + if (!state) return; + if (state.id == 'All') return; + return state.id; + }, + + /** + * Return the current states in the filter + */ + getStates: function () { + return this.states; + }, + + /** + * Return the Store for the ListView of the FilterPanel + * @returns {Ext.data.Store} the ListView store + */ + getStore: function () { + return this.list.getStore(); + }, + + /** + * Update the states in the FilterPanel + */ + updateStates: function (states) { + this.states = {}; + Ext.each( + states, + function (state) { + this.states[state[0]] = state[1]; + }, + this + ); + + var show_zero = + this.show_zero == null + ? deluge.config.sidebar_show_zero + : this.show_zero; + if (!show_zero) { + var newStates = []; + Ext.each(states, function (state) { + if (state[1] > 0 || state[0] == 'All') { + newStates.push(state); + } + }); + states = newStates; + } + + var store = this.getStore(); + var filters = {}; + Ext.each( + states, + function (s, i) { + var record = store.getById(s[0]); + if (!record) { + record = new store.recordType({ + filter: s[0], + count: s[1], + }); + record.id = s[0]; + store.insert(i, record); + } + record.beginEdit(); + record.set('filter', _(s[0])); + record.set('count', s[1]); + record.endEdit(); + filters[s[0]] = true; + }, + this + ); + + store.each(function (record) { + if (filters[record.id]) return; + store.remove(record); + var selected = this.list.getSelectedRecords()[0]; + if (!selected) return; + if (selected.id == record.id) { + this.list.select(0); + } + }, this); + + store.commitChanges(); + + if (!this.list.getSelectionCount()) { + this.list.select(0); + } + }, +}); + +Deluge.FilterPanel.templates = { + tracker_host: + '
{filter:htmlEncode} ({count})
', +}; diff --git a/deluge/ui/web/js/deluge-all/Formatters.js b/deluge/ui/web/js/deluge-all/Formatters.js new file mode 100644 index 0000000..6b09abe --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Formatters.js @@ -0,0 +1,206 @@ +/** + * Deluge.Formatters.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * A collection of functions for string formatting values. + * @class Deluge.Formatters + * @author Damien Churchill + * @version 1.3 + * @singleton + */ +Deluge.Formatters = (function () { + var charToEntity = { + '&': '&', + '>': '>', + '<': '<', + '"': '"', + "'": ''', + }; + + var charToEntityRegex = new RegExp( + '(' + Object.keys(charToEntity).join('|') + ')', + 'g' + ); + var htmlEncodeReplaceFn = function (match, capture) { + return charToEntity[capture]; + }; + + /** + * Formats a date string in the date representation of the current locale, + * based on the systems timezone. + * + * @param {Number} timestamp time in seconds since the Epoch. + * @return {String} a string in the date representation of the current locale + * or "" if seconds < 0. + */ + return (Formatters = { + date: function (timestamp) { + function zeroPad(num, count) { + var numZeropad = num + ''; + while (numZeropad.length < count) { + numZeropad = '0' + numZeropad; + } + return numZeropad; + } + timestamp = timestamp * 1000; + var date = new Date(timestamp); + return String.format( + '{0}/{1}/{2} {3}:{4}:{5}', + zeroPad(date.getDate(), 2), + zeroPad(date.getMonth() + 1, 2), + date.getFullYear(), + zeroPad(date.getHours(), 2), + zeroPad(date.getMinutes(), 2), + zeroPad(date.getSeconds(), 2) + ); + }, + + /** + * Formats the bytes value into a string with KiB, MiB or GiB units. + * + * @param {Number} bytes the filesize in bytes + * @param {Boolean} showZero pass in true to displays 0 values + * @return {String} formatted string with KiB, MiB or GiB units. + */ + size: function (bytes, showZero) { + if (!bytes && !showZero) return ''; + bytes = bytes / 1024.0; + + if (bytes < 1024) { + return bytes.toFixed(1) + ' KiB'; + } else { + bytes = bytes / 1024; + } + + if (bytes < 1024) { + return bytes.toFixed(1) + ' MiB'; + } else { + bytes = bytes / 1024; + } + + return bytes.toFixed(1) + ' GiB'; + }, + + /** + * Formats the bytes value into a string with K, M or G units. + * + * @param {Number} bytes the filesize in bytes + * @param {Boolean} showZero pass in true to displays 0 values + * @return {String} formatted string with K, M or G units. + */ + sizeShort: function (bytes, showZero) { + if (!bytes && !showZero) return ''; + bytes = bytes / 1024.0; + + if (bytes < 1024) { + return bytes.toFixed(1) + ' K'; + } else { + bytes = bytes / 1024; + } + + if (bytes < 1024) { + return bytes.toFixed(1) + ' M'; + } else { + bytes = bytes / 1024; + } + + return bytes.toFixed(1) + ' G'; + }, + + /** + * Formats a string to display a transfer speed utilizing {@link #size} + * + * @param {Number} bytes the number of bytes per second + * @param {Boolean} showZero pass in true to displays 0 values + * @return {String} formatted string with KiB, MiB or GiB units. + */ + speed: function (bytes, showZero) { + return !bytes && !showZero ? '' : fsize(bytes, showZero) + '/s'; + }, + + /** + * Formats a string to show time in a human readable form. + * + * @param {Number} time the number of seconds + * @return {String} a formatted time string. will return '' if seconds == 0 + */ + timeRemaining: function (time) { + if (time <= 0) { + return '∞'; + } + time = time.toFixed(0); + if (time < 60) { + return time + 's'; + } else { + time = time / 60; + } + + if (time < 60) { + var minutes = Math.floor(time); + var seconds = Math.round(60 * (time - minutes)); + if (seconds > 0) { + return minutes + 'm ' + seconds + 's'; + } else { + return minutes + 'm'; + } + } else { + time = time / 60; + } + + if (time < 24) { + var hours = Math.floor(time); + var minutes = Math.round(60 * (time - hours)); + if (minutes > 0) { + return hours + 'h ' + minutes + 'm'; + } else { + return hours + 'h'; + } + } else { + time = time / 24; + } + + var days = Math.floor(time); + var hours = Math.round(24 * (time - days)); + if (hours > 0) { + return days + 'd ' + hours + 'h'; + } else { + return days + 'd'; + } + }, + + /** + * Simply returns the value untouched, for when no formatting is required. + * + * @param {Mixed} value the value to be displayed + * @return the untouched value. + */ + plain: function (value) { + return value; + }, + + cssClassEscape: function (value) { + return value.toLowerCase().replace('.', '_'); + }, + + htmlEncode: function (value) { + return !value + ? value + : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn); + }, + }); +})(); +var fsize = Deluge.Formatters.size; +var fsize_short = Deluge.Formatters.sizeShort; +var fspeed = Deluge.Formatters.speed; +var ftime = Deluge.Formatters.timeRemaining; +var fdate = Deluge.Formatters.date; +var fplain = Deluge.Formatters.plain; +Ext.util.Format.cssClassEscape = Deluge.Formatters.cssClassEscape; +Ext.util.Format.htmlEncode = Deluge.Formatters.htmlEncode; diff --git a/deluge/ui/web/js/deluge-all/Keys.js b/deluge/ui/web/js/deluge-all/Keys.js new file mode 100644 index 0000000..7b3e3af --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Keys.js @@ -0,0 +1,138 @@ +/** + * Deluge.Keys.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * @description The torrent status keys that are commonly used around the UI. + * @class Deluge.Keys + * @singleton + */ +Deluge.Keys = { + /** + * Keys that are used within the torrent grid. + *
['queue', 'name', 'total_wanted', 'state', 'progress', 'num_seeds',
+     * 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
+     * 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
+     * 'is_auto_managed', 'time_added', 'tracker_host', 'download_location', 'last_seen_complete',
+     * 'total_done', 'total_uploaded', 'max_download_speed', 'max_upload_speed',
+     * 'seeds_peers_ratio', 'total_remaining', 'completed_time', 'time_since_transfer']
+ */ + Grid: [ + 'queue', + 'name', + 'total_wanted', + 'state', + 'progress', + 'num_seeds', + 'total_seeds', + 'num_peers', + 'total_peers', + 'download_payload_rate', + 'upload_payload_rate', + 'eta', + 'ratio', + 'distributed_copies', + 'is_auto_managed', + 'time_added', + 'tracker_host', + 'download_location', + 'last_seen_complete', + 'total_done', + 'total_uploaded', + 'max_download_speed', + 'max_upload_speed', + 'seeds_peers_ratio', + 'total_remaining', + 'completed_time', + 'time_since_transfer', + ], + + /** + * Keys used in the status tab of the statistics panel. + * These get updated to include the keys in {@link #Grid}. + *
['total_done', 'total_payload_download', 'total_uploaded',
+     * 'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
+     * 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time', 'time_since_transfer',
+     * 'seed_rank', 'last_seen_complete', 'completed_time', 'owner', 'public', 'shared']
+ */ + Status: [ + 'total_done', + 'total_payload_download', + 'total_uploaded', + 'total_payload_upload', + 'next_announce', + 'tracker_status', + 'num_pieces', + 'piece_length', + 'is_auto_managed', + 'active_time', + 'seeding_time', + 'time_since_transfer', + 'seed_rank', + 'last_seen_complete', + 'completed_time', + 'owner', + 'public', + 'shared', + ], + + /** + * Keys used in the files tab of the statistics panel. + *
['files', 'file_progress', 'file_priorities']
+ */ + Files: ['files', 'file_progress', 'file_priorities'], + + /** + * Keys used in the peers tab of the statistics panel. + *
['peers']
+ */ + Peers: ['peers'], + + /** + * Keys used in the details tab of the statistics panel. + */ + Details: [ + 'name', + 'download_location', + 'total_size', + 'num_files', + 'message', + 'tracker_host', + 'comment', + 'creator', + ], + + /** + * Keys used in the options tab of the statistics panel. + *
['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
+     *  'is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'remove_at_ratio', 'private',
+     *  'prioritize_first_last']
+ */ + Options: [ + 'max_download_speed', + 'max_upload_speed', + 'max_connections', + 'max_upload_slots', + 'is_auto_managed', + 'stop_at_ratio', + 'stop_ratio', + 'remove_at_ratio', + 'private', + 'prioritize_first_last', + 'move_completed', + 'move_completed_path', + 'super_seeding', + ], +}; + +// Merge the grid and status keys together as the status keys contain all the +// grid ones. +Ext.each(Deluge.Keys.Grid, function (key) { + Deluge.Keys.Status.push(key); +}); diff --git a/deluge/ui/web/js/deluge-all/LoginWindow.js b/deluge/ui/web/js/deluge-all/LoginWindow.js new file mode 100644 index 0000000..a055a69 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/LoginWindow.js @@ -0,0 +1,134 @@ +/** + * Deluge.LoginWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Deluge.LoginWindow = Ext.extend(Ext.Window, { + firstShow: true, + bodyStyle: 'padding: 10px 5px;', + buttonAlign: 'center', + closable: false, + closeAction: 'hide', + iconCls: 'x-deluge-login-window-icon', + layout: 'fit', + modal: true, + plain: true, + resizable: false, + title: _('Login'), + width: 300, + height: 120, + + initComponent: function () { + Deluge.LoginWindow.superclass.initComponent.call(this); + this.on('show', this.onShow, this); + + this.addButton({ + text: _('Login'), + handler: this.onLogin, + scope: this, + }); + + this.form = this.add({ + xtype: 'form', + baseCls: 'x-plain', + labelWidth: 120, + labelAlign: 'right', + defaults: { width: 110 }, + defaultType: 'textfield', + }); + + this.passwordField = this.form.add({ + xtype: 'textfield', + fieldLabel: _('Password:'), + labelSeparator: '', + grow: true, + growMin: '110', + growMax: '145', + id: '_password', + name: 'password', + inputType: 'password', + }); + this.passwordField.on('specialkey', this.onSpecialKey, this); + }, + + logout: function () { + deluge.events.fire('logout'); + deluge.client.auth.delete_session({ + success: function (result) { + this.show(true); + }, + scope: this, + }); + }, + + show: function (skipCheck) { + if (this.firstShow) { + deluge.client.on('error', this.onClientError, this); + this.firstShow = false; + } + + if (skipCheck) { + return Deluge.LoginWindow.superclass.show.call(this); + } + + deluge.client.auth.check_session({ + success: function (result) { + if (result) { + deluge.events.fire('login'); + } else { + this.show(true); + } + }, + failure: function (result) { + this.show(true); + }, + scope: this, + }); + }, + + onSpecialKey: function (field, e) { + if (e.getKey() == 13) this.onLogin(); + }, + + onLogin: function () { + var passwordField = this.passwordField; + deluge.client.auth.login(passwordField.getValue(), { + success: function (result) { + if (result) { + deluge.events.fire('login'); + this.hide(); + passwordField.setRawValue(''); + } else { + Ext.MessageBox.show({ + title: _('Login Failed'), + msg: _('You entered an incorrect password'), + buttons: Ext.MessageBox.OK, + modal: false, + fn: function () { + passwordField.focus(true, 10); + }, + icon: Ext.MessageBox.WARNING, + iconCls: 'x-deluge-icon-warning', + }); + } + }, + scope: this, + }); + }, + + onClientError: function (errorObj, response, requestOptions) { + if (errorObj.error.code == 1) { + deluge.events.fire('logout'); + this.show(true); + } + }, + + onShow: function () { + this.passwordField.focus(true, 300); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/Menus.js b/deluge/ui/web/js/deluge-all/Menus.js new file mode 100644 index 0000000..34550a6 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Menus.js @@ -0,0 +1,398 @@ +/** + * Deluge.Menus.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +deluge.menus = { + onTorrentActionSetOpt: function (item, e) { + var ids = deluge.torrents.getSelectedIds(); + var action = item.initialConfig.torrentAction; + var opts = {}; + opts[action[0]] = action[1]; + deluge.client.core.set_torrent_options(ids, opts); + }, + + onTorrentActionMethod: function (item, e) { + var ids = deluge.torrents.getSelectedIds(); + var action = item.initialConfig.torrentAction; + deluge.client.core[action](ids, { + success: function () { + deluge.ui.update(); + }, + }); + }, + + onTorrentActionShow: function (item, e) { + var ids = deluge.torrents.getSelectedIds(); + var action = item.initialConfig.torrentAction; + switch (action) { + case 'copy_magnet': + deluge.copyMagnetWindow.show(); + break; + case 'edit_trackers': + deluge.editTrackers.show(); + break; + case 'remove': + deluge.removeWindow.show(ids); + break; + case 'move': + deluge.moveStorage.show(ids); + break; + } + }, +}; + +deluge.menus.torrent = new Ext.menu.Menu({ + id: 'torrentMenu', + items: [ + { + torrentAction: 'pause_torrent', + text: _('Pause'), + iconCls: 'icon-pause', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'resume_torrent', + text: _('Resume'), + iconCls: 'icon-resume', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + '-', + { + text: _('Options'), + iconCls: 'icon-options', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + text: _('D/L Speed Limit'), + iconCls: 'x-deluge-downloading', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: ['max_download_speed', 5], + text: _('5 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_download_speed', 10], + text: _('10 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_download_speed', 30], + text: _('30 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_download_speed', 80], + text: _('80 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_download_speed', 300], + text: _('300 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_download_speed', -1], + text: _('Unlimited'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + ], + }), + }, + { + text: _('U/L Speed Limit'), + iconCls: 'x-deluge-seeding', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: ['max_upload_speed', 5], + text: _('5 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_speed', 10], + text: _('10 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_speed', 30], + text: _('30 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_speed', 80], + text: _('80 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_speed', 300], + text: _('300 KiB/s'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_speed', -1], + text: _('Unlimited'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + ], + }), + }, + { + text: _('Connection Limit'), + iconCls: 'x-deluge-connections', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: ['max_connections', 50], + text: '50', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_connections', 100], + text: '100', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_connections', 200], + text: '200', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_connections', 300], + text: '300', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_connections', 500], + text: '500', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_connections', -1], + text: _('Unlimited'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + ], + }), + }, + { + text: _('Upload Slot Limit'), + iconCls: 'icon-upload-slots', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: ['max_upload_slots', 0], + text: '0', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_slots', 1], + text: '1', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_slots', 2], + text: '2', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_slots', 3], + text: '3', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_slots', 5], + text: '5', + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['max_upload_slots', -1], + text: _('Unlimited'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + ], + }), + }, + { + id: 'auto_managed', + text: _('Auto Managed'), + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: ['auto_managed', true], + text: _('On'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + { + torrentAction: ['auto_managed', false], + text: _('Off'), + handler: deluge.menus.onTorrentActionSetOpt, + scope: deluge.menus, + }, + ], + }), + }, + ], + }), + }, + '-', + { + text: _('Queue'), + iconCls: 'icon-queue', + hideOnClick: false, + menu: new Ext.menu.Menu({ + items: [ + { + torrentAction: 'queue_top', + text: _('Top'), + iconCls: 'icon-top', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'queue_up', + text: _('Up'), + iconCls: 'icon-up', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'queue_down', + text: _('Down'), + iconCls: 'icon-down', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'queue_bottom', + text: _('Bottom'), + iconCls: 'icon-bottom', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + ], + }), + }, + '-', + { + torrentAction: 'copy_magnet', + text: _('Copy Magnet URI'), + iconCls: 'icon-magnet-copy', + handler: deluge.menus.onTorrentActionShow, + scope: deluge.menus, + }, + { + torrentAction: 'force_reannounce', + text: _('Update Tracker'), + iconCls: 'icon-update-tracker', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'edit_trackers', + text: _('Edit Trackers'), + iconCls: 'icon-edit-trackers', + handler: deluge.menus.onTorrentActionShow, + scope: deluge.menus, + }, + '-', + { + torrentAction: 'remove', + text: _('Remove Torrent'), + iconCls: 'icon-remove', + handler: deluge.menus.onTorrentActionShow, + scope: deluge.menus, + }, + '-', + { + torrentAction: 'force_recheck', + text: _('Force Recheck'), + iconCls: 'icon-recheck', + handler: deluge.menus.onTorrentActionMethod, + scope: deluge.menus, + }, + { + torrentAction: 'move', + text: _('Move Download Folder'), + iconCls: 'icon-move', + handler: deluge.menus.onTorrentActionShow, + scope: deluge.menus, + }, + ], +}); + +deluge.menus.filePriorities = new Ext.menu.Menu({ + id: 'filePrioritiesMenu', + items: [ + { + id: 'expandAll', + text: _('Expand All'), + iconCls: 'icon-expand-all', + }, + '-', + { + id: 'skip', + text: _('Skip'), + iconCls: 'icon-do-not-download', + filePriority: FILE_PRIORITY['Skip'], + }, + { + id: 'low', + text: _('Low'), + iconCls: 'icon-low', + filePriority: FILE_PRIORITY['Low'], + }, + { + id: 'normal', + text: _('Normal'), + iconCls: 'icon-normal', + filePriority: FILE_PRIORITY['Normal'], + }, + { + id: 'high', + text: _('High'), + iconCls: 'icon-high', + filePriority: FILE_PRIORITY['High'], + }, + ], +}); diff --git a/deluge/ui/web/js/deluge-all/MoveStorage.js b/deluge/ui/web/js/deluge-all/MoveStorage.js new file mode 100644 index 0000000..9ba638a --- /dev/null +++ b/deluge/ui/web/js/deluge-all/MoveStorage.js @@ -0,0 +1,85 @@ +/** + * Deluge.MoveStorage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.namespace('Deluge'); +Deluge.MoveStorage = Ext.extend(Ext.Window, { + constructor: function (config) { + config = Ext.apply( + { + title: _('Move Download Folder'), + width: 375, + height: 110, + layout: 'fit', + buttonAlign: 'right', + closeAction: 'hide', + closable: true, + iconCls: 'x-deluge-move-storage', + plain: true, + constrainHeader: true, + resizable: false, + }, + config + ); + Deluge.MoveStorage.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.MoveStorage.superclass.initComponent.call(this); + + this.addButton(_('Cancel'), this.onCancel, this); + this.addButton(_('Move'), this.onMove, this); + + this.form = this.add({ + xtype: 'form', + border: false, + defaultType: 'textfield', + width: 300, + bodyStyle: 'padding: 5px', + }); + + this.moveLocation = this.form.add({ + fieldLabel: _('Download Folder'), + name: 'location', + width: 240, + }); + //this.form.add({ + // xtype: 'button', + // text: _('Browse'), + // handler: function() { + // if (!this.fileBrowser) { + // this.fileBrowser = new Deluge.FileBrowser(); + // } + // this.fileBrowser.show(); + // }, + // scope: this + //}); + }, + + hide: function () { + Deluge.MoveStorage.superclass.hide.call(this); + this.torrentIds = null; + }, + + show: function (torrentIds) { + Deluge.MoveStorage.superclass.show.call(this); + this.torrentIds = torrentIds; + }, + + onCancel: function () { + this.hide(); + }, + + onMove: function () { + var dest = this.moveLocation.getValue(); + deluge.client.core.move_storage(this.torrentIds, dest); + this.hide(); + }, +}); +deluge.moveStorage = new Deluge.MoveStorage(); diff --git a/deluge/ui/web/js/deluge-all/MultiOptionsManager.js b/deluge/ui/web/js/deluge-all/MultiOptionsManager.js new file mode 100644 index 0000000..82f9838 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/MultiOptionsManager.js @@ -0,0 +1,218 @@ +/** + * Deluge.MultiOptionsManager.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * @description A class that can be used to manage options throughout the ui. + * @namespace Deluge + * @class Deluge.MultiOptionsManager + * @extends Deluge.OptionsManager + */ +Deluge.MultiOptionsManager = Ext.extend(Deluge.OptionsManager, { + constructor: function (config) { + this.currentId = null; + this.stored = {}; + Deluge.MultiOptionsManager.superclass.constructor.call(this, config); + }, + + /** + * Changes bound fields to use the specified id. + * @param {String} id + */ + changeId: function (id, dontUpdateBinds) { + var oldId = this.currentId; + this.currentId = id; + if (!dontUpdateBinds) { + for (var option in this.options) { + if (!this.binds[option]) continue; + Ext.each( + this.binds[option], + function (bind) { + bind.setValue(this.get(option)); + }, + this + ); + } + } + return oldId; + }, + + /** + * Changes all the changed values to be the default values + * @param {String} id + */ + commit: function () { + this.stored[this.currentId] = Ext.apply( + this.stored[this.currentId], + this.changed[this.currentId] + ); + this.reset(); + }, + + /** + * Get the value for an option + * @param {String/Array} option A single option or an array of options to return. + * @returns {Object} the options value. + */ + get: function () { + if (arguments.length == 1) { + var option = arguments[0]; + return this.isDirty(option) + ? this.changed[this.currentId][option] + : this.getDefault(option); + } else if (arguments.length == 0) { + var options = {}; + for (var option in this.options) { + options[option] = this.isDirty(option) + ? this.changed[this.currentId][option] + : this.getDefault(option); + } + return options; + } else { + var options = {}; + Ext.each( + arguments, + function (option) { + options[option] = this.isDirty(option) + ? this.changed[this.currentId][option] + : this.getDefault(option); + }, + this + ); + return options; + } + }, + + /** + * Get the default value for an option. + * @param {String} option A single option. + * @returns {Object} the value of the option + */ + getDefault: function (option) { + return this.has(option) + ? this.stored[this.currentId][option] + : this.options[option]; + }, + + /** + * Returns the dirty (changed) values. + * @returns {Object} the changed options + */ + getDirty: function () { + return this.changed[this.currentId] ? this.changed[this.currentId] : {}; + }, + + /** + * Check to see if the option has been changed. + * @param {String} option + * @returns {Boolean} true if the option has been changed, else false. + */ + isDirty: function (option) { + return ( + this.changed[this.currentId] && + !Ext.isEmpty(this.changed[this.currentId][option]) + ); + }, + + /** + * Check to see if an id has had an option set to something other than the + * default value. + * @param {String} option + * @returns {Boolean} true if the id has an option, else false. + */ + has: function (option) { + return ( + this.stored[this.currentId] && + !Ext.isEmpty(this.stored[this.currentId][option]) + ); + }, + + /** + * Reset the options back to the default values for the specified id. + */ + reset: function () { + if (this.changed[this.currentId]) delete this.changed[this.currentId]; + if (this.stored[this.currentId]) delete this.stored[this.currentId]; + }, + + /** + * Reset the options back to their defaults for all ids. + */ + resetAll: function () { + this.changed = {}; + this.stored = {}; + this.changeId(null); + }, + + /** + * Sets the value of specified option for the passed in id. + * @param {String} id + * @param {String} option + * @param {Object} value The value for the option + */ + setDefault: function (option, value) { + if (option === undefined) { + return; + } else if (value === undefined) { + for (var key in option) { + this.setDefault(key, option[key]); + } + } else { + var oldValue = this.getDefault(option); + value = this.convertValueType(oldValue, value); + + // If the value is the same as the old value there is + // no point in setting it again. + if (oldValue == value) return; + + // Store the new default + if (!this.stored[this.currentId]) this.stored[this.currentId] = {}; + this.stored[this.currentId][option] = value; + + if (!this.isDirty(option)) { + this.fireEvent('changed', option, value, oldValue); + } + } + }, + + /** + * Update the value for the specified option and id. + * @param {String} id + * @param {String/Object} option or options to update + * @param {Object} [value]; + */ + update: function (option, value) { + if (option === undefined) { + return; + } else if (value === undefined) { + for (var key in option) { + this.update(key, option[key]); + } + } else { + if (!this.changed[this.currentId]) + this.changed[this.currentId] = {}; + + var defaultValue = this.getDefault(option); + value = this.convertValueType(defaultValue, value); + + var oldValue = this.get(option); + if (oldValue == value) return; + + if (defaultValue == value) { + if (this.isDirty(option)) + delete this.changed[this.currentId][option]; + this.fireEvent('changed', option, value, oldValue); + return; + } else { + this.changed[this.currentId][option] = value; + this.fireEvent('changed', option, value, oldValue); + } + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/OptionsManager.js b/deluge/ui/web/js/deluge-all/OptionsManager.js new file mode 100644 index 0000000..529f7af --- /dev/null +++ b/deluge/ui/web/js/deluge-all/OptionsManager.js @@ -0,0 +1,279 @@ +/** + * Deluge.OptionsManager.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge'); + +/** + * @class Deluge.OptionsManager + * @extends Ext.util.Observable + * A class that can be used to manage options throughout the ui. + * @constructor + * Creates a new OptionsManager + * @param {Object} config Configuration options + */ +Deluge.OptionsManager = Ext.extend(Ext.util.Observable, { + constructor: function (config) { + config = config || {}; + this.binds = {}; + this.changed = {}; + this.options = (config && config['options']) || {}; + this.focused = null; + + this.addEvents({ + /** + * @event add + * Fires when an option is added + */ + add: true, + + /** + * @event changed + * Fires when an option is changed + * @param {String} option The changed option + * @param {Mixed} value The options new value + * @param {Mixed} oldValue The options old value + */ + changed: true, + + /** + * @event reset + * Fires when the options are reset + */ + reset: true, + }); + this.on('changed', this.onChange, this); + + Deluge.OptionsManager.superclass.constructor.call(this); + }, + + /** + * Add a set of default options and values to the options manager + * @param {Object} options The default options. + */ + addOptions: function (options) { + this.options = Ext.applyIf(this.options, options); + }, + + /** + * Binds a form field to the specified option. + * @param {String} option + * @param {Ext.form.Field} field + */ + bind: function (option, field) { + this.binds[option] = this.binds[option] || []; + this.binds[option].push(field); + field._doption = option; + + field.on('focus', this.onFieldFocus, this); + field.on('blur', this.onFieldBlur, this); + field.on('change', this.onFieldChange, this); + field.on('check', this.onFieldChange, this); + field.on('spin', this.onFieldChange, this); + return field; + }, + + /** + * Changes all the changed values to be the default values + */ + commit: function () { + this.options = Ext.apply(this.options, this.changed); + this.reset(); + }, + + /** + * Converts the value so it matches the originals type + * @param {Mixed} oldValue The original value + * @param {Mixed} value The new value to convert + */ + convertValueType: function (oldValue, value) { + if (Ext.type(oldValue) != Ext.type(value)) { + switch (Ext.type(oldValue)) { + case 'string': + value = String(value); + break; + case 'number': + value = Number(value); + break; + case 'boolean': + if (Ext.type(value) == 'string') { + value = value.toLowerCase(); + value = + value == 'true' || value == '1' || value == 'on' + ? true + : false; + } else { + value = Boolean(value); + } + break; + } + } + return value; + }, + + /** + * Get the value for an option or options. + * @param {String} [option] A single option or an array of options to return. + * @returns {Object} the options value. + */ + get: function () { + if (arguments.length == 1) { + var option = arguments[0]; + return this.isDirty(option) + ? this.changed[option] + : this.options[option]; + } else { + var options = {}; + Ext.each( + arguments, + function (option) { + if (!this.has(option)) return; + options[option] = this.isDirty(option) + ? this.changed[option] + : this.options[option]; + }, + this + ); + return options; + } + }, + + /** + * Get the default value for an option or options. + * @param {String|Array} [option] A single option or an array of options to return. + * @returns {Object} the value of the option + */ + getDefault: function (option) { + return this.options[option]; + }, + + /** + * Returns the dirty (changed) values. + * @returns {Object} the changed options + */ + getDirty: function () { + return this.changed; + }, + + /** + * @param {String} [option] The option to check + * @returns {Boolean} true if the option has been changed from the default. + */ + isDirty: function (option) { + return !Ext.isEmpty(this.changed[option]); + }, + + /** + * Check to see if an option exists in the options manager + * @param {String} option + * @returns {Boolean} true if the option exists, else false. + */ + has: function (option) { + return this.options[option]; + }, + + /** + * Reset the options back to the default values. + */ + reset: function () { + this.changed = {}; + }, + + /** + * Sets the value of specified option(s) for the passed in id. + * @param {String} option + * @param {Object} value The value for the option + */ + set: function (option, value) { + if (option === undefined) { + return; + } else if (typeof option == 'object') { + var options = option; + this.options = Ext.apply(this.options, options); + for (var option in options) { + this.onChange(option, options[option]); + } + } else { + this.options[option] = value; + this.onChange(option, value); + } + }, + + /** + * Update the value for the specified option and id. + * @param {String/Object} option or options to update + * @param {Object} [value]; + */ + update: function (option, value) { + if (option === undefined) { + return; + } else if (value === undefined) { + for (var key in option) { + this.update(key, option[key]); + } + } else { + var defaultValue = this.getDefault(option); + value = this.convertValueType(defaultValue, value); + + var oldValue = this.get(option); + if (oldValue == value) return; + + if (defaultValue == value) { + if (this.isDirty(option)) delete this.changed[option]; + this.fireEvent('changed', option, value, oldValue); + return; + } + + this.changed[option] = value; + this.fireEvent('changed', option, value, oldValue); + } + }, + + /** + * Lets the option manager know when a field is blurred so if a value + * so value changing operations can continue on that field. + */ + onFieldBlur: function (field, event) { + if (this.focused == field) { + this.focused = null; + } + }, + + /** + * Stops a form fields value from being blocked by the change functions + * @param {Ext.form.Field} field + * @private + */ + onFieldChange: function (field, event) { + if (field.field) field = field.field; // fix for spinners + this.update(field._doption, field.getValue()); + }, + + /** + * Lets the option manager know when a field is focused so if a value changing + * operation is performed it will not change the value of the field. + */ + onFieldFocus: function (field, event) { + this.focused = field; + }, + + onChange: function (option, newValue, oldValue) { + // If we don't have a bind there's nothing to do. + if (Ext.isEmpty(this.binds[option])) return; + Ext.each( + this.binds[option], + function (bind) { + // The field is currently focused so we do not want to change it. + if (bind == this.focused) return; + // Set the form field to the new value. + bind.setValue(newValue); + }, + this + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/OtherLimitWindow.js b/deluge/ui/web/js/deluge-all/OtherLimitWindow.js new file mode 100644 index 0000000..0d53d4a --- /dev/null +++ b/deluge/ui/web/js/deluge-all/OtherLimitWindow.js @@ -0,0 +1,79 @@ +/** + * Deluge.OtherLimitWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.OtherLimitWindow + * @extends Ext.Window + */ +Deluge.OtherLimitWindow = Ext.extend(Ext.Window, { + layout: 'fit', + width: 210, + height: 100, + constrainHeader: true, + closeAction: 'hide', + + initComponent: function () { + Deluge.OtherLimitWindow.superclass.initComponent.call(this); + this.form = this.add({ + xtype: 'form', + baseCls: 'x-plain', + bodyStyle: 'padding: 5px', + layout: 'hbox', + layoutConfig: { + pack: 'start', + }, + items: [ + { + xtype: 'spinnerfield', + name: 'limit', + }, + ], + }); + if (this.initialConfig.unit) { + this.form.add({ + border: false, + baseCls: 'x-plain', + bodyStyle: 'padding: 5px', + html: this.initialConfig.unit, + }); + } else { + this.setSize(180, 100); + } + + this.addButton(_('Cancel'), this.onCancelClick, this); + this.addButton(_('OK'), this.onOkClick, this); + this.afterMethod('show', this.doFocusField, this); + }, + + setValue: function (value) { + this.form.getForm().setValues({ limit: value }); + }, + + onCancelClick: function () { + this.form.getForm().reset(); + this.hide(); + }, + + onOkClick: function () { + var config = {}; + config[this.group] = this.form.getForm().getValues().limit; + deluge.client.core.set_config(config, { + success: function () { + deluge.ui.update(); + }, + }); + this.hide(); + }, + + doFocusField: function () { + this.form.getForm().findField('limit').focus(true, 10); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/Plugin.js b/deluge/ui/web/js/deluge-all/Plugin.js new file mode 100644 index 0000000..26971f7 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Plugin.js @@ -0,0 +1,106 @@ +/** + * Deluge.Plugin.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * @class Deluge.Plugin + * @extends Ext.util.Observable + */ +Deluge.Plugin = Ext.extend(Ext.util.Observable, { + /** + * The plugins name + * @property name + * @type {String} + */ + name: null, + + constructor: function (config) { + this.isDelugePlugin = true; + this.addEvents({ + /** + * @event enabled + * @param {Plugin} plugin the plugin instance + */ + enabled: true, + + /** + * @event disabled + * @param {Plugin} plugin the plugin instance + */ + disabled: true, + }); + Deluge.Plugin.superclass.constructor.call(this, config); + }, + + /** + * Disables the plugin, firing the "{@link #disabled}" event and + * then executing the plugins clean up method onDisabled. + */ + disable: function () { + this.fireEvent('disabled', this); + if (this.onDisable) this.onDisable(); + }, + + /** + * Enables the plugin, firing the "{@link #enabled}" event and + * then executes the plugins setup method, onEnabled. + */ + enable: function () { + deluge.client.reloadMethods(); + this.fireEvent('enable', this); + if (this.onEnable) this.onEnable(); + }, + + registerTorrentStatus: function (key, header, options) { + options = options || {}; + var cc = options.colCfg || {}, + sc = options.storeCfg || {}; + sc = Ext.apply(sc, { name: key }); + deluge.torrents.meta.fields.push(sc); + deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta); + + cc = Ext.apply(cc, { + header: header, + dataIndex: key, + }); + var cols = deluge.torrents.columns.slice(0); + cols.push(cc); + deluge.torrents.colModel.setConfig(cols); + deluge.torrents.columns = cols; + + Deluge.Keys.Grid.push(key); + deluge.torrents.getView().refresh(true); + }, + + deregisterTorrentStatus: function (key) { + var fields = []; + Ext.each(deluge.torrents.meta.fields, function (field) { + if (field.name != key) fields.push(field); + }); + deluge.torrents.meta.fields = fields; + deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta); + + var cols = []; + Ext.each(deluge.torrents.columns, function (col) { + if (col.dataIndex != key) cols.push(col); + }); + deluge.torrents.colModel.setConfig(cols); + deluge.torrents.columns = cols; + + var keys = []; + Ext.each(Deluge.Keys.Grid, function (k) { + if (k == key) keys.push(k); + }); + Deluge.Keys.Grid = keys; + deluge.torrents.getView().refresh(true); + }, +}); + +Ext.ns('Deluge.plugins'); diff --git a/deluge/ui/web/js/deluge-all/RemoveWindow.js b/deluge/ui/web/js/deluge-all/RemoveWindow.js new file mode 100644 index 0000000..ccac2ef --- /dev/null +++ b/deluge/ui/web/js/deluge-all/RemoveWindow.js @@ -0,0 +1,77 @@ +/** + * Deluge.RemoveWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * @class Deluge.RemoveWindow + * @extends Ext.Window + */ +Deluge.RemoveWindow = Ext.extend(Ext.Window, { + title: _('Remove Torrent'), + layout: 'fit', + width: 350, + height: 100, + constrainHeader: true, + buttonAlign: 'right', + closeAction: 'hide', + closable: true, + iconCls: 'x-deluge-remove-window-icon', + plain: true, + + bodyStyle: 'padding: 5px; padding-left: 10px;', + html: 'Are you sure you wish to remove the torrent (s)?', + + initComponent: function () { + Deluge.RemoveWindow.superclass.initComponent.call(this); + this.addButton(_('Cancel'), this.onCancel, this); + this.addButton(_('Remove With Data'), this.onRemoveData, this); + this.addButton(_('Remove Torrent'), this.onRemove, this); + }, + + remove: function (removeData) { + deluge.client.core.remove_torrents(this.torrentIds, removeData, { + success: function (result) { + if (result == true) { + console.log( + 'Error(s) occured when trying to delete torrent(s).' + ); + } + this.onRemoved(this.torrentIds); + }, + scope: this, + torrentIds: this.torrentIds, + }); + }, + + show: function (ids) { + Deluge.RemoveWindow.superclass.show.call(this); + this.torrentIds = ids; + }, + + onCancel: function () { + this.hide(); + this.torrentIds = null; + }, + + onRemove: function () { + this.remove(false); + }, + + onRemoveData: function () { + this.remove(true); + }, + + onRemoved: function (torrentIds) { + deluge.events.fire('torrentsRemoved', torrentIds); + this.hide(); + deluge.ui.update(); + }, +}); + +deluge.removeWindow = new Deluge.RemoveWindow(); diff --git a/deluge/ui/web/js/deluge-all/Sidebar.js b/deluge/ui/web/js/deluge-all/Sidebar.js new file mode 100644 index 0000000..a6512b2 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Sidebar.js @@ -0,0 +1,146 @@ +/** + * Deluge.Sidebar.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +// These are just so gen_gettext.py will pick up the strings +// _('State') +// _('Tracker Host') + +/** + * @class Deluge.Sidebar + * @author Damien Churchill + * @version 1.3 + */ +Deluge.Sidebar = Ext.extend(Ext.Panel, { + // private + panels: {}, + + // private + selected: null, + + constructor: function (config) { + config = Ext.apply( + { + id: 'sidebar', + region: 'west', + cls: 'deluge-sidebar', + title: _('Filters'), + layout: 'accordion', + split: true, + width: 200, + minSize: 100, + collapsible: true, + }, + config + ); + Deluge.Sidebar.superclass.constructor.call(this, config); + }, + + // private + initComponent: function () { + Deluge.Sidebar.superclass.initComponent.call(this); + deluge.events.on('disconnect', this.onDisconnect, this); + }, + + createFilter: function (filter, states) { + var panel = new Deluge.FilterPanel({ + filter: filter, + }); + panel.on('selectionchange', function (view, nodes) { + deluge.ui.update(); + }); + this.add(panel); + + this.doLayout(); + this.panels[filter] = panel; + + if (panel.header) { + panel.header.on('click', function (header) { + if (!deluge.config.sidebar_multiple_filters) { + deluge.ui.update(); + } + if (!panel.list.getSelectionCount()) { + panel.list.select(0); + } + }); + } + this.fireEvent('filtercreate', this, panel); + + panel.updateStates(states); + this.fireEvent('afterfiltercreate', this, panel); + }, + + getFilter: function (filter) { + return this.panels[filter]; + }, + + getFilterStates: function () { + var states = {}; + + if (deluge.config.sidebar_multiple_filters) { + // Grab the filters from each of the filter panels + this.items.each(function (panel) { + var state = panel.getState(); + if (state == null) return; + states[panel.filterType] = state; + }, this); + } else { + var panel = this.getLayout().activeItem; + if (panel) { + var state = panel.getState(); + if (!state == null) return; + states[panel.filterType] = state; + } + } + + return states; + }, + + hasFilter: function (filter) { + return this.panels[filter] ? true : false; + }, + + // private + onDisconnect: function () { + for (var filter in this.panels) { + this.remove(this.panels[filter]); + } + this.panels = {}; + this.selected = null; + }, + + onFilterSelect: function (selModel, rowIndex, record) { + deluge.ui.update(); + }, + + update: function (filters) { + for (var filter in filters) { + var states = filters[filter]; + if (Ext.getKeys(this.panels).indexOf(filter) > -1) { + this.panels[filter].updateStates(states); + } else { + this.createFilter(filter, states); + } + } + + // Perform a cleanup of fitlers that are not enabled any more. + Ext.each( + Ext.keys(this.panels), + function (filter) { + if (Ext.keys(filters).indexOf(filter) == -1) { + // We need to remove the panel + this.remove(this.panels[filter]); + this.doLayout(); + delete this.panels[filter]; + } + }, + this + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/Statusbar.js b/deluge/ui/web/js/deluge-all/Statusbar.js new file mode 100644 index 0000000..00ad6b2 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Statusbar.js @@ -0,0 +1,362 @@ +/** + * Deluge.Statusbar.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge'); + +Deluge.Statusbar = Ext.extend(Ext.ux.StatusBar, { + constructor: function (config) { + config = Ext.apply( + { + id: 'deluge-statusbar', + defaultIconCls: 'x-deluge-statusbar x-not-connected', + defaultText: _('Not Connected'), + }, + config + ); + Deluge.Statusbar.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.Statusbar.superclass.initComponent.call(this); + + deluge.events.on('connect', this.onConnect, this); + deluge.events.on('disconnect', this.onDisconnect, this); + }, + + createButtons: function () { + this.buttons = this.add( + { + id: 'statusbar-connections', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-connections', + tooltip: _('Connections'), + menu: new Deluge.StatusbarMenu({ + items: [ + { + text: '50', + value: '50', + group: 'max_connections_global', + checked: false, + }, + { + text: '100', + value: '100', + group: 'max_connections_global', + checked: false, + }, + { + text: '200', + value: '200', + group: 'max_connections_global', + checked: false, + }, + { + text: '300', + value: '300', + group: 'max_connections_global', + checked: false, + }, + { + text: '500', + value: '500', + group: 'max_connections_global', + checked: false, + }, + { + text: _('Unlimited'), + value: '-1', + group: 'max_connections_global', + checked: false, + }, + '-', + { + text: _('Other'), + value: 'other', + group: 'max_connections_global', + checked: false, + }, + ], + otherWin: { + title: _('Set Maximum Connections'), + }, + }), + }, + '-', + { + id: 'statusbar-downspeed', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-downloading', + tooltip: _('Download Speed'), + menu: new Deluge.StatusbarMenu({ + items: [ + { + value: '5', + text: _('5 KiB/s'), + group: 'max_download_speed', + checked: false, + }, + { + value: '10', + text: _('10 KiB/s'), + group: 'max_download_speed', + checked: false, + }, + { + value: '30', + text: _('30 KiB/s'), + group: 'max_download_speed', + checked: false, + }, + { + value: '80', + text: _('80 KiB/s'), + group: 'max_download_speed', + checked: false, + }, + { + value: '300', + text: _('300 KiB/s'), + group: 'max_download_speed', + checked: false, + }, + { + value: '-1', + text: _('Unlimited'), + group: 'max_download_speed', + checked: false, + }, + '-', + { + value: 'other', + text: _('Other'), + group: 'max_download_speed', + checked: false, + }, + ], + otherWin: { + title: _('Set Maximum Download Speed'), + unit: _('KiB/s'), + }, + }), + }, + '-', + { + id: 'statusbar-upspeed', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-seeding', + tooltip: _('Upload Speed'), + menu: new Deluge.StatusbarMenu({ + items: [ + { + value: '5', + text: _('5 KiB/s'), + group: 'max_upload_speed', + checked: false, + }, + { + value: '10', + text: _('10 KiB/s'), + group: 'max_upload_speed', + checked: false, + }, + { + value: '30', + text: _('30 KiB/s'), + group: 'max_upload_speed', + checked: false, + }, + { + value: '80', + text: _('80 KiB/s'), + group: 'max_upload_speed', + checked: false, + }, + { + value: '300', + text: _('300 KiB/s'), + group: 'max_upload_speed', + checked: false, + }, + { + value: '-1', + text: _('Unlimited'), + group: 'max_upload_speed', + checked: false, + }, + '-', + { + value: 'other', + text: _('Other'), + group: 'max_upload_speed', + checked: false, + }, + ], + otherWin: { + title: _('Set Maximum Upload Speed'), + unit: _('KiB/s'), + }, + }), + }, + '-', + { + id: 'statusbar-traffic', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-traffic', + tooltip: _('Protocol Traffic Download/Upload'), + handler: function () { + deluge.preferences.show(); + deluge.preferences.selectPage('Network'); + }, + }, + '-', + { + id: 'statusbar-externalip', + text: ' ', + cls: 'x-btn-text', + tooltip: _('External IP Address'), + }, + '-', + { + id: 'statusbar-dht', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-dht', + tooltip: _('DHT Nodes'), + }, + '-', + { + id: 'statusbar-freespace', + text: ' ', + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-freespace', + tooltip: _('Freespace in download folder'), + handler: function () { + deluge.preferences.show(); + deluge.preferences.selectPage('Downloads'); + }, + } + ); + this.created = true; + }, + + onConnect: function () { + this.setStatus({ + iconCls: 'x-connected', + text: '', + }); + if (!this.created) { + this.createButtons(); + } else { + Ext.each(this.buttons, function (item) { + item.show(); + item.enable(); + }); + } + this.doLayout(); + }, + + onDisconnect: function () { + this.clearStatus({ useDefaults: true }); + Ext.each(this.buttons, function (item) { + item.hide(); + item.disable(); + }); + this.doLayout(); + }, + + update: function (stats) { + if (!stats) return; + + function addSpeed(val) { + return val + ' KiB/s'; + } + + var updateStat = function (name, config) { + var item = this.items.get('statusbar-' + name); + if (config.limit.value > 0) { + var value = config.value.formatter + ? config.value.formatter(config.value.value, true) + : config.value.value; + var limit = config.limit.formatter + ? config.limit.formatter(config.limit.value, true) + : config.limit.value; + var str = String.format(config.format, value, limit); + } else { + var str = config.value.formatter + ? config.value.formatter(config.value.value, true) + : config.value.value; + } + item.setText(str); + + if (!item.menu) return; + item.menu.setValue(config.limit.value); + }.createDelegate(this); + + updateStat('connections', { + value: { value: stats.num_connections }, + limit: { value: stats.max_num_connections }, + format: '{0} ({1})', + }); + + updateStat('downspeed', { + value: { + value: stats.download_rate, + formatter: Deluge.Formatters.speed, + }, + limit: { + value: stats.max_download, + formatter: addSpeed, + }, + format: '{0} ({1})', + }); + + updateStat('upspeed', { + value: { + value: stats.upload_rate, + formatter: Deluge.Formatters.speed, + }, + limit: { + value: stats.max_upload, + formatter: addSpeed, + }, + format: '{0} ({1})', + }); + + updateStat('traffic', { + value: { + value: stats.download_protocol_rate, + formatter: Deluge.Formatters.speed, + }, + limit: { + value: stats.upload_protocol_rate, + formatter: Deluge.Formatters.speed, + }, + format: '{0}/{1}', + }); + + this.items.get('statusbar-dht').setText(stats.dht_nodes); + this.items + .get('statusbar-freespace') + .setText( + stats.free_space >= 0 ? fsize(stats.free_space) : _('Error') + ); + this.items + .get('statusbar-externalip') + .setText( + String.format( + _('IP {0}'), + stats.external_ip ? stats.external_ip : _('n/a') + ) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/StatusbarMenu.js b/deluge/ui/web/js/deluge-all/StatusbarMenu.js new file mode 100644 index 0000000..1365c9c --- /dev/null +++ b/deluge/ui/web/js/deluge-all/StatusbarMenu.js @@ -0,0 +1,79 @@ +/** + * Deluge.StatusbarMenu.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge'); + +/** + * Menu that handles setting the statusbar limits correctly. + * @class Deluge.StatusbarMenu + * @extends Ext.menu.Menu + */ +Deluge.StatusbarMenu = Ext.extend(Ext.menu.Menu, { + initComponent: function () { + Deluge.StatusbarMenu.superclass.initComponent.call(this); + this.otherWin = new Deluge.OtherLimitWindow( + this.initialConfig.otherWin || {} + ); + + this.items.each(function (item) { + if (item.getXType() != 'menucheckitem') return; + if (item.value == 'other') { + item.on('click', this.onOtherClicked, this); + } else { + item.on('checkchange', this.onLimitChanged, this); + } + }, this); + }, + + setValue: function (value) { + var beenSet = false; + // set the new value + this.value = value = value == 0 ? -1 : value; + + var other = null; + // uncheck all items + this.items.each(function (item) { + if (item.setChecked) { + item.suspendEvents(); + if (item.value == value) { + item.setChecked(true); + beenSet = true; + } else { + item.setChecked(false); + } + item.resumeEvents(); + } + + if (item.value == 'other') other = item; + }); + + if (beenSet) return; + + other.suspendEvents(); + other.setChecked(true); + other.resumeEvents(); + }, + + onLimitChanged: function (item, checked) { + if (!checked || item.value == 'other') return; // We do not care about unchecked or other. + var config = {}; + config[item.group] = item.value; + deluge.client.core.set_config(config, { + success: function () { + deluge.ui.update(); + }, + }); + }, + + onOtherClicked: function (item, e) { + this.otherWin.group = item.group; + this.otherWin.setValue(this.value); + this.otherWin.show(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/Toolbar.js b/deluge/ui/web/js/deluge-all/Toolbar.js new file mode 100644 index 0000000..1ecdd75 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/Toolbar.js @@ -0,0 +1,206 @@ +/** + * Deluge.Toolbar.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * An extension of the Ext.Toolbar class that provides an extensible toolbar for Deluge. + * @class Deluge.Toolbar + * @extends Ext.Toolbar + */ +Deluge.Toolbar = Ext.extend(Ext.Toolbar, { + constructor: function (config) { + config = Ext.apply( + { + items: [ + { + id: 'tbar-deluge-text', + text: _('Deluge'), + iconCls: 'x-deluge-main-panel', + handler: this.onAboutClick, + }, + new Ext.Toolbar.Separator(), + { + id: 'create', + disabled: true, + hidden: true, + text: _('Create'), + iconCls: 'icon-create', + handler: this.onTorrentAction, + }, + { + id: 'add', + disabled: true, + text: _('Add'), + iconCls: 'icon-add', + handler: this.onTorrentAdd, + }, + { + id: 'remove', + disabled: true, + text: _('Remove'), + iconCls: 'icon-remove', + handler: this.onTorrentAction, + }, + new Ext.Toolbar.Separator(), + { + id: 'pause', + disabled: true, + text: _('Pause'), + iconCls: 'icon-pause', + handler: this.onTorrentAction, + }, + { + id: 'resume', + disabled: true, + text: _('Resume'), + iconCls: 'icon-resume', + handler: this.onTorrentAction, + }, + new Ext.Toolbar.Separator(), + { + id: 'up', + cls: 'x-btn-text-icon', + disabled: true, + text: _('Up'), + iconCls: 'icon-up', + handler: this.onTorrentAction, + }, + { + id: 'down', + disabled: true, + text: _('Down'), + iconCls: 'icon-down', + handler: this.onTorrentAction, + }, + new Ext.Toolbar.Separator(), + { + id: 'preferences', + text: _('Preferences'), + iconCls: 'x-deluge-preferences', + handler: this.onPreferencesClick, + scope: this, + }, + { + id: 'connectionman', + text: _('Connection Manager'), + iconCls: 'x-deluge-connection-manager', + handler: this.onConnectionManagerClick, + scope: this, + }, + '->', + { + id: 'help', + iconCls: 'icon-help', + text: _('Help'), + handler: this.onHelpClick, + scope: this, + }, + { + id: 'logout', + iconCls: 'icon-logout', + disabled: true, + text: _('Logout'), + handler: this.onLogout, + scope: this, + }, + ], + }, + config + ); + Deluge.Toolbar.superclass.constructor.call(this, config); + }, + + connectedButtons: ['add', 'remove', 'pause', 'resume', 'up', 'down'], + + initComponent: function () { + Deluge.Toolbar.superclass.initComponent.call(this); + deluge.events.on('connect', this.onConnect, this); + deluge.events.on('login', this.onLogin, this); + }, + + onConnect: function () { + Ext.each( + this.connectedButtons, + function (buttonId) { + this.items.get(buttonId).enable(); + }, + this + ); + }, + + onDisconnect: function () { + Ext.each( + this.connectedButtons, + function (buttonId) { + this.items.get(buttonId).disable(); + }, + this + ); + }, + + onLogin: function () { + this.items.get('logout').enable(); + }, + + onLogout: function () { + this.items.get('logout').disable(); + deluge.login.logout(); + }, + + onConnectionManagerClick: function () { + deluge.connectionManager.show(); + }, + + onHelpClick: function () { + window.open('http://dev.deluge-torrent.org/wiki/UserGuide'); + }, + + onAboutClick: function () { + var about = new Deluge.about.AboutWindow(); + about.show(); + }, + + onPreferencesClick: function () { + deluge.preferences.show(); + }, + + onTorrentAction: function (item) { + var selection = deluge.torrents.getSelections(); + var ids = []; + Ext.each(selection, function (record) { + ids.push(record.id); + }); + + switch (item.id) { + case 'remove': + deluge.removeWindow.show(ids); + break; + case 'pause': + case 'resume': + deluge.client.core[item.id + '_torrent'](ids, { + success: function () { + deluge.ui.update(); + }, + }); + break; + case 'up': + case 'down': + deluge.client.core['queue_' + item.id](ids, { + success: function () { + deluge.ui.update(); + }, + }); + break; + } + }, + + onTorrentAdd: function () { + deluge.add.show(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/TorrentGrid.js b/deluge/ui/web/js/deluge-all/TorrentGrid.js new file mode 100644 index 0000000..5db7e9f --- /dev/null +++ b/deluge/ui/web/js/deluge-all/TorrentGrid.js @@ -0,0 +1,516 @@ +/** + * Deluge.TorrentGrid.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +(function () { + /* Renderers for the Torrent Grid */ + function queueRenderer(value) { + return value == -1 ? '' : value + 1; + } + function torrentNameRenderer(value, p, r) { + return String.format( + '
{1}
', + r.data['state'].toLowerCase(), + Ext.util.Format.htmlEncode(value) + ); + } + function torrentSpeedRenderer(value) { + if (!value) return; + return fspeed(value); + } + function torrentLimitRenderer(value) { + if (value == -1) return ''; + return fspeed(value * 1024.0); + } + function torrentProgressRenderer(value, p, r) { + value = new Number(value); + var progress = value; + var text = _(r.data['state']) + ' ' + value.toFixed(2) + '%'; + if (this.style) { + var style = this.style; + } else { + var style = p.style; + } + var width = new Number(style.match(/\w+:\s*(\d+)\w+/)[1]); + return Deluge.progressBar(value, width - 8, text); + } + function seedsRenderer(value, p, r) { + if (r.data['total_seeds'] > -1) { + return String.format('{0} ({1})', value, r.data['total_seeds']); + } else { + return value; + } + } + function peersRenderer(value, p, r) { + if (r.data['total_peers'] > -1) { + return String.format('{0} ({1})', value, r.data['total_peers']); + } else { + return value; + } + } + function availRenderer(value, p, r) { + return value < 0 ? '∞' : parseFloat(new Number(value).toFixed(3)); + } + function trackerRenderer(value, p, r) { + return String.format( + '
{0}
', + Ext.util.Format.htmlEncode(value) + ); + } + + function etaSorter(eta) { + if (eta === 0) return Number.MAX_VALUE; + if (eta <= -1) return Number.MAX_SAFE_INTEGER; + return eta; + } + + function dateOrNever(date) { + return date > 0.0 ? fdate(date) : _('Never'); + } + + function timeOrInf(time) { + if (time === 0) return ''; + if (time <= -1) return '∞'; + return ftime(time); + } + + /** + * Deluge.TorrentGrid Class + * + * @author Damien Churchill + * @version 1.3 + * + * @class Deluge.TorrentGrid + * @extends Ext.grid.GridPanel + * @constructor + * @param {Object} config Configuration options + */ + Deluge.TorrentGrid = Ext.extend(Ext.grid.GridPanel, { + // object to store contained torrent ids + torrents: {}, + + columns: [ + { + id: 'queue', + header: '#', + width: 30, + sortable: true, + renderer: queueRenderer, + dataIndex: 'queue', + }, + { + id: 'name', + header: _('Name'), + width: 150, + sortable: true, + renderer: torrentNameRenderer, + dataIndex: 'name', + }, + { + header: _('Size'), + width: 75, + sortable: true, + renderer: fsize, + dataIndex: 'total_wanted', + }, + { + header: _('Progress'), + width: 150, + sortable: true, + renderer: torrentProgressRenderer, + dataIndex: 'progress', + }, + { + header: _('Seeds'), + hidden: true, + width: 60, + sortable: true, + renderer: seedsRenderer, + dataIndex: 'num_seeds', + }, + { + header: _('Peers'), + hidden: true, + width: 60, + sortable: true, + renderer: peersRenderer, + dataIndex: 'num_peers', + }, + { + header: _('Down Speed'), + width: 80, + sortable: true, + renderer: torrentSpeedRenderer, + dataIndex: 'download_payload_rate', + }, + { + header: _('Up Speed'), + width: 80, + sortable: true, + renderer: torrentSpeedRenderer, + dataIndex: 'upload_payload_rate', + }, + { + header: _('ETA'), + width: 60, + sortable: true, + renderer: timeOrInf, + dataIndex: 'eta', + }, + { + header: _('Ratio'), + hidden: true, + width: 60, + sortable: true, + renderer: availRenderer, + dataIndex: 'ratio', + }, + { + header: _('Avail'), + hidden: true, + width: 60, + sortable: true, + renderer: availRenderer, + dataIndex: 'distributed_copies', + }, + { + header: _('Added'), + hidden: true, + width: 80, + sortable: true, + renderer: fdate, + dataIndex: 'time_added', + }, + { + header: _('Complete Seen'), + hidden: true, + width: 80, + sortable: true, + renderer: dateOrNever, + dataIndex: 'last_seen_complete', + }, + { + header: _('Completed'), + hidden: true, + width: 80, + sortable: true, + renderer: dateOrNever, + dataIndex: 'completed_time', + }, + { + header: _('Tracker'), + hidden: true, + width: 120, + sortable: true, + renderer: trackerRenderer, + dataIndex: 'tracker_host', + }, + { + header: _('Download Folder'), + hidden: true, + width: 120, + sortable: true, + renderer: fplain, + dataIndex: 'download_location', + }, + { + header: _('Owner'), + width: 80, + sortable: true, + renderer: fplain, + dataIndex: 'owner', + }, + { + header: _('Public'), + hidden: true, + width: 80, + sortable: true, + renderer: fplain, + dataIndex: 'public', + }, + { + header: _('Shared'), + hidden: true, + width: 80, + sortable: true, + renderer: fplain, + dataIndex: 'shared', + }, + { + header: _('Downloaded'), + hidden: true, + width: 75, + sortable: true, + renderer: fsize, + dataIndex: 'total_done', + }, + { + header: _('Uploaded'), + hidden: true, + width: 75, + sortable: true, + renderer: fsize, + dataIndex: 'total_uploaded', + }, + { + header: _('Remaining'), + hidden: true, + width: 75, + sortable: true, + renderer: fsize, + dataIndex: 'total_remaining', + }, + { + header: _('Down Limit'), + hidden: true, + width: 75, + sortable: true, + renderer: torrentLimitRenderer, + dataIndex: 'max_download_speed', + }, + { + header: _('Up Limit'), + hidden: true, + width: 75, + sortable: true, + renderer: torrentLimitRenderer, + dataIndex: 'max_upload_speed', + }, + { + header: _('Seeds:Peers'), + hidden: true, + width: 75, + sortable: true, + renderer: availRenderer, + dataIndex: 'seeds_peers_ratio', + }, + { + header: _('Last Transfer'), + hidden: true, + width: 75, + sortable: true, + renderer: ftime, + dataIndex: 'time_since_transfer', + }, + ], + + meta: { + root: 'torrents', + idProperty: 'id', + fields: [ + { + name: 'queue', + sortType: Deluge.data.SortTypes.asQueuePosition, + }, + { name: 'name', sortType: Deluge.data.SortTypes.asName }, + { name: 'total_wanted', type: 'int' }, + { name: 'state' }, + { name: 'progress', type: 'float' }, + { name: 'num_seeds', type: 'int' }, + { name: 'total_seeds', type: 'int' }, + { name: 'num_peers', type: 'int' }, + { name: 'total_peers', type: 'int' }, + { name: 'download_payload_rate', type: 'int' }, + { name: 'upload_payload_rate', type: 'int' }, + { name: 'eta', type: 'int', sortType: etaSorter }, + { name: 'ratio', type: 'float' }, + { name: 'distributed_copies', type: 'float' }, + { name: 'time_added', type: 'int' }, + { name: 'last_seen_complete', type: 'int' }, + { name: 'completed_time', type: 'int' }, + { name: 'tracker_host' }, + { name: 'download_location' }, + { name: 'total_done', type: 'int' }, + { name: 'total_uploaded', type: 'int' }, + { name: 'total_remaining', type: 'int' }, + { name: 'max_download_speed', type: 'int' }, + { name: 'max_upload_speed', type: 'int' }, + { name: 'seeds_peers_ratio', type: 'float' }, + { name: 'time_since_transfer', type: 'int' }, + ], + }, + + keys: [ + { + key: 'a', + ctrl: true, + stopEvent: true, + handler: function () { + deluge.torrents.getSelectionModel().selectAll(); + }, + }, + { + key: [46], + stopEvent: true, + handler: function () { + ids = deluge.torrents.getSelectedIds(); + deluge.removeWindow.show(ids); + }, + }, + ], + + constructor: function (config) { + config = Ext.apply( + { + id: 'torrentGrid', + store: new Ext.data.JsonStore(this.meta), + columns: this.columns, + keys: this.keys, + region: 'center', + cls: 'deluge-torrents', + stripeRows: true, + autoExpandColumn: 'name', + autoExpandMin: 150, + deferredRender: false, + autoScroll: true, + stateful: true, + view: new Ext.ux.grid.BufferView({ + rowHeight: 26, + scrollDelay: false, + }), + }, + config + ); + Deluge.TorrentGrid.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.TorrentGrid.superclass.initComponent.call(this); + deluge.events.on('torrentsRemoved', this.onTorrentsRemoved, this); + deluge.events.on('disconnect', this.onDisconnect, this); + + this.on('rowcontextmenu', function (grid, rowIndex, e) { + e.stopEvent(); + var selection = grid.getSelectionModel(); + if (!selection.isSelected(rowIndex)) { + selection.selectRow(rowIndex); + } + deluge.menus.torrent.showAt(e.getPoint()); + }); + }, + + /** + * Returns the record representing the torrent at the specified index. + * + * @param index {int} The row index of the torrent you wish to retrieve. + * @return {Ext.data.Record} The record representing the torrent. + */ + getTorrent: function (index) { + return this.getStore().getAt(index); + }, + + /** + * Returns the currently selected record. + * @ return {Array/Ext.data.Record} The record(s) representing the rows + */ + getSelected: function () { + return this.getSelectionModel().getSelected(); + }, + + /** + * Returns the currently selected records. + */ + getSelections: function () { + return this.getSelectionModel().getSelections(); + }, + + /** + * Return the currently selected torrent id. + * @return {String} The currently selected id. + */ + getSelectedId: function () { + return this.getSelectionModel().getSelected().id; + }, + + /** + * Return the currently selected torrent ids. + * @return {Array} The currently selected ids. + */ + getSelectedIds: function () { + var ids = []; + Ext.each(this.getSelectionModel().getSelections(), function (r) { + ids.push(r.id); + }); + return ids; + }, + + update: function (torrents, wipe) { + var store = this.getStore(); + + // Need to perform a complete reload of the torrent grid. + if (wipe) { + store.removeAll(); + this.torrents = {}; + } + + var newTorrents = []; + + // Update and add any new torrents. + for (var t in torrents) { + var torrent = torrents[t]; + + if (this.torrents[t]) { + var record = store.getById(t); + record.beginEdit(); + for (var k in torrent) { + if (record.get(k) != torrent[k]) { + record.set(k, torrent[k]); + } + } + record.endEdit(); + } else { + var record = new Deluge.data.Torrent(torrent); + record.id = t; + this.torrents[t] = 1; + newTorrents.push(record); + } + } + store.add(newTorrents); + + // Remove any torrents that should not be in the store. + store.each(function (record) { + if (!torrents[record.id]) { + store.remove(record); + delete this.torrents[record.id]; + } + }, this); + store.commitChanges(); + + var sortState = store.getSortState(); + if (!sortState) return; + store.sort(sortState.field, sortState.direction); + }, + + // private + onDisconnect: function () { + this.getStore().removeAll(); + this.torrents = {}; + }, + + // private + onTorrentsRemoved: function (torrentIds) { + var selModel = this.getSelectionModel(); + Ext.each( + torrentIds, + function (torrentId) { + var record = this.getStore().getById(torrentId); + if (selModel.isSelected(record)) { + selModel.deselectRow(this.getStore().indexOf(record)); + } + this.getStore().remove(record); + delete this.torrents[torrentId]; + }, + this + ); + }, + }); + deluge.torrents = new Deluge.TorrentGrid(); +})(); diff --git a/deluge/ui/web/js/deluge-all/UI.js b/deluge/ui/web/js/deluge-all/UI.js new file mode 100644 index 0000000..f7edc84 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/UI.js @@ -0,0 +1,311 @@ +/** + * Deluge.UI.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** Dummy translation arrays so Torrent states are available for gettext.js and Translators. + * + * All entries in deluge.common.TORRENT_STATE should be added here. + * + * No need to import these, just simply use the `_()` function around a status variable. + */ +var TORRENT_STATE_TRANSLATION = [ + _('All'), + _('Active'), + _('Allocating'), + _('Checking'), + _('Downloading'), + _('Seeding'), + _('Paused'), + _('Checking'), + _('Queued'), + _('Error'), +]; + +/** + * @static + * @class Deluge.UI + * The controller for the whole interface, that ties all the components + * together and handles the 2 second poll. + */ +deluge.ui = { + errorCount: 0, + + filters: null, + + /** + * @description Create all the interface components, the json-rpc client + * and set up various events that the UI will utilise. + */ + initialize: function () { + deluge.add = new Deluge.add.AddWindow(); + deluge.details = new Deluge.details.DetailsPanel(); + deluge.connectionManager = new Deluge.ConnectionManager(); + deluge.editTrackers = new Deluge.EditTrackersWindow(); + deluge.login = new Deluge.LoginWindow(); + deluge.preferences = new Deluge.preferences.PreferencesWindow(); + deluge.sidebar = new Deluge.Sidebar(); + deluge.statusbar = new Deluge.Statusbar(); + deluge.toolbar = new Deluge.Toolbar(); + + this.detailsPanel = new Ext.Panel({ + id: 'detailsPanel', + cls: 'detailsPanel', + region: 'south', + split: true, + height: 215, + minSize: 100, + collapsible: true, + layout: 'fit', + items: [deluge.details], + }); + + this.MainPanel = new Ext.Panel({ + id: 'mainPanel', + iconCls: 'x-deluge-main-panel', + layout: 'border', + border: false, + tbar: deluge.toolbar, + items: [deluge.sidebar, this.detailsPanel, deluge.torrents], + bbar: deluge.statusbar, + }); + + this.Viewport = new Ext.Viewport({ + layout: 'fit', + items: [this.MainPanel], + }); + + deluge.events.on('connect', this.onConnect, this); + deluge.events.on('disconnect', this.onDisconnect, this); + deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this); + deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this); + deluge.client = new Ext.ux.util.RpcClient({ + url: deluge.config.base + 'json', + }); + + // enable all the already active plugins + for (var plugin in Deluge.pluginStore) { + plugin = Deluge.createPlugin(plugin); + plugin.enable(); + deluge.plugins[plugin.name] = plugin; + } + + // Initialize quicktips so all the tooltip configs start working. + Ext.QuickTips.init(); + + deluge.client.on( + 'connected', + function (e) { + deluge.login.show(); + }, + this, + { single: true } + ); + + this.update = this.update.createDelegate(this); + this.checkConnection = this.checkConnection.createDelegate(this); + + this.originalTitle = document.title; + }, + + checkConnection: function () { + deluge.client.web.connected({ + success: this.onConnectionSuccess, + failure: this.onConnectionError, + scope: this, + }); + }, + + update: function () { + var filters = deluge.sidebar.getFilterStates(); + this.oldFilters = this.filters; + this.filters = filters; + + deluge.client.web.update_ui(Deluge.Keys.Grid, filters, { + success: this.onUpdate, + failure: this.onUpdateError, + scope: this, + }); + deluge.details.update(); + }, + + onConnectionError: function (error) { + if (this.checking) { + clearTimeout(this.checking); + } + this.checking = setTimeout(this.checkConnection, 2000); + }, + + onConnectionSuccess: function (result) { + if (this.checking) { + clearTimeout(this.checking); + this.checking = undefined; + } + this.running = setTimeout(this.update, 2000); + this.update(); + deluge.statusbar.setStatus({ + iconCls: 'x-deluge-statusbar icon-ok', + text: _('Connection restored'), + }); + if (!result) { + deluge.connectionManager.show(); + } + }, + + onUpdateError: function (error) { + if (this.errorCount == 2) { + Ext.MessageBox.show({ + title: _('Lost Connection'), + msg: _('The connection to the webserver has been lost!'), + buttons: Ext.MessageBox.OK, + icon: Ext.MessageBox.ERROR, + }); + deluge.events.fire('disconnect'); + deluge.statusbar.setStatus({ + text: _('Lost connection to webserver'), + }); + this.checking = setTimeout(this.checkConnection, 2000); + } + this.errorCount++; + if (this.running) { + clearTimeout(this.running); + this.running = undefined; + } + }, + + /** + * @static + * @private + * Updates the various components in the interface. + */ + onUpdate: function (data) { + if (this.running) { + clearTimeout(this.running); + this.running = undefined; + } + if (!data['connected']) { + deluge.connectionManager.disconnect(true); + return; + } + this.running = setTimeout(this.update, 2000); + + if (deluge.config.show_session_speed) { + document.title = + 'D: ' + + fsize_short(data['stats'].download_rate, true) + + ' U: ' + + fsize_short(data['stats'].upload_rate, true) + + ' - ' + + this.originalTitle; + } + if (Ext.areObjectsEqual(this.filters, this.oldFilters)) { + deluge.torrents.update(data['torrents']); + } else { + deluge.torrents.update(data['torrents'], true); + } + deluge.statusbar.update(data['stats']); + deluge.sidebar.update(data['filters']); + this.errorCount = 0; + }, + + /** + * @static + * @private + * Start the Deluge UI polling the server and update the interface. + */ + onConnect: function () { + if (!this.running) { + this.running = setTimeout(this.update, 2000); + this.update(); + } + deluge.client.web.get_plugins({ + success: this.onGotPlugins, + scope: this, + }); + }, + + /** + * @static + * @private + */ + onDisconnect: function () { + this.stop(); + }, + + onGotPlugins: function (plugins) { + Ext.each( + plugins.enabled_plugins, + function (plugin) { + if (deluge.plugins[plugin]) return; + deluge.client.web.get_plugin_resources(plugin, { + success: this.onGotPluginResources, + scope: this, + }); + }, + this + ); + }, + + onPluginEnabled: function (pluginName) { + if (deluge.plugins[pluginName]) { + deluge.plugins[pluginName].enable(); + } else { + deluge.client.web.get_plugin_resources(pluginName, { + success: this.onGotPluginResources, + scope: this, + }); + } + }, + + onGotPluginResources: function (resources) { + var scripts = Deluge.debug + ? resources.debug_scripts + : resources.scripts; + Ext.each( + scripts, + function (script) { + Ext.ux.JSLoader({ + url: deluge.config.base + script, + onLoad: this.onPluginLoaded, + pluginName: resources.name, + }); + }, + this + ); + }, + + onPluginDisabled: function (pluginName) { + if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable(); + }, + + onPluginLoaded: function (options) { + // This could happen if the plugin has multiple scripts + if (!Deluge.hasPlugin(options.pluginName)) return; + + // Enable the plugin + plugin = Deluge.createPlugin(options.pluginName); + plugin.enable(); + deluge.plugins[plugin.name] = plugin; + }, + + /** + * @static + * Stop the Deluge UI polling the server and clear the interface. + */ + stop: function () { + if (this.running) { + clearTimeout(this.running); + this.running = undefined; + deluge.torrents.getStore().removeAll(); + } + }, +}; + +Ext.onReady(function (e) { + deluge.ui.initialize(); +}); diff --git a/deluge/ui/web/js/deluge-all/add/.order b/deluge/ui/web/js/deluge-all/add/.order new file mode 100644 index 0000000..dbd1ab9 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/.order @@ -0,0 +1 @@ ++ Window.js diff --git a/deluge/ui/web/js/deluge-all/add/AddWindow.js b/deluge/ui/web/js/deluge-all/add/AddWindow.js new file mode 100644 index 0000000..f5f2fdf --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/AddWindow.js @@ -0,0 +1,332 @@ +/** + * Deluge.add.AddWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.namespace('Deluge.add'); + +// This override allows file upload buttons to contain icons +Ext.override(Ext.ux.form.FileUploadField, { + onRender: function (ct, position) { + Ext.ux.form.FileUploadField.superclass.onRender.call( + this, + ct, + position + ); + + this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' }); + this.el.addClass('x-form-file-text'); + this.el.dom.removeAttribute('name'); + this.createFileInput(); + + var btnCfg = Ext.applyIf(this.buttonCfg || {}, { + text: this.buttonText, + }); + this.button = new Ext.Button( + Ext.apply(btnCfg, { + renderTo: this.wrap, + cls: + 'x-form-file-btn' + + (btnCfg.iconCls ? ' x-btn-text-icon' : ''), + }) + ); + + if (this.buttonOnly) { + this.el.hide(); + this.wrap.setWidth(this.button.getEl().getWidth()); + } + + this.bindListeners(); + this.resizeEl = this.positionEl = this.wrap; + }, +}); + +Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, { + title: _('Add Torrents'), + layout: 'border', + width: 470, + height: 450, + bodyStyle: 'padding: 10px 5px;', + buttonAlign: 'right', + closeAction: 'hide', + closable: true, + plain: true, + iconCls: 'x-deluge-add-window-icon', + + initComponent: function () { + Deluge.add.AddWindow.superclass.initComponent.call(this); + + this.addButton(_('Cancel'), this.onCancelClick, this); + this.addButton(_('Add'), this.onAddClick, this); + + this.list = new Ext.list.ListView({ + store: new Ext.data.SimpleStore({ + fields: [ + { name: 'info_hash', mapping: 1 }, + { name: 'text', mapping: 2 }, + ], + id: 0, + }), + columns: [ + { + id: 'torrent', + width: 150, + sortable: true, + dataIndex: 'text', + tpl: new Ext.XTemplate( + '
{text:htmlEncode}
' + ), + }, + ], + stripeRows: true, + singleSelect: true, + listeners: { + selectionchange: { + fn: this.onSelect, + scope: this, + }, + }, + hideHeaders: true, + autoExpandColumn: 'torrent', + height: '100%', + autoScroll: true, + }); + + this.add({ + region: 'center', + items: [this.list], + border: false, + bbar: new Ext.Toolbar({ + items: [ + { + id: 'fileUploadForm', + xtype: 'form', + layout: 'fit', + baseCls: 'x-plain', + fileUpload: true, + items: [ + { + buttonOnly: true, + xtype: 'fileuploadfield', + id: 'torrentFile', + name: 'file', + multiple: true, + buttonCfg: { + iconCls: 'x-deluge-add-file', + text: _('File'), + }, + listeners: { + scope: this, + fileselected: this.onFileSelected, + }, + }, + ], + }, + { + text: _('Url'), + iconCls: 'icon-add-url', + handler: this.onUrl, + scope: this, + }, + { + text: _('Infohash'), + iconCls: 'icon-magnet-add', + hidden: true, + disabled: true, + }, + '->', + { + text: _('Remove'), + iconCls: 'icon-remove', + handler: this.onRemove, + scope: this, + }, + ], + }), + }); + + this.fileUploadForm = Ext.getCmp('fileUploadForm').getForm(); + this.optionsPanel = this.add(new Deluge.add.OptionsPanel()); + this.on('hide', this.onHide, this); + this.on('show', this.onShow, this); + }, + + clear: function () { + this.list.getStore().removeAll(); + this.optionsPanel.clear(); + // Reset upload form so handler fires when a canceled file is reselected + this.fileUploadForm.reset(); + }, + + onAddClick: function () { + var torrents = []; + if (!this.list) return; + this.list.getStore().each(function (r) { + var id = r.get('info_hash'); + torrents.push({ + path: this.optionsPanel.getFilename(id), + options: this.optionsPanel.getOptions(id), + }); + }, this); + + deluge.client.web.add_torrents(torrents, { + success: function (result) {}, + }); + this.clear(); + this.hide(); + }, + + onCancelClick: function () { + this.clear(); + this.hide(); + }, + + onFile: function () { + if (!this.file) this.file = new Deluge.add.FileWindow(); + this.file.show(); + }, + + onHide: function () { + this.optionsPanel.setActiveTab(0); + this.optionsPanel.files.setDisabled(true); + this.optionsPanel.form.setDisabled(true); + }, + + onRemove: function () { + if (!this.list.getSelectionCount()) return; + var torrent = this.list.getSelectedRecords()[0]; + if (!torrent) return; + this.list.getStore().remove(torrent); + this.optionsPanel.clear(); + + if (this.torrents && this.torrents[torrent.id]) + delete this.torrents[torrent.id]; + }, + + onSelect: function (list, selections) { + if (selections.length) { + var record = this.list.getRecord(selections[0]); + this.optionsPanel.setTorrent(record.get('info_hash')); + } else { + this.optionsPanel.files.setDisabled(true); + this.optionsPanel.form.setDisabled(true); + } + }, + + onShow: function () { + if (!this.url) { + this.url = new Deluge.add.UrlWindow(); + this.url.on('beforeadd', this.onTorrentBeforeAdd, this); + this.url.on('add', this.onTorrentAdd, this); + this.url.on('addfailed', this.onTorrentAddFailed, this); + } + + this.optionsPanel.form.getDefaults(); + }, + + onFileSelected: function () { + if (this.fileUploadForm.isValid()) { + var torrentIds = []; + var files = this.fileUploadForm.findField('torrentFile').value; + var randomId = this.createTorrentId(); + Array.prototype.forEach.call( + files, + function (file, i) { + // Append index for batch of unique torrentIds. + var torrentId = randomId + i.toString(); + torrentIds.push(torrentId); + this.onTorrentBeforeAdd(torrentId, file.name); + }.bind(this) + ); + this.fileUploadForm.submit({ + url: deluge.config.base + 'upload', + waitMsg: _('Uploading your torrent...'), + success: this.onUploadSuccess, + failure: this.onUploadFailure, + scope: this, + torrentIds: torrentIds, + }); + } + }, + + onUploadSuccess: function (fp, upload) { + if (!upload.result.success) { + this.clear(); + return; + } + + upload.result.files.forEach( + function (filename, i) { + deluge.client.web.get_torrent_info(filename, { + success: this.onGotInfo, + scope: this, + filename: filename, + torrentId: upload.options.torrentIds[i], + }); + }.bind(this) + ); + this.fileUploadForm.reset(); + }, + + onUploadFailure: function (form, action) { + this.hide(); + Ext.MessageBox.show({ + title: _('Error'), + msg: _('Failed to upload torrent'), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + this.fireEvent('addfailed', this.torrentId); + }, + + onGotInfo: function (info, obj, response, request) { + info.filename = request.options.filename; + torrentId = request.options.torrentId; + this.onTorrentAdd(torrentId, info); + }, + + onTorrentBeforeAdd: function (torrentId, text) { + var store = this.list.getStore(); + store.loadData([[torrentId, null, text]], true); + }, + + onTorrentAdd: function (torrentId, info) { + var r = this.list.getStore().getById(torrentId); + if (!info) { + Ext.MessageBox.show({ + title: _('Error'), + msg: _('Not a valid torrent'), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + this.list.getStore().remove(r); + } else { + r.set('info_hash', info['info_hash']); + r.set('text', info['name']); + this.list.getStore().commitChanges(); + this.optionsPanel.addTorrent(info); + this.list.select(r); + } + }, + + onTorrentAddFailed: function (torrentId) { + var store = this.list.getStore(); + var torrentRecord = store.getById(torrentId); + if (torrentRecord) { + store.remove(torrentRecord); + } + }, + + onUrl: function (button, event) { + this.url.show(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/add/FilesTab.js b/deluge/ui/web/js/deluge-all/add/FilesTab.js new file mode 100644 index 0000000..d712c02 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/FilesTab.js @@ -0,0 +1,100 @@ +/** + * Deluge.add.FilesTab.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.add'); + +/** + * @class Deluge.add.FilesTab + * @extends Ext.ux.tree.TreeGrid + */ +Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, { + layout: 'fit', + title: _('Files'), + + autoScroll: false, + animate: false, + border: false, + disabled: true, + rootVisible: false, + + columns: [ + { + header: _('Filename'), + width: 295, + dataIndex: 'filename', + tpl: new Ext.XTemplate('{filename:htmlEncode}'), + }, + { + header: _('Size'), + width: 60, + dataIndex: 'size', + tpl: new Ext.XTemplate('{size:this.fsize}', { + fsize: function (v) { + return fsize(v); + }, + }), + }, + { + header: _('Download'), + width: 65, + dataIndex: 'download', + tpl: new Ext.XTemplate('{download:this.format}', { + format: function (v) { + return ( + '
' + ); + }, + }), + }, + ], + + initComponent: function () { + Deluge.add.FilesTab.superclass.initComponent.call(this); + this.on('click', this.onNodeClick, this); + }, + + clearFiles: function () { + var root = this.getRootNode(); + if (!root.hasChildNodes()) return; + root.cascade(function (node) { + if (!node.parentNode || !node.getOwnerTree()) return; + node.remove(); + }); + }, + + setDownload: function (node, value, suppress) { + node.attributes.download = value; + node.ui.updateColumns(); + + if (node.isLeaf()) { + if (!suppress) { + return this.fireEvent('fileschecked', [node], value, !value); + } + } else { + var nodes = [node]; + node.cascade(function (n) { + n.attributes.download = value; + n.ui.updateColumns(); + nodes.push(n); + }, this); + if (!suppress) { + return this.fireEvent('fileschecked', nodes, value, !value); + } + } + }, + + onNodeClick: function (node, e) { + var el = new Ext.Element(e.target); + if (el.getAttribute('rel') == 'chkbox') { + this.setDownload(node, !node.attributes.download); + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/add/Infohash.js b/deluge/ui/web/js/deluge-all/add/Infohash.js new file mode 100644 index 0000000..0105e02 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/Infohash.js @@ -0,0 +1,10 @@ +/** + * Deluge.add.Infohash.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Ext.deluge.add'); diff --git a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js new file mode 100644 index 0000000..365b001 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js @@ -0,0 +1,145 @@ +/** + * Deluge.add.OptionsPanel.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.add'); + +Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, { + torrents: {}, + + // layout options + region: 'south', + border: false, + activeTab: 0, + height: 265, + + initComponent: function () { + Deluge.add.OptionsPanel.superclass.initComponent.call(this); + this.files = this.add(new Deluge.add.FilesTab()); + this.form = this.add(new Deluge.add.OptionsTab()); + + this.files.on('fileschecked', this.onFilesChecked, this); + }, + + addTorrent: function (torrent) { + this.torrents[torrent['info_hash']] = torrent; + var fileIndexes = {}; + this.walkFileTree( + torrent['files_tree'], + function (filename, type, entry, parent) { + if (type != 'file') return; + fileIndexes[entry.index] = entry.download; + }, + this + ); + + var priorities = []; + Ext.each(Ext.keys(fileIndexes), function (index) { + priorities[index] = fileIndexes[index]; + }); + + var oldId = this.form.optionsManager.changeId( + torrent['info_hash'], + true + ); + this.form.optionsManager.setDefault('file_priorities', priorities); + this.form.optionsManager.changeId(oldId, true); + }, + + clear: function () { + this.files.clearFiles(); + this.form.optionsManager.resetAll(); + }, + + getFilename: function (torrentId) { + return this.torrents[torrentId]['filename']; + }, + + getOptions: function (torrentId) { + var oldId = this.form.optionsManager.changeId(torrentId, true); + var options = this.form.optionsManager.get(); + this.form.optionsManager.changeId(oldId, true); + Ext.each(options['file_priorities'], function (priority, index) { + options['file_priorities'][index] = priority ? 1 : 0; + }); + return options; + }, + + setTorrent: function (torrentId) { + if (!torrentId) return; + + this.torrentId = torrentId; + this.form.optionsManager.changeId(torrentId); + + this.files.clearFiles(); + var root = this.files.getRootNode(); + var priorities = this.form.optionsManager.get('file_priorities'); + + this.form.setDisabled(false); + + if (this.torrents[torrentId]['files_tree']) { + this.walkFileTree( + this.torrents[torrentId]['files_tree'], + function (filename, type, entry, parentNode) { + var node = new Ext.tree.TreeNode({ + download: entry.index ? priorities[entry.index] : true, + filename: filename, + fileindex: entry.index, + leaf: type != 'dir', + size: entry.length, + }); + parentNode.appendChild(node); + if (type == 'dir') return node; + }, + this, + root + ); + root.firstChild.expand(); + this.files.setDisabled(false); + this.files.show(); + } else { + // Files tab is empty so show options tab + this.form.show(); + this.files.setDisabled(true); + } + }, + + walkFileTree: function (files, callback, scope, parentNode) { + for (var filename in files.contents) { + var entry = files.contents[filename]; + var type = entry.type; + + if (scope) { + var ret = callback.apply(scope, [ + filename, + type, + entry, + parentNode, + ]); + } else { + var ret = callback(filename, type, entry, parentNode); + } + + if (type == 'dir') this.walkFileTree(entry, callback, scope, ret); + } + }, + + onFilesChecked: function (nodes, newValue, oldValue) { + Ext.each( + nodes, + function (node) { + if (node.attributes.fileindex < 0) return; + var priorities = + this.form.optionsManager.get('file_priorities'); + priorities[node.attributes.fileindex] = newValue; + this.form.optionsManager.update('file_priorities', priorities); + }, + this + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/add/OptionsTab.js b/deluge/ui/web/js/deluge-all/add/OptionsTab.js new file mode 100644 index 0000000..73a8a5c --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/OptionsTab.js @@ -0,0 +1,217 @@ +/** + * Deluge.add.OptionsPanel.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.add'); + +/** + * @class Deluge.add.OptionsTab + * @extends Ext.form.FormPanel + */ +Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, { + title: _('Options'), + height: 170, + border: false, + bodyStyle: 'padding: 5px', + disabled: true, + labelWidth: 1, + + initComponent: function () { + Deluge.add.OptionsTab.superclass.initComponent.call(this); + + this.optionsManager = new Deluge.MultiOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + title: _('Download Folder'), + border: false, + autoHeight: true, + defaultType: 'textfield', + labelWidth: 1, + fieldLabel: '', + style: 'padding: 5px 0; margin-bottom: 0;', + }); + this.optionsManager.bind( + 'download_location', + fieldset.add({ + fieldLabel: '', + name: 'download_location', + anchor: '95%', + labelSeparator: '', + }) + ); + var fieldset = this.add({ + xtype: 'fieldset', + title: _('Move Completed Folder'), + border: false, + autoHeight: true, + defaultType: 'togglefield', + labelWidth: 1, + fieldLabel: '', + style: 'padding: 5px 0; margin-bottom: 0;', + }); + var field = fieldset.add({ + fieldLabel: '', + name: 'move_completed_path', + anchor: '98%', + }); + this.optionsManager.bind('move_completed', field.toggle); + this.optionsManager.bind('move_completed_path', field.input); + + var panel = this.add({ + border: false, + layout: 'column', + defaultType: 'fieldset', + }); + + fieldset = panel.add({ + title: _('Bandwidth'), + border: false, + autoHeight: true, + bodyStyle: 'padding: 2px 5px', + labelWidth: 105, + width: 200, + defaultType: 'spinnerfield', + style: 'padding-right: 10px;', + }); + this.optionsManager.bind( + 'max_download_speed', + fieldset.add({ + fieldLabel: _('Max Down Speed'), + name: 'max_download_speed', + width: 60, + }) + ); + this.optionsManager.bind( + 'max_upload_speed', + fieldset.add({ + fieldLabel: _('Max Up Speed'), + name: 'max_upload_speed', + width: 60, + }) + ); + this.optionsManager.bind( + 'max_connections', + fieldset.add({ + fieldLabel: _('Max Connections'), + name: 'max_connections', + width: 60, + }) + ); + this.optionsManager.bind( + 'max_upload_slots', + fieldset.add({ + fieldLabel: _('Max Upload Slots'), + name: 'max_upload_slots', + width: 60, + }) + ); + + fieldset = panel.add({ + // title: _('General'), + border: false, + autoHeight: true, + defaultType: 'checkbox', + }); + this.optionsManager.bind( + 'add_paused', + fieldset.add({ + name: 'add_paused', + boxLabel: _('Add In Paused State'), + fieldLabel: '', + labelSeparator: '', + }) + ); + this.optionsManager.bind( + 'prioritize_first_last_pieces', + fieldset.add({ + name: 'prioritize_first_last_pieces', + boxLabel: _('Prioritize First/Last Pieces'), + fieldLabel: '', + labelSeparator: '', + }) + ); + this.optionsManager.bind( + 'sequential_download', + fieldset.add({ + name: 'sequential_download', + boxLabel: _('Sequential Download'), + fieldLabel: '', + labelSeparator: '', + }) + ); + this.optionsManager.bind( + 'seed_mode', + fieldset.add({ + name: 'seed_mode', + boxLabel: _('Skip File Hash Check'), + fieldLabel: '', + labelSeparator: '', + }) + ); + this.optionsManager.bind( + 'super_seeding', + fieldset.add({ + name: 'super_seeding', + boxLabel: _('Super Seed'), + fieldLabel: '', + labelSeparator: '', + }) + ); + this.optionsManager.bind( + 'pre_allocate_storage', + fieldset.add({ + name: 'pre_allocate_storage', + boxLabel: _('Preallocate Disk Space'), + fieldLabel: '', + labelSeparator: '', + }) + ); + }, + + getDefaults: function () { + var keys = [ + 'add_paused', + 'pre_allocate_storage', + 'download_location', + 'max_connections_per_torrent', + 'max_download_speed_per_torrent', + 'move_completed', + 'move_completed_path', + 'max_upload_slots_per_torrent', + 'max_upload_speed_per_torrent', + 'prioritize_first_last_pieces', + 'sequential_download', + ]; + + deluge.client.core.get_config_values(keys, { + success: function (config) { + var options = { + file_priorities: [], + add_paused: config.add_paused, + sequential_download: config.sequential_download, + pre_allocate_storage: config.pre_allocate_storage, + download_location: config.download_location, + move_completed: config.move_completed, + move_completed_path: config.move_completed_path, + max_connections: config.max_connections_per_torrent, + max_download_speed: config.max_download_speed_per_torrent, + max_upload_slots: config.max_upload_slots_per_torrent, + max_upload_speed: config.max_upload_speed_per_torrent, + prioritize_first_last_pieces: + config.prioritize_first_last_pieces, + seed_mode: false, + super_seeding: false, + }; + this.optionsManager.options = options; + this.optionsManager.resetAll(); + }, + scope: this, + }); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/add/UrlWindow.js b/deluge/ui/web/js/deluge-all/add/UrlWindow.js new file mode 100644 index 0000000..caf2250 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/UrlWindow.js @@ -0,0 +1,112 @@ +/** + * Deluge.add.UrlWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.namespace('Deluge.add'); +Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, { + title: _('Add from Url'), + modal: true, + plain: true, + layout: 'fit', + width: 350, + height: 155, + + buttonAlign: 'center', + closeAction: 'hide', + bodyStyle: 'padding: 10px 5px;', + iconCls: 'x-deluge-add-url-window-icon', + + initComponent: function () { + Deluge.add.UrlWindow.superclass.initComponent.call(this); + this.addButton(_('Add'), this.onAddClick, this); + + var form = this.add({ + xtype: 'form', + defaultType: 'textfield', + baseCls: 'x-plain', + labelWidth: 55, + }); + + this.urlField = form.add({ + fieldLabel: _('Url'), + id: 'url', + name: 'url', + width: '97%', + }); + this.urlField.on('specialkey', this.onAdd, this); + + this.cookieField = form.add({ + fieldLabel: _('Cookies'), + id: 'cookies', + name: 'cookies', + width: '97%', + }); + this.cookieField.on('specialkey', this.onAdd, this); + }, + + onAddClick: function (field, e) { + if ( + (field.id == 'url' || field.id == 'cookies') && + e.getKey() != e.ENTER + ) + return; + + var field = this.urlField; + var url = field.getValue(); + var cookies = this.cookieField.getValue(); + var torrentId = this.createTorrentId(); + + if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) { + deluge.client.web.get_magnet_info(url, { + success: this.onGotInfo, + scope: this, + filename: url, + torrentId: torrentId, + }); + } else { + deluge.client.web.download_torrent_from_url(url, cookies, { + success: this.onDownload, + failure: this.onDownloadFailed, + scope: this, + torrentId: torrentId, + }); + } + + this.hide(); + this.urlField.setValue(''); + this.fireEvent('beforeadd', torrentId, url); + }, + + onDownload: function (filename, obj, resp, req) { + deluge.client.web.get_torrent_info(filename, { + success: this.onGotInfo, + failure: this.onDownloadFailed, + scope: this, + filename: filename, + torrentId: req.options.torrentId, + }); + }, + + onDownloadFailed: function (obj, resp, req) { + Ext.MessageBox.show({ + title: _('Error'), + msg: _('Failed to download torrent'), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + this.fireEvent('addfailed', req.options.torrentId); + }, + + onGotInfo: function (info, obj, response, request) { + info['filename'] = request.options.filename; + this.fireEvent('add', request.options.torrentId, info); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/add/Window.js b/deluge/ui/web/js/deluge-all/add/Window.js new file mode 100644 index 0000000..20851e7 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/add/Window.js @@ -0,0 +1,29 @@ +/** + * Deluge.add.Window.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.add'); + +/** + * @class Deluge.add.Window + * @extends Ext.Window + * Base class for an add Window + */ +Deluge.add.Window = Ext.extend(Ext.Window, { + initComponent: function () { + Deluge.add.Window.superclass.initComponent.call(this); + this.addEvents('beforeadd', 'add', 'addfailed'); + }, + + /** + * Create an id for the torrent before we have any info about it. + */ + createTorrentId: function () { + return new Date().getTime().toString(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/data/.order b/deluge/ui/web/js/deluge-all/data/.order new file mode 100644 index 0000000..f9befc4 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/data/.order @@ -0,0 +1 @@ ++ SortTypes.js diff --git a/deluge/ui/web/js/deluge-all/data/PeerRecord.js b/deluge/ui/web/js/deluge-all/data/PeerRecord.js new file mode 100644 index 0000000..7f33769 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/data/PeerRecord.js @@ -0,0 +1,53 @@ +/** + * Deluge.data.PeerRecord.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.data'); + +/** + * Deluge.data.Peer record + * + * @author Damien Churchill + * @version 1.3 + * + * @class Deluge.data.Peer + * @extends Ext.data.Record + * @constructor + * @param {Object} data The peer data + */ +Deluge.data.Peer = Ext.data.Record.create([ + { + name: 'country', + type: 'string', + }, + { + name: 'ip', + type: 'string', + sortType: Deluge.data.SortTypes.asIPAddress, + }, + { + name: 'client', + type: 'string', + }, + { + name: 'progress', + type: 'float', + }, + { + name: 'down_speed', + type: 'int', + }, + { + name: 'up_speed', + type: 'int', + }, + { + name: 'seed', + type: 'int', + }, +]); diff --git a/deluge/ui/web/js/deluge-all/data/SortTypes.js b/deluge/ui/web/js/deluge-all/data/SortTypes.js new file mode 100644 index 0000000..ac915d1 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/data/SortTypes.js @@ -0,0 +1,37 @@ +/** + * Deluge.data.SortTypes.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.data'); + +/** + * Common sort functions that can be used for data Stores. + * + * @author Damien Churchill + * @version 1.3 + * + * @class Deluge.data.SortTypes + * @singleton + */ +Deluge.data.SortTypes = { + // prettier-ignore + asIPAddress: function(value) { + var d = value.match( + /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/ + ); + return ((+d[1] * 256 + (+d[2])) * 256 + (+d[3])) * 256 + (+d[4]); + }, + + asQueuePosition: function (value) { + return value > -1 ? value : Number.MAX_VALUE; + }, + + asName: function (value) { + return String(value).toLowerCase(); + }, +}; diff --git a/deluge/ui/web/js/deluge-all/data/TorrentRecord.js b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js new file mode 100644 index 0000000..e510234 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js @@ -0,0 +1,121 @@ +/** + * Deluge.data.TorrentRecord.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.data'); + +/** + * Deluge.data.Torrent record + * + * @author Damien Churchill + * @version 1.3 + * + * @class Deluge.data.Torrent + * @extends Ext.data.Record + * @constructor + * @param {Object} data The torrents data + */ +Deluge.data.Torrent = Ext.data.Record.create([ + { + name: 'queue', + type: 'int', + }, + { + name: 'name', + type: 'string', + sortType: Deluge.data.SortTypes.asName, + }, + { + name: 'total_wanted', + type: 'int', + }, + { + name: 'state', + type: 'string', + }, + { + name: 'progress', + type: 'int', + }, + { + name: 'num_seeds', + type: 'int', + }, + { + name: 'total_seeds', + type: 'int', + }, + { + name: 'num_peers', + type: 'int', + }, + { + name: 'total_peers', + type: 'int', + }, + { + name: 'download_payload_rate', + type: 'int', + }, + { + name: 'upload_payload_rate', + type: 'int', + }, + { + name: 'eta', + type: 'int', + }, + { + name: 'ratio', + type: 'float', + }, + { + name: 'distributed_copies', + type: 'float', + }, + { + name: 'time_added', + type: 'int', + }, + { + name: 'tracker_host', + type: 'string', + }, + { + name: 'save_path', + type: 'string', + }, + { + name: 'total_done', + type: 'int', + }, + { + name: 'total_uploaded', + type: 'int', + }, + { + name: 'total_remaining', + type: 'int', + }, + { + name: 'max_download_speed', + type: 'int', + }, + { + name: 'max_upload_speed', + type: 'int', + }, + { + name: 'seeds_peers_ratio', + type: 'float', + }, + { + name: 'time_since_transfer', + type: 'int', + }, +]); diff --git a/deluge/ui/web/js/deluge-all/details/DetailsPanel.js b/deluge/ui/web/js/deluge-all/details/DetailsPanel.js new file mode 100644 index 0000000..3f28b25 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/DetailsPanel.js @@ -0,0 +1,81 @@ +/** + * Deluge.details.DetailsPanel.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.details'); + +/** + * @class Deluge.details.DetailsPanel + */ +Deluge.details.DetailsPanel = Ext.extend(Ext.TabPanel, { + id: 'torrentDetails', + activeTab: 0, + + initComponent: function () { + Deluge.details.DetailsPanel.superclass.initComponent.call(this); + this.add(new Deluge.details.StatusTab()); + this.add(new Deluge.details.DetailsTab()); + this.add(new Deluge.details.FilesTab()); + this.add(new Deluge.details.PeersTab()); + this.add(new Deluge.details.OptionsTab()); + }, + + clear: function () { + this.items.each(function (panel) { + if (panel.clear) { + panel.clear.defer(100, panel); + panel.disable(); + } + }); + }, + + update: function (tab) { + var torrent = deluge.torrents.getSelected(); + if (!torrent) { + this.clear(); + return; + } + + this.items.each(function (tab) { + if (tab.disabled) tab.enable(); + }); + + tab = tab || this.getActiveTab(); + if (tab.update) tab.update(torrent.id); + }, + + /* Event Handlers */ + + // We need to add the events in onRender since Deluge.Torrents has not been created yet. + onRender: function (ct, position) { + Deluge.details.DetailsPanel.superclass.onRender.call( + this, + ct, + position + ); + deluge.events.on('disconnect', this.clear, this); + deluge.torrents.on('rowclick', this.onTorrentsClick, this); + this.on('tabchange', this.onTabChange, this); + + deluge.torrents.getSelectionModel().on( + 'selectionchange', + function (selModel) { + if (!selModel.hasSelection()) this.clear(); + }, + this + ); + }, + + onTabChange: function (panel, tab) { + this.update(tab); + }, + + onTorrentsClick: function (grid, rowIndex, e) { + this.update(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/details/DetailsTab.js b/deluge/ui/web/js/deluge-all/details/DetailsTab.js new file mode 100644 index 0000000..f1da178 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/DetailsTab.js @@ -0,0 +1,100 @@ +/** + * Deluge.Details.Details.js + * The details tab displayed in the details panel. + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Deluge.details.DetailsTab = Ext.extend(Ext.Panel, { + title: _('Details'), + + fields: {}, + autoScroll: true, + queuedItems: {}, + + oldData: {}, + + initComponent: function () { + Deluge.details.DetailsTab.superclass.initComponent.call(this); + this.addItem('torrent_name', _('Name:')); + this.addItem('hash', _('Hash:')); + this.addItem('path', _('Download Folder:')); + this.addItem('size', _('Total Size:')); + this.addItem('files', _('Total Files:')); + this.addItem('comment', _('Comment:')); + this.addItem('status', _('Status:')); + this.addItem('tracker', _('Tracker:')); + this.addItem('creator', _('Created By:')); + }, + + onRender: function (ct, position) { + Deluge.details.DetailsTab.superclass.onRender.call(this, ct, position); + this.body.setStyle('padding', '10px'); + this.dl = Ext.DomHelper.append(this.body, { tag: 'dl' }, true); + + for (var id in this.queuedItems) { + this.doAddItem(id, this.queuedItems[id]); + } + }, + + addItem: function (id, label) { + if (!this.rendered) { + this.queuedItems[id] = label; + } else { + this.doAddItem(id, label); + } + }, + + // private + doAddItem: function (id, label) { + Ext.DomHelper.append(this.dl, { tag: 'dt', cls: id, html: label }); + this.fields[id] = Ext.DomHelper.append( + this.dl, + { tag: 'dd', cls: id, html: '' }, + true + ); + }, + + clear: function () { + if (!this.fields) return; + for (var k in this.fields) { + this.fields[k].dom.innerHTML = ''; + } + this.oldData = {}; + }, + + update: function (torrentId) { + deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Details, { + success: this.onRequestComplete, + scope: this, + torrentId: torrentId, + }); + }, + + onRequestComplete: function (torrent, request, response, options) { + var data = { + torrent_name: torrent.name, + hash: options.options.torrentId, + path: torrent.download_location, + size: fsize(torrent.total_size), + files: torrent.num_files, + status: torrent.message, + tracker: torrent.tracker_host, + comment: torrent.comment, + creator: torrent.creator, + }; + + for (var field in this.fields) { + if (!Ext.isDefined(data[field])) continue; // This is a field we are not responsible for. + if (data[field] == this.oldData[field]) continue; + this.fields[field].dom.innerHTML = Ext.util.Format.htmlEncode( + data[field] + ); + } + this.oldData = data; + }, +}); diff --git a/deluge/ui/web/js/deluge-all/details/FilesTab.js b/deluge/ui/web/js/deluge-all/details/FilesTab.js new file mode 100644 index 0000000..36ef968 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/FilesTab.js @@ -0,0 +1,236 @@ +/** + * Deluge.details.FilesTab.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, { + title: _('Files'), + + rootVisible: false, + + columns: [ + { + header: _('Filename'), + width: 330, + dataIndex: 'filename', + tpl: new Ext.XTemplate('{filename:htmlEncode}'), + }, + { + header: _('Size'), + width: 150, + dataIndex: 'size', + tpl: new Ext.XTemplate('{size:this.fsize}', { + fsize: function (v) { + return fsize(v); + }, + }), + }, + { + xtype: 'tgrendercolumn', + header: _('Progress'), + width: 150, + dataIndex: 'progress', + renderer: function (v) { + var progress = v * 100; + return Deluge.progressBar( + progress, + this.col.width, + progress.toFixed(2) + '%', + 0 + ); + }, + }, + { + header: _('Priority'), + width: 150, + dataIndex: 'priority', + tpl: new Ext.XTemplate( + '' + + '
' + + '{priority:this.getName}' + + '
', + { + getClass: function (v) { + return FILE_PRIORITY_CSS[v]; + }, + + getName: function (v) { + return _(FILE_PRIORITY[v]); + }, + } + ), + }, + ], + + selModel: new Ext.tree.MultiSelectionModel(), + + initComponent: function () { + Deluge.details.FilesTab.superclass.initComponent.call(this); + this.setRootNode(new Ext.tree.TreeNode({ text: _('Files') })); + }, + + clear: function () { + var root = this.getRootNode(); + if (!root.hasChildNodes()) return; + root.cascade(function (node) { + var parentNode = node.parentNode; + if (!parentNode) return; + if (!parentNode.ownerTree) return; + parentNode.removeChild(node); + }); + }, + + createFileTree: function (files) { + function walk(files, parentNode) { + for (var file in files.contents) { + var item = files.contents[file]; + if (item.type == 'dir') { + walk( + item, + parentNode.appendChild( + new Ext.tree.TreeNode({ + text: file, + filename: file, + size: item.size, + progress: item.progress, + priority: item.priority, + }) + ) + ); + } else { + parentNode.appendChild( + new Ext.tree.TreeNode({ + text: file, + filename: file, + fileIndex: item.index, + size: item.size, + progress: item.progress, + priority: item.priority, + leaf: true, + iconCls: 'x-deluge-file', + uiProvider: Ext.ux.tree.TreeGridNodeUI, + }) + ); + } + } + } + var root = this.getRootNode(); + walk(files, root); + root.firstChild.expand(); + }, + + update: function (torrentId) { + if (this.torrentId != torrentId) { + this.clear(); + this.torrentId = torrentId; + } + + deluge.client.web.get_torrent_files(torrentId, { + success: this.onRequestComplete, + scope: this, + torrentId: torrentId, + }); + }, + + updateFileTree: function (files) { + function walk(files, parentNode) { + for (var file in files.contents) { + var item = files.contents[file]; + var node = parentNode.findChild('filename', file); + node.attributes.size = item.size; + node.attributes.progress = item.progress; + node.attributes.priority = item.priority; + node.ui.updateColumns(); + if (item.type == 'dir') { + walk(item, node); + } + } + } + walk(files, this.getRootNode()); + }, + + onRender: function (ct, position) { + Deluge.details.FilesTab.superclass.onRender.call(this, ct, position); + deluge.menus.filePriorities.on('itemclick', this.onItemClick, this); + this.on('contextmenu', this.onContextMenu, this); + this.sorter = new Ext.tree.TreeSorter(this, { + folderSort: true, + }); + }, + + onContextMenu: function (node, e) { + e.stopEvent(); + var selModel = this.getSelectionModel(); + if (selModel.getSelectedNodes().length < 2) { + selModel.clearSelections(); + node.select(); + } + deluge.menus.filePriorities.showAt(e.getPoint()); + }, + + onItemClick: function (baseItem, e) { + switch (baseItem.id) { + case 'expandAll': + this.expandAll(); + break; + default: + var indexes = {}; + var walk = function (node) { + if (Ext.isEmpty(node.attributes.fileIndex)) return; + indexes[node.attributes.fileIndex] = + node.attributes.priority; + }; + this.getRootNode().cascade(walk); + + var nodes = this.getSelectionModel().getSelectedNodes(); + Ext.each(nodes, function (node) { + if (!node.isLeaf()) { + var setPriorities = function (node) { + if (Ext.isEmpty(node.attributes.fileIndex)) return; + indexes[node.attributes.fileIndex] = + baseItem.filePriority; + }; + node.cascade(setPriorities); + } else if (!Ext.isEmpty(node.attributes.fileIndex)) { + indexes[node.attributes.fileIndex] = + baseItem.filePriority; + return; + } + }); + + var priorities = new Array(Ext.keys(indexes).length); + for (var index in indexes) { + priorities[index] = indexes[index]; + } + + deluge.client.core.set_torrent_options( + [this.torrentId], + { file_priorities: priorities }, + { + success: function () { + Ext.each(nodes, function (node) { + node.attributes.priority = + baseItem.filePriority; + node.ui.updateColumns(); + }); + }, + scope: this, + } + ); + break; + } + }, + + onRequestComplete: function (files, options) { + if (!this.getRootNode().hasChildNodes()) { + this.createFileTree(files); + } else { + this.updateFileTree(files); + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/details/OptionsTab.js b/deluge/ui/web/js/deluge-all/details/OptionsTab.js new file mode 100644 index 0000000..f8a08be --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/OptionsTab.js @@ -0,0 +1,417 @@ +/** + * Deluge.details.OptionsTab.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, { + constructor: function (config) { + config = Ext.apply( + { + autoScroll: true, + bodyStyle: 'padding: 5px;', + border: false, + cls: 'x-deluge-options', + defaults: { + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }, + deferredRender: false, + layout: 'column', + title: _('Options'), + }, + config + ); + Deluge.details.OptionsTab.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.details.OptionsTab.superclass.initComponent.call(this); + + (this.fieldsets = {}), (this.fields = {}); + this.optionsManager = new Deluge.MultiOptionsManager({ + options: { + max_download_speed: -1, + max_upload_speed: -1, + max_connections: -1, + max_upload_slots: -1, + auto_managed: false, + stop_at_ratio: false, + stop_ratio: 2.0, + remove_at_ratio: false, + move_completed: false, + move_completed_path: '', + private: false, + prioritize_first_last: false, + super_seeding: false, + }, + }); + + /* + * Bandwidth Options + */ + this.fieldsets.bandwidth = this.add({ + xtype: 'fieldset', + defaultType: 'spinnerfield', + bodyStyle: 'padding: 5px', + + layout: 'table', + layoutConfig: { columns: 3 }, + labelWidth: 150, + + style: 'margin-left: 10px; margin-right: 5px; padding: 5px', + title: _('Bandwidth'), + width: 250, + }); + + /* + * Max Download Speed + */ + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('Max Download Speed:'), + forId: 'max_download_speed', + cls: 'x-deluge-options-label', + }); + this.fields.max_download_speed = this.fieldsets.bandwidth.add({ + id: 'max_download_speed', + name: 'max_download_speed', + width: 70, + strategy: { + xtype: 'number', + decimalPrecision: 1, + minValue: -1, + maxValue: 9999999, + }, + }); + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('KiB/s'), + style: 'margin-left: 10px', + }); + + /* + * Max Upload Speed + */ + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('Max Upload Speed:'), + forId: 'max_upload_speed', + cls: 'x-deluge-options-label', + }); + this.fields.max_upload_speed = this.fieldsets.bandwidth.add({ + id: 'max_upload_speed', + name: 'max_upload_speed', + width: 70, + value: -1, + strategy: { + xtype: 'number', + decimalPrecision: 1, + minValue: -1, + maxValue: 9999999, + }, + }); + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('KiB/s'), + style: 'margin-left: 10px', + }); + + /* + * Max Connections + */ + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('Max Connections:'), + forId: 'max_connections', + cls: 'x-deluge-options-label', + }); + this.fields.max_connections = this.fieldsets.bandwidth.add({ + id: 'max_connections', + name: 'max_connections', + width: 70, + value: -1, + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }, + colspan: 2, + }); + + /* + * Max Upload Slots + */ + this.fieldsets.bandwidth.add({ + xtype: 'label', + text: _('Max Upload Slots:'), + forId: 'max_upload_slots', + cls: 'x-deluge-options-label', + }); + this.fields.max_upload_slots = this.fieldsets.bandwidth.add({ + id: 'max_upload_slots', + name: 'max_upload_slots', + width: 70, + value: -1, + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }, + colspan: 2, + }); + + /* + * Queue Options + */ + this.fieldsets.queue = this.add({ + xtype: 'fieldset', + title: _('Queue'), + style: 'margin-left: 5px; margin-right: 5px; padding: 5px', + width: 210, + + layout: 'table', + layoutConfig: { columns: 2 }, + labelWidth: 0, + + defaults: { + fieldLabel: '', + labelSeparator: '', + }, + }); + + this.fields.auto_managed = this.fieldsets.queue.add({ + xtype: 'checkbox', + fieldLabel: '', + labelSeparator: '', + name: 'is_auto_managed', + boxLabel: _('Auto Managed'), + width: 200, + colspan: 2, + }); + + this.fields.stop_at_ratio = this.fieldsets.queue.add({ + fieldLabel: '', + labelSeparator: '', + id: 'stop_at_ratio', + width: 120, + boxLabel: _('Stop seed at ratio:'), + handler: this.onStopRatioChecked, + scope: this, + }); + + this.fields.stop_ratio = this.fieldsets.queue.add({ + xtype: 'spinnerfield', + id: 'stop_ratio', + name: 'stop_ratio', + disabled: true, + width: 50, + value: 2.0, + strategy: { + xtype: 'number', + minValue: -1, + maxValue: 99999, + incrementValue: 0.1, + alternateIncrementValue: 1, + decimalPrecision: 1, + }, + }); + + this.fields.remove_at_ratio = this.fieldsets.queue.add({ + fieldLabel: '', + labelSeparator: '', + id: 'remove_at_ratio', + ctCls: 'x-deluge-indent-checkbox', + bodyStyle: 'padding-left: 10px', + boxLabel: _('Remove at ratio'), + disabled: true, + colspan: 2, + }); + + this.fields.move_completed = this.fieldsets.queue.add({ + fieldLabel: '', + labelSeparator: '', + id: 'move_completed', + boxLabel: _('Move Completed:'), + colspan: 2, + handler: this.onMoveCompletedChecked, + scope: this, + }); + + this.fields.move_completed_path = this.fieldsets.queue.add({ + xtype: 'textfield', + fieldLabel: '', + id: 'move_completed_path', + colspan: 3, + bodyStyle: 'margin-left: 20px', + width: 180, + disabled: true, + }); + + /* + * General Options + */ + this.rightColumn = this.add({ + border: false, + autoHeight: true, + style: 'margin-left: 5px', + width: 210, + }); + + this.fieldsets.general = this.rightColumn.add({ + xtype: 'fieldset', + autoHeight: true, + defaultType: 'checkbox', + title: _('General'), + layout: 'form', + }); + + this.fields['private'] = this.fieldsets.general.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Private'), + id: 'private', + disabled: true, + }); + + this.fields.prioritize_first_last = this.fieldsets.general.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Prioritize First/Last'), + id: 'prioritize_first_last', + }); + + this.fields.super_seeding = this.fieldsets.general.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Super Seeding'), + id: 'super_seeding', + }); + + // Bind the fields so the options manager can manage them. + for (var id in this.fields) { + this.optionsManager.bind(id, this.fields[id]); + } + + /* + * Buttons + */ + this.buttonPanel = this.rightColumn.add({ + layout: 'hbox', + xtype: 'panel', + border: false, + }); + + /* + * Edit Trackers button + */ + this.buttonPanel.add({ + id: 'edit_trackers', + xtype: 'button', + text: _('Edit Trackers'), + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-edit-trackers', + border: false, + width: 100, + handler: this.onEditTrackers, + scope: this, + }); + + /* + * Apply button + */ + this.buttonPanel.add({ + id: 'apply', + xtype: 'button', + text: _('Apply'), + style: 'margin-left: 10px;', + border: false, + width: 100, + handler: this.onApply, + scope: this, + }); + }, + + onRender: function (ct, position) { + Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position); + + // This is another hack I think, so keep an eye out here when upgrading. + this.layout = new Ext.layout.ColumnLayout(); + this.layout.setContainer(this); + this.doLayout(); + }, + + clear: function () { + if (this.torrentId == null) return; + this.torrentId = null; + this.optionsManager.changeId(null); + }, + + reset: function () { + if (this.torrentId) this.optionsManager.reset(); + }, + + update: function (torrentId) { + if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds + + if (!torrentId) return; // We do not care about null torrentIds. + + if (this.torrentId != torrentId) { + this.torrentId = torrentId; + this.optionsManager.changeId(torrentId); + } + deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Options, { + success: this.onRequestComplete, + scope: this, + }); + }, + + onApply: function () { + var changed = this.optionsManager.getDirty(); + deluge.client.core.set_torrent_options([this.torrentId], changed, { + success: function () { + this.optionsManager.commit(); + }, + scope: this, + }); + }, + + onEditTrackers: function () { + deluge.editTrackers.show(); + }, + + onMoveCompletedChecked: function (checkbox, checked) { + this.fields.move_completed_path.setDisabled(!checked); + + if (!checked) return; + this.fields.move_completed_path.focus(); + }, + + onStopRatioChecked: function (checkbox, checked) { + this.fields.remove_at_ratio.setDisabled(!checked); + this.fields.stop_ratio.setDisabled(!checked); + }, + + onRequestComplete: function (torrent, options) { + this.fields['private'].setValue(torrent['private']); + this.fields['private'].setDisabled(true); + delete torrent['private']; + torrent['auto_managed'] = torrent['is_auto_managed']; + torrent['prioritize_first_last_pieces'] = + torrent['prioritize_first_last']; + this.optionsManager.setDefault(torrent); + var stop_at_ratio = this.optionsManager.get('stop_at_ratio'); + this.fields.remove_at_ratio.setDisabled(!stop_at_ratio); + this.fields.stop_ratio.setDisabled(!stop_at_ratio); + this.fields.move_completed_path.setDisabled( + !this.optionsManager.get('move_completed') + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/details/PeersTab.js b/deluge/ui/web/js/deluge-all/details/PeersTab.js new file mode 100644 index 0000000..a191963 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/PeersTab.js @@ -0,0 +1,166 @@ +/** + * Deluge.details.PeersTab.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +(function () { + function flagRenderer(value) { + if (!value.replace(' ', '').replace(' ', '')) { + return ''; + } + return String.format( + '{1}', + deluge.config.base, + value + ); + } + function peerAddressRenderer(value, p, record) { + var seed = + record.data['seed'] == 1024 ? 'x-deluge-seed' : 'x-deluge-peer'; + // Modify display of IPv6 to include brackets + var peer_ip = value.split(':'); + if (peer_ip.length > 2) { + var port = peer_ip.pop(); + var ip = peer_ip.join(':'); + value = '[' + ip + ']:' + port; + } + return String.format('
{1}
', seed, value); + } + function peerProgressRenderer(value) { + var progress = (value * 100).toFixed(0); + return Deluge.progressBar(progress, this.width - 8, progress + '%'); + } + + Deluge.details.PeersTab = Ext.extend(Ext.grid.GridPanel, { + // fast way to figure out if we have a peer already. + peers: {}, + + constructor: function (config) { + config = Ext.apply( + { + title: _('Peers'), + cls: 'x-deluge-peers', + store: new Ext.data.Store({ + reader: new Ext.data.JsonReader( + { + idProperty: 'ip', + root: 'peers', + }, + Deluge.data.Peer + ), + }), + columns: [ + { + header: ' ', + width: 30, + sortable: true, + renderer: flagRenderer, + dataIndex: 'country', + }, + { + header: _('Address'), + width: 125, + sortable: true, + renderer: peerAddressRenderer, + dataIndex: 'ip', + }, + { + header: _('Client'), + width: 125, + sortable: true, + renderer: 'htmlEncode', + dataIndex: 'client', + }, + { + header: _('Progress'), + width: 150, + sortable: true, + renderer: peerProgressRenderer, + dataIndex: 'progress', + }, + { + header: _('Down Speed'), + width: 100, + sortable: true, + renderer: fspeed, + dataIndex: 'down_speed', + }, + { + header: _('Up Speed'), + width: 100, + sortable: true, + renderer: fspeed, + dataIndex: 'up_speed', + }, + ], + stripeRows: true, + deferredRender: false, + autoScroll: true, + }, + config + ); + Deluge.details.PeersTab.superclass.constructor.call(this, config); + }, + + clear: function () { + this.getStore().removeAll(); + this.peers = {}; + }, + + update: function (torrentId) { + deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, { + success: this.onRequestComplete, + scope: this, + }); + }, + + onRequestComplete: function (torrent, options) { + if (!torrent) return; + + var store = this.getStore(); + var newPeers = []; + var addresses = {}; + + // Go through the peers updating and creating peer records + Ext.each( + torrent.peers, + function (peer) { + if (this.peers[peer.ip]) { + var record = store.getById(peer.ip); + record.beginEdit(); + for (var k in peer) { + if (record.get(k) != peer[k]) { + record.set(k, peer[k]); + } + } + record.endEdit(); + } else { + this.peers[peer.ip] = 1; + newPeers.push(new Deluge.data.Peer(peer, peer.ip)); + } + addresses[peer.ip] = 1; + }, + this + ); + store.add(newPeers); + + // Remove any peers that should not be left in the store. + store.each(function (record) { + if (!addresses[record.id]) { + store.remove(record); + delete this.peers[record.id]; + } + }, this); + store.commitChanges(); + + var sortState = store.getSortState(); + if (!sortState) return; + store.sort(sortState.field, sortState.direction); + }, + }); +})(); diff --git a/deluge/ui/web/js/deluge-all/details/StatusTab.js b/deluge/ui/web/js/deluge-all/details/StatusTab.js new file mode 100644 index 0000000..6055161 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/details/StatusTab.js @@ -0,0 +1,155 @@ +/** + * Deluge.details.StatusTab.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.details'); + +/** + * @class Deluge.details.StatusTab + * @extends Ext.Panel + */ +Deluge.details.StatusTab = Ext.extend(Ext.Panel, { + title: _('Status'), + autoScroll: true, + + onRender: function (ct, position) { + Deluge.details.StatusTab.superclass.onRender.call(this, ct, position); + + this.progressBar = this.add({ + xtype: 'progress', + cls: 'x-deluge-status-progressbar', + }); + + this.status = this.add({ + cls: 'x-deluge-status', + id: 'deluge-details-status', + + border: false, + width: 1000, + listeners: { + render: { + fn: function (panel) { + panel.load({ + url: deluge.config.base + 'render/tab_status.html', + text: _('Loading') + '...', + }); + panel + .getUpdater() + .on('update', this.onPanelUpdate, this); + }, + scope: this, + }, + }, + }); + }, + + clear: function () { + this.progressBar.updateProgress(0, ' '); + for (var k in this.fields) { + this.fields[k].innerHTML = ''; + } + }, + + update: function (torrentId) { + if (!this.fields) this.getFields(); + deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Status, { + success: this.onRequestComplete, + scope: this, + }); + }, + + onPanelUpdate: function (el, response) { + this.fields = {}; + Ext.each( + Ext.query('dd', this.status.body.dom), + function (field) { + this.fields[field.className] = field; + }, + this + ); + }, + + onRequestComplete: function (status) { + seeds = + status.total_seeds > -1 + ? status.num_seeds + ' (' + status.total_seeds + ')' + : status.num_seeds; + peers = + status.total_peers > -1 + ? status.num_peers + ' (' + status.total_peers + ')' + : status.num_peers; + last_seen_complete = + status.last_seen_complete > 0.0 + ? fdate(status.last_seen_complete) + : 'Never'; + completed_time = + status.completed_time > 0.0 ? fdate(status.completed_time) : ''; + + var data = { + downloaded: fsize(status.total_done, true), + uploaded: fsize(status.total_uploaded, true), + share: status.ratio == -1 ? '∞' : status.ratio.toFixed(3), + announce: ftime(status.next_announce), + tracker_status: status.tracker_status, + downspeed: status.download_payload_rate + ? fspeed(status.download_payload_rate) + : '0.0 KiB/s', + upspeed: status.upload_payload_rate + ? fspeed(status.upload_payload_rate) + : '0.0 KiB/s', + eta: status.eta < 0 ? '∞' : ftime(status.eta), + pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')', + seeds: seeds, + peers: peers, + avail: status.distributed_copies.toFixed(3), + active_time: ftime(status.active_time), + seeding_time: ftime(status.seeding_time), + seed_rank: status.seed_rank, + time_added: fdate(status.time_added), + last_seen_complete: last_seen_complete, + completed_time: completed_time, + time_since_transfer: ftime(status.time_since_transfer), + }; + data.auto_managed = _(status.is_auto_managed ? 'True' : 'False'); + + var translate_tracker_status = { + Error: _('Error'), + Warning: _('Warning'), + 'Announce OK': _('Announce OK'), + 'Announce Sent': _('Announce Sent'), + }; + for (var key in translate_tracker_status) { + if (data.tracker_status.indexOf(key) != -1) { + data.tracker_status = data.tracker_status.replace( + key, + translate_tracker_status[key] + ); + break; + } + } + + data.downloaded += + ' (' + + (status.total_payload_download + ? fsize(status.total_payload_download) + : '0.0 KiB') + + ')'; + data.uploaded += + ' (' + + (status.total_payload_upload + ? fsize(status.total_payload_upload) + : '0.0 KiB') + + ')'; + + for (var field in this.fields) { + this.fields[field].innerHTML = data[field]; + } + var text = status.state + ' ' + status.progress.toFixed(2) + '%'; + this.progressBar.updateProgress(status.progress / 100.0, text); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js new file mode 100644 index 0000000..563dedd --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js @@ -0,0 +1,202 @@ +/** + * Deluge.preferences.BandwidthPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Bandwidth + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, { + constructor: function (config) { + config = Ext.apply( + { + border: false, + title: _('Bandwidth'), + header: false, + layout: 'form', + labelWidth: 10, + }, + config + ); + Deluge.preferences.Bandwidth.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.preferences.Bandwidth.superclass.initComponent.call(this); + + var om = deluge.preferences.getOptionsManager(); + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Global Bandwidth Usage'), + labelWidth: 200, + defaultType: 'spinnerfield', + defaults: { + minValue: -1, + maxValue: 9999999, + }, + style: 'margin-bottom: 0px; padding-bottom: 0px;', + autoHeight: true, + }); + om.bind( + 'max_connections_global', + fieldset.add({ + name: 'max_connections_global', + fieldLabel: _('Maximum Connections:'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_upload_slots_global', + fieldset.add({ + name: 'max_upload_slots_global', + fieldLabel: _('Maximum Upload Slots'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_download_speed', + fieldset.add({ + name: 'max_download_speed', + fieldLabel: _('Maximum Download Speed (KiB/s):'), + labelSeparator: '', + width: 80, + value: -1.0, + decimalPrecision: 1, + }) + ); + om.bind( + 'max_upload_speed', + fieldset.add({ + name: 'max_upload_speed', + fieldLabel: _('Maximum Upload Speed (KiB/s):'), + labelSeparator: '', + width: 80, + value: -1.0, + decimalPrecision: 1, + }) + ); + om.bind( + 'max_half_open_connections', + fieldset.add({ + name: 'max_half_open_connections', + fieldLabel: _('Maximum Half-Open Connections:'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_connections_per_second', + fieldset.add({ + name: 'max_connections_per_second', + fieldLabel: _('Maximum Connection Attempts per Second:'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: '', + defaultType: 'checkbox', + style: 'padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;', + autoHeight: true, + }); + om.bind( + 'ignore_limits_on_local_network', + fieldset.add({ + name: 'ignore_limits_on_local_network', + height: 22, + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Ignore limits on local network'), + }) + ); + om.bind( + 'rate_limit_ip_overhead', + fieldset.add({ + name: 'rate_limit_ip_overhead', + height: 22, + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Rate limit IP overhead'), + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Per Torrent Bandwidth Usage'), + style: 'margin-bottom: 0px; padding-bottom: 0px;', + defaultType: 'spinnerfield', + labelWidth: 200, + defaults: { + minValue: -1, + maxValue: 99999, + }, + autoHeight: true, + }); + om.bind( + 'max_connections_per_torrent', + fieldset.add({ + name: 'max_connections_per_torrent', + fieldLabel: _('Maximum Connections:'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_upload_slots_per_torrent', + fieldset.add({ + name: 'max_upload_slots_per_torrent', + fieldLabel: _('Maximum Upload Slots:'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_download_speed_per_torrent', + fieldset.add({ + name: 'max_download_speed_per_torrent', + fieldLabel: _('Maximum Download Speed (KiB/s):'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + om.bind( + 'max_upload_speed_per_torrent', + fieldset.add({ + name: 'max_upload_speed_per_torrent', + fieldLabel: _('Maximum Upload Speed (KiB/s):'), + labelSeparator: '', + width: 80, + value: -1, + decimalPrecision: 0, + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/CachePage.js b/deluge/ui/web/js/deluge-all/preferences/CachePage.js new file mode 100644 index 0000000..bd5acd8 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/CachePage.js @@ -0,0 +1,61 @@ +/** + * Deluge.preferences.CachePage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Cache + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Cache = Ext.extend(Ext.form.FormPanel, { + border: false, + title: _('Cache'), + header: false, + layout: 'form', + + initComponent: function () { + Deluge.preferences.Cache.superclass.initComponent.call(this); + + var om = deluge.preferences.getOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Settings'), + autoHeight: true, + labelWidth: 180, + defaultType: 'spinnerfield', + defaults: { + decimalPrecision: 0, + minValue: -1, + maxValue: 999999, + }, + }); + om.bind( + 'cache_size', + fieldset.add({ + fieldLabel: _('Cache Size (16 KiB Blocks):'), + labelSeparator: '', + name: 'cache_size', + width: 60, + value: 512, + }) + ); + om.bind( + 'cache_expiry', + fieldset.add({ + fieldLabel: _('Cache Expiry (seconds):'), + labelSeparator: '', + name: 'cache_expiry', + width: 60, + value: 60, + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js new file mode 100644 index 0000000..da205c2 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js @@ -0,0 +1,85 @@ +/** + * Deluge.preferences.DaemonPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Daemon + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, { + border: false, + title: _('Daemon'), + header: false, + layout: 'form', + + initComponent: function () { + Deluge.preferences.Daemon.superclass.initComponent.call(this); + + var om = deluge.preferences.getOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Port'), + autoHeight: true, + defaultType: 'spinnerfield', + }); + om.bind( + 'daemon_port', + fieldset.add({ + fieldLabel: _('Daemon port:'), + labelSeparator: '', + name: 'daemon_port', + value: 58846, + decimalPrecision: 0, + minValue: -1, + maxValue: 65535, + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Connections'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + om.bind( + 'allow_remote', + fieldset.add({ + fieldLabel: '', + height: 22, + labelSeparator: '', + boxLabel: _('Allow Remote Connections'), + name: 'allow_remote', + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Other'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + om.bind( + 'new_release_check', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 40, + boxLabel: _('Periodically check the website for new releases'), + id: 'new_release_check', + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js b/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js new file mode 100644 index 0000000..04ffd15 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js @@ -0,0 +1,124 @@ +/** + * Deluge.preferences.DownloadsPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Downloads + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Downloads = Ext.extend(Ext.FormPanel, { + constructor: function (config) { + config = Ext.apply( + { + border: false, + title: _('Downloads'), + header: false, + layout: 'form', + autoHeight: true, + width: 320, + }, + config + ); + Deluge.preferences.Downloads.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.preferences.Downloads.superclass.initComponent.call(this); + + var optMan = deluge.preferences.getOptionsManager(); + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Folders'), + labelWidth: 150, + defaultType: 'togglefield', + autoHeight: true, + labelAlign: 'top', + width: 300, + style: 'margin-bottom: 5px; padding-bottom: 5px;', + }); + + optMan.bind( + 'download_location', + fieldset.add({ + xtype: 'textfield', + name: 'download_location', + fieldLabel: _('Download to:'), + labelSeparator: '', + width: 280, + }) + ); + + var field = fieldset.add({ + name: 'move_completed_path', + fieldLabel: _('Move completed to:'), + labelSeparator: '', + width: 280, + }); + optMan.bind('move_completed', field.toggle); + optMan.bind('move_completed_path', field.input); + + field = fieldset.add({ + name: 'torrentfiles_location', + fieldLabel: _('Copy of .torrent files to:'), + labelSeparator: '', + width: 280, + }); + optMan.bind('copy_torrent_file', field.toggle); + optMan.bind('torrentfiles_location', field.input); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Options'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + style: 'margin-bottom: 0; padding-bottom: 0;', + width: 280, + }); + optMan.bind( + 'prioritize_first_last_pieces', + fieldset.add({ + name: 'prioritize_first_last_pieces', + labelSeparator: '', + height: 22, + boxLabel: _('Prioritize first and last pieces of torrent'), + }) + ); + optMan.bind( + 'sequential_download', + fieldset.add({ + name: 'sequential_download', + labelSeparator: '', + height: 22, + boxLabel: _('Sequential download'), + }) + ); + optMan.bind( + 'add_paused', + fieldset.add({ + name: 'add_paused', + labelSeparator: '', + height: 22, + boxLabel: _('Add torrents in Paused state'), + }) + ); + optMan.bind( + 'pre_allocate_storage', + fieldset.add({ + name: 'pre_allocate_storage', + labelSeparator: '', + height: 22, + boxLabel: _('Pre-allocate disk space'), + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js b/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js new file mode 100644 index 0000000..1bcf95e --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js @@ -0,0 +1,99 @@ +/** + * Deluge.preferences.EncryptionPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Encryption + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Encryption = Ext.extend(Ext.form.FormPanel, { + border: false, + title: _('Encryption'), + header: false, + + initComponent: function () { + Deluge.preferences.Encryption.superclass.initComponent.call(this); + + var optMan = deluge.preferences.getOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Settings'), + header: false, + autoHeight: true, + defaultType: 'combo', + width: 300, + }); + optMan.bind( + 'enc_in_policy', + fieldset.add({ + fieldLabel: _('Incoming:'), + labelSeparator: '', + mode: 'local', + width: 150, + store: new Ext.data.ArrayStore({ + fields: ['id', 'text'], + data: [ + [0, _('Forced')], + [1, _('Enabled')], + [2, _('Disabled')], + ], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }) + ); + optMan.bind( + 'enc_out_policy', + fieldset.add({ + fieldLabel: _('Outgoing:'), + labelSeparator: '', + mode: 'local', + width: 150, + store: new Ext.data.SimpleStore({ + fields: ['id', 'text'], + data: [ + [0, _('Forced')], + [1, _('Enabled')], + [2, _('Disabled')], + ], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }) + ); + optMan.bind( + 'enc_level', + fieldset.add({ + fieldLabel: _('Level:'), + labelSeparator: '', + mode: 'local', + width: 150, + store: new Ext.data.SimpleStore({ + fields: ['id', 'text'], + data: [ + [0, _('Handshake')], + [1, _('Full Stream')], + [2, _('Either')], + ], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js b/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js new file mode 100644 index 0000000..9aefce3 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js @@ -0,0 +1,83 @@ +/** + * Deluge.preferences.InstallPluginWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.InstallPluginWindow + * @extends Ext.Window + */ +Deluge.preferences.InstallPluginWindow = Ext.extend(Ext.Window, { + title: _('Install Plugin'), + layout: 'fit', + height: 115, + width: 350, + constrainHeader: true, + bodyStyle: 'padding: 10px 5px;', + buttonAlign: 'center', + closeAction: 'hide', + iconCls: 'x-deluge-install-plugin', + modal: true, + plain: true, + + initComponent: function () { + Deluge.preferences.InstallPluginWindow.superclass.initComponent.call( + this + ); + this.addButton(_('Install'), this.onInstall, this); + + this.form = this.add({ + xtype: 'form', + baseCls: 'x-plain', + labelWidth: 70, + autoHeight: true, + fileUpload: true, + items: [ + { + xtype: 'fileuploadfield', + width: 240, + emptyText: _('Select an egg'), + fieldLabel: _('Plugin Egg'), + name: 'file', + buttonCfg: { + text: _('Browse...'), + }, + }, + ], + }); + }, + + onInstall: function (field, e) { + this.form.getForm().submit({ + url: deluge.config.base + 'upload', + waitMsg: _('Uploading your plugin...'), + success: this.onUploadSuccess, + scope: this, + }); + }, + + onUploadPlugin: function (info, obj, response, request) { + this.fireEvent('pluginadded'); + }, + + onUploadSuccess: function (fp, upload) { + this.hide(); + if (upload.result.success) { + var filename = this.form.getForm().getFieldValues().file; + filename = filename.split('\\').slice(-1)[0]; + var path = upload.result.files[0]; + this.form.getForm().setValues({ file: '' }); + deluge.client.web.upload_plugin(filename, path, { + success: this.onUploadPlugin, + scope: this, + filename: filename, + }); + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js new file mode 100644 index 0000000..a5a7909 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js @@ -0,0 +1,358 @@ +/** + * Deluge.preferences.InterfacePage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Interface + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, { + border: false, + title: _('Interface'), + header: false, + layout: 'form', + + initComponent: function () { + Deluge.preferences.Interface.superclass.initComponent.call(this); + + var om = (this.optionsManager = new Deluge.OptionsManager()); + this.on('show', this.onPageShow, this); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Interface'), + style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + defaults: { + height: 17, + fieldLabel: '', + labelSeparator: '', + }, + }); + om.bind( + 'show_session_speed', + fieldset.add({ + name: 'show_session_speed', + boxLabel: _('Show session speed in titlebar'), + }) + ); + om.bind( + 'sidebar_show_zero', + fieldset.add({ + name: 'sidebar_show_zero', + boxLabel: _('Show filters with zero torrents'), + }) + ); + om.bind( + 'sidebar_multiple_filters', + fieldset.add({ + name: 'sidebar_multiple_filters', + boxLabel: _('Allow the use of multiple filters at once'), + }) + ); + + var languagePanel = this.add({ + xtype: 'fieldset', + border: false, + title: _('Language'), + style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + this.language = om.bind( + 'language', + languagePanel.add({ + xtype: 'combo', + labelSeparator: '', + name: 'language', + mode: 'local', + width: 200, + store: new Ext.data.ArrayStore({ + fields: ['id', 'text'], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }) + ); + + var themePanel = this.add({ + xtype: 'fieldset', + border: false, + title: _('Theme'), + style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + this.theme = om.bind( + 'theme', + themePanel.add({ + xtype: 'combo', + name: 'theme', + labelSeparator: '', + mode: 'local', + width: 200, + store: new Ext.data.ArrayStore({ + fields: ['id', 'text'], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('WebUI Password'), + style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px', + autoHeight: true, + labelWidth: 100, + defaultType: 'textfield', + defaults: { + width: 100, + inputType: 'password', + labelStyle: 'padding-left: 5px', + height: 20, + labelSeparator: '', + }, + }); + + this.oldPassword = fieldset.add({ + name: 'old_password', + fieldLabel: _('Old:'), + }); + this.newPassword = fieldset.add({ + name: 'new_password', + fieldLabel: _('New:'), + }); + this.confirmPassword = fieldset.add({ + name: 'confirm_password', + fieldLabel: _('Confirm:'), + }); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Server'), + style: 'padding-top: 5px; margin-bottom: 0px; padding-bottom: 5px', + autoHeight: true, + labelWidth: 100, + defaultType: 'spinnerfield', + defaults: { + labelSeparator: '', + labelStyle: 'padding-left: 5px', + height: 20, + width: 80, + }, + }); + om.bind( + 'session_timeout', + fieldset.add({ + name: 'session_timeout', + fieldLabel: _('Session Timeout:'), + decimalPrecision: 0, + minValue: -1, + maxValue: Number.MAX_SAFE_INTEGER || Number.MAX_VALUE, + }) + ); + om.bind( + 'port', + fieldset.add({ + name: 'port', + fieldLabel: _('Port:'), + decimalPrecision: 0, + minValue: 1, + maxValue: 65535, + }) + ); + this.httpsField = om.bind( + 'https', + fieldset.add({ + xtype: 'checkbox', + name: 'https', + hideLabel: true, + width: 300, + style: 'margin-left: 5px', + boxLabel: _( + 'Enable SSL (paths relative to Deluge config folder)' + ), + }) + ); + this.httpsField.on('check', this.onSSLCheck, this); + this.pkeyField = om.bind( + 'pkey', + fieldset.add({ + xtype: 'textfield', + disabled: true, + name: 'pkey', + width: 180, + fieldLabel: _('Private Key:'), + }) + ); + this.certField = om.bind( + 'cert', + fieldset.add({ + xtype: 'textfield', + disabled: true, + name: 'cert', + width: 180, + fieldLabel: _('Certificate:'), + }) + ); + }, + + onApply: function () { + var changed = this.optionsManager.getDirty(); + if (!Ext.isObjectEmpty(changed)) { + deluge.client.web.set_config(changed, { + success: this.onSetConfig, + scope: this, + }); + + for (var key in deluge.config) { + deluge.config[key] = this.optionsManager.get(key); + } + if ('language' in changed) { + Ext.Msg.show({ + title: _('WebUI Language Changed'), + msg: _( + 'Do you want to refresh the page now to use the new language?' + ), + buttons: { + yes: _('Refresh'), + no: _('Close'), + }, + multiline: false, + fn: function (btnText) { + if (btnText === 'yes') location.reload(); + }, + icon: Ext.MessageBox.QUESTION, + }); + } + if ('theme' in changed) { + deluge.client.web.set_theme(changed['theme']); + Ext.Msg.show({ + title: _('WebUI Theme Changed'), + msg: _( + 'Do you want to refresh the page now to use the new theme?' + ), + buttons: { + yes: _('Refresh'), + no: _('Close'), + }, + multiline: false, + fn: function (btnText) { + if (btnText === 'yes') location.reload(); + }, + icon: Ext.MessageBox.QUESTION, + }); + } + } + if (this.oldPassword.getValue() || this.newPassword.getValue()) { + this.onPasswordChange(); + } + }, + + onOk: function () { + this.onApply(); + }, + + onGotConfig: function (config) { + this.optionsManager.set(config); + }, + + onGotLanguages: function (info, obj, response, request) { + info.unshift(['', _('System Default')]); + this.language.store.loadData(info); + this.language.setValue(this.optionsManager.get('language')); + }, + + onGotThemes: function (info, obj, response, request) { + this.theme.store.loadData(info); + this.theme.setValue(this.optionsManager.get('theme')); + }, + + onPasswordChange: function () { + var newPassword = this.newPassword.getValue(); + if (newPassword != this.confirmPassword.getValue()) { + Ext.MessageBox.show({ + title: _('Invalid Password'), + msg: _("Your passwords don't match!"), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + return; + } + + var oldPassword = this.oldPassword.getValue(); + deluge.client.auth.change_password(oldPassword, newPassword, { + success: function (result) { + if (!result) { + Ext.MessageBox.show({ + title: _('Password'), + msg: _('Your old password was incorrect!'), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.ERROR, + iconCls: 'x-deluge-icon-error', + }); + this.oldPassword.setValue(''); + } else { + Ext.MessageBox.show({ + title: _('Change Successful'), + msg: _('Your password was successfully changed!'), + buttons: Ext.MessageBox.OK, + modal: false, + icon: Ext.MessageBox.INFO, + iconCls: 'x-deluge-icon-info', + }); + this.oldPassword.setValue(''); + this.newPassword.setValue(''); + this.confirmPassword.setValue(''); + } + }, + scope: this, + }); + }, + + onSetConfig: function () { + this.optionsManager.commit(); + }, + + onPageShow: function () { + deluge.client.web.get_config({ + success: this.onGotConfig, + scope: this, + }); + deluge.client.webutils.get_languages({ + success: this.onGotLanguages, + scope: this, + }); + deluge.client.webutils.get_themes({ + success: this.onGotThemes, + scope: this, + }); + }, + + onSSLCheck: function (e, checked) { + this.pkeyField.setDisabled(!checked); + this.certField.setDisabled(!checked); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js b/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js new file mode 100644 index 0000000..5ba98e7 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js @@ -0,0 +1,257 @@ +/** + * Deluge.preferences.NetworkPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +// custom Vtype for vtype:'IPAddress' +Ext.apply(Ext.form.VTypes, { + IPAddress: function (v) { + return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v); + }, + IPAddressText: 'Must be a numeric IP address', + IPAddressMask: /[\d\.]/i, +}); + +/** + * @class Deluge.preferences.Network + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, { + border: false, + layout: 'form', + title: _('Network'), + header: false, + + initComponent: function () { + Deluge.preferences.Network.superclass.initComponent.call(this); + var optMan = deluge.preferences.getOptionsManager(); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Incoming Address'), + style: 'margin-bottom: 5px; padding-bottom: 0px;', + autoHeight: true, + labelWidth: 1, + defaultType: 'textfield', + }); + optMan.bind( + 'listen_interface', + fieldset.add({ + name: 'listen_interface', + fieldLabel: '', + labelSeparator: '', + width: 200, + vtype: 'IPAddress', + }) + ); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Incoming Port'), + style: 'margin-bottom: 5px; padding-bottom: 0px;', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + optMan.bind( + 'random_port', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Use Random Port'), + name: 'random_port', + height: 22, + listeners: { + check: { + fn: function (e, checked) { + this.listenPort.setDisabled(checked); + }, + scope: this, + }, + }, + }) + ); + + this.listenPort = fieldset.add({ + xtype: 'spinnerfield', + name: 'listen_port', + fieldLabel: '', + labelSeparator: '', + width: 75, + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: 0, + maxValue: 65535, + }, + }); + optMan.bind('listen_ports', this.listenPort); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Outgoing Interface'), + style: 'margin-bottom: 5px; padding-bottom: 0px;', + autoHeight: true, + labelWidth: 1, + defaultType: 'textfield', + }); + optMan.bind( + 'outgoing_interface', + fieldset.add({ + name: 'outgoing_interface', + fieldLabel: '', + labelSeparator: '', + width: 40, + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Outgoing Ports'), + style: 'margin-bottom: 5px; padding-bottom: 0px;', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + optMan.bind( + 'random_outgoing_ports', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Use Random Ports'), + name: 'random_outgoing_ports', + height: 22, + listeners: { + check: { + fn: function (e, checked) { + this.outgoingPorts.setDisabled(checked); + }, + scope: this, + }, + }, + }) + ); + this.outgoingPorts = fieldset.add({ + xtype: 'spinnergroup', + name: 'outgoing_ports', + fieldLabel: '', + labelSeparator: '', + colCfg: { + labelWidth: 40, + style: 'margin-right: 10px;', + }, + items: [ + { + fieldLabel: _('From:'), + labelSeparator: '', + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: 0, + maxValue: 65535, + }, + }, + { + fieldLabel: _('To:'), + labelSeparator: '', + strategy: { + xtype: 'number', + decimalPrecision: 0, + minValue: 0, + maxValue: 65535, + }, + }, + ], + }); + optMan.bind('outgoing_ports', this.outgoingPorts); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Network Extras'), + autoHeight: true, + layout: 'table', + layoutConfig: { + columns: 3, + }, + defaultType: 'checkbox', + }); + optMan.bind( + 'upnp', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('UPnP'), + name: 'upnp', + }) + ); + optMan.bind( + 'natpmp', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('NAT-PMP'), + ctCls: 'x-deluge-indent-checkbox', + name: 'natpmp', + }) + ); + optMan.bind( + 'utpex', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('Peer Exchange'), + ctCls: 'x-deluge-indent-checkbox', + name: 'utpex', + }) + ); + optMan.bind( + 'lsd', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('LSD'), + name: 'lsd', + }) + ); + optMan.bind( + 'dht', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + boxLabel: _('DHT'), + ctCls: 'x-deluge-indent-checkbox', + name: 'dht', + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Type Of Service'), + style: 'margin-bottom: 5px; padding-bottom: 0px;', + bodyStyle: 'margin: 0px; padding: 0px', + autoHeight: true, + defaultType: 'textfield', + }); + optMan.bind( + 'peer_tos', + fieldset.add({ + name: 'peer_tos', + fieldLabel: _('Peer TOS Byte:'), + labelSeparator: '', + width: 40, + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/OtherPage.js b/deluge/ui/web/js/deluge-all/preferences/OtherPage.js new file mode 100644 index 0000000..607da22 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/OtherPage.js @@ -0,0 +1,100 @@ +/** + * Deluge.preferences.OtherPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Other + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, { + constructor: function (config) { + config = Ext.apply( + { + border: false, + title: _('Other'), + header: false, + layout: 'form', + }, + config + ); + Deluge.preferences.Other.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.preferences.Other.superclass.initComponent.call(this); + + var optMan = deluge.preferences.getOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Updates'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + optMan.bind( + 'new_release_check', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 22, + name: 'new_release_check', + boxLabel: _('Be alerted about new releases'), + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('System Information'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + fieldset.add({ + xtype: 'panel', + border: false, + bodyCfg: { + html: _( + 'Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.' + ), + }, + }); + optMan.bind( + 'send_info', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 22, + boxLabel: _('Yes, please send anonymous statistics'), + name: 'send_info', + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('GeoIP Database'), + autoHeight: true, + labelWidth: 80, + defaultType: 'textfield', + }); + optMan.bind( + 'geoip_db_location', + fieldset.add({ + name: 'geoip_db_location', + fieldLabel: _('Path:'), + labelSeparator: '', + width: 200, + }) + ); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js b/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js new file mode 100644 index 0000000..f771d96 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js @@ -0,0 +1,277 @@ +/** + * Deluge.preferences.PluginsPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Plugins + * @extends Ext.Panel + */ +Deluge.preferences.Plugins = Ext.extend(Ext.Panel, { + layout: 'border', + title: _('Plugins'), + header: false, + border: false, + cls: 'x-deluge-plugins', + + pluginTemplate: new Ext.Template( + '
' + + '
' + + _('Author:') + + '
{author}
' + + '
' + + _('Version:') + + '
{version}
' + + '
' + + _('Author Email:') + + '
{email}
' + + '
' + + _('Homepage:') + + '
{homepage}
' + + '
' + + _('Details:') + + '
{details}
' + + '
' + ), + + initComponent: function () { + Deluge.preferences.Plugins.superclass.initComponent.call(this); + this.defaultValues = { + version: '', + email: '', + homepage: '', + details: '', + }; + this.pluginTemplate.compile(); + + var checkboxRenderer = function (v, p, record) { + p.css += ' x-grid3-check-col-td'; + return ( + '
' + ); + }; + + this.list = this.add({ + xtype: 'listview', + store: new Ext.data.ArrayStore({ + fields: [ + { name: 'enabled', mapping: 0 }, + { name: 'plugin', mapping: 1, sortType: 'asUCString' }, + ], + }), + columns: [ + { + id: 'enabled', + header: _('Enabled'), + width: 0.2, + sortable: true, + tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', { + getCheckbox: function (v) { + return ( + '
' + ); + }, + }), + dataIndex: 'enabled', + }, + { + id: 'plugin', + header: _('Plugin'), + width: 0.8, + sortable: true, + dataIndex: 'plugin', + }, + ], + singleSelect: true, + autoExpandColumn: 'plugin', + listeners: { + selectionchange: { fn: this.onPluginSelect, scope: this }, + }, + }); + + this.panel = this.add({ + region: 'center', + autoScroll: true, + items: [this.list], + bbar: new Ext.Toolbar({ + items: [ + { + cls: 'x-btn-text-icon', + iconCls: 'x-deluge-install-plugin', + text: _('Install'), + handler: this.onInstallPluginWindow, + scope: this, + }, + '->', + { + cls: 'x-btn-text-icon', + text: _('Find More'), + iconCls: 'x-deluge-find-more', + handler: this.onFindMorePlugins, + scope: this, + }, + ], + }), + }); + + var pp = (this.pluginInfo = this.add({ + xtype: 'panel', + border: false, + height: 100, + region: 'south', + padding: '5', + autoScroll: true, + bodyCfg: { + style: 'white-space: nowrap', + }, + })); + + this.pluginInfo.on('render', this.onPluginInfoRender, this); + this.list.on('click', this.onNodeClick, this); + deluge.preferences.on('show', this.onPreferencesShow, this); + deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this); + deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this); + }, + + disablePlugin: function (plugin) { + deluge.client.core.disable_plugin(plugin); + }, + + enablePlugin: function (plugin) { + deluge.client.core.enable_plugin(plugin); + }, + + setInfo: function (plugin) { + if (!this.pluginInfo.rendered) return; + var values = plugin || this.defaultValues; + this.pluginInfo.body.dom.innerHTML = this.pluginTemplate.apply(values); + }, + + updatePlugins: function () { + var onGotAvailablePlugins = function (plugins) { + this.availablePlugins = plugins.sort(function (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); + + deluge.client.core.get_enabled_plugins({ + success: onGotEnabledPlugins, + scope: this, + }); + }; + + var onGotEnabledPlugins = function (plugins) { + this.enabledPlugins = plugins; + this.onGotPlugins(); + }; + + deluge.client.core.get_available_plugins({ + success: onGotAvailablePlugins, + scope: this, + }); + }, + + updatePluginsGrid: function () { + var plugins = []; + Ext.each( + this.availablePlugins, + function (plugin) { + if (this.enabledPlugins.indexOf(plugin) > -1) { + plugins.push([true, plugin]); + } else { + plugins.push([false, plugin]); + } + }, + this + ); + this.list.getStore().loadData(plugins); + }, + + onNodeClick: function (dv, index, node, e) { + var el = new Ext.Element(e.target); + if (el.getAttribute('rel') != 'chkbox') return; + + var r = dv.getStore().getAt(index); + if (r.get('plugin') == 'WebUi') return; + r.set('enabled', !r.get('enabled')); + r.commit(); + if (r.get('enabled')) { + this.enablePlugin(r.get('plugin')); + } else { + this.disablePlugin(r.get('plugin')); + } + }, + + onFindMorePlugins: function () { + window.open('http://dev.deluge-torrent.org/wiki/Plugins'); + }, + + onGotPlugins: function () { + this.setInfo(); + this.updatePluginsGrid(); + }, + + onGotPluginInfo: function (info) { + var values = { + author: info['Author'], + version: info['Version'], + email: info['Author-email'], + homepage: info['Home-page'], + details: info['Description'], + }; + this.setInfo(values); + delete info; + }, + + onInstallPluginWindow: function () { + if (!this.installWindow) { + this.installWindow = new Deluge.preferences.InstallPluginWindow(); + this.installWindow.on('pluginadded', this.onPluginInstall, this); + } + this.installWindow.show(); + }, + + onPluginEnabled: function (pluginName) { + var index = this.list.getStore().find('plugin', pluginName); + if (index == -1) return; + var plugin = this.list.getStore().getAt(index); + plugin.set('enabled', true); + plugin.commit(); + }, + + onPluginDisabled: function (pluginName) { + var index = this.list.getStore().find('plugin', pluginName); + if (index == -1) return; + var plugin = this.list.getStore().getAt(index); + plugin.set('enabled', false); + plugin.commit(); + }, + + onPluginInstall: function () { + this.updatePlugins(); + }, + + onPluginSelect: function (dv, selections) { + if (selections.length == 0) return; + var r = dv.getRecords(selections)[0]; + deluge.client.web.get_plugin_info(r.get('plugin'), { + success: this.onGotPluginInfo, + scope: this, + }); + }, + + onPreferencesShow: function () { + this.updatePlugins(); + }, + + onPluginInfoRender: function (ct, position) { + this.setInfo(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js b/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js new file mode 100644 index 0000000..4cfed01 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js @@ -0,0 +1,245 @@ +/** + * Deluge.preferences.PreferencesWindow.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +PreferencesRecord = Ext.data.Record.create([{ name: 'name', type: 'string' }]); + +/** + * @class Deluge.preferences.PreferencesWindow + * @extends Ext.Window + */ +Deluge.preferences.PreferencesWindow = Ext.extend(Ext.Window, { + /** + * @property {String} currentPage The currently selected page. + */ + currentPage: null, + + title: _('Preferences'), + layout: 'border', + width: 485, + height: 500, + border: false, + constrainHeader: true, + buttonAlign: 'right', + closeAction: 'hide', + closable: true, + iconCls: 'x-deluge-preferences', + plain: true, + resizable: false, + + pages: {}, + + initComponent: function () { + Deluge.preferences.PreferencesWindow.superclass.initComponent.call( + this + ); + + this.list = new Ext.list.ListView({ + store: new Ext.data.Store(), + columns: [ + { + id: 'name', + dataIndex: 'name', + }, + ], + singleSelect: true, + listeners: { + selectionchange: { + fn: this.onPageSelect, + scope: this, + }, + }, + hideHeaders: true, + autoExpandColumn: 'name', + deferredRender: false, + autoScroll: true, + collapsible: true, + }); + this.add({ + region: 'west', + items: [this.list], + width: 120, + margins: '0 5 0 0', + cmargins: '0 5 0 0', + }); + + this.configPanel = this.add({ + type: 'container', + autoDestroy: false, + region: 'center', + layout: 'card', + layoutConfig: { + deferredRender: true, + }, + autoScroll: true, + width: 300, + }); + + this.addButton(_('Close'), this.onClose, this); + this.addButton(_('Apply'), this.onApply, this); + this.addButton(_('OK'), this.onOk, this); + + this.optionsManager = new Deluge.OptionsManager(); + this.on('afterrender', this.onAfterRender, this); + this.on('show', this.onShow, this); + + this.initPages(); + }, + + initPages: function () { + deluge.preferences = this; + this.addPage(new Deluge.preferences.Downloads()); + this.addPage(new Deluge.preferences.Network()); + this.addPage(new Deluge.preferences.Encryption()); + this.addPage(new Deluge.preferences.Bandwidth()); + this.addPage(new Deluge.preferences.Interface()); + this.addPage(new Deluge.preferences.Other()); + this.addPage(new Deluge.preferences.Daemon()); + this.addPage(new Deluge.preferences.Queue()); + this.addPage(new Deluge.preferences.Proxy()); + this.addPage(new Deluge.preferences.Cache()); + this.addPage(new Deluge.preferences.Plugins()); + }, + + onApply: function (e) { + var changed = this.optionsManager.getDirty(); + if (!Ext.isObjectEmpty(changed)) { + // Workaround for only displaying single listen port but still pass array to core. + if ('listen_ports' in changed) { + changed.listen_ports = [ + changed.listen_ports, + changed.listen_ports, + ]; + } + deluge.client.core.set_config(changed, { + success: this.onSetConfig, + scope: this, + }); + } + + for (var page in this.pages) { + if (this.pages[page].onApply) this.pages[page].onApply(); + } + }, + + /** + * Return the options manager for the preferences window. + * @returns {Deluge.OptionsManager} the options manager + */ + getOptionsManager: function () { + return this.optionsManager; + }, + + /** + * Adds a page to the preferences window. + * @param {Mixed} page + */ + addPage: function (page) { + var store = this.list.getStore(); + var name = page.title; + store.add([new PreferencesRecord({ name: name })]); + page['bodyStyle'] = 'padding: 5px'; + page.preferences = this; + this.pages[name] = this.configPanel.add(page); + this.pages[name].index = -1; + return this.pages[name]; + }, + + /** + * Removes a preferences page from the window. + * @param {mixed} name + */ + removePage: function (page) { + var name = page.title; + var store = this.list.getStore(); + store.removeAt(store.find('name', name)); + this.configPanel.remove(page); + delete this.pages[page.title]; + }, + + /** + * Select which preferences page is displayed. + * @param {String} page The page name to change to + */ + selectPage: function (page) { + if (this.pages[page].index < 0) { + this.pages[page].index = this.configPanel.items.indexOf( + this.pages[page] + ); + } + this.list.select(this.pages[page].index); + }, + + // private + doSelectPage: function (page) { + if (this.pages[page].index < 0) { + this.pages[page].index = this.configPanel.items.indexOf( + this.pages[page] + ); + } + this.configPanel.getLayout().setActiveItem(this.pages[page].index); + this.currentPage = page; + }, + + // private + onGotConfig: function (config) { + this.getOptionsManager().set(config); + }, + + // private + onPageSelect: function (list, selections) { + var r = list.getRecord(selections[0]); + this.doSelectPage(r.get('name')); + }, + + // private + onSetConfig: function () { + this.getOptionsManager().commit(); + }, + + // private + onAfterRender: function () { + if (!this.list.getSelectionCount()) { + this.list.select(0); + } + this.configPanel.getLayout().setActiveItem(0); + }, + + // private + onShow: function () { + if (!deluge.client.core) return; + deluge.client.core.get_config({ + success: this.onGotConfig, + scope: this, + }); + }, + + // private + onClose: function () { + this.hide(); + }, + + // private + onOk: function () { + var changed = this.optionsManager.getDirty(); + if (!Ext.isObjectEmpty(changed)) { + deluge.client.core.set_config(changed, { + success: this.onSetConfig, + scope: this, + }); + } + + for (var page in this.pages) { + if (this.pages[page].onOk) this.pages[page].onOk(); + } + + this.hide(); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js new file mode 100644 index 0000000..d3bb0bf --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js @@ -0,0 +1,225 @@ +/** + * Deluge.preferences.ProxyField.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Deluge.preferences'); + +/** + * @class Deluge.preferences.ProxyField + * @extends Ext.form.FieldSet + */ +Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, { + border: false, + autoHeight: true, + labelWidth: 70, + + initComponent: function () { + Deluge.preferences.ProxyField.superclass.initComponent.call(this); + this.proxyType = this.add({ + xtype: 'combo', + fieldLabel: _('Type:'), + labelSeparator: '', + name: 'proxytype', + mode: 'local', + width: 150, + store: new Ext.data.ArrayStore({ + fields: ['id', 'text'], + data: [ + [0, _('None')], + [1, _('Socks4')], + [2, _('Socks5')], + [3, _('Socks5 Auth')], + [4, _('HTTP')], + [5, _('HTTP Auth')], + [6, _('I2P')], + ], + }), + editable: false, + triggerAction: 'all', + valueField: 'id', + displayField: 'text', + }); + this.proxyType.on('change', this.onFieldChange, this); + this.proxyType.on('select', this.onTypeSelect, this); + + this.hostname = this.add({ + xtype: 'textfield', + name: 'hostname', + fieldLabel: _('Host:'), + labelSeparator: '', + width: 220, + }); + this.hostname.on('change', this.onFieldChange, this); + + this.port = this.add({ + xtype: 'spinnerfield', + name: 'port', + fieldLabel: _('Port:'), + labelSeparator: '', + width: 80, + decimalPrecision: 0, + minValue: 0, + maxValue: 65535, + }); + this.port.on('change', this.onFieldChange, this); + + this.username = this.add({ + xtype: 'textfield', + name: 'username', + fieldLabel: _('Username:'), + labelSeparator: '', + width: 220, + }); + this.username.on('change', this.onFieldChange, this); + + this.password = this.add({ + xtype: 'textfield', + name: 'password', + fieldLabel: _('Password:'), + labelSeparator: '', + inputType: 'password', + width: 220, + }); + this.password.on('change', this.onFieldChange, this); + + this.proxy_host_resolve = this.add({ + xtype: 'checkbox', + name: 'proxy_host_resolve', + fieldLabel: '', + boxLabel: _('Proxy Hostnames'), + width: 220, + }); + this.proxy_host_resolve.on('change', this.onFieldChange, this); + + this.proxy_peer_conn = this.add({ + xtype: 'checkbox', + name: 'proxy_peer_conn', + fieldLabel: '', + boxLabel: _('Proxy Peers'), + width: 220, + }); + this.proxy_peer_conn.on('change', this.onFieldChange, this); + + this.proxy_tracker_conn = this.add({ + xtype: 'checkbox', + name: 'proxy_tracker_conn', + fieldLabel: '', + boxLabel: _('Proxy Trackers'), + width: 220, + }); + this.proxy_tracker_conn.on('change', this.onFieldChange, this); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Force Proxy'), + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + style: 'padding-left: 0px; margin-top: 10px', + }); + + this.force_proxy = fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 20, + name: 'force_proxy', + boxLabel: _('Force Use of Proxy'), + }); + this.force_proxy.on('change', this.onFieldChange, this); + + this.anonymous_mode = fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 20, + name: 'anonymous_mode', + boxLabel: _('Hide Client Identity'), + }); + this.anonymous_mode.on('change', this.onFieldChange, this); + + this.setting = false; + }, + + getName: function () { + return this.initialConfig.name; + }, + + getValue: function () { + return { + type: this.proxyType.getValue(), + hostname: this.hostname.getValue(), + port: Number(this.port.getValue()), + username: this.username.getValue(), + password: this.password.getValue(), + proxy_hostnames: this.proxy_host_resolve.getValue(), + proxy_peer_connections: this.proxy_peer_conn.getValue(), + proxy_tracker_connections: this.proxy_tracker_conn.getValue(), + force_proxy: this.force_proxy.getValue(), + anonymous_mode: this.anonymous_mode.getValue(), + }; + }, + + // Set the values of the proxies + setValue: function (value) { + this.setting = true; + this.proxyType.setValue(value['type']); + var index = this.proxyType.getStore().find('id', value['type']); + var record = this.proxyType.getStore().getAt(index); + + this.hostname.setValue(value['hostname']); + this.port.setValue(value['port']); + this.username.setValue(value['username']); + this.password.setValue(value['password']); + this.proxy_host_resolve.setValue(value['proxy_hostnames']); + this.proxy_peer_conn.setValue(value['proxy_peer_connections']); + this.proxy_tracker_conn.setValue(value['proxy_tracker_connections']); + this.force_proxy.setValue(value['force_proxy']); + this.anonymous_mode.setValue(value['anonymous_mode']); + + this.onTypeSelect(this.type, record, index); + this.setting = false; + }, + + onFieldChange: function (field, newValue, oldValue) { + if (this.setting) return; + var newValues = this.getValue(); + var oldValues = Ext.apply({}, newValues); + oldValues[field.getName()] = oldValue; + + this.fireEvent('change', this, newValues, oldValues); + }, + + onTypeSelect: function (combo, record, index) { + var typeId = record.get('id'); + if (typeId > 0) { + this.hostname.show(); + this.port.show(); + this.proxy_peer_conn.show(); + this.proxy_tracker_conn.show(); + if (typeId > 1 && typeId < 6) { + this.proxy_host_resolve.show(); + } else { + this.proxy_host_resolve.hide(); + } + } else { + this.hostname.hide(); + this.port.hide(); + this.proxy_host_resolve.hide(); + this.proxy_peer_conn.hide(); + this.proxy_tracker_conn.hide(); + } + + if (typeId == 3 || typeId == 5) { + this.username.show(); + this.password.show(); + } else { + this.username.hide(); + this.password.hide(); + } + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js new file mode 100644 index 0000000..2dc4cae --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js @@ -0,0 +1,62 @@ +/** + * Deluge.preferences.ProxyPage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Proxy + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, { + constructor: function (config) { + config = Ext.apply( + { + border: false, + title: _('Proxy'), + header: false, + layout: 'form', + autoScroll: true, + }, + config + ); + Deluge.preferences.Proxy.superclass.constructor.call(this, config); + }, + + initComponent: function () { + Deluge.preferences.Proxy.superclass.initComponent.call(this); + this.proxy = this.add( + new Deluge.preferences.ProxyField({ + title: _('Proxy'), + name: 'proxy', + }) + ); + this.proxy.on('change', this.onProxyChange, this); + deluge.preferences.getOptionsManager().bind('proxy', this.proxy); + }, + + getValue: function () { + return { + proxy: this.proxy.getValue(), + }; + }, + + setValue: function (value) { + for (var proxy in value) { + this[proxy].setValue(value[proxy]); + } + }, + + onProxyChange: function (field, newValue, oldValue) { + var newValues = this.getValue(); + var oldValues = Ext.apply({}, newValues); + oldValues[field.getName()] = oldValue; + + this.fireEvent('change', this, newValues, oldValues); + }, +}); diff --git a/deluge/ui/web/js/deluge-all/preferences/QueuePage.js b/deluge/ui/web/js/deluge-all/preferences/QueuePage.js new file mode 100644 index 0000000..c7b47c5 --- /dev/null +++ b/deluge/ui/web/js/deluge-all/preferences/QueuePage.js @@ -0,0 +1,234 @@ +/** + * Deluge.preferences.QueuePage.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Deluge.preferences'); + +/** + * @class Deluge.preferences.Queue + * @extends Ext.form.FormPanel + */ +Deluge.preferences.Queue = Ext.extend(Ext.form.FormPanel, { + border: false, + title: _('Queue'), + header: false, + layout: 'form', + + initComponent: function () { + Deluge.preferences.Queue.superclass.initComponent.call(this); + + var om = deluge.preferences.getOptionsManager(); + + var fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('New Torrents'), + style: 'padding-top: 5px; margin-bottom: 0px;', + autoHeight: true, + labelWidth: 1, + defaultType: 'checkbox', + }); + om.bind( + 'queue_new_to_top', + fieldset.add({ + fieldLabel: '', + labelSeparator: '', + height: 22, + boxLabel: _('Queue to top'), + name: 'queue_new_to_top', + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Active Torrents'), + autoHeight: true, + labelWidth: 150, + defaultType: 'spinnerfield', + style: 'padding-top: 5px; margin-bottom: 0px', + }); + om.bind( + 'max_active_limit', + fieldset.add({ + fieldLabel: _('Total:'), + labelSeparator: '', + name: 'max_active_limit', + value: 8, + width: 80, + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }) + ); + om.bind( + 'max_active_downloading', + fieldset.add({ + fieldLabel: _('Downloading:'), + labelSeparator: '', + name: 'max_active_downloading', + value: 3, + width: 80, + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }) + ); + om.bind( + 'max_active_seeding', + fieldset.add({ + fieldLabel: _('Seeding:'), + labelSeparator: '', + name: 'max_active_seeding', + value: 5, + width: 80, + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }) + ); + om.bind( + 'dont_count_slow_torrents', + fieldset.add({ + xtype: 'checkbox', + name: 'dont_count_slow_torrents', + height: 22, + hideLabel: true, + boxLabel: _('Ignore slow torrents'), + }) + ); + om.bind( + 'auto_manage_prefer_seeds', + fieldset.add({ + xtype: 'checkbox', + name: 'auto_manage_prefer_seeds', + hideLabel: true, + boxLabel: _('Prefer seeding torrents'), + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + title: _('Seeding Rotation'), + autoHeight: true, + labelWidth: 150, + defaultType: 'spinnerfield', + style: 'padding-top: 5px; margin-bottom: 0px', + }); + om.bind( + 'share_ratio_limit', + fieldset.add({ + fieldLabel: _('Share Ratio:'), + labelSeparator: '', + name: 'share_ratio_limit', + value: 8, + width: 80, + incrementValue: 0.1, + minValue: -1, + maxValue: 99999, + alternateIncrementValue: 1, + decimalPrecision: 2, + }) + ); + om.bind( + 'seed_time_ratio_limit', + fieldset.add({ + fieldLabel: _('Time Ratio:'), + labelSeparator: '', + name: 'seed_time_ratio_limit', + value: 3, + width: 80, + incrementValue: 0.1, + minValue: -1, + maxValue: 99999, + alternateIncrementValue: 1, + decimalPrecision: 2, + }) + ); + om.bind( + 'seed_time_limit', + fieldset.add({ + fieldLabel: _('Time (m):'), + labelSeparator: '', + name: 'seed_time_limit', + value: 5, + width: 80, + decimalPrecision: 0, + minValue: -1, + maxValue: 99999, + }) + ); + + fieldset = this.add({ + xtype: 'fieldset', + border: false, + autoHeight: true, + style: 'padding-top: 5px; margin-bottom: 0px', + title: _('Share Ratio Reached'), + + layout: 'table', + layoutConfig: { columns: 2 }, + labelWidth: 0, + defaultType: 'checkbox', + + defaults: { + fieldLabel: '', + labelSeparator: '', + }, + }); + this.stopAtRatio = fieldset.add({ + name: 'stop_seed_at_ratio', + boxLabel: _('Share Ratio:'), + }); + this.stopAtRatio.on('check', this.onStopRatioCheck, this); + om.bind('stop_seed_at_ratio', this.stopAtRatio); + + this.stopRatio = fieldset.add({ + xtype: 'spinnerfield', + name: 'stop_seed_ratio', + ctCls: 'x-deluge-indent-checkbox', + disabled: true, + value: '2.0', + width: 60, + incrementValue: 0.1, + minValue: -1, + maxValue: 99999, + alternateIncrementValue: 1, + decimalPrecision: 2, + }); + om.bind('stop_seed_ratio', this.stopRatio); + + this.removeAtRatio = fieldset.add({ + xtype: 'radiogroup', + columns: 1, + colspan: 2, + disabled: true, + style: 'margin-left: 10px', + items: [ + { + boxLabel: _('Pause torrent'), + name: 'at_ratio', + inputValue: false, + checked: true, + }, + { + boxLabel: _('Remove torrent'), + name: 'at_ratio', + inputValue: true, + }, + ], + }); + om.bind('remove_seed_at_ratio', this.removeAtRatio); + }, + + onStopRatioCheck: function (e, checked) { + this.stopRatio.setDisabled(!checked); + this.removeAtRatio.setDisabled(!checked); + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-all-debug.js b/deluge/ui/web/js/extjs/ext-all-debug.js new file mode 100644 index 0000000..0b15e6e --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-all-debug.js @@ -0,0 +1,52270 @@ +/* +This file is part of Ext JS 3.4 + +Copyright (c) 2011-2013 Sencha Inc + +Contact: http://www.sencha.com/contact + +GNU General Public License Usage +This file may be used under the terms of the GNU General Public License version 3.0 as +published by the Free Software Foundation and appearing in the file LICENSE included in the +packaging of this file. + +Please review the following information to ensure the GNU General Public License version 3.0 +requirements will be met: http://www.gnu.org/copyleft/gpl.html. + +If you are unsure which license is appropriate for your use, please contact the sales department +at http://www.sencha.com/contact. + +Build date: 2013-04-03 15:07:25 +*/ +(function(){ + +var EXTUTIL = Ext.util, + EACH = Ext.each, + TRUE = true, + FALSE = false; + +EXTUTIL.Observable = function(){ + + var me = this, e = me.events; + if(me.listeners){ + me.on(me.listeners); + delete me.listeners; + } + me.events = e || {}; +}; + +EXTUTIL.Observable.prototype = { + + filterOptRe : /^(?:scope|delay|buffer|single)$/, + + + fireEvent : function(){ + var a = Array.prototype.slice.call(arguments, 0), + ename = a[0].toLowerCase(), + me = this, + ret = TRUE, + ce = me.events[ename], + cc, + q, + c; + if (me.eventsSuspended === TRUE) { + if (q = me.eventQueue) { + q.push(a); + } + } + else if(typeof ce == 'object') { + if (ce.bubble){ + if(ce.fire.apply(ce, a.slice(1)) === FALSE) { + return FALSE; + } + c = me.getBubbleTarget && me.getBubbleTarget(); + if(c && c.enableBubble) { + cc = c.events[ename]; + if(!cc || typeof cc != 'object' || !cc.bubble) { + c.enableBubble(ename); + } + return c.fireEvent.apply(c, a); + } + } + else { + a.shift(); + ret = ce.fire.apply(ce, a); + } + } + return ret; + }, + + + addListener : function(eventName, fn, scope, o){ + var me = this, + e, + oe, + ce; + + if (typeof eventName == 'object') { + o = eventName; + for (e in o) { + oe = o[e]; + if (!me.filterOptRe.test(e)) { + me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o); + } + } + } else { + eventName = eventName.toLowerCase(); + ce = me.events[eventName] || TRUE; + if (typeof ce == 'boolean') { + me.events[eventName] = ce = new EXTUTIL.Event(me, eventName); + } + ce.addListener(fn, scope, typeof o == 'object' ? o : {}); + } + }, + + + removeListener : function(eventName, fn, scope){ + var ce = this.events[eventName.toLowerCase()]; + if (typeof ce == 'object') { + ce.removeListener(fn, scope); + } + }, + + + purgeListeners : function(){ + var events = this.events, + evt, + key; + for(key in events){ + evt = events[key]; + if(typeof evt == 'object'){ + evt.clearListeners(); + } + } + }, + + + addEvents : function(o){ + var me = this; + me.events = me.events || {}; + if (typeof o == 'string') { + var a = arguments, + i = a.length; + while(i--) { + me.events[a[i]] = me.events[a[i]] || TRUE; + } + } else { + Ext.applyIf(me.events, o); + } + }, + + + hasListener : function(eventName){ + var e = this.events[eventName.toLowerCase()]; + return typeof e == 'object' && e.listeners.length > 0; + }, + + + suspendEvents : function(queueSuspended){ + this.eventsSuspended = TRUE; + if(queueSuspended && !this.eventQueue){ + this.eventQueue = []; + } + }, + + + resumeEvents : function(){ + var me = this, + queued = me.eventQueue || []; + me.eventsSuspended = FALSE; + delete me.eventQueue; + EACH(queued, function(e) { + me.fireEvent.apply(me, e); + }); + } +}; + +var OBSERVABLE = EXTUTIL.Observable.prototype; + +OBSERVABLE.on = OBSERVABLE.addListener; + +OBSERVABLE.un = OBSERVABLE.removeListener; + + +EXTUTIL.Observable.releaseCapture = function(o){ + o.fireEvent = OBSERVABLE.fireEvent; +}; + +function createTargeted(h, o, scope){ + return function(){ + if(o.target == arguments[0]){ + h.apply(scope, Array.prototype.slice.call(arguments, 0)); + } + }; +}; + +function createBuffered(h, o, l, scope){ + l.task = new EXTUTIL.DelayedTask(); + return function(){ + l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0)); + }; +}; + +function createSingle(h, e, fn, scope){ + return function(){ + e.removeListener(fn, scope); + return h.apply(scope, arguments); + }; +}; + +function createDelayed(h, o, l, scope){ + return function(){ + var task = new EXTUTIL.DelayedTask(), + args = Array.prototype.slice.call(arguments, 0); + if(!l.tasks) { + l.tasks = []; + } + l.tasks.push(task); + task.delay(o.delay || 10, function(){ + l.tasks.remove(task); + h.apply(scope, args); + }, scope); + }; +}; + +EXTUTIL.Event = function(obj, name){ + this.name = name; + this.obj = obj; + this.listeners = []; +}; + +EXTUTIL.Event.prototype = { + addListener : function(fn, scope, options){ + var me = this, + l; + scope = scope || me.obj; + if(!me.isListening(fn, scope)){ + l = me.createListener(fn, scope, options); + if(me.firing){ + me.listeners = me.listeners.slice(0); + } + me.listeners.push(l); + } + }, + + createListener: function(fn, scope, o){ + o = o || {}; + scope = scope || this.obj; + var l = { + fn: fn, + scope: scope, + options: o + }, h = fn; + if(o.target){ + h = createTargeted(h, o, scope); + } + if(o.delay){ + h = createDelayed(h, o, l, scope); + } + if(o.single){ + h = createSingle(h, this, fn, scope); + } + if(o.buffer){ + h = createBuffered(h, o, l, scope); + } + l.fireFn = h; + return l; + }, + + findListener : function(fn, scope){ + var list = this.listeners, + i = list.length, + l; + + scope = scope || this.obj; + while(i--){ + l = list[i]; + if(l){ + if(l.fn == fn && l.scope == scope){ + return i; + } + } + } + return -1; + }, + + isListening : function(fn, scope){ + return this.findListener(fn, scope) != -1; + }, + + removeListener : function(fn, scope){ + var index, + l, + k, + me = this, + ret = FALSE; + if((index = me.findListener(fn, scope)) != -1){ + if (me.firing) { + me.listeners = me.listeners.slice(0); + } + l = me.listeners[index]; + if(l.task) { + l.task.cancel(); + delete l.task; + } + k = l.tasks && l.tasks.length; + if(k) { + while(k--) { + l.tasks[k].cancel(); + } + delete l.tasks; + } + me.listeners.splice(index, 1); + ret = TRUE; + } + return ret; + }, + + + clearListeners : function(){ + var me = this, + l = me.listeners, + i = l.length; + while(i--) { + me.removeListener(l[i].fn, l[i].scope); + } + }, + + fire : function(){ + var me = this, + listeners = me.listeners, + len = listeners.length, + i = 0, + l; + + if(len > 0){ + me.firing = TRUE; + var args = Array.prototype.slice.call(arguments, 0); + for (; i < len; i++) { + l = listeners[i]; + if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) { + return (me.firing = FALSE); + } + } + } + me.firing = FALSE; + return TRUE; + } + +}; +})(); + +Ext.DomHelper = function(){ + var tempTableEl = null, + emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i, + tableRe = /^table|tbody|tr|td$/i, + confRe = /tag|children|cn|html$/i, + tableElRe = /td|tr|tbody/i, + cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, + endRe = /end/i, + pub, + + afterbegin = 'afterbegin', + afterend = 'afterend', + beforebegin = 'beforebegin', + beforeend = 'beforeend', + ts = '', + te = '
', + tbs = ts+'', + tbe = ''+te, + trs = tbs + '', + tre = ''+tbe; + + + function doInsert(el, o, returnElement, pos, sibling, append){ + var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o)); + return returnElement ? Ext.get(newNode, true) : newNode; + } + + + function createHtml(o){ + var b = '', + attr, + val, + key, + cn; + + if(typeof o == "string"){ + b = o; + } else if (Ext.isArray(o)) { + for (var i=0; i < o.length; i++) { + if(o[i]) { + b += createHtml(o[i]); + } + }; + } else { + b += '<' + (o.tag = o.tag || 'div'); + for (attr in o) { + val = o[attr]; + if(!confRe.test(attr)){ + if (typeof val == "object") { + b += ' ' + attr + '="'; + for (key in val) { + b += key + ':' + val[key] + ';'; + }; + b += '"'; + }else{ + b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"'; + } + } + }; + + if (emptyTags.test(o.tag)) { + b += '/>'; + } else { + b += '>'; + if ((cn = o.children || o.cn)) { + b += createHtml(cn); + } else if(o.html){ + b += o.html; + } + b += ''; + } + } + return b; + } + + function ieTable(depth, s, h, e){ + tempTableEl.innerHTML = [s, h, e].join(''); + var i = -1, + el = tempTableEl, + ns; + while(++i < depth){ + el = el.firstChild; + } + + if(ns = el.nextSibling){ + var df = document.createDocumentFragment(); + while(el){ + ns = el.nextSibling; + df.appendChild(el); + el = ns; + } + el = df; + } + return el; + } + + + function insertIntoTable(tag, where, el, html) { + var node, + before; + + tempTableEl = tempTableEl || document.createElement('div'); + + if(tag == 'td' && (where == afterbegin || where == beforeend) || + !tableElRe.test(tag) && (where == beforebegin || where == afterend)) { + return; + } + before = where == beforebegin ? el : + where == afterend ? el.nextSibling : + where == afterbegin ? el.firstChild : null; + + if (where == beforebegin || where == afterend) { + el = el.parentNode; + } + + if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) { + node = ieTable(4, trs, html, tre); + } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) || + (tag == 'tr' && (where == beforebegin || where == afterend))) { + node = ieTable(3, tbs, html, tbe); + } else { + node = ieTable(2, ts, html, te); + } + el.insertBefore(node, before); + return node; + } + + + function createContextualFragment(html){ + var div = document.createElement("div"), + fragment = document.createDocumentFragment(), + i = 0, + length, childNodes; + + div.innerHTML = html; + childNodes = div.childNodes; + length = childNodes.length; + + for (; i < length; i++) { + fragment.appendChild(childNodes[i].cloneNode(true)); + } + + return fragment; + } + + pub = { + + markup : function(o){ + return createHtml(o); + }, + + + applyStyles : function(el, styles){ + if (styles) { + var matches; + + el = Ext.fly(el); + if (typeof styles == "function") { + styles = styles.call(); + } + if (typeof styles == "string") { + + cssRe.lastIndex = 0; + while ((matches = cssRe.exec(styles))) { + el.setStyle(matches[1], matches[2]); + } + } else if (typeof styles == "object") { + el.setStyle(styles); + } + } + }, + + insertHtml : function(where, el, html){ + var hash = {}, + hashVal, + range, + rangeEl, + setStart, + frag, + rs; + + where = where.toLowerCase(); + + hash[beforebegin] = ['BeforeBegin', 'previousSibling']; + hash[afterend] = ['AfterEnd', 'nextSibling']; + + if (el.insertAdjacentHTML) { + if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){ + return rs; + } + + hash[afterbegin] = ['AfterBegin', 'firstChild']; + hash[beforeend] = ['BeforeEnd', 'lastChild']; + if ((hashVal = hash[where])) { + el.insertAdjacentHTML(hashVal[0], html); + return el[hashVal[1]]; + } + } else { + range = el.ownerDocument.createRange(); + setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before'); + if (hash[where]) { + range[setStart](el); + if (!range.createContextualFragment) { + frag = createContextualFragment(html); + } + else { + frag = range.createContextualFragment(html); + } + el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling); + return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling']; + } else { + rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child'; + if (el.firstChild) { + range[setStart](el[rangeEl]); + if (!range.createContextualFragment) { + frag = createContextualFragment(html); + } + else { + frag = range.createContextualFragment(html); + } + if(where == afterbegin){ + el.insertBefore(frag, el.firstChild); + }else{ + el.appendChild(frag); + } + } else { + el.innerHTML = html; + } + return el[rangeEl]; + } + } + throw 'Illegal insertion point -> "' + where + '"'; + }, + + + insertBefore : function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforebegin); + }, + + + insertAfter : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterend, 'nextSibling'); + }, + + + insertFirst : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterbegin, 'firstChild'); + }, + + + append : function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforeend, '', true); + }, + + + overwrite : function(el, o, returnElement){ + el = Ext.getDom(el); + el.innerHTML = createHtml(o); + return returnElement ? Ext.get(el.firstChild) : el.firstChild; + }, + + createHtml : createHtml + }; + return pub; +}(); + +Ext.Template = function(html){ + var me = this, + a = arguments, + buf = [], + v; + + if (Ext.isArray(html)) { + html = html.join(""); + } else if (a.length > 1) { + for(var i = 0, len = a.length; i < len; i++){ + v = a[i]; + if(typeof v == 'object'){ + Ext.apply(me, v); + } else { + buf.push(v); + } + }; + html = buf.join(''); + } + + + me.html = html; + + if (me.compiled) { + me.compile(); + } +}; +Ext.Template.prototype = { + + re : /\{([\w\-]+)\}/g, + + + + applyTemplate : function(values){ + var me = this; + + return me.compiled ? + me.compiled(values) : + me.html.replace(me.re, function(m, name){ + return values[name] !== undefined ? values[name] : ""; + }); + }, + + + set : function(html, compile){ + var me = this; + me.html = html; + me.compiled = null; + return compile ? me.compile() : me; + }, + + + compile : function(){ + var me = this, + sep = Ext.isGecko ? "+" : ","; + + function fn(m, name){ + name = "values['" + name + "']"; + return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'"; + } + + eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") + + me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) + + (Ext.isGecko ? "';};" : "'].join('');};")); + return me; + }, + + + insertFirst: function(el, values, returnElement){ + return this.doInsert('afterBegin', el, values, returnElement); + }, + + + insertBefore: function(el, values, returnElement){ + return this.doInsert('beforeBegin', el, values, returnElement); + }, + + + insertAfter : function(el, values, returnElement){ + return this.doInsert('afterEnd', el, values, returnElement); + }, + + + append : function(el, values, returnElement){ + return this.doInsert('beforeEnd', el, values, returnElement); + }, + + doInsert : function(where, el, values, returnEl){ + el = Ext.getDom(el); + var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values)); + return returnEl ? Ext.get(newNode, true) : newNode; + }, + + + overwrite : function(el, values, returnElement){ + el = Ext.getDom(el); + el.innerHTML = this.applyTemplate(values); + return returnElement ? Ext.get(el.firstChild, true) : el.firstChild; + } +}; + +Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; + + +Ext.Template.from = function(el, config){ + el = Ext.getDom(el); + return new Ext.Template(el.value || el.innerHTML, config || ''); +}; + + +Ext.DomQuery = function(){ + var cache = {}, + simpleCache = {}, + valueCache = {}, + nonSpace = /\S/, + trimRe = /^\s+|\s+$/g, + tplRe = /\{(\d+)\}/g, + modeRe = /^(\s?[\/>+~]\s?|\s|$)/, + tagTokenRe = /^(#)?([\w\-\*]+)/, + nthRe = /(\d*)n\+?(\d*)/, + nthRe2 = /\D/, + + + + isIE = window.ActiveXObject ? true : false, + key = 30803; + + + + eval("var batch = 30803;"); + + + + function child(parent, index){ + var i = 0, + n = parent.firstChild; + while(n){ + if(n.nodeType == 1){ + if(++i == index){ + return n; + } + } + n = n.nextSibling; + } + return null; + } + + + function next(n){ + while((n = n.nextSibling) && n.nodeType != 1); + return n; + } + + + function prev(n){ + while((n = n.previousSibling) && n.nodeType != 1); + return n; + } + + + + function children(parent){ + var n = parent.firstChild, + nodeIndex = -1, + nextNode; + while(n){ + nextNode = n.nextSibling; + + if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ + parent.removeChild(n); + }else{ + + n.nodeIndex = ++nodeIndex; + } + n = nextNode; + } + return this; + } + + + + + function byClassName(nodeSet, cls){ + if(!cls){ + return nodeSet; + } + var result = [], ri = -1; + for(var i = 0, ci; ci = nodeSet[i]; i++){ + if((' '+ci.className+' ').indexOf(cls) != -1){ + result[++ri] = ci; + } + } + return result; + }; + + function attrValue(n, attr){ + + if(!n.tagName && typeof n.length != "undefined"){ + n = n[0]; + } + if(!n){ + return null; + } + + if(attr == "for"){ + return n.htmlFor; + } + if(attr == "class" || attr == "className"){ + return n.className; + } + return n.getAttribute(attr) || n[attr]; + + }; + + + + + + function getNodes(ns, mode, tagName){ + var result = [], ri = -1, cs; + if(!ns){ + return result; + } + tagName = tagName || "*"; + + if(typeof ns.getElementsByTagName != "undefined"){ + ns = [ns]; + } + + + + if(!mode){ + for(var i = 0, ni; ni = ns[i]; i++){ + cs = ni.getElementsByTagName(tagName); + for(var j = 0, ci; ci = cs[j]; j++){ + result[++ri] = ci; + } + } + + + } else if(mode == "/" || mode == ">"){ + var utag = tagName.toUpperCase(); + for(var i = 0, ni, cn; ni = ns[i]; i++){ + cn = ni.childNodes; + for(var j = 0, cj; cj = cn[j]; j++){ + if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){ + result[++ri] = cj; + } + } + } + + + }else if(mode == "+"){ + var utag = tagName.toUpperCase(); + for(var i = 0, n; n = ns[i]; i++){ + while((n = n.nextSibling) && n.nodeType != 1); + if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){ + result[++ri] = n; + } + } + + + }else if(mode == "~"){ + var utag = tagName.toUpperCase(); + for(var i = 0, n; n = ns[i]; i++){ + while((n = n.nextSibling)){ + if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){ + result[++ri] = n; + } + } + } + } + return result; + } + + function concat(a, b){ + if(b.slice){ + return a.concat(b); + } + for(var i = 0, l = b.length; i < l; i++){ + a[a.length] = b[i]; + } + return a; + } + + function byTag(cs, tagName){ + if(cs.tagName || cs == document){ + cs = [cs]; + } + if(!tagName){ + return cs; + } + var result = [], ri = -1; + tagName = tagName.toLowerCase(); + for(var i = 0, ci; ci = cs[i]; i++){ + if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){ + result[++ri] = ci; + } + } + return result; + } + + function byId(cs, id){ + if(cs.tagName || cs == document){ + cs = [cs]; + } + if(!id){ + return cs; + } + var result = [], ri = -1; + for(var i = 0, ci; ci = cs[i]; i++){ + if(ci && ci.id == id){ + result[++ri] = ci; + return result; + } + } + return result; + } + + + + function byAttribute(cs, attr, value, op, custom){ + var result = [], + ri = -1, + useGetStyle = custom == "{", + fn = Ext.DomQuery.operators[op], + a, + xml, + hasXml; + + for(var i = 0, ci; ci = cs[i]; i++){ + + if(ci.nodeType != 1){ + continue; + } + + if(!hasXml){ + xml = Ext.DomQuery.isXml(ci); + hasXml = true; + } + + + if(!xml){ + if(useGetStyle){ + a = Ext.DomQuery.getStyle(ci, attr); + } else if (attr == "class" || attr == "className"){ + a = ci.className; + } else if (attr == "for"){ + a = ci.htmlFor; + } else if (attr == "href"){ + + + a = ci.getAttribute("href", 2); + } else{ + a = ci.getAttribute(attr); + } + }else{ + a = ci.getAttribute(attr); + } + if((fn && fn(a, value)) || (!fn && a)){ + result[++ri] = ci; + } + } + return result; + } + + function byPseudo(cs, name, value){ + return Ext.DomQuery.pseudos[name](cs, value); + } + + function nodupIEXml(cs){ + var d = ++key, + r; + cs[0].setAttribute("_nodup", d); + r = [cs[0]]; + for(var i = 1, len = cs.length; i < len; i++){ + var c = cs[i]; + if(!c.getAttribute("_nodup") != d){ + c.setAttribute("_nodup", d); + r[r.length] = c; + } + } + for(var i = 0, len = cs.length; i < len; i++){ + cs[i].removeAttribute("_nodup"); + } + return r; + } + + function nodup(cs){ + if(!cs){ + return []; + } + var len = cs.length, c, i, r = cs, cj, ri = -1; + if(!len || typeof cs.nodeType != "undefined" || len == 1){ + return cs; + } + if(isIE && typeof cs[0].selectSingleNode != "undefined"){ + return nodupIEXml(cs); + } + var d = ++key; + cs[0]._nodup = d; + for(i = 1; c = cs[i]; i++){ + if(c._nodup != d){ + c._nodup = d; + }else{ + r = []; + for(var j = 0; j < i; j++){ + r[++ri] = cs[j]; + } + for(j = i+1; cj = cs[j]; j++){ + if(cj._nodup != d){ + cj._nodup = d; + r[++ri] = cj; + } + } + return r; + } + } + return r; + } + + function quickDiffIEXml(c1, c2){ + var d = ++key, + r = []; + for(var i = 0, len = c1.length; i < len; i++){ + c1[i].setAttribute("_qdiff", d); + } + for(var i = 0, len = c2.length; i < len; i++){ + if(c2[i].getAttribute("_qdiff") != d){ + r[r.length] = c2[i]; + } + } + for(var i = 0, len = c1.length; i < len; i++){ + c1[i].removeAttribute("_qdiff"); + } + return r; + } + + function quickDiff(c1, c2){ + var len1 = c1.length, + d = ++key, + r = []; + if(!len1){ + return c2; + } + if(isIE && typeof c1[0].selectSingleNode != "undefined"){ + return quickDiffIEXml(c1, c2); + } + for(var i = 0; i < len1; i++){ + c1[i]._qdiff = d; + } + for(var i = 0, len = c2.length; i < len; i++){ + if(c2[i]._qdiff != d){ + r[r.length] = c2[i]; + } + } + return r; + } + + function quickId(ns, mode, root, id){ + if(ns == root){ + var d = root.ownerDocument || root; + return d.getElementById(id); + } + ns = getNodes(ns, mode, "*"); + return byId(ns, id); + } + + return { + getStyle : function(el, name){ + return Ext.fly(el).getStyle(name); + }, + + compile : function(path, type){ + type = type || "select"; + + + var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"], + mode, + lastPath, + matchers = Ext.DomQuery.matchers, + matchersLn = matchers.length, + modeMatch, + + lmode = path.match(modeRe); + + if(lmode && lmode[1]){ + fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";'; + path = path.replace(lmode[1], ""); + } + + + while(path.substr(0, 1)=="/"){ + path = path.substr(1); + } + + while(path && lastPath != path){ + lastPath = path; + var tokenMatch = path.match(tagTokenRe); + if(type == "select"){ + if(tokenMatch){ + + if(tokenMatch[1] == "#"){ + fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");'; + }else{ + fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");'; + } + path = path.replace(tokenMatch[0], ""); + }else if(path.substr(0, 1) != '@'){ + fn[fn.length] = 'n = getNodes(n, mode, "*");'; + } + + }else{ + if(tokenMatch){ + if(tokenMatch[1] == "#"){ + fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");'; + }else{ + fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");'; + } + path = path.replace(tokenMatch[0], ""); + } + } + while(!(modeMatch = path.match(modeRe))){ + var matched = false; + for(var j = 0; j < matchersLn; j++){ + var t = matchers[j]; + var m = path.match(t.re); + if(m){ + fn[fn.length] = t.select.replace(tplRe, function(x, i){ + return m[i]; + }); + path = path.replace(m[0], ""); + matched = true; + break; + } + } + + if(!matched){ + throw 'Error parsing selector, parsing failed at "' + path + '"'; + } + } + if(modeMatch[1]){ + fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";'; + path = path.replace(modeMatch[1], ""); + } + } + + fn[fn.length] = "return nodup(n);\n}"; + + + eval(fn.join("")); + return f; + }, + + + jsSelect: function(path, root, type){ + + root = root || document; + + if(typeof root == "string"){ + root = document.getElementById(root); + } + var paths = path.split(","), + results = []; + + + for(var i = 0, len = paths.length; i < len; i++){ + var subPath = paths[i].replace(trimRe, ""); + + if(!cache[subPath]){ + cache[subPath] = Ext.DomQuery.compile(subPath); + if(!cache[subPath]){ + throw subPath + " is not a valid selector"; + } + } + var result = cache[subPath](root); + if(result && result != document){ + results = results.concat(result); + } + } + + + + if(paths.length > 1){ + return nodup(results); + } + return results; + }, + isXml: function(el) { + var docEl = (el ? el.ownerDocument || el : 0).documentElement; + return docEl ? docEl.nodeName !== "HTML" : false; + }, + select : document.querySelectorAll ? function(path, root, type) { + root = root || document; + if (!Ext.DomQuery.isXml(root)) { + try { + var cs = root.querySelectorAll(path); + return Ext.toArray(cs); + } + catch (ex) {} + } + return Ext.DomQuery.jsSelect.call(this, path, root, type); + } : function(path, root, type) { + return Ext.DomQuery.jsSelect.call(this, path, root, type); + }, + + + selectNode : function(path, root){ + return Ext.DomQuery.select(path, root)[0]; + }, + + + selectValue : function(path, root, defaultValue){ + path = path.replace(trimRe, ""); + if(!valueCache[path]){ + valueCache[path] = Ext.DomQuery.compile(path, "select"); + } + var n = valueCache[path](root), v; + n = n[0] ? n[0] : n; + + + + + + if (typeof n.normalize == 'function') n.normalize(); + + v = (n && n.firstChild ? n.firstChild.nodeValue : null); + return ((v === null||v === undefined||v==='') ? defaultValue : v); + }, + + + selectNumber : function(path, root, defaultValue){ + var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0); + return parseFloat(v); + }, + + + is : function(el, ss){ + if(typeof el == "string"){ + el = document.getElementById(el); + } + var isArray = Ext.isArray(el), + result = Ext.DomQuery.filter(isArray ? el : [el], ss); + return isArray ? (result.length == el.length) : (result.length > 0); + }, + + + filter : function(els, ss, nonMatches){ + ss = ss.replace(trimRe, ""); + if(!simpleCache[ss]){ + simpleCache[ss] = Ext.DomQuery.compile(ss, "simple"); + } + var result = simpleCache[ss](els); + return nonMatches ? quickDiff(result, els) : result; + }, + + + matchers : [{ + re: /^\.([\w\-]+)/, + select: 'n = byClassName(n, " {1} ");' + }, { + re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, + select: 'n = byPseudo(n, "{1}", "{2}");' + },{ + re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/, + select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");' + }, { + re: /^#([\w\-]+)/, + select: 'n = byId(n, "{1}");' + },{ + re: /^@([\w\-]+)/, + select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};' + } + ], + + /** + * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=. + * New operators can be added as long as the match the format c= where c is any character other than space, > <. + */ + operators : { + "=" : function(a, v){ + return a == v; + }, + "!=" : function(a, v){ + return a != v; + }, + "^=" : function(a, v){ + return a && a.substr(0, v.length) == v; + }, + "$=" : function(a, v){ + return a && a.substr(a.length-v.length) == v; + }, + "*=" : function(a, v){ + return a && a.indexOf(v) !== -1; + }, + "%=" : function(a, v){ + return (a % v) == 0; + }, + "|=" : function(a, v){ + return a && (a == v || a.substr(0, v.length+1) == v+'-'); + }, + "~=" : function(a, v){ + return a && (' '+a+' ').indexOf(' '+v+' ') != -1; + } + }, + + /** + *

Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed + * two parameters:

    + *
  • c : Array
    An Array of DOM elements to filter.
  • + *
  • v : String
    The argument (if any) supplied in the selector.
  • + *
+ *

A filter function returns an Array of DOM elements which conform to the pseudo class.

+ *

In addition to the provided pseudo classes listed above such as first-child and nth-child, + * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.

+ *

For example, to filter <a> elements to only return links to external resources:

+ *
+Ext.DomQuery.pseudos.external = function(c, v){
+    var r = [], ri = -1;
+    for(var i = 0, ci; ci = c[i]; i++){
+//      Include in result set only if it's a link to an external resource
+        if(ci.hostname != location.hostname){
+            r[++ri] = ci;
+        }
+    }
+    return r;
+};
+ * Then external links could be gathered with the following statement:
+var externalLinks = Ext.select("a:external");
+
+ */ + pseudos : { + "first-child" : function(c){ + var r = [], ri = -1, n; + for(var i = 0, ci; ci = n = c[i]; i++){ + while((n = n.previousSibling) && n.nodeType != 1); + if(!n){ + r[++ri] = ci; + } + } + return r; + }, + + "last-child" : function(c){ + var r = [], ri = -1, n; + for(var i = 0, ci; ci = n = c[i]; i++){ + while((n = n.nextSibling) && n.nodeType != 1); + if(!n){ + r[++ri] = ci; + } + } + return r; + }, + + "nth-child" : function(c, a) { + var r = [], ri = -1, + m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), + f = (m[1] || 1) - 0, l = m[2] - 0; + for(var i = 0, n; n = c[i]; i++){ + var pn = n.parentNode; + if (batch != pn._batch) { + var j = 0; + for(var cn = pn.firstChild; cn; cn = cn.nextSibling){ + if(cn.nodeType == 1){ + cn.nodeIndex = ++j; + } + } + pn._batch = batch; + } + if (f == 1) { + if (l == 0 || n.nodeIndex == l){ + r[++ri] = n; + } + } else if ((n.nodeIndex + l) % f == 0){ + r[++ri] = n; + } + } + + return r; + }, + + "only-child" : function(c){ + var r = [], ri = -1;; + for(var i = 0, ci; ci = c[i]; i++){ + if(!prev(ci) && !next(ci)){ + r[++ri] = ci; + } + } + return r; + }, + + "empty" : function(c){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var cns = ci.childNodes, j = 0, cn, empty = true; + while(cn = cns[j]){ + ++j; + if(cn.nodeType == 1 || cn.nodeType == 3){ + empty = false; + break; + } + } + if(empty){ + r[++ri] = ci; + } + } + return r; + }, + + "contains" : function(c, v){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if((ci.textContent||ci.innerText||'').indexOf(v) != -1){ + r[++ri] = ci; + } + } + return r; + }, + + "nodeValue" : function(c, v){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(ci.firstChild && ci.firstChild.nodeValue == v){ + r[++ri] = ci; + } + } + return r; + }, + + "checked" : function(c){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(ci.checked == true){ + r[++ri] = ci; + } + } + return r; + }, + + "not" : function(c, ss){ + return Ext.DomQuery.filter(c, ss, true); + }, + + "any" : function(c, selectors){ + var ss = selectors.split('|'), + r = [], ri = -1, s; + for(var i = 0, ci; ci = c[i]; i++){ + for(var j = 0; s = ss[j]; j++){ + if(Ext.DomQuery.is(ci, s)){ + r[++ri] = ci; + break; + } + } + } + return r; + }, + + "odd" : function(c){ + return this["nth-child"](c, "odd"); + }, + + "even" : function(c){ + return this["nth-child"](c, "even"); + }, + + "nth" : function(c, a){ + return c[a-1] || []; + }, + + "first" : function(c){ + return c[0] || []; + }, + + "last" : function(c){ + return c[c.length-1] || []; + }, + + "has" : function(c, ss){ + var s = Ext.DomQuery.select, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(s(ss, ci).length > 0){ + r[++ri] = ci; + } + } + return r; + }, + + "next" : function(c, ss){ + var is = Ext.DomQuery.is, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var n = next(ci); + if(n && is(n, ss)){ + r[++ri] = ci; + } + } + return r; + }, + + "prev" : function(c, ss){ + var is = Ext.DomQuery.is, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var n = prev(ci); + if(n && is(n, ss)){ + r[++ri] = ci; + } + } + return r; + } + } + }; +}(); + +/** + * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select} + * @param {String} path The selector/xpath query + * @param {Node} root (optional) The start of the query (defaults to document). + * @return {Array} + * @member Ext + * @method query + */ +Ext.query = Ext.DomQuery.select; +/** + * @class Ext.util.DelayedTask + *

The DelayedTask class provides a convenient way to "buffer" the execution of a method, + * performing setTimeout where a new timeout cancels the old timeout. When called, the + * task will wait the specified time period before executing. If durng that time period, + * the task is called again, the original call will be cancelled. This continues so that + * the function is only called a single time for each iteration.

+ *

This method is especially useful for things like detecting whether a user has finished + * typing in a text field. An example would be performing validation on a keypress. You can + * use this class to buffer the keypress events for a certain number of milliseconds, and + * perform only if they stop for that amount of time. Usage:


+var task = new Ext.util.DelayedTask(function(){
+    alert(Ext.getDom('myInputField').value.length);
+});
+// Wait 500ms before calling our function. If the user presses another key
+// during that 500ms, it will be cancelled and we'll wait another 500ms.
+Ext.get('myInputField').on('keypress', function(){
+    task.{@link #delay}(500);
+});
+ * 
+ *

Note that we are using a DelayedTask here to illustrate a point. The configuration + * option buffer for {@link Ext.util.Observable#addListener addListener/on} will + * also setup a delayed task for you to buffer events.

+ * @constructor The parameters to this constructor serve as defaults and are not required. + * @param {Function} fn (optional) The default function to call. + * @param {Object} scope (optional) The default scope (The this reference) in which the + * function is called. If not specified, this will refer to the browser window. + * @param {Array} args (optional) The default Array of arguments. + */ +Ext.util.DelayedTask = function(fn, scope, args){ + var me = this, + id, + call = function(){ + clearInterval(id); + id = null; + fn.apply(scope, args || []); + }; + + /** + * Cancels any pending timeout and queues a new one + * @param {Number} delay The milliseconds to delay + * @param {Function} newFn (optional) Overrides function passed to constructor + * @param {Object} newScope (optional) Overrides scope passed to constructor. Remember that if no scope + * is specified, this will refer to the browser window. + * @param {Array} newArgs (optional) Overrides args passed to constructor + */ + me.delay = function(delay, newFn, newScope, newArgs){ + me.cancel(); + fn = newFn || fn; + scope = newScope || scope; + args = newArgs || args; + id = setInterval(call, delay); + }; + + /** + * Cancel the last queued timeout + */ + me.cancel = function(){ + if(id){ + clearInterval(id); + id = null; + } + }; +};/** + * @class Ext.Element + *

Encapsulates a DOM element, adding simple DOM manipulation facilities, normalizing for browser differences.

+ *

All instances of this class inherit the methods of {@link Ext.Fx} making visual effects easily available to all DOM elements.

+ *

Note that the events documented in this class are not Ext events, they encapsulate browser events. To + * access the underlying browser event, see {@link Ext.EventObject#browserEvent}. Some older + * browsers may not support the full range of events. Which events are supported is beyond the control of ExtJs.

+ * Usage:
+

+// by id
+var el = Ext.get("my-div");
+
+// by DOM element reference
+var el = Ext.get(myDivElement);
+
+ * Animations
+ *

When an element is manipulated, by default there is no animation.

+ *

+var el = Ext.get("my-div");
+
+// no animation
+el.setWidth(100);
+ * 
+ *

Many of the functions for manipulating an element have an optional "animate" parameter. This + * parameter can be specified as boolean (true) for default animation effects.

+ *

+// default animation
+el.setWidth(100, true);
+ * 
+ * + *

To configure the effects, an object literal with animation options to use as the Element animation + * configuration object can also be specified. Note that the supported Element animation configuration + * options are a subset of the {@link Ext.Fx} animation options specific to Fx effects. The supported + * Element animation configuration options are:

+
+Option    Default   Description
+--------- --------  ---------------------------------------------
+{@link Ext.Fx#duration duration}  .35       The duration of the animation in seconds
+{@link Ext.Fx#easing easing}    easeOut   The easing method
+{@link Ext.Fx#callback callback}  none      A function to execute when the anim completes
+{@link Ext.Fx#scope scope}     this      The scope (this) of the callback function
+
+ * + *

+// Element animation options object
+var opt = {
+    {@link Ext.Fx#duration duration}: 1,
+    {@link Ext.Fx#easing easing}: 'elasticIn',
+    {@link Ext.Fx#callback callback}: this.foo,
+    {@link Ext.Fx#scope scope}: this
+};
+// animation with some options set
+el.setWidth(100, opt);
+ * 
+ *

The Element animation object being used for the animation will be set on the options + * object as "anim", which allows you to stop or manipulate the animation. Here is an example:

+ *

+// using the "anim" property to get the Anim object
+if(opt.anim.isAnimated()){
+    opt.anim.stop();
+}
+ * 
+ *

Also see the {@link #animate} method for another animation technique.

+ *

Composite (Collections of) Elements

+ *

For working with collections of Elements, see {@link Ext.CompositeElement}

+ * @constructor Create a new Element directly. + * @param {String/HTMLElement} element + * @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class). + */ +(function(){ +var DOC = document; + +Ext.Element = function(element, forceNew){ + var dom = typeof element == "string" ? + DOC.getElementById(element) : element, + id; + + if(!dom) return null; + + id = dom.id; + + if(!forceNew && id && Ext.elCache[id]){ // element object already exists + return Ext.elCache[id].el; + } + + /** + * The DOM element + * @type HTMLElement + */ + this.dom = dom; + + /** + * The DOM element ID + * @type String + */ + this.id = id || Ext.id(dom); +}; + +var DH = Ext.DomHelper, + El = Ext.Element, + EC = Ext.elCache; + +El.prototype = { + /** + * Sets the passed attributes as attributes of this element (a style attribute can be a string, object or function) + * @param {Object} o The object with the attributes + * @param {Boolean} useSet (optional) false to override the default setAttribute to use expandos. + * @return {Ext.Element} this + */ + set : function(o, useSet){ + var el = this.dom, + attr, + val, + useSet = (useSet !== false) && !!el.setAttribute; + + for (attr in o) { + if (o.hasOwnProperty(attr)) { + val = o[attr]; + if (attr == 'style') { + DH.applyStyles(el, val); + } else if (attr == 'cls') { + el.className = val; + } else if (useSet) { + el.setAttribute(attr, val); + } else { + el[attr] = val; + } + } + } + return this; + }, + +// Mouse events + /** + * @event click + * Fires when a mouse click is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event contextmenu + * Fires when a right click is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event dblclick + * Fires when a mouse double click is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mousedown + * Fires when a mousedown is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mouseup + * Fires when a mouseup is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mouseover + * Fires when a mouseover is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mousemove + * Fires when a mousemove is detected with the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mouseout + * Fires when a mouseout is detected with the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mouseenter + * Fires when the mouse enters the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event mouseleave + * Fires when the mouse leaves the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + +// Keyboard events + /** + * @event keypress + * Fires when a keypress is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event keydown + * Fires when a keydown is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event keyup + * Fires when a keyup is detected within the element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + + +// HTML frame/object events + /** + * @event load + * Fires when the user agent finishes loading all content within the element. Only supported by window, frames, objects and images. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event unload + * Fires when the user agent removes all content from a window or frame. For elements, it fires when the target element or any of its content has been removed. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event abort + * Fires when an object/image is stopped from loading before completely loaded. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event error + * Fires when an object/image/frame cannot be loaded properly. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event resize + * Fires when a document view is resized. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event scroll + * Fires when a document view is scrolled. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + +// Form events + /** + * @event select + * Fires when a user selects some text in a text field, including input and textarea. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event change + * Fires when a control loses the input focus and its value has been modified since gaining focus. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event submit + * Fires when a form is submitted. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event reset + * Fires when a form is reset. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event focus + * Fires when an element receives focus either via the pointing device or by tab navigation. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event blur + * Fires when an element loses focus either via the pointing device or by tabbing navigation. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + +// User Interface events + /** + * @event DOMFocusIn + * Where supported. Similar to HTML focus event, but can be applied to any focusable element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMFocusOut + * Where supported. Similar to HTML blur event, but can be applied to any focusable element. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMActivate + * Where supported. Fires when an element is activated, for instance, through a mouse click or a keypress. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + +// DOM Mutation events + /** + * @event DOMSubtreeModified + * Where supported. Fires when the subtree is modified. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMNodeInserted + * Where supported. Fires when a node has been added as a child of another node. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMNodeRemoved + * Where supported. Fires when a descendant node of the element is removed. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMNodeRemovedFromDocument + * Where supported. Fires when a node is being removed from a document. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMNodeInsertedIntoDocument + * Where supported. Fires when a node is being inserted into a document. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMAttrModified + * Where supported. Fires when an attribute has been modified. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + /** + * @event DOMCharacterDataModified + * Where supported. Fires when the character data has been modified. + * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event. + * @param {HtmlElement} t The target of the event. + * @param {Object} o The options configuration passed to the {@link #addListener} call. + */ + + /** + * The default unit to append to CSS values where a unit isn't provided (defaults to px). + * @type String + */ + defaultUnit : "px", + + /** + * Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child) + * @param {String} selector The simple selector to test + * @return {Boolean} True if this element matches the selector, else false + */ + is : function(simpleSelector){ + return Ext.DomQuery.is(this.dom, simpleSelector); + }, + + /** + * Tries to focus the element. Any exceptions are caught and ignored. + * @param {Number} defer (optional) Milliseconds to defer the focus + * @return {Ext.Element} this + */ + focus : function(defer, /* private */ dom) { + var me = this, + dom = dom || me.dom; + try{ + if(Number(defer)){ + me.focus.defer(defer, null, [null, dom]); + }else{ + dom.focus(); + } + }catch(e){} + return me; + }, + + /** + * Tries to blur the element. Any exceptions are caught and ignored. + * @return {Ext.Element} this + */ + blur : function() { + try{ + this.dom.blur(); + }catch(e){} + return this; + }, + + /** + * Returns the value of the "value" attribute + * @param {Boolean} asNumber true to parse the value as a number + * @return {String/Number} + */ + getValue : function(asNumber){ + var val = this.dom.value; + return asNumber ? parseInt(val, 10) : val; + }, + + /** + * Appends an event handler to this element. The shorthand version {@link #on} is equivalent. + * @param {String} eventName The name of event to handle. + * @param {Function} fn The handler function the event invokes. This function is passed + * the following parameters:
    + *
  • evt : EventObject
    The {@link Ext.EventObject EventObject} describing the event.
  • + *
  • el : HtmlElement
    The DOM element which was the target of the event. + * Note that this may be filtered by using the delegate option.
  • + *
  • o : Object
    The options object from the addListener call.
  • + *
+ * @param {Object} scope (optional) The scope (this reference) in which the handler function is executed. + * If omitted, defaults to this Element.. + * @param {Object} options (optional) An object containing handler configuration properties. + * This may contain any of the following properties:
    + *
  • scope Object :
    The scope (this reference) in which the handler function is executed. + * If omitted, defaults to this Element.
  • + *
  • delegate String:
    A simple selector to filter the target or look for a descendant of the target. See below for additional details.
  • + *
  • stopEvent Boolean:
    True to stop the event. That is stop propagation, and prevent the default action.
  • + *
  • preventDefault Boolean:
    True to prevent the default action
  • + *
  • stopPropagation Boolean:
    True to prevent event propagation
  • + *
  • normalized Boolean:
    False to pass a browser event to the handler function instead of an Ext.EventObject
  • + *
  • target Ext.Element:
    Only call the handler if the event was fired on the target Element, not if the event was bubbled up from a child node.
  • + *
  • delay Number:
    The number of milliseconds to delay the invocation of the handler after the event fires.
  • + *
  • single Boolean:
    True to add a handler to handle just the next firing of the event, and then remove itself.
  • + *
  • buffer Number:
    Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed + * by the specified number of milliseconds. If the event fires again within that time, the original + * handler is not invoked, but the new handler is scheduled in its place.
  • + *

+ *

+ * Combining Options
+ * In the following examples, the shorthand form {@link #on} is used rather than the more verbose + * addListener. The two are equivalent. Using the options argument, it is possible to combine different + * types of listeners:
+ *
+ * A delayed, one-time listener that auto stops the event and adds a custom argument (forumId) to the + * options object. The options object is available as the third parameter in the handler function.

+ * Code:

+el.on('click', this.onClick, this, {
+    single: true,
+    delay: 100,
+    stopEvent : true,
+    forumId: 4
+});

+ *

+ * Attaching multiple handlers in 1 call
+ * The method also allows for a single argument to be passed which is a config object containing properties + * which specify multiple handlers.

+ *

+ * Code:


+el.on({
+    'click' : {
+        fn: this.onClick,
+        scope: this,
+        delay: 100
+    },
+    'mouseover' : {
+        fn: this.onMouseOver,
+        scope: this
+    },
+    'mouseout' : {
+        fn: this.onMouseOut,
+        scope: this
+    }
+});
+ *

+ * Or a shorthand syntax:
+ * Code:

+el.on({ + 'click' : this.onClick, + 'mouseover' : this.onMouseOver, + 'mouseout' : this.onMouseOut, + scope: this +}); + *

+ *

delegate

+ *

This is a configuration option that you can pass along when registering a handler for + * an event to assist with event delegation. Event delegation is a technique that is used to + * reduce memory consumption and prevent exposure to memory-leaks. By registering an event + * for a container element as opposed to each element within a container. By setting this + * configuration option to a simple selector, the target element will be filtered to look for + * a descendant of the target. + * For example:


+// using this markup:
+<div id='elId'>
+    <p id='p1'>paragraph one</p>
+    <p id='p2' class='clickable'>paragraph two</p>
+    <p id='p3'>paragraph three</p>
+</div>
+// utilize event delegation to registering just one handler on the container element:
+el = Ext.get('elId');
+el.on(
+    'click',
+    function(e,t) {
+        // handle click
+        console.info(t.id); // 'p2'
+    },
+    this,
+    {
+        // filter the target element to be a descendant with the class 'clickable'
+        delegate: '.clickable'
+    }
+);
+     * 

+ * @return {Ext.Element} this + */ + addListener : function(eventName, fn, scope, options){ + Ext.EventManager.on(this.dom, eventName, fn, scope || this, options); + return this; + }, + + /** + * Removes an event handler from this element. The shorthand version {@link #un} is equivalent. + * Note: if a scope was explicitly specified when {@link #addListener adding} the + * listener, the same scope must be specified here. + * Example: + *

+el.removeListener('click', this.handlerFn);
+// or
+el.un('click', this.handlerFn);
+
+ * @param {String} eventName The name of the event from which to remove the handler. + * @param {Function} fn The handler function to remove. This must be a reference to the function passed into the {@link #addListener} call. + * @param {Object} scope If a scope (this reference) was specified when the listener was added, + * then this must refer to the same object. + * @return {Ext.Element} this + */ + removeListener : function(eventName, fn, scope){ + Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this); + return this; + }, + + /** + * Removes all previous added listeners from this element + * @return {Ext.Element} this + */ + removeAllListeners : function(){ + Ext.EventManager.removeAll(this.dom); + return this; + }, + + /** + * Recursively removes all previous added listeners from this element and its children + * @return {Ext.Element} this + */ + purgeAllListeners : function() { + Ext.EventManager.purgeElement(this, true); + return this; + }, + /** + * @private Test if size has a unit, otherwise appends the default + */ + addUnits : function(size){ + if(size === "" || size == "auto" || size === undefined){ + size = size || ''; + } else if(!isNaN(size) || !unitPattern.test(size)){ + size = size + (this.defaultUnit || 'px'); + } + return size; + }, + + /** + *

Updates the Same Origin Policy

+ *

Updating innerHTML of an element will not execute embedded <script> elements. This is a browser restriction.

+ * @param {Mixed} options. Either a sring containing the URL from which to load the HTML, or an {@link Ext.Ajax#request} options object specifying + * exactly how to request the HTML. + * @return {Ext.Element} this + */ + load : function(url, params, cb){ + Ext.Ajax.request(Ext.apply({ + params: params, + url: url.url || url, + callback: cb, + el: this.dom, + indicatorText: url.indicatorText || '' + }, Ext.isObject(url) ? url : {})); + return this; + }, + + + isBorderBox : function(){ + return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()]; + }, + + + remove : function(){ + var me = this, + dom = me.dom; + + if (dom) { + delete me.dom; + Ext.removeNode(dom); + } + }, + + + hover : function(overFn, outFn, scope, options){ + var me = this; + me.on('mouseenter', overFn, scope || me.dom, options); + me.on('mouseleave', outFn, scope || me.dom, options); + return me; + }, + + + contains : function(el){ + return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el); + }, + + + getAttributeNS : function(ns, name){ + return this.getAttribute(name, ns); + }, + + + getAttribute: (function(){ + var test = document.createElement('table'), + isBrokenOnTable = false, + hasGetAttribute = 'getAttribute' in test, + unknownRe = /undefined|unknown/; + + if (hasGetAttribute) { + + try { + test.getAttribute('ext:qtip'); + } catch (e) { + isBrokenOnTable = true; + } + + return function(name, ns) { + var el = this.dom, + value; + + if (el.getAttributeNS) { + value = el.getAttributeNS(ns, name) || null; + } + + if (value == null) { + if (ns) { + if (isBrokenOnTable && el.tagName.toUpperCase() == 'TABLE') { + try { + value = el.getAttribute(ns + ':' + name); + } catch (e) { + value = ''; + } + } else { + value = el.getAttribute(ns + ':' + name); + } + } else { + value = el.getAttribute(name) || el[name]; + } + } + return value || ''; + }; + } else { + return function(name, ns) { + var el = this.om, + value, + attribute; + + if (ns) { + attribute = el[ns + ':' + name]; + value = unknownRe.test(typeof attribute) ? undefined : attribute; + } else { + value = el[name]; + } + return value || ''; + }; + } + test = null; + })(), + + + update : function(html) { + if (this.dom) { + this.dom.innerHTML = html; + } + return this; + } +}; + +var ep = El.prototype; + +El.addMethods = function(o){ + Ext.apply(ep, o); +}; + + +ep.on = ep.addListener; + + +ep.un = ep.removeListener; + + +ep.autoBoxAdjust = true; + + +var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, + docEl; + + +El.get = function(el){ + var ex, + elm, + id; + if(!el){ return null; } + if (typeof el == "string") { + if (!(elm = DOC.getElementById(el))) { + return null; + } + if (EC[el] && EC[el].el) { + ex = EC[el].el; + ex.dom = elm; + } else { + ex = El.addToCache(new El(elm)); + } + return ex; + } else if (el.tagName) { + if(!(id = el.id)){ + id = Ext.id(el); + } + if (EC[id] && EC[id].el) { + ex = EC[id].el; + ex.dom = el; + } else { + ex = El.addToCache(new El(el)); + } + return ex; + } else if (el instanceof El) { + if(el != docEl){ + + + + + if (Ext.isIE && (el.id == undefined || el.id == '')) { + el.dom = el.dom; + } else { + el.dom = DOC.getElementById(el.id) || el.dom; + } + } + return el; + } else if(el.isComposite) { + return el; + } else if(Ext.isArray(el)) { + return El.select(el); + } else if(el == DOC) { + + if(!docEl){ + var f = function(){}; + f.prototype = El.prototype; + docEl = new f(); + docEl.dom = DOC; + } + return docEl; + } + return null; +}; + +El.addToCache = function(el, id){ + id = id || el.id; + EC[id] = { + el: el, + data: {}, + events: {} + }; + return el; +}; + + +El.data = function(el, key, value){ + el = El.get(el); + if (!el) { + return null; + } + var c = EC[el.id].data; + if(arguments.length == 2){ + return c[key]; + }else{ + return (c[key] = value); + } +}; + + + + +function garbageCollect(){ + if(!Ext.enableGarbageCollector){ + clearInterval(El.collectorThreadId); + } else { + var eid, + el, + d, + o; + + for(eid in EC){ + o = EC[eid]; + if(o.skipGC){ + Ext.EventManager.removeFromSpecialCache(o.el); + continue; + } + el = o.el; + d = el.dom; + + + + + + + + + + + + + + + + + + if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){ + if(Ext.enableListenerCollection){ + Ext.EventManager.removeAll(d); + } + delete EC[eid]; + } + } + + if (Ext.isIE) { + var t = {}; + for (eid in EC) { + t[eid] = EC[eid]; + } + EC = Ext.elCache = t; + } + } +} +El.collectorThreadId = setInterval(garbageCollect, 30000); + +var flyFn = function(){}; +flyFn.prototype = El.prototype; + + +El.Flyweight = function(dom){ + this.dom = dom; +}; + +El.Flyweight.prototype = new flyFn(); +El.Flyweight.prototype.isFlyweight = true; +El._flyweights = {}; + + +El.fly = function(el, named){ + var ret = null; + named = named || '_global'; + + if (el = Ext.getDom(el)) { + (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el; + ret = El._flyweights[named]; + } + return ret; +}; + + +Ext.get = El.get; + + +Ext.fly = El.fly; + + +var noBoxAdjust = Ext.isStrict ? { + select:1 +} : { + input:1, select:1, textarea:1 +}; +if(Ext.isIE || Ext.isGecko){ + noBoxAdjust['button'] = 1; +} + +})(); + +Ext.Element.addMethods(function(){ + var PARENTNODE = 'parentNode', + NEXTSIBLING = 'nextSibling', + PREVIOUSSIBLING = 'previousSibling', + DQ = Ext.DomQuery, + GET = Ext.get; + + return { + + findParent : function(simpleSelector, maxDepth, returnEl){ + var p = this.dom, + b = document.body, + depth = 0, + stopEl; + if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') { + return null; + } + maxDepth = maxDepth || 50; + if (isNaN(maxDepth)) { + stopEl = Ext.getDom(maxDepth); + maxDepth = Number.MAX_VALUE; + } + while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){ + if(DQ.is(p, simpleSelector)){ + return returnEl ? GET(p) : p; + } + depth++; + p = p.parentNode; + } + return null; + }, + + + findParentNode : function(simpleSelector, maxDepth, returnEl){ + var p = Ext.fly(this.dom.parentNode, '_internal'); + return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null; + }, + + + up : function(simpleSelector, maxDepth){ + return this.findParentNode(simpleSelector, maxDepth, true); + }, + + + select : function(selector){ + return Ext.Element.select(selector, this.dom); + }, + + + query : function(selector){ + return DQ.select(selector, this.dom); + }, + + + child : function(selector, returnDom){ + var n = DQ.selectNode(selector, this.dom); + return returnDom ? n : GET(n); + }, + + + down : function(selector, returnDom){ + var n = DQ.selectNode(" > " + selector, this.dom); + return returnDom ? n : GET(n); + }, + + + parent : function(selector, returnDom){ + return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom); + }, + + + next : function(selector, returnDom){ + return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom); + }, + + + prev : function(selector, returnDom){ + return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom); + }, + + + + first : function(selector, returnDom){ + return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom); + }, + + + last : function(selector, returnDom){ + return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom); + }, + + matchNode : function(dir, start, selector, returnDom){ + var n = this.dom[start]; + while(n){ + if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){ + return !returnDom ? GET(n) : n; + } + n = n[dir]; + } + return null; + } + }; +}()); +Ext.Element.addMethods( +function() { + var GETDOM = Ext.getDom, + GET = Ext.get, + DH = Ext.DomHelper; + + return { + + appendChild: function(el){ + return GET(el).appendTo(this); + }, + + + appendTo: function(el){ + GETDOM(el).appendChild(this.dom); + return this; + }, + + + insertBefore: function(el){ + (el = GETDOM(el)).parentNode.insertBefore(this.dom, el); + return this; + }, + + + insertAfter: function(el){ + (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling); + return this; + }, + + + insertFirst: function(el, returnDom){ + el = el || {}; + if(el.nodeType || el.dom || typeof el == 'string'){ + el = GETDOM(el); + this.dom.insertBefore(el, this.dom.firstChild); + return !returnDom ? GET(el) : el; + }else{ + return this.createChild(el, this.dom.firstChild, returnDom); + } + }, + + + replace: function(el){ + el = GET(el); + this.insertBefore(el); + el.remove(); + return this; + }, + + + replaceWith: function(el){ + var me = this; + + if(el.nodeType || el.dom || typeof el == 'string'){ + el = GETDOM(el); + me.dom.parentNode.insertBefore(el, me.dom); + }else{ + el = DH.insertBefore(me.dom, el); + } + + delete Ext.elCache[me.id]; + Ext.removeNode(me.dom); + me.id = Ext.id(me.dom = el); + Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me); + return me; + }, + + + createChild: function(config, insertBefore, returnDom){ + config = config || {tag:'div'}; + return insertBefore ? + DH.insertBefore(insertBefore, config, returnDom !== true) : + DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true); + }, + + + wrap: function(config, returnDom){ + var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom); + newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom); + return newEl; + }, + + + insertHtml : function(where, html, returnEl){ + var el = DH.insertHtml(where, this.dom, html); + return returnEl ? Ext.get(el) : el; + } + }; +}()); +Ext.Element.addMethods(function(){ + + var supports = Ext.supports, + propCache = {}, + camelRe = /(-[a-z])/gi, + view = document.defaultView, + opacityRe = /alpha\(opacity=(.*)\)/i, + trimRe = /^\s+|\s+$/g, + EL = Ext.Element, + spacesRe = /\s+/, + wordsRe = /\w/g, + PADDING = "padding", + MARGIN = "margin", + BORDER = "border", + LEFT = "-left", + RIGHT = "-right", + TOP = "-top", + BOTTOM = "-bottom", + WIDTH = "-width", + MATH = Math, + HIDDEN = 'hidden', + ISCLIPPED = 'isClipped', + OVERFLOW = 'overflow', + OVERFLOWX = 'overflow-x', + OVERFLOWY = 'overflow-y', + ORIGINALCLIP = 'originalClip', + + borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH}, + paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM}, + margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM}, + data = Ext.Element.data; + + + + function camelFn(m, a) { + return a.charAt(1).toUpperCase(); + } + + function chkCache(prop) { + return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn)); + } + + return { + + adjustWidth : function(width) { + var me = this; + var isNum = (typeof width == "number"); + if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ + width -= (me.getBorderWidth("lr") + me.getPadding("lr")); + } + return (isNum && width < 0) ? 0 : width; + }, + + + adjustHeight : function(height) { + var me = this; + var isNum = (typeof height == "number"); + if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ + height -= (me.getBorderWidth("tb") + me.getPadding("tb")); + } + return (isNum && height < 0) ? 0 : height; + }, + + + + addClass : function(className){ + var me = this, + i, + len, + v, + cls = []; + + if (!Ext.isArray(className)) { + if (typeof className == 'string' && !this.hasClass(className)) { + me.dom.className += " " + className; + } + } + else { + for (i = 0, len = className.length; i < len; i++) { + v = className[i]; + if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) { + cls.push(v); + } + } + if (cls.length) { + me.dom.className += " " + cls.join(" "); + } + } + return me; + }, + + + removeClass : function(className){ + var me = this, + i, + idx, + len, + cls, + elClasses; + if (!Ext.isArray(className)){ + className = [className]; + } + if (me.dom && me.dom.className) { + elClasses = me.dom.className.replace(trimRe, '').split(spacesRe); + for (i = 0, len = className.length; i < len; i++) { + cls = className[i]; + if (typeof cls == 'string') { + cls = cls.replace(trimRe, ''); + idx = elClasses.indexOf(cls); + if (idx != -1) { + elClasses.splice(idx, 1); + } + } + } + me.dom.className = elClasses.join(" "); + } + return me; + }, + + + radioClass : function(className){ + var cn = this.dom.parentNode.childNodes, + v, + i, + len; + className = Ext.isArray(className) ? className : [className]; + for (i = 0, len = cn.length; i < len; i++) { + v = cn[i]; + if (v && v.nodeType == 1) { + Ext.fly(v, '_internal').removeClass(className); + } + }; + return this.addClass(className); + }, + + + toggleClass : function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + + hasClass : function(className){ + return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1; + }, + + + replaceClass : function(oldClassName, newClassName){ + return this.removeClass(oldClassName).addClass(newClassName); + }, + + isStyle : function(style, val) { + return this.getStyle(style) == val; + }, + + + getStyle : function(){ + return view && view.getComputedStyle ? + function(prop){ + var el = this.dom, + v, + cs, + out, + display; + + if(el == document){ + return null; + } + prop = chkCache(prop); + out = (v = el.style[prop]) ? v : + (cs = view.getComputedStyle(el, "")) ? cs[prop] : null; + + + + if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){ + display = el.style.display; + el.style.display = 'inline-block'; + out = view.getComputedStyle(el, '').marginRight; + el.style.display = display; + } + + if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){ + out = 'transparent'; + } + return out; + } : + function(prop){ + var el = this.dom, + m, + cs; + + if(el == document) return null; + if (prop == 'opacity') { + if (el.style.filter.match) { + if(m = el.style.filter.match(opacityRe)){ + var fv = parseFloat(m[1]); + if(!isNaN(fv)){ + return fv ? fv / 100 : 0; + } + } + } + return 1; + } + prop = chkCache(prop); + return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); + }; + }(), + + + getColor : function(attr, defaultValue, prefix){ + var v = this.getStyle(attr), + color = (typeof prefix != 'undefined') ? prefix : '#', + h; + + if(!v || (/transparent|inherit/.test(v))) { + return defaultValue; + } + if(/^r/.test(v)){ + Ext.each(v.slice(4, v.length -1).split(','), function(s){ + h = parseInt(s, 10); + color += (h < 16 ? '0' : '') + h.toString(16); + }); + }else{ + v = v.replace('#', ''); + color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v; + } + return(color.length > 5 ? color.toLowerCase() : defaultValue); + }, + + + setStyle : function(prop, value){ + var tmp, style; + + if (typeof prop != 'object') { + tmp = {}; + tmp[prop] = value; + prop = tmp; + } + for (style in prop) { + value = prop[style]; + style == 'opacity' ? + this.setOpacity(value) : + this.dom.style[chkCache(style)] = value; + } + return this; + }, + + + setOpacity : function(opacity, animate){ + var me = this, + s = me.dom.style; + + if(!animate || !me.anim){ + if(Ext.isIE9m){ + var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', + val = s.filter.replace(opacityRe, '').replace(trimRe, ''); + + s.zoom = 1; + s.filter = val + (val.length > 0 ? ' ' : '') + opac; + }else{ + s.opacity = opacity; + } + }else{ + me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn'); + } + return me; + }, + + + clearOpacity : function(){ + var style = this.dom.style; + if(Ext.isIE9m){ + if(!Ext.isEmpty(style.filter)){ + style.filter = style.filter.replace(opacityRe, '').replace(trimRe, ''); + } + }else{ + style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = ''; + } + return this; + }, + + + getHeight : function(contentHeight){ + var me = this, + dom = me.dom, + hidden = Ext.isIE9m && me.isStyle('display', 'none'), + h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0; + + h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb"); + return h < 0 ? 0 : h; + }, + + + getWidth : function(contentWidth){ + var me = this, + dom = me.dom, + hidden = Ext.isIE9m && me.isStyle('display', 'none'), + w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0; + w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); + return w < 0 ? 0 : w; + }, + + + setWidth : function(width, animate){ + var me = this; + width = me.adjustWidth(width); + !animate || !me.anim ? + me.dom.style.width = me.addUnits(width) : + me.anim({width : {to : width}}, me.preanim(arguments, 1)); + return me; + }, + + + setHeight : function(height, animate){ + var me = this; + height = me.adjustHeight(height); + !animate || !me.anim ? + me.dom.style.height = me.addUnits(height) : + me.anim({height : {to : height}}, me.preanim(arguments, 1)); + return me; + }, + + + getBorderWidth : function(side){ + return this.addStyles(side, borders); + }, + + + getPadding : function(side){ + return this.addStyles(side, paddings); + }, + + + clip : function(){ + var me = this, + dom = me.dom; + + if(!data(dom, ISCLIPPED)){ + data(dom, ISCLIPPED, true); + data(dom, ORIGINALCLIP, { + o: me.getStyle(OVERFLOW), + x: me.getStyle(OVERFLOWX), + y: me.getStyle(OVERFLOWY) + }); + me.setStyle(OVERFLOW, HIDDEN); + me.setStyle(OVERFLOWX, HIDDEN); + me.setStyle(OVERFLOWY, HIDDEN); + } + return me; + }, + + + unclip : function(){ + var me = this, + dom = me.dom; + + if(data(dom, ISCLIPPED)){ + data(dom, ISCLIPPED, false); + var o = data(dom, ORIGINALCLIP); + if(o.o){ + me.setStyle(OVERFLOW, o.o); + } + if(o.x){ + me.setStyle(OVERFLOWX, o.x); + } + if(o.y){ + me.setStyle(OVERFLOWY, o.y); + } + } + return me; + }, + + + addStyles : function(sides, styles){ + var ttlSize = 0, + sidesArr = sides.match(wordsRe), + side, + size, + i, + len = sidesArr.length; + for (i = 0; i < len; i++) { + side = sidesArr[i]; + size = side && parseInt(this.getStyle(styles[side]), 10); + if (size) { + ttlSize += MATH.abs(size); + } + } + return ttlSize; + }, + + margins : margins + }; +}() +); + +(function(){ +var D = Ext.lib.Dom, + LEFT = "left", + RIGHT = "right", + TOP = "top", + BOTTOM = "bottom", + POSITION = "position", + STATIC = "static", + RELATIVE = "relative", + AUTO = "auto", + ZINDEX = "z-index"; + +Ext.Element.addMethods({ + + getX : function(){ + return D.getX(this.dom); + }, + + + getY : function(){ + return D.getY(this.dom); + }, + + + getXY : function(){ + return D.getXY(this.dom); + }, + + + getOffsetsTo : function(el){ + var o = this.getXY(), + e = Ext.fly(el, '_internal').getXY(); + return [o[0]-e[0],o[1]-e[1]]; + }, + + + setX : function(x, animate){ + return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1)); + }, + + + setY : function(y, animate){ + return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1)); + }, + + + setLeft : function(left){ + this.setStyle(LEFT, this.addUnits(left)); + return this; + }, + + + setTop : function(top){ + this.setStyle(TOP, this.addUnits(top)); + return this; + }, + + + setRight : function(right){ + this.setStyle(RIGHT, this.addUnits(right)); + return this; + }, + + + setBottom : function(bottom){ + this.setStyle(BOTTOM, this.addUnits(bottom)); + return this; + }, + + + setXY : function(pos, animate){ + var me = this; + if(!animate || !me.anim){ + D.setXY(me.dom, pos); + }else{ + me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion'); + } + return me; + }, + + + setLocation : function(x, y, animate){ + return this.setXY([x, y], this.animTest(arguments, animate, 2)); + }, + + + moveTo : function(x, y, animate){ + return this.setXY([x, y], this.animTest(arguments, animate, 2)); + }, + + + getLeft : function(local){ + return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0; + }, + + + getRight : function(local){ + var me = this; + return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0; + }, + + + getTop : function(local) { + return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0; + }, + + + getBottom : function(local){ + var me = this; + return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0; + }, + + + position : function(pos, zIndex, x, y){ + var me = this; + + if(!pos && me.isStyle(POSITION, STATIC)){ + me.setStyle(POSITION, RELATIVE); + } else if(pos) { + me.setStyle(POSITION, pos); + } + if(zIndex){ + me.setStyle(ZINDEX, zIndex); + } + if(x || y) me.setXY([x || false, y || false]); + }, + + + clearPositioning : function(value){ + value = value || ''; + this.setStyle({ + left : value, + right : value, + top : value, + bottom : value, + "z-index" : "", + position : STATIC + }); + return this; + }, + + + getPositioning : function(){ + var l = this.getStyle(LEFT); + var t = this.getStyle(TOP); + return { + "position" : this.getStyle(POSITION), + "left" : l, + "right" : l ? "" : this.getStyle(RIGHT), + "top" : t, + "bottom" : t ? "" : this.getStyle(BOTTOM), + "z-index" : this.getStyle(ZINDEX) + }; + }, + + + setPositioning : function(pc){ + var me = this, + style = me.dom.style; + + me.setStyle(pc); + + if(pc.right == AUTO){ + style.right = ""; + } + if(pc.bottom == AUTO){ + style.bottom = ""; + } + + return me; + }, + + + translatePoints : function(x, y){ + y = isNaN(x[1]) ? y : x[1]; + x = isNaN(x[0]) ? x : x[0]; + var me = this, + relative = me.isStyle(POSITION, RELATIVE), + o = me.getXY(), + l = parseInt(me.getStyle(LEFT), 10), + t = parseInt(me.getStyle(TOP), 10); + + l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft); + t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop); + + return {left: (x - o[0] + l), top: (y - o[1] + t)}; + }, + + animTest : function(args, animate, i) { + return !!animate && this.preanim ? this.preanim(args, i) : false; + } +}); +})(); +Ext.Element.addMethods({ + + isScrollable : function(){ + var dom = this.dom; + return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; + }, + + + scrollTo : function(side, value){ + this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value; + return this; + }, + + + getScroll : function(){ + var d = this.dom, + doc = document, + body = doc.body, + docElement = doc.documentElement, + l, + t, + ret; + + if(d == doc || d == body){ + if(Ext.isIE && Ext.isStrict){ + l = docElement.scrollLeft; + t = docElement.scrollTop; + }else{ + l = window.pageXOffset; + t = window.pageYOffset; + } + ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)}; + }else{ + ret = {left: d.scrollLeft, top: d.scrollTop}; + } + return ret; + } +}); + +Ext.Element.VISIBILITY = 1; + +Ext.Element.DISPLAY = 2; + + +Ext.Element.OFFSETS = 3; + + +Ext.Element.ASCLASS = 4; + + +Ext.Element.visibilityCls = 'x-hide-nosize'; + +Ext.Element.addMethods(function(){ + var El = Ext.Element, + OPACITY = "opacity", + VISIBILITY = "visibility", + DISPLAY = "display", + HIDDEN = "hidden", + OFFSETS = "offsets", + ASCLASS = "asclass", + NONE = "none", + NOSIZE = 'nosize', + ORIGINALDISPLAY = 'originalDisplay', + VISMODE = 'visibilityMode', + ISVISIBLE = 'isVisible', + data = El.data, + getDisplay = function(dom){ + var d = data(dom, ORIGINALDISPLAY); + if(d === undefined){ + data(dom, ORIGINALDISPLAY, d = ''); + } + return d; + }, + getVisMode = function(dom){ + var m = data(dom, VISMODE); + if(m === undefined){ + data(dom, VISMODE, m = 1); + } + return m; + }; + + return { + + originalDisplay : "", + visibilityMode : 1, + + + setVisibilityMode : function(visMode){ + data(this.dom, VISMODE, visMode); + return this; + }, + + + animate : function(args, duration, onComplete, easing, animType){ + this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType); + return this; + }, + + + anim : function(args, opt, animType, defaultDur, defaultEase, cb){ + animType = animType || 'run'; + opt = opt || {}; + var me = this, + anim = Ext.lib.Anim[animType]( + me.dom, + args, + (opt.duration || defaultDur) || .35, + (opt.easing || defaultEase) || 'easeOut', + function(){ + if(cb) cb.call(me); + if(opt.callback) opt.callback.call(opt.scope || me, me, opt); + }, + me + ); + opt.anim = anim; + return anim; + }, + + + preanim : function(a, i){ + return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]}); + }, + + + isVisible : function() { + var me = this, + dom = me.dom, + visible = data(dom, ISVISIBLE); + + if(typeof visible == 'boolean'){ + return visible; + } + + visible = !me.isStyle(VISIBILITY, HIDDEN) && + !me.isStyle(DISPLAY, NONE) && + !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls)); + + data(dom, ISVISIBLE, visible); + return visible; + }, + + + setVisible : function(visible, animate){ + var me = this, isDisplay, isVisibility, isOffsets, isNosize, + dom = me.dom, + visMode = getVisMode(dom); + + + + if (typeof animate == 'string'){ + switch (animate) { + case DISPLAY: + visMode = El.DISPLAY; + break; + case VISIBILITY: + visMode = El.VISIBILITY; + break; + case OFFSETS: + visMode = El.OFFSETS; + break; + case NOSIZE: + case ASCLASS: + visMode = El.ASCLASS; + break; + } + me.setVisibilityMode(visMode); + animate = false; + } + + if (!animate || !me.anim) { + if(visMode == El.ASCLASS ){ + + me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls); + + } else if (visMode == El.DISPLAY){ + + return me.setDisplayed(visible); + + } else if (visMode == El.OFFSETS){ + + if (!visible){ + me.hideModeStyles = { + position: me.getStyle('position'), + top: me.getStyle('top'), + left: me.getStyle('left') + }; + me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'}); + } else { + me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''}); + delete me.hideModeStyles; + } + + }else{ + me.fixDisplay(); + dom.style.visibility = visible ? "visible" : HIDDEN; + } + }else{ + + if(visible){ + me.setOpacity(.01); + me.setVisible(true); + } + me.anim({opacity: { to: (visible?1:0) }}, + me.preanim(arguments, 1), + null, + .35, + 'easeIn', + function(){ + visible || me.setVisible(false).setOpacity(1); + }); + } + data(dom, ISVISIBLE, visible); + return me; + }, + + + + hasMetrics : function(){ + var dom = this.dom; + return this.isVisible() || (getVisMode(dom) == El.VISIBILITY); + }, + + + toggle : function(animate){ + var me = this; + me.setVisible(!me.isVisible(), me.preanim(arguments, 0)); + return me; + }, + + + setDisplayed : function(value) { + if(typeof value == "boolean"){ + value = value ? getDisplay(this.dom) : NONE; + } + this.setStyle(DISPLAY, value); + return this; + }, + + + fixDisplay : function(){ + var me = this; + if(me.isStyle(DISPLAY, NONE)){ + me.setStyle(VISIBILITY, HIDDEN); + me.setStyle(DISPLAY, getDisplay(this.dom)); + if(me.isStyle(DISPLAY, NONE)){ + me.setStyle(DISPLAY, "block"); + } + } + }, + + + hide : function(animate){ + + if (typeof animate == 'string'){ + this.setVisible(false, animate); + return this; + } + this.setVisible(false, this.preanim(arguments, 0)); + return this; + }, + + + show : function(animate){ + + if (typeof animate == 'string'){ + this.setVisible(true, animate); + return this; + } + this.setVisible(true, this.preanim(arguments, 0)); + return this; + } + }; +}());(function(){ + + var NULL = null, + UNDEFINED = undefined, + TRUE = true, + FALSE = false, + SETX = "setX", + SETY = "setY", + SETXY = "setXY", + LEFT = "left", + BOTTOM = "bottom", + TOP = "top", + RIGHT = "right", + HEIGHT = "height", + WIDTH = "width", + POINTS = "points", + HIDDEN = "hidden", + ABSOLUTE = "absolute", + VISIBLE = "visible", + MOTION = "motion", + POSITION = "position", + EASEOUT = "easeOut", + + flyEl = new Ext.Element.Flyweight(), + queues = {}, + getObject = function(o){ + return o || {}; + }, + fly = function(dom){ + flyEl.dom = dom; + flyEl.id = Ext.id(dom); + return flyEl; + }, + + getQueue = function(id){ + if(!queues[id]){ + queues[id] = []; + } + return queues[id]; + }, + setQueue = function(id, value){ + queues[id] = value; + }; + + +Ext.enableFx = TRUE; + + +Ext.Fx = { + + + + switchStatements : function(key, fn, argHash){ + return fn.apply(this, argHash[key]); + }, + + + slideIn : function(anchor, o){ + o = getObject(o); + var me = this, + dom = me.dom, + st = dom.style, + xy, + r, + b, + wrap, + after, + st, + args, + pt, + bw, + bh; + + anchor = anchor || "t"; + + me.queueFx(o, function(){ + xy = fly(dom).getXY(); + + fly(dom).fixDisplay(); + + + r = fly(dom).getFxRestore(); + b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}; + b.right = b.x + b.width; + b.bottom = b.y + b.height; + + + fly(dom).setWidth(b.width).setHeight(b.height); + + + wrap = fly(dom).fxWrap(r.pos, o, HIDDEN); + + st.visibility = VISIBLE; + st.position = ABSOLUTE; + + + function after(){ + fly(dom).fxUnwrap(wrap, r.pos, o); + st.width = r.width; + st.height = r.height; + fly(dom).afterFx(o); + } + + + pt = {to: [b.x, b.y]}; + bw = {to: b.width}; + bh = {to: b.height}; + + function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){ + var ret = {}; + fly(wrap).setWidth(ww).setHeight(wh); + if(fly(wrap)[sXY]){ + fly(wrap)[sXY](sXYval); + } + style[s1] = style[s2] = "0"; + if(w){ + ret.width = w; + } + if(h){ + ret.height = h; + } + if(p){ + ret.points = p; + } + return ret; + }; + + args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, { + t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL], + l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL], + r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt], + b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt], + tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt], + bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt], + br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt], + tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt] + }); + + st.visibility = VISIBLE; + fly(wrap).show(); + + arguments.callee.anim = fly(wrap).fxanim(args, + o, + MOTION, + .5, + EASEOUT, + after); + }); + return me; + }, + + + slideOut : function(anchor, o){ + o = getObject(o); + var me = this, + dom = me.dom, + st = dom.style, + xy = me.getXY(), + wrap, + r, + b, + a, + zero = {to: 0}; + + anchor = anchor || "t"; + + me.queueFx(o, function(){ + + + r = fly(dom).getFxRestore(); + b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}; + b.right = b.x + b.width; + b.bottom = b.y + b.height; + + + fly(dom).setWidth(b.width).setHeight(b.height); + + + wrap = fly(dom).fxWrap(r.pos, o, VISIBLE); + + st.visibility = VISIBLE; + st.position = ABSOLUTE; + fly(wrap).setWidth(b.width).setHeight(b.height); + + function after(){ + o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); + fly(dom).fxUnwrap(wrap, r.pos, o); + st.width = r.width; + st.height = r.height; + fly(dom).afterFx(o); + } + + function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){ + var ret = {}; + + style[s1] = style[s2] = "0"; + ret[p1] = v1; + if(p2){ + ret[p2] = v2; + } + if(p3){ + ret[p3] = v3; + } + + return ret; + }; + + a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, { + t : [st, LEFT, BOTTOM, HEIGHT, zero], + l : [st, RIGHT, TOP, WIDTH, zero], + r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}], + b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}], + tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero], + bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}], + br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}], + tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}] + }); + + arguments.callee.anim = fly(wrap).fxanim(a, + o, + MOTION, + .5, + EASEOUT, + after); + }); + return me; + }, + + + puff : function(o){ + o = getObject(o); + var me = this, + dom = me.dom, + st = dom.style, + width, + height, + r; + + me.queueFx(o, function(){ + width = fly(dom).getWidth(); + height = fly(dom).getHeight(); + fly(dom).clearOpacity(); + fly(dom).show(); + + + r = fly(dom).getFxRestore(); + + function after(){ + o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); + fly(dom).clearOpacity(); + fly(dom).setPositioning(r.pos); + st.width = r.width; + st.height = r.height; + st.fontSize = ''; + fly(dom).afterFx(o); + } + + arguments.callee.anim = fly(dom).fxanim({ + width : {to : fly(dom).adjustWidth(width * 2)}, + height : {to : fly(dom).adjustHeight(height * 2)}, + points : {by : [-width * .5, -height * .5]}, + opacity : {to : 0}, + fontSize: {to : 200, unit: "%"} + }, + o, + MOTION, + .5, + EASEOUT, + after); + }); + return me; + }, + + + switchOff : function(o){ + o = getObject(o); + var me = this, + dom = me.dom, + st = dom.style, + r; + + me.queueFx(o, function(){ + fly(dom).clearOpacity(); + fly(dom).clip(); + + + r = fly(dom).getFxRestore(); + + function after(){ + o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); + fly(dom).clearOpacity(); + fly(dom).setPositioning(r.pos); + st.width = r.width; + st.height = r.height; + fly(dom).afterFx(o); + }; + + fly(dom).fxanim({opacity : {to : 0.3}}, + NULL, + NULL, + .1, + NULL, + function(){ + fly(dom).clearOpacity(); + (function(){ + fly(dom).fxanim({ + height : {to : 1}, + points : {by : [0, fly(dom).getHeight() * .5]} + }, + o, + MOTION, + 0.3, + 'easeIn', + after); + }).defer(100); + }); + }); + return me; + }, + + + highlight : function(color, o){ + o = getObject(o); + var me = this, + dom = me.dom, + attr = o.attr || "backgroundColor", + a = {}, + restore; + + me.queueFx(o, function(){ + fly(dom).clearOpacity(); + fly(dom).show(); + + function after(){ + dom.style[attr] = restore; + fly(dom).afterFx(o); + } + restore = dom.style[attr]; + a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"}; + arguments.callee.anim = fly(dom).fxanim(a, + o, + 'color', + 1, + 'easeIn', + after); + }); + return me; + }, + + + frame : function(color, count, o){ + o = getObject(o); + var me = this, + dom = me.dom, + proxy, + active; + + me.queueFx(o, function(){ + color = color || '#C3DAF9'; + if(color.length == 6){ + color = '#' + color; + } + count = count || 1; + fly(dom).show(); + + var xy = fly(dom).getXY(), + b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}, + queue = function(){ + proxy = fly(document.body || document.documentElement).createChild({ + style:{ + position : ABSOLUTE, + 'z-index': 35000, + border : '0px solid ' + color + } + }); + return proxy.queueFx({}, animFn); + }; + + + arguments.callee.anim = { + isAnimated: true, + stop: function() { + count = 0; + proxy.stopFx(); + } + }; + + function animFn(){ + var scale = Ext.isBorderBox ? 2 : 1; + active = proxy.anim({ + top : {from : b.y, to : b.y - 20}, + left : {from : b.x, to : b.x - 20}, + borderWidth : {from : 0, to : 10}, + opacity : {from : 1, to : 0}, + height : {from : b.height, to : b.height + 20 * scale}, + width : {from : b.width, to : b.width + 20 * scale} + },{ + duration: o.duration || 1, + callback: function() { + proxy.remove(); + --count > 0 ? queue() : fly(dom).afterFx(o); + } + }); + arguments.callee.anim = { + isAnimated: true, + stop: function(){ + active.stop(); + } + }; + }; + queue(); + }); + return me; + }, + + + pause : function(seconds){ + var dom = this.dom, + t; + + this.queueFx({}, function(){ + t = setTimeout(function(){ + fly(dom).afterFx({}); + }, seconds * 1000); + arguments.callee.anim = { + isAnimated: true, + stop: function(){ + clearTimeout(t); + fly(dom).afterFx({}); + } + }; + }); + return this; + }, + + + fadeIn : function(o){ + o = getObject(o); + var me = this, + dom = me.dom, + to = o.endOpacity || 1; + + me.queueFx(o, function(){ + fly(dom).setOpacity(0); + fly(dom).fixDisplay(); + dom.style.visibility = VISIBLE; + arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}}, + o, NULL, .5, EASEOUT, function(){ + if(to == 1){ + fly(dom).clearOpacity(); + } + fly(dom).afterFx(o); + }); + }); + return me; + }, + + + fadeOut : function(o){ + o = getObject(o); + var me = this, + dom = me.dom, + style = dom.style, + to = o.endOpacity || 0; + + me.queueFx(o, function(){ + arguments.callee.anim = fly(dom).fxanim({ + opacity : {to : to}}, + o, + NULL, + .5, + EASEOUT, + function(){ + if(to == 0){ + Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? + style.display = "none" : + style.visibility = HIDDEN; + + fly(dom).clearOpacity(); + } + fly(dom).afterFx(o); + }); + }); + return me; + }, + + + scale : function(w, h, o){ + this.shift(Ext.apply({}, o, { + width: w, + height: h + })); + return this; + }, + + + shift : function(o){ + o = getObject(o); + var dom = this.dom, + a = {}; + + this.queueFx(o, function(){ + for (var prop in o) { + if (o[prop] != UNDEFINED) { + a[prop] = {to : o[prop]}; + } + } + + a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a; + a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a; + + if (a.x || a.y || a.xy) { + a.points = a.xy || + {to : [ a.x ? a.x.to : fly(dom).getX(), + a.y ? a.y.to : fly(dom).getY()]}; + } + + arguments.callee.anim = fly(dom).fxanim(a, + o, + MOTION, + .35, + EASEOUT, + function(){ + fly(dom).afterFx(o); + }); + }); + return this; + }, + + + ghost : function(anchor, o){ + o = getObject(o); + var me = this, + dom = me.dom, + st = dom.style, + a = {opacity: {to: 0}, points: {}}, + pt = a.points, + r, + w, + h; + + anchor = anchor || "b"; + + me.queueFx(o, function(){ + + r = fly(dom).getFxRestore(); + w = fly(dom).getWidth(); + h = fly(dom).getHeight(); + + function after(){ + o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); + fly(dom).clearOpacity(); + fly(dom).setPositioning(r.pos); + st.width = r.width; + st.height = r.height; + fly(dom).afterFx(o); + } + + pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, { + t : [0, -h], + l : [-w, 0], + r : [w, 0], + b : [0, h], + tl : [-w, -h], + bl : [-w, h], + br : [w, h], + tr : [w, -h] + }); + + arguments.callee.anim = fly(dom).fxanim(a, + o, + MOTION, + .5, + EASEOUT, after); + }); + return me; + }, + + + syncFx : function(){ + var me = this; + me.fxDefaults = Ext.apply(me.fxDefaults || {}, { + block : FALSE, + concurrent : TRUE, + stopFx : FALSE + }); + return me; + }, + + + sequenceFx : function(){ + var me = this; + me.fxDefaults = Ext.apply(me.fxDefaults || {}, { + block : FALSE, + concurrent : FALSE, + stopFx : FALSE + }); + return me; + }, + + + nextFx : function(){ + var ef = getQueue(this.dom.id)[0]; + if(ef){ + ef.call(this); + } + }, + + + hasActiveFx : function(){ + return getQueue(this.dom.id)[0]; + }, + + + stopFx : function(finish){ + var me = this, + id = me.dom.id; + if(me.hasActiveFx()){ + var cur = getQueue(id)[0]; + if(cur && cur.anim){ + if(cur.anim.isAnimated){ + setQueue(id, [cur]); + cur.anim.stop(finish !== undefined ? finish : TRUE); + }else{ + setQueue(id, []); + } + } + } + return me; + }, + + + beforeFx : function(o){ + if(this.hasActiveFx() && !o.concurrent){ + if(o.stopFx){ + this.stopFx(); + return TRUE; + } + return FALSE; + } + return TRUE; + }, + + + hasFxBlock : function(){ + var q = getQueue(this.dom.id); + return q && q[0] && q[0].block; + }, + + + queueFx : function(o, fn){ + var me = fly(this.dom); + if(!me.hasFxBlock()){ + Ext.applyIf(o, me.fxDefaults); + if(!o.concurrent){ + var run = me.beforeFx(o); + fn.block = o.block; + getQueue(me.dom.id).push(fn); + if(run){ + me.nextFx(); + } + }else{ + fn.call(me); + } + } + return me; + }, + + + fxWrap : function(pos, o, vis){ + var dom = this.dom, + wrap, + wrapXY; + if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){ + if(o.fixPosition){ + wrapXY = fly(dom).getXY(); + } + var div = document.createElement("div"); + div.style.visibility = vis; + wrap = dom.parentNode.insertBefore(div, dom); + fly(wrap).setPositioning(pos); + if(fly(wrap).isStyle(POSITION, "static")){ + fly(wrap).position("relative"); + } + fly(dom).clearPositioning('auto'); + fly(wrap).clip(); + wrap.appendChild(dom); + if(wrapXY){ + fly(wrap).setXY(wrapXY); + } + } + return wrap; + }, + + + fxUnwrap : function(wrap, pos, o){ + var dom = this.dom; + fly(dom).clearPositioning(); + fly(dom).setPositioning(pos); + if(!o.wrap){ + var pn = fly(wrap).dom.parentNode; + pn.insertBefore(dom, wrap); + fly(wrap).remove(); + } + }, + + + getFxRestore : function(){ + var st = this.dom.style; + return {pos: this.getPositioning(), width: st.width, height : st.height}; + }, + + + afterFx : function(o){ + var dom = this.dom, + id = dom.id; + if(o.afterStyle){ + fly(dom).setStyle(o.afterStyle); + } + if(o.afterCls){ + fly(dom).addClass(o.afterCls); + } + if(o.remove == TRUE){ + fly(dom).remove(); + } + if(o.callback){ + o.callback.call(o.scope, fly(dom)); + } + if(!o.concurrent){ + getQueue(id).shift(); + fly(dom).nextFx(); + } + }, + + + fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){ + animType = animType || 'run'; + opt = opt || {}; + var anim = Ext.lib.Anim[animType]( + this.dom, + args, + (opt.duration || defaultDur) || .35, + (opt.easing || defaultEase) || EASEOUT, + cb, + this + ); + opt.anim = anim; + return anim; + } +}; + + +Ext.Fx.resize = Ext.Fx.scale; + + + +Ext.Element.addMethods(Ext.Fx); +})(); + +Ext.CompositeElementLite = function(els, root){ + + this.elements = []; + this.add(els, root); + this.el = new Ext.Element.Flyweight(); +}; + +Ext.CompositeElementLite.prototype = { + isComposite: true, + + + getElement : function(el){ + + var e = this.el; + e.dom = el; + e.id = el.id; + return e; + }, + + + transformElement : function(el){ + return Ext.getDom(el); + }, + + + getCount : function(){ + return this.elements.length; + }, + + add : function(els, root){ + var me = this, + elements = me.elements; + if(!els){ + return this; + } + if(typeof els == "string"){ + els = Ext.Element.selectorFunction(els, root); + }else if(els.isComposite){ + els = els.elements; + }else if(!Ext.isIterable(els)){ + els = [els]; + } + + for(var i = 0, len = els.length; i < len; ++i){ + elements.push(me.transformElement(els[i])); + } + return me; + }, + + invoke : function(fn, args){ + var me = this, + els = me.elements, + len = els.length, + e, + i; + + for(i = 0; i < len; i++) { + e = els[i]; + if(e){ + Ext.Element.prototype[fn].apply(me.getElement(e), args); + } + } + return me; + }, + + item : function(index){ + var me = this, + el = me.elements[index], + out = null; + + if(el){ + out = me.getElement(el); + } + return out; + }, + + + addListener : function(eventName, handler, scope, opt){ + var els = this.elements, + len = els.length, + i, e; + + for(i = 0; i -1){ + replacement = Ext.getDom(replacement); + if(domReplace){ + d = this.elements[index]; + d.parentNode.insertBefore(replacement, d); + Ext.removeNode(d); + } + this.elements.splice(index, 1, replacement); + } + return this; + }, + + + clear : function(){ + this.elements = []; + } +}; + +Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener; + + +Ext.CompositeElementLite.importElementMethods = function() { + var fnName, + ElProto = Ext.Element.prototype, + CelProto = Ext.CompositeElementLite.prototype; + + for (fnName in ElProto) { + if (typeof ElProto[fnName] == 'function'){ + (function(fnName) { + CelProto[fnName] = CelProto[fnName] || function() { + return this.invoke(fnName, arguments); + }; + }).call(CelProto, fnName); + + } + } +}; + +Ext.CompositeElementLite.importElementMethods(); + +if(Ext.DomQuery){ + Ext.Element.selectorFunction = Ext.DomQuery.select; +} + + +Ext.Element.select = function(selector, root){ + var els; + if(typeof selector == "string"){ + els = Ext.Element.selectorFunction(selector, root); + }else if(selector.length !== undefined){ + els = selector; + }else{ + throw "Invalid selector"; + } + return new Ext.CompositeElementLite(els); +}; + +Ext.select = Ext.Element.select; +(function(){ + var BEFOREREQUEST = "beforerequest", + REQUESTCOMPLETE = "requestcomplete", + REQUESTEXCEPTION = "requestexception", + UNDEFINED = undefined, + LOAD = 'load', + POST = 'POST', + GET = 'GET', + WINDOW = window; + + + Ext.data.Connection = function(config){ + Ext.apply(this, config); + this.addEvents( + + BEFOREREQUEST, + + REQUESTCOMPLETE, + + REQUESTEXCEPTION + ); + Ext.data.Connection.superclass.constructor.call(this); + }; + + Ext.extend(Ext.data.Connection, Ext.util.Observable, { + + + + + + timeout : 30000, + + autoAbort:false, + + + disableCaching: true, + + + disableCachingParam: '_dc', + + + request : function(o){ + var me = this; + if(me.fireEvent(BEFOREREQUEST, me, o)){ + if (o.el) { + if(!Ext.isEmpty(o.indicatorText)){ + me.indicatorText = '
'+o.indicatorText+"
"; + } + if(me.indicatorText) { + Ext.getDom(o.el).innerHTML = me.indicatorText; + } + o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) { + Ext.getDom(o.el).innerHTML = response.responseText; + }); + } + + var p = o.params, + url = o.url || me.url, + method, + cb = {success: me.handleResponse, + failure: me.handleFailure, + scope: me, + argument: {options: o}, + timeout : Ext.num(o.timeout, me.timeout) + }, + form, + serForm; + + + if (Ext.isFunction(p)) { + p = p.call(o.scope||WINDOW, o); + } + + p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p); + + if (Ext.isFunction(url)) { + url = url.call(o.scope || WINDOW, o); + } + + if((form = Ext.getDom(o.form))){ + url = url || form.action; + if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) { + return me.doFormUpload.call(me, o, p, url); + } + serForm = Ext.lib.Ajax.serializeForm(form); + p = p ? (p + '&' + serForm) : serForm; + } + + method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET); + + if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){ + var dcp = o.disableCachingParam || me.disableCachingParam; + url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime())); + } + + o.headers = Ext.applyIf(o.headers || {}, me.defaultHeaders || {}); + + if(o.autoAbort === true || me.autoAbort) { + me.abort(); + } + + if((method == GET || o.xmlData || o.jsonData) && p){ + url = Ext.urlAppend(url, p); + p = ''; + } + return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o)); + }else{ + return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null; + } + }, + + + isLoading : function(transId){ + return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId; + }, + + + abort : function(transId){ + if(transId || this.isLoading()){ + Ext.lib.Ajax.abort(transId || this.transId); + } + }, + + + handleResponse : function(response){ + this.transId = false; + var options = response.argument.options; + response.argument = options ? options.argument : null; + this.fireEvent(REQUESTCOMPLETE, this, response, options); + if(options.success){ + options.success.call(options.scope, response, options); + } + if(options.callback){ + options.callback.call(options.scope, options, true, response); + } + }, + + + handleFailure : function(response, e){ + this.transId = false; + var options = response.argument.options; + response.argument = options ? options.argument : null; + this.fireEvent(REQUESTEXCEPTION, this, response, options, e); + if(options.failure){ + options.failure.call(options.scope, response, options); + } + if(options.callback){ + options.callback.call(options.scope, options, false, response); + } + }, + + + doFormUpload : function(o, ps, url){ + var id = Ext.id(), + doc = document, + frame = doc.createElement('iframe'), + form = Ext.getDom(o.form), + hiddens = [], + hd, + encoding = 'multipart/form-data', + buf = { + target: form.target, + method: form.method, + encoding: form.encoding, + enctype: form.enctype, + action: form.action + }; + + + Ext.fly(frame).set({ + id: id, + name: id, + cls: 'x-hidden', + src: Ext.SSL_SECURE_URL + }); + + doc.body.appendChild(frame); + + + if(Ext.isIE){ + document.frames[id].name = id; + } + + + Ext.fly(form).set({ + target: id, + method: POST, + enctype: encoding, + encoding: encoding, + action: url || buf.action + }); + + + Ext.iterate(Ext.urlDecode(ps, false), function(k, v){ + hd = doc.createElement('input'); + Ext.fly(hd).set({ + type: 'hidden', + value: v, + name: k + }); + form.appendChild(hd); + hiddens.push(hd); + }); + + function cb(){ + var me = this, + + r = {responseText : '', + responseXML : null, + argument : o.argument}, + doc, + firstChild; + + try{ + doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document; + if(doc){ + if(doc.body){ + if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ + r.responseText = firstChild.value; + }else{ + r.responseText = doc.body.innerHTML; + } + } + + r.responseXML = doc.XMLDocument || doc; + } + } + catch(e) {} + + Ext.EventManager.removeListener(frame, LOAD, cb, me); + + me.fireEvent(REQUESTCOMPLETE, me, r, o); + + function runCallback(fn, scope, args){ + if(Ext.isFunction(fn)){ + fn.apply(scope, args); + } + } + + runCallback(o.success, o.scope, [r, o]); + runCallback(o.callback, o.scope, [o, true, r]); + + if(!me.debugUploads){ + setTimeout(function(){Ext.removeNode(frame);}, 100); + } + } + + Ext.EventManager.on(frame, LOAD, cb, this); + form.submit(); + + Ext.fly(form).set(buf); + Ext.each(hiddens, function(h) { + Ext.removeNode(h); + }); + } + }); +})(); + + +Ext.Ajax = new Ext.data.Connection({ + + + + + + + + + + + + + + + + + + autoAbort : false, + + + serializeForm : function(form){ + return Ext.lib.Ajax.serializeForm(form); + } +}); + +Ext.util.JSON = new (function(){ + var useHasOwn = !!{}.hasOwnProperty, + isNative = function() { + var useNative = null; + + return function() { + if (useNative === null) { + useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]'; + } + + return useNative; + }; + }(), + pad = function(n) { + return n < 10 ? "0" + n : n; + }, + doDecode = function(json){ + return json ? eval("(" + json + ")") : ""; + }, + doEncode = function(o){ + if(!Ext.isDefined(o) || o === null){ + return "null"; + }else if(Ext.isArray(o)){ + return encodeArray(o); + }else if(Ext.isDate(o)){ + return Ext.util.JSON.encodeDate(o); + }else if(Ext.isString(o)){ + return encodeString(o); + }else if(typeof o == "number"){ + + return isFinite(o) ? String(o) : "null"; + }else if(Ext.isBoolean(o)){ + return String(o); + }else { + var a = ["{"], b, i, v; + for (i in o) { + + if(!o.getElementsByTagName){ + if(!useHasOwn || o.hasOwnProperty(i)) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "function": + case "unknown": + break; + default: + if(b){ + a.push(','); + } + a.push(doEncode(i), ":", + v === null ? "null" : doEncode(v)); + b = true; + } + } + } + } + a.push("}"); + return a.join(""); + } + }, + m = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"' : '\\"', + "\\": '\\\\' + }, + encodeString = function(s){ + if (/["\\\x00-\x1f]/.test(s)) { + return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) { + var c = m[b]; + if(c){ + return c; + } + c = b.charCodeAt(); + return "\\u00" + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }) + '"'; + } + return '"' + s + '"'; + }, + encodeArray = function(o){ + var a = ["["], b, i, l = o.length, v; + for (i = 0; i < l; i += 1) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "function": + case "unknown": + break; + default: + if (b) { + a.push(','); + } + a.push(v === null ? "null" : Ext.util.JSON.encode(v)); + b = true; + } + } + a.push("]"); + return a.join(""); + }; + + + this.encodeDate = function(o){ + return '"' + o.getFullYear() + "-" + + pad(o.getMonth() + 1) + "-" + + pad(o.getDate()) + "T" + + pad(o.getHours()) + ":" + + pad(o.getMinutes()) + ":" + + pad(o.getSeconds()) + '"'; + }; + + + this.encode = function() { + var ec; + return function(o) { + if (!ec) { + + ec = isNative() ? JSON.stringify : doEncode; + } + return ec(o); + }; + }(); + + + + this.decode = function() { + var dc; + return function(json) { + if (!dc) { + + dc = isNative() ? JSON.parse : doDecode; + } + return dc(json); + }; + }(); + +})(); + +Ext.encode = Ext.util.JSON.encode; + +Ext.decode = Ext.util.JSON.decode; + +Ext.EventManager = function(){ + var docReadyEvent, + docReadyProcId, + docReadyState = false, + DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari || Ext.isIE10p, + E = Ext.lib.Event, + D = Ext.lib.Dom, + DOC = document, + WINDOW = window, + DOMCONTENTLOADED = "DOMContentLoaded", + COMPLETE = 'complete', + propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/, + + specialElCache = []; + + function getId(el){ + var id = false, + i = 0, + len = specialElCache.length, + skip = false, + o; + + if (el) { + if (el.getElementById || el.navigator) { + + for(; i < len; ++i){ + o = specialElCache[i]; + if(o.el === el){ + id = o.id; + break; + } + } + if(!id){ + + id = Ext.id(el); + specialElCache.push({ + id: id, + el: el + }); + skip = true; + } + }else{ + id = Ext.id(el); + } + if(!Ext.elCache[id]){ + Ext.Element.addToCache(new Ext.Element(el), id); + if(skip){ + Ext.elCache[id].skipGC = true; + } + } + } + return id; + } + + + function addListener(el, ename, fn, task, wrap, scope){ + el = Ext.getDom(el); + var id = getId(el), + es = Ext.elCache[id].events, + wfn; + + wfn = E.on(el, ename, wrap); + es[ename] = es[ename] || []; + + + es[ename].push([fn, wrap, scope, wfn, task]); + + + + + + if(el.addEventListener && ename == "mousewheel"){ + var args = ["DOMMouseScroll", wrap, false]; + el.addEventListener.apply(el, args); + Ext.EventManager.addListener(WINDOW, 'unload', function(){ + el.removeEventListener.apply(el, args); + }); + } + + + if(el == DOC && ename == "mousedown"){ + Ext.EventManager.stoppedMouseDownEvent.addListener(wrap); + } + } + + function doScrollChk(){ + + if(window != top){ + return false; + } + + try{ + DOC.documentElement.doScroll('left'); + }catch(e){ + return false; + } + + fireDocReady(); + return true; + } + + function checkReadyState(e){ + + if(Ext.isIE9m && doScrollChk()){ + return true; + } + if(DOC.readyState == COMPLETE){ + fireDocReady(); + return true; + } + docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2)); + return false; + } + + var styles; + function checkStyleSheets(e){ + styles || (styles = Ext.query('style, link[rel=stylesheet]')); + if(styles.length == DOC.styleSheets.length){ + fireDocReady(); + return true; + } + docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2)); + return false; + } + + function OperaDOMContentLoaded(e){ + DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false); + checkStyleSheets(); + } + + function fireDocReady(e){ + if(!docReadyState){ + docReadyState = true; + + if(docReadyProcId){ + clearTimeout(docReadyProcId); + } + if(DETECT_NATIVE) { + DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false); + } + if(Ext.isIE9m && checkReadyState.bindIE){ + DOC.detachEvent('onreadystatechange', checkReadyState); + } + E.un(WINDOW, "load", arguments.callee); + } + if(docReadyEvent && !Ext.isReady){ + Ext.isReady = true; + docReadyEvent.fire(); + docReadyEvent.listeners = []; + } + + } + + function initDocReady(){ + docReadyEvent || (docReadyEvent = new Ext.util.Event()); + if (DETECT_NATIVE) { + DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false); + } + + if (Ext.isIE9m){ + + + if(!checkReadyState()){ + checkReadyState.bindIE = true; + DOC.attachEvent('onreadystatechange', checkReadyState); + } + + }else if(Ext.isOpera ){ + + + + (DOC.readyState == COMPLETE && checkStyleSheets()) || + DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false); + + }else if (Ext.isWebKit){ + + checkReadyState(); + } + + E.on(WINDOW, "load", fireDocReady); + } + + function createTargeted(h, o){ + return function(){ + var args = Ext.toArray(arguments); + if(o.target == Ext.EventObject.setEvent(args[0]).target){ + h.apply(this, args); + } + }; + } + + function createBuffered(h, o, task){ + return function(e){ + + task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]); + }; + } + + function createSingle(h, el, ename, fn, scope){ + return function(e){ + Ext.EventManager.removeListener(el, ename, fn, scope); + h(e); + }; + } + + function createDelayed(h, o, fn){ + return function(e){ + var task = new Ext.util.DelayedTask(h); + if(!fn.tasks) { + fn.tasks = []; + } + fn.tasks.push(task); + task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]); + }; + } + + function listen(element, ename, opt, fn, scope){ + var o = (!opt || typeof opt == "boolean") ? {} : opt, + el = Ext.getDom(element), task; + + fn = fn || o.fn; + scope = scope || o.scope; + + if(!el){ + throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.'; + } + function h(e){ + + if(!Ext){ + return; + } + e = Ext.EventObject.setEvent(e); + var t; + if (o.delegate) { + if(!(t = e.getTarget(o.delegate, el))){ + return; + } + } else { + t = e.target; + } + if (o.stopEvent) { + e.stopEvent(); + } + if (o.preventDefault) { + e.preventDefault(); + } + if (o.stopPropagation) { + e.stopPropagation(); + } + if (o.normalized === false) { + e = e.browserEvent; + } + + fn.call(scope || el, e, t, o); + } + if(o.target){ + h = createTargeted(h, o); + } + if(o.delay){ + h = createDelayed(h, o, fn); + } + if(o.single){ + h = createSingle(h, el, ename, fn, scope); + } + if(o.buffer){ + task = new Ext.util.DelayedTask(h); + h = createBuffered(h, o, task); + } + + addListener(el, ename, fn, task, h, scope); + return h; + } + + var pub = { + + addListener : function(element, eventName, fn, scope, options){ + if(typeof eventName == 'object'){ + var o = eventName, e, val; + for(e in o){ + val = o[e]; + if(!propRe.test(e)){ + if(Ext.isFunction(val)){ + + listen(element, e, o, val, o.scope); + }else{ + + listen(element, e, val); + } + } + } + } else { + listen(element, eventName, options, fn, scope); + } + }, + + + removeListener : function(el, eventName, fn, scope){ + el = Ext.getDom(el); + var id = getId(el), + f = el && (Ext.elCache[id].events)[eventName] || [], + wrap, i, l, k, len, fnc; + + for (i = 0, len = f.length; i < len; i++) { + + + if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) { + if(fnc[4]) { + fnc[4].cancel(); + } + k = fn.tasks && fn.tasks.length; + if(k) { + while(k--) { + fn.tasks[k].cancel(); + } + delete fn.tasks; + } + wrap = fnc[1]; + E.un(el, eventName, E.extAdapter ? fnc[3] : wrap); + + + if(wrap && el.addEventListener && eventName == "mousewheel"){ + el.removeEventListener("DOMMouseScroll", wrap, false); + } + + + if(wrap && el == DOC && eventName == "mousedown"){ + Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap); + } + + f.splice(i, 1); + if (f.length === 0) { + delete Ext.elCache[id].events[eventName]; + } + for (k in Ext.elCache[id].events) { + return false; + } + Ext.elCache[id].events = {}; + return false; + } + } + }, + + + removeAll : function(el){ + el = Ext.getDom(el); + var id = getId(el), + ec = Ext.elCache[id] || {}, + es = ec.events || {}, + f, i, len, ename, fn, k, wrap; + + for(ename in es){ + if(es.hasOwnProperty(ename)){ + f = es[ename]; + + for (i = 0, len = f.length; i < len; i++) { + fn = f[i]; + if(fn[4]) { + fn[4].cancel(); + } + if(fn[0].tasks && (k = fn[0].tasks.length)) { + while(k--) { + fn[0].tasks[k].cancel(); + } + delete fn.tasks; + } + wrap = fn[1]; + E.un(el, ename, E.extAdapter ? fn[3] : wrap); + + + if(el.addEventListener && wrap && ename == "mousewheel"){ + el.removeEventListener("DOMMouseScroll", wrap, false); + } + + + if(wrap && el == DOC && ename == "mousedown"){ + Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap); + } + } + } + } + if (Ext.elCache[id]) { + Ext.elCache[id].events = {}; + } + }, + + getListeners : function(el, eventName) { + el = Ext.getDom(el); + var id = getId(el), + ec = Ext.elCache[id] || {}, + es = ec.events || {}, + results = []; + if (es && es[eventName]) { + return es[eventName]; + } else { + return null; + } + }, + + removeFromSpecialCache: function(o) { + var i = 0, + len = specialElCache.length; + + for (; i < len; ++i) { + if (specialElCache[i].el == o) { + specialElCache.splice(i, 1); + } + } + }, + + purgeElement : function(el, recurse, eventName) { + el = Ext.getDom(el); + var id = getId(el), + ec = Ext.elCache[id] || {}, + es = ec.events || {}, + i, f, len; + if (eventName) { + if (es && es.hasOwnProperty(eventName)) { + f = es[eventName]; + for (i = 0, len = f.length; i < len; i++) { + Ext.EventManager.removeListener(el, eventName, f[i][0]); + } + } + } else { + Ext.EventManager.removeAll(el); + } + if (recurse && el && el.childNodes) { + for (i = 0, len = el.childNodes.length; i < len; i++) { + Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName); + } + } + }, + + _unload : function() { + var el; + for (el in Ext.elCache) { + Ext.EventManager.removeAll(el); + } + delete Ext.elCache; + delete Ext.Element._flyweights; + + + var c, + conn, + tid, + ajax = Ext.lib.Ajax; + (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {}; + for (tid in conn) { + c = conn[tid]; + if (c) { + ajax.abort({conn: c, tId: tid}); + } + } + }, + + onDocumentReady : function(fn, scope, options){ + if (Ext.isReady) { + docReadyEvent || (docReadyEvent = new Ext.util.Event()); + docReadyEvent.addListener(fn, scope, options); + docReadyEvent.fire(); + docReadyEvent.listeners = []; + } else { + if (!docReadyEvent) { + initDocReady(); + } + options = options || {}; + options.delay = options.delay || 1; + docReadyEvent.addListener(fn, scope, options); + } + }, + + + fireDocReady : fireDocReady + }; + + pub.on = pub.addListener; + + pub.un = pub.removeListener; + + pub.stoppedMouseDownEvent = new Ext.util.Event(); + return pub; +}(); + +Ext.onReady = Ext.EventManager.onDocumentReady; + + + +(function(){ + var initExtCss = function() { + + var bd = document.body || document.getElementsByTagName('body')[0]; + if (!bd) { + return false; + } + + var cls = []; + + if (Ext.isIE) { + + if (!Ext.isIE10p) { + cls.push('ext-ie'); + } + if (Ext.isIE6) { + cls.push('ext-ie6'); + } else if (Ext.isIE7) { + cls.push('ext-ie7', 'ext-ie7m'); + } else if (Ext.isIE8) { + cls.push('ext-ie8', 'ext-ie8m'); + } else if (Ext.isIE9) { + cls.push('ext-ie9', 'ext-ie9m'); + } else if (Ext.isIE10) { + cls.push('ext-ie10'); + } + } + + if (Ext.isGecko) { + if (Ext.isGecko2) { + cls.push('ext-gecko2'); + } else { + cls.push('ext-gecko3'); + } + } + + if (Ext.isOpera) { + cls.push('ext-opera'); + } + + if (Ext.isWebKit) { + cls.push('ext-webkit'); + } + + if (Ext.isSafari) { + cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4'))); + } else if(Ext.isChrome) { + cls.push("ext-chrome"); + } + + if (Ext.isMac) { + cls.push("ext-mac"); + } + if (Ext.isLinux) { + cls.push("ext-linux"); + } + + + if (Ext.isStrict || Ext.isBorderBox) { + var p = bd.parentNode; + if (p) { + if (!Ext.isStrict) { + Ext.fly(p, '_internal').addClass('x-quirks'); + if (Ext.isIE9m && !Ext.isStrict) { + Ext.isIEQuirks = true; + } + } + Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box'); + } + } + + + if (Ext.enableForcedBoxModel && !Ext.isIE) { + Ext.isForcedBorderBox = true; + cls.push("ext-forced-border-box"); + } + + Ext.fly(bd, '_internal').addClass(cls); + return true; + }; + + if (!initExtCss()) { + Ext.onReady(initExtCss); + } +})(); + + +(function(){ + + var supports = Ext.apply(Ext.supports, { + + correctRightMargin: true, + + + correctTransparentColor: true, + + + cssFloat: true + }); + + var supportTests = function(){ + var div = document.createElement('div'), + doc = document, + view, + last; + + div.innerHTML = '
'; + doc.body.appendChild(div); + last = div.lastChild; + + if((view = doc.defaultView)){ + if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){ + supports.correctRightMargin = false; + } + if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){ + supports.correctTransparentColor = false; + } + } + supports.cssFloat = !!last.style.cssFloat; + doc.body.removeChild(div); + }; + + if (Ext.isReady) { + supportTests(); + } else { + Ext.onReady(supportTests); + } +})(); + + + +Ext.EventObject = function(){ + var E = Ext.lib.Event, + clickRe = /(dbl)?click/, + + safariKeys = { + 3 : 13, + 63234 : 37, + 63235 : 39, + 63232 : 38, + 63233 : 40, + 63276 : 33, + 63277 : 34, + 63272 : 46, + 63273 : 36, + 63275 : 35 + }, + + btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2}; + + Ext.EventObjectImpl = function(e){ + if(e){ + this.setEvent(e.browserEvent || e); + } + }; + + Ext.EventObjectImpl.prototype = { + + setEvent : function(e){ + var me = this; + if(e == me || (e && e.browserEvent)){ + return e; + } + me.browserEvent = e; + if(e){ + + me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1); + if(clickRe.test(e.type) && me.button == -1){ + me.button = 0; + } + me.type = e.type; + me.shiftKey = e.shiftKey; + + me.ctrlKey = e.ctrlKey || e.metaKey || false; + me.altKey = e.altKey; + + me.keyCode = e.keyCode; + me.charCode = e.charCode; + + me.target = E.getTarget(e); + + me.xy = E.getXY(e); + }else{ + me.button = -1; + me.shiftKey = false; + me.ctrlKey = false; + me.altKey = false; + me.keyCode = 0; + me.charCode = 0; + me.target = null; + me.xy = [0, 0]; + } + return me; + }, + + + stopEvent : function(){ + var me = this; + if(me.browserEvent){ + if(me.browserEvent.type == 'mousedown'){ + Ext.EventManager.stoppedMouseDownEvent.fire(me); + } + E.stopEvent(me.browserEvent); + } + }, + + + preventDefault : function(){ + if(this.browserEvent){ + E.preventDefault(this.browserEvent); + } + }, + + + stopPropagation : function(){ + var me = this; + if(me.browserEvent){ + if(me.browserEvent.type == 'mousedown'){ + Ext.EventManager.stoppedMouseDownEvent.fire(me); + } + E.stopPropagation(me.browserEvent); + } + }, + + + getCharCode : function(){ + return this.charCode || this.keyCode; + }, + + + getKey : function(){ + return this.normalizeKey(this.keyCode || this.charCode); + }, + + + normalizeKey: function(k){ + return Ext.isSafari ? (safariKeys[k] || k) : k; + }, + + + getPageX : function(){ + return this.xy[0]; + }, + + + getPageY : function(){ + return this.xy[1]; + }, + + + getXY : function(){ + return this.xy; + }, + + + getTarget : function(selector, maxDepth, returnEl){ + return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target); + }, + + + getRelatedTarget : function(){ + return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null; + }, + + + getWheelDelta : function(){ + var e = this.browserEvent; + var delta = 0; + if(e.wheelDelta){ + delta = e.wheelDelta/120; + }else if(e.detail){ + delta = -e.detail/3; + } + return delta; + }, + + + within : function(el, related, allowEl){ + if(el){ + var t = this[related ? "getRelatedTarget" : "getTarget"](); + return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t)); + } + return false; + } + }; + + return new Ext.EventObjectImpl(); +}(); +Ext.Loader = Ext.apply({}, { + + load: function(fileList, callback, scope, preserveOrder) { + var scope = scope || this, + head = document.getElementsByTagName("head")[0], + fragment = document.createDocumentFragment(), + numFiles = fileList.length, + loadedFiles = 0, + me = this; + + + var loadFileIndex = function(index) { + head.appendChild( + me.buildScriptTag(fileList[index], onFileLoaded) + ); + }; + + + var onFileLoaded = function() { + loadedFiles ++; + + + if (numFiles == loadedFiles && typeof callback == 'function') { + callback.call(scope); + } else { + if (preserveOrder === true) { + loadFileIndex(loadedFiles); + } + } + }; + + if (preserveOrder === true) { + loadFileIndex.call(this, 0); + } else { + + Ext.each(fileList, function(file, index) { + fragment.appendChild( + this.buildScriptTag(file, onFileLoaded) + ); + }, this); + + head.appendChild(fragment); + } + }, + + + buildScriptTag: function(filename, callback) { + var script = document.createElement('script'); + script.type = "text/javascript"; + script.src = filename; + + + if (script.readyState) { + script.onreadystatechange = function() { + if (script.readyState == "loaded" || script.readyState == "complete") { + script.onreadystatechange = null; + callback(); + } + }; + } else { + script.onload = callback; + } + + return script; + } +}); + + +Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu", + "Ext.state", "Ext.layout.boxOverflow", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct", "Ext.slider"); + + +Ext.apply(Ext, function(){ + var E = Ext, + idSeed = 0, + scrollWidth = null; + + return { + + emptyFn : function(){}, + + + BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ? + 'http:/' + '/www.extjs.com/s.gif' : + 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + + extendX : function(supr, fn){ + return Ext.extend(supr, fn(supr.prototype)); + }, + + + getDoc : function(){ + return Ext.get(document); + }, + + + num : function(v, defaultValue){ + v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v); + return isNaN(v) ? defaultValue : v; + }, + + + value : function(v, defaultValue, allowBlank){ + return Ext.isEmpty(v, allowBlank) ? defaultValue : v; + }, + + + escapeRe : function(s) { + return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); + }, + + sequence : function(o, name, fn, scope){ + o[name] = o[name].createSequence(fn, scope); + }, + + + addBehaviors : function(o){ + if(!Ext.isReady){ + Ext.onReady(function(){ + Ext.addBehaviors(o); + }); + } else { + var cache = {}, + parts, + b, + s; + for (b in o) { + if ((parts = b.split('@'))[1]) { + s = parts[0]; + if(!cache[s]){ + cache[s] = Ext.select(s); + } + cache[s].on(parts[1], o[b]); + } + } + cache = null; + } + }, + + + getScrollBarWidth: function(force){ + if(!Ext.isReady){ + return 0; + } + + if(force === true || scrollWidth === null){ + + var div = Ext.getBody().createChild('
'), + child = div.child('div', true); + var w1 = child.offsetWidth; + div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); + var w2 = child.offsetWidth; + div.remove(); + + scrollWidth = w1 - w2 + 2; + } + return scrollWidth; + }, + + + + combine : function(){ + var as = arguments, l = as.length, r = []; + for(var i = 0; i < l; i++){ + var a = as[i]; + if(Ext.isArray(a)){ + r = r.concat(a); + }else if(a.length !== undefined && !a.substr){ + r = r.concat(Array.prototype.slice.call(a, 0)); + }else{ + r.push(a); + } + } + return r; + }, + + + copyTo : function(dest, source, names){ + if(typeof names == 'string'){ + names = names.split(/[,;\s]/); + } + Ext.each(names, function(name){ + if(source.hasOwnProperty(name)){ + dest[name] = source[name]; + } + }, this); + return dest; + }, + + + destroy : function(){ + Ext.each(arguments, function(arg){ + if(arg){ + if(Ext.isArray(arg)){ + this.destroy.apply(this, arg); + }else if(typeof arg.destroy == 'function'){ + arg.destroy(); + }else if(arg.dom){ + arg.remove(); + } + } + }, this); + }, + + + destroyMembers : function(o, arg1, arg2, etc){ + for(var i = 1, a = arguments, len = a.length; i < len; i++) { + Ext.destroy(o[a[i]]); + delete o[a[i]]; + } + }, + + + clean : function(arr){ + var ret = []; + Ext.each(arr, function(v){ + if(!!v){ + ret.push(v); + } + }); + return ret; + }, + + + unique : function(arr){ + var ret = [], + collect = {}; + + Ext.each(arr, function(v) { + if(!collect[v]){ + ret.push(v); + } + collect[v] = true; + }); + return ret; + }, + + + flatten : function(arr){ + var worker = []; + function rFlatten(a) { + Ext.each(a, function(v) { + if(Ext.isArray(v)){ + rFlatten(v); + }else{ + worker.push(v); + } + }); + return worker; + } + return rFlatten(arr); + }, + + + min : function(arr, comp){ + var ret = arr[0]; + comp = comp || function(a,b){ return a < b ? -1 : 1; }; + Ext.each(arr, function(v) { + ret = comp(ret, v) == -1 ? ret : v; + }); + return ret; + }, + + + max : function(arr, comp){ + var ret = arr[0]; + comp = comp || function(a,b){ return a > b ? 1 : -1; }; + Ext.each(arr, function(v) { + ret = comp(ret, v) == 1 ? ret : v; + }); + return ret; + }, + + + mean : function(arr){ + return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined; + }, + + + sum : function(arr){ + var ret = 0; + Ext.each(arr, function(v) { + ret += v; + }); + return ret; + }, + + + partition : function(arr, truth){ + var ret = [[],[]]; + Ext.each(arr, function(v, i, a) { + ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v); + }); + return ret; + }, + + + invoke : function(arr, methodName){ + var ret = [], + args = Array.prototype.slice.call(arguments, 2); + Ext.each(arr, function(v,i) { + if (v && typeof v[methodName] == 'function') { + ret.push(v[methodName].apply(v, args)); + } else { + ret.push(undefined); + } + }); + return ret; + }, + + + pluck : function(arr, prop){ + var ret = []; + Ext.each(arr, function(v) { + ret.push( v[prop] ); + }); + return ret; + }, + + + zip : function(){ + var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }), + arrs = parts[0], + fn = parts[1][0], + len = Ext.max(Ext.pluck(arrs, "length")), + ret = []; + + for (var i = 0; i < len; i++) { + ret[i] = []; + if(fn){ + ret[i] = fn.apply(fn, Ext.pluck(arrs, i)); + }else{ + for (var j = 0, aLen = arrs.length; j < aLen; j++){ + ret[i].push( arrs[j][i] ); + } + } + } + return ret; + }, + + + getCmp : function(id){ + return Ext.ComponentMgr.get(id); + }, + + + useShims: E.isIE6 || (E.isMac && E.isGecko2), + + + + type : function(o){ + if(o === undefined || o === null){ + return false; + } + if(o.htmlElement){ + return 'element'; + } + var t = typeof o; + if(t == 'object' && o.nodeName) { + switch(o.nodeType) { + case 1: return 'element'; + case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace'; + } + } + if(t == 'object' || t == 'function') { + switch(o.constructor) { + case Array: return 'array'; + case RegExp: return 'regexp'; + case Date: return 'date'; + } + if(typeof o.length == 'number' && typeof o.item == 'function') { + return 'nodelist'; + } + } + return t; + }, + + intercept : function(o, name, fn, scope){ + o[name] = o[name].createInterceptor(fn, scope); + }, + + + callback : function(cb, scope, args, delay){ + if(typeof cb == 'function'){ + if(delay){ + cb.defer(delay, scope, args || []); + }else{ + cb.apply(scope, args || []); + } + } + } + }; +}()); + + +Ext.apply(Function.prototype, { + + createSequence : function(fcn, scope){ + var method = this; + return (typeof fcn != 'function') ? + this : + function(){ + var retval = method.apply(this || window, arguments); + fcn.apply(scope || this || window, arguments); + return retval; + }; + } +}); + + + +Ext.applyIf(String, { + + + escape : function(string) { + return string.replace(/('|\\)/g, "\\$1"); + }, + + + leftPad : function (val, size, ch) { + var result = String(val); + if(!ch) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result; + } +}); + + +String.prototype.toggle = function(value, other){ + return this == value ? other : value; +}; + + +String.prototype.trim = function(){ + var re = /^\s+|\s+$/g; + return function(){ return this.replace(re, ""); }; +}(); + + + +Date.prototype.getElapsed = function(date) { + return Math.abs((date || new Date()).getTime()-this.getTime()); +}; + + + +Ext.applyIf(Number.prototype, { + + constrain : function(min, max){ + return Math.min(Math.max(this, min), max); + } +}); +Ext.lib.Dom.getRegion = function(el) { + return Ext.lib.Region.getRegion(el); +}; Ext.lib.Region = function(t, r, b, l) { + var me = this; + me.top = t; + me[1] = t; + me.right = r; + me.bottom = b; + me.left = l; + me[0] = l; + }; + + Ext.lib.Region.prototype = { + contains : function(region) { + var me = this; + return ( region.left >= me.left && + region.right <= me.right && + region.top >= me.top && + region.bottom <= me.bottom ); + + }, + + getArea : function() { + var me = this; + return ( (me.bottom - me.top) * (me.right - me.left) ); + }, + + intersect : function(region) { + var me = this, + t = Math.max(me.top, region.top), + r = Math.min(me.right, region.right), + b = Math.min(me.bottom, region.bottom), + l = Math.max(me.left, region.left); + + if (b >= t && r >= l) { + return new Ext.lib.Region(t, r, b, l); + } + }, + + union : function(region) { + var me = this, + t = Math.min(me.top, region.top), + r = Math.max(me.right, region.right), + b = Math.max(me.bottom, region.bottom), + l = Math.min(me.left, region.left); + + return new Ext.lib.Region(t, r, b, l); + }, + + constrainTo : function(r) { + var me = this; + me.top = me.top.constrain(r.top, r.bottom); + me.bottom = me.bottom.constrain(r.top, r.bottom); + me.left = me.left.constrain(r.left, r.right); + me.right = me.right.constrain(r.left, r.right); + return me; + }, + + adjust : function(t, l, b, r) { + var me = this; + me.top += t; + me.left += l; + me.right += r; + me.bottom += b; + return me; + } + }; + + Ext.lib.Region.getRegion = function(el) { + var p = Ext.lib.Dom.getXY(el), + t = p[1], + r = p[0] + el.offsetWidth, + b = p[1] + el.offsetHeight, + l = p[0]; + + return new Ext.lib.Region(t, r, b, l); + }; Ext.lib.Point = function(x, y) { + if (Ext.isArray(x)) { + y = x[1]; + x = x[0]; + } + var me = this; + me.x = me.right = me.left = me[0] = x; + me.y = me.top = me.bottom = me[1] = y; + }; + + Ext.lib.Point.prototype = new Ext.lib.Region(); + +Ext.apply(Ext.DomHelper, +function(){ + var pub, + afterbegin = 'afterbegin', + afterend = 'afterend', + beforebegin = 'beforebegin', + beforeend = 'beforeend', + confRe = /tag|children|cn|html$/i; + + + function doInsert(el, o, returnElement, pos, sibling, append){ + el = Ext.getDom(el); + var newNode; + if (pub.useDom) { + newNode = createDom(o, null); + if (append) { + el.appendChild(newNode); + } else { + (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el); + } + } else { + newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o)); + } + return returnElement ? Ext.get(newNode, true) : newNode; + } + + + + function createDom(o, parentNode){ + var el, + doc = document, + useSet, + attr, + val, + cn; + + if (Ext.isArray(o)) { + el = doc.createDocumentFragment(); + for (var i = 0, l = o.length; i < l; i++) { + createDom(o[i], el); + } + } else if (typeof o == 'string') { + el = doc.createTextNode(o); + } else { + el = doc.createElement( o.tag || 'div' ); + useSet = !!el.setAttribute; + for (var attr in o) { + if(!confRe.test(attr)){ + val = o[attr]; + if(attr == 'cls'){ + el.className = val; + }else{ + if(useSet){ + el.setAttribute(attr, val); + }else{ + el[attr] = val; + } + } + } + } + Ext.DomHelper.applyStyles(el, o.style); + + if ((cn = o.children || o.cn)) { + createDom(cn, el); + } else if (o.html) { + el.innerHTML = o.html; + } + } + if(parentNode){ + parentNode.appendChild(el); + } + return el; + } + + pub = { + + createTemplate : function(o){ + var html = Ext.DomHelper.createHtml(o); + return new Ext.Template(html); + }, + + + useDom : false, + + + insertBefore : function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforebegin); + }, + + + insertAfter : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterend, 'nextSibling'); + }, + + + insertFirst : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterbegin, 'firstChild'); + }, + + + append: function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforeend, '', true); + }, + + + createDom: createDom + }; + return pub; +}()); + +Ext.apply(Ext.Template.prototype, { + + disableFormats : false, + + + + re : /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, + argsRe : /^\s*['"](.*)["']\s*$/, + compileARe : /\\/g, + compileBRe : /(\r\n|\n)/g, + compileCRe : /'/g, + + /** + * Returns an HTML fragment of this template with the specified values applied. + * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) + * @return {String} The HTML fragment + * @hide repeat doc + */ + applyTemplate : function(values){ + var me = this, + useF = me.disableFormats !== true, + fm = Ext.util.Format, + tpl = me; + + if(me.compiled){ + return me.compiled(values); + } + function fn(m, name, format, args){ + if (format && useF) { + if (format.substr(0, 5) == "this.") { + return tpl.call(format.substr(5), values[name], values); + } else { + if (args) { + // quoted values are required for strings in compiled templates, + // but for non compiled we need to strip them + // quoted reversed for jsmin + var re = me.argsRe; + args = args.split(','); + for(var i = 0, len = args.length; i < len; i++){ + args[i] = args[i].replace(re, "$1"); + } + args = [values[name]].concat(args); + } else { + args = [values[name]]; + } + return fm[format].apply(fm, args); + } + } else { + return values[name] !== undefined ? values[name] : ""; + } + } + return me.html.replace(me.re, fn); + }, + + /** + * Compiles the template into an internal function, eliminating the RegEx overhead. + * @return {Ext.Template} this + * @hide repeat doc + */ + compile : function(){ + var me = this, + fm = Ext.util.Format, + useF = me.disableFormats !== true, + sep = Ext.isGecko ? "+" : ",", + body; + + function fn(m, name, format, args){ + if(format && useF){ + args = args ? ',' + args : ""; + if(format.substr(0, 5) != "this."){ + format = "fm." + format + '('; + }else{ + format = 'this.call("'+ format.substr(5) + '", '; + args = ", values"; + } + }else{ + args= ''; format = "(values['" + name + "'] == undefined ? '' : "; + } + return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'"; + } + + // branched to use + in gecko and [].join() in others + if(Ext.isGecko){ + body = "this.compiled = function(values){ return '" + + me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) + + "';};"; + }else{ + body = ["this.compiled = function(values){ return ['"]; + body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn)); + body.push("'].join('');};"); + body = body.join(''); + } + eval(body); + return me; + }, + + // private function used to call members + call : function(fnName, value, allValues){ + return this[fnName](value, allValues); + } +}); +Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; +/** + * @class Ext.util.Functions + * @singleton + */ +Ext.util.Functions = { + /** + * Creates an interceptor function. The passed function is called before the original one. If it returns false, + * the original one is not called. The resulting function returns the results of the original function. + * The passed function is called with the parameters of the original function. Example usage: + *

+var sayHi = function(name){
+    alert('Hi, ' + name);
+}
+
+sayHi('Fred'); // alerts "Hi, Fred"
+
+// create a new function that validates input without
+// directly modifying the original function:
+var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
+    return name == 'Brian';
+});
+
+sayHiToFriend('Fred');  // no alert
+sayHiToFriend('Brian'); // alerts "Hi, Brian"
+       
+ * @param {Function} origFn The original function. + * @param {Function} newFn The function to call before the original + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + */ + createInterceptor: function(origFn, newFn, scope) { + var method = origFn; + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var me = this, + args = arguments; + newFn.target = me; + newFn.method = origFn; + return (newFn.apply(scope || me || window, args) !== false) ? + origFn.apply(me || window, args) : + null; + }; + } + }, + + /** + * Creates a delegate (callback) that sets the scope to obj. + * Call directly on any function. Example: Ext.createDelegate(this.myFunction, this, [arg1, arg2]) + * Will create a function that is automatically scoped to obj so that the this variable inside the + * callback points to obj. Example usage: + *

+var sayHi = function(name){
+    // Note this use of "this.text" here.  This function expects to
+    // execute within a scope that contains a text property.  In this
+    // example, the "this" variable is pointing to the btn object that
+    // was passed in createDelegate below.
+    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
+}
+
+var btn = new Ext.Button({
+    text: 'Say Hi',
+    renderTo: Ext.getBody()
+});
+
+// This callback will execute in the scope of the
+// button instance. Clicking the button alerts
+// "Hi, Fred. You clicked the "Say Hi" button."
+btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
+       
+ * @param {Function} fn The function to delegate. + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Function} The new function + */ + createDelegate: function(fn, obj, args, appendArgs) { + if (!Ext.isFunction(fn)) { + return fn; + } + return function() { + var callArgs = args || arguments; + if (appendArgs === true) { + callArgs = Array.prototype.slice.call(arguments, 0); + callArgs = callArgs.concat(args); + } + else if (Ext.isNumber(appendArgs)) { + callArgs = Array.prototype.slice.call(arguments, 0); + // copy arguments first + var applyArgs = [appendArgs, 0].concat(args); + // create method call params + Array.prototype.splice.apply(callArgs, applyArgs); + // splice them in + } + return fn.apply(obj || window, callArgs); + }; + }, + + /** + * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: + *

+var sayHi = function(name){
+    alert('Hi, ' + name);
+}
+
+// executes immediately:
+sayHi('Fred');
+
+// executes after 2 seconds:
+Ext.defer(sayHi, 2000, this, ['Fred']);
+
+// this syntax is sometimes useful for deferring
+// execution of an anonymous function:
+Ext.defer(function(){
+    alert('Anonymous');
+}, 100);
+       
+ * @param {Function} fn The function to defer. + * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Number} The timeout id that can be used with clearTimeout + */ + defer: function(fn, millis, obj, args, appendArgs) { + fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs); + if (millis > 0) { + return setTimeout(fn, millis); + } + fn(); + return 0; + }, + + + /** + * Create a combined function call sequence of the original function + the passed function. + * The resulting function returns the results of the original function. + * The passed fcn is called with the parameters of the original function. Example usage: + * + +var sayHi = function(name){ + alert('Hi, ' + name); +} + +sayHi('Fred'); // alerts "Hi, Fred" + +var sayGoodbye = Ext.createSequence(sayHi, function(name){ + alert('Bye, ' + name); +}); + +sayGoodbye('Fred'); // both alerts show + + * @param {Function} origFn The original function. + * @param {Function} newFn The function to sequence + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + */ + createSequence: function(origFn, newFn, scope) { + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var retval = origFn.apply(this || window, arguments); + newFn.apply(scope || this || window, arguments); + return retval; + }; + } + } +}; + +/** + * Shorthand for {@link Ext.util.Functions#defer} + * @param {Function} fn The function to defer. + * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Number} The timeout id that can be used with clearTimeout + * @member Ext + * @method defer + */ + +Ext.defer = Ext.util.Functions.defer; + +/** + * Shorthand for {@link Ext.util.Functions#createInterceptor} + * @param {Function} origFn The original function. + * @param {Function} newFn The function to call before the original + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + * @member Ext + * @method createInterceptor + */ + +Ext.createInterceptor = Ext.util.Functions.createInterceptor; + +/** + * Shorthand for {@link Ext.util.Functions#createSequence} + * @param {Function} origFn The original function. + * @param {Function} newFn The function to sequence + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + * @member Ext + * @method createSequence + */ + +Ext.createSequence = Ext.util.Functions.createSequence; + +/** + * Shorthand for {@link Ext.util.Functions#createDelegate} + * @param {Function} fn The function to delegate. + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Function} The new function + * @member Ext + * @method createDelegate + */ +Ext.createDelegate = Ext.util.Functions.createDelegate; +/** + * @class Ext.util.Observable + */ +Ext.apply(Ext.util.Observable.prototype, function(){ + // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?) + // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call + // private + function getMethodEvent(method){ + var e = (this.methodEvents = this.methodEvents || + {})[method], returnValue, v, cancel, obj = this; + + if (!e) { + this.methodEvents[method] = e = {}; + e.originalFn = this[method]; + e.methodName = method; + e.before = []; + e.after = []; + + var makeCall = function(fn, scope, args){ + if((v = fn.apply(scope || obj, args)) !== undefined){ + if (typeof v == 'object') { + if(v.returnValue !== undefined){ + returnValue = v.returnValue; + }else{ + returnValue = v; + } + cancel = !!v.cancel; + } + else + if (v === false) { + cancel = true; + } + else { + returnValue = v; + } + } + }; + + this[method] = function(){ + var args = Array.prototype.slice.call(arguments, 0), + b; + returnValue = v = undefined; + cancel = false; + + for(var i = 0, len = e.before.length; i < len; i++){ + b = e.before[i]; + makeCall(b.fn, b.scope, args); + if (cancel) { + return returnValue; + } + } + + if((v = e.originalFn.apply(obj, args)) !== undefined){ + returnValue = v; + } + + for(var i = 0, len = e.after.length; i < len; i++){ + b = e.after[i]; + makeCall(b.fn, b.scope, args); + if (cancel) { + return returnValue; + } + } + return returnValue; + }; + } + return e; + } + + return { + // these are considered experimental + // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call + // adds an 'interceptor' called before the original method + beforeMethod : function(method, fn, scope){ + getMethodEvent.call(this, method).before.push({ + fn: fn, + scope: scope + }); + }, + + // adds a 'sequence' called after the original method + afterMethod : function(method, fn, scope){ + getMethodEvent.call(this, method).after.push({ + fn: fn, + scope: scope + }); + }, + + removeMethodListener: function(method, fn, scope){ + var e = this.getMethodEvent(method); + for(var i = 0, len = e.before.length; i < len; i++){ + if(e.before[i].fn == fn && e.before[i].scope == scope){ + e.before.splice(i, 1); + return; + } + } + for(var i = 0, len = e.after.length; i < len; i++){ + if(e.after[i].fn == fn && e.after[i].scope == scope){ + e.after.splice(i, 1); + return; + } + } + }, + + /** + * Relays selected events from the specified Observable as if the events were fired by this. + * @param {Object} o The Observable whose events this object is to relay. + * @param {Array} events Array of event names to relay. + */ + relayEvents : function(o, events){ + var me = this; + function createHandler(ename){ + return function(){ + return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0))); + }; + } + for(var i = 0, len = events.length; i < len; i++){ + var ename = events[i]; + me.events[ename] = me.events[ename] || true; + o.on(ename, createHandler(ename), me); + } + }, + + /** + *

Enables events fired by this Observable to bubble up an owner hierarchy by calling + * this.getBubbleTarget() if present. There is no implementation in the Observable base class.

+ *

This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default + * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to + * access the required target more quickly.

+ *

Example:


+Ext.override(Ext.form.Field, {
+
+    initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
+        this.enableBubble('change');
+    }),
+
+
+    getBubbleTarget : function() {
+        if (!this.formPanel) {
+            this.formPanel = this.findParentByType('form');
+        }
+        return this.formPanel;
+    }
+});
+
+var myForm = new Ext.formPanel({
+    title: 'User Details',
+    items: [{
+        ...
+    }],
+    listeners: {
+        change: function() {
+
+            myForm.header.setStyle('color', 'red');
+        }
+    }
+});
+
+ * @param {String/Array} events The event name to bubble, or an Array of event names. + */ + enableBubble : function(events){ + var me = this; + if(!Ext.isEmpty(events)){ + events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0); + for(var i = 0, len = events.length; i < len; i++){ + var ename = events[i]; + ename = ename.toLowerCase(); + var ce = me.events[ename] || true; + if (typeof ce == 'boolean') { + ce = new Ext.util.Event(me, ename); + me.events[ename] = ce; + } + ce.bubble = true; + } + } + } + }; +}()); + + + +Ext.util.Observable.capture = function(o, fn, scope){ + o.fireEvent = o.fireEvent.createInterceptor(fn, scope); +}; + + + +Ext.util.Observable.observeClass = function(c, listeners){ + if(c){ + if(!c.fireEvent){ + Ext.apply(c, new Ext.util.Observable()); + Ext.util.Observable.capture(c.prototype, c.fireEvent, c); + } + if(typeof listeners == 'object'){ + c.on(listeners); + } + return c; + } +}; + +Ext.apply(Ext.EventManager, function(){ + var resizeEvent, + resizeTask, + textEvent, + textSize, + D = Ext.lib.Dom, + propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/, + unload = Ext.EventManager._unload, + curWidth = 0, + curHeight = 0, + + + + useKeydown = Ext.isWebKit ? + Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 : + !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera); + + return { + _unload: function(){ + Ext.EventManager.un(window, "resize", this.fireWindowResize, this); + unload.call(Ext.EventManager); + }, + + + doResizeEvent: function(){ + var h = D.getViewHeight(), + w = D.getViewWidth(); + + + if(curHeight != h || curWidth != w){ + resizeEvent.fire(curWidth = w, curHeight = h); + } + }, + + + onWindowResize : function(fn, scope, options){ + if(!resizeEvent){ + resizeEvent = new Ext.util.Event(); + resizeTask = new Ext.util.DelayedTask(this.doResizeEvent); + Ext.EventManager.on(window, "resize", this.fireWindowResize, this); + } + resizeEvent.addListener(fn, scope, options); + }, + + + fireWindowResize : function(){ + if(resizeEvent){ + resizeTask.delay(100); + } + }, + + + onTextResize : function(fn, scope, options){ + if(!textEvent){ + textEvent = new Ext.util.Event(); + var textEl = new Ext.Element(document.createElement('div')); + textEl.dom.className = 'x-text-resize'; + textEl.dom.innerHTML = 'X'; + textEl.appendTo(document.body); + textSize = textEl.dom.offsetHeight; + setInterval(function(){ + if(textEl.dom.offsetHeight != textSize){ + textEvent.fire(textSize, textSize = textEl.dom.offsetHeight); + } + }, this.textResizeInterval); + } + textEvent.addListener(fn, scope, options); + }, + + + removeResizeListener : function(fn, scope){ + if(resizeEvent){ + resizeEvent.removeListener(fn, scope); + } + }, + + + fireResize : function(){ + if(resizeEvent){ + resizeEvent.fire(D.getViewWidth(), D.getViewHeight()); + } + }, + + + textResizeInterval : 50, + + + ieDeferSrc : false, + + + getKeyEvent : function(){ + return useKeydown ? 'keydown' : 'keypress'; + }, + + + + useKeydown: useKeydown + }; +}()); + +Ext.EventManager.on = Ext.EventManager.addListener; + + +Ext.apply(Ext.EventObjectImpl.prototype, { + + BACKSPACE: 8, + + TAB: 9, + + NUM_CENTER: 12, + + ENTER: 13, + + RETURN: 13, + + SHIFT: 16, + + CTRL: 17, + CONTROL : 17, + + ALT: 18, + + PAUSE: 19, + + CAPS_LOCK: 20, + + ESC: 27, + + SPACE: 32, + + PAGE_UP: 33, + PAGEUP : 33, + + PAGE_DOWN: 34, + PAGEDOWN : 34, + + END: 35, + + HOME: 36, + + LEFT: 37, + + UP: 38, + + RIGHT: 39, + + DOWN: 40, + + PRINT_SCREEN: 44, + + INSERT: 45, + + DELETE: 46, + + ZERO: 48, + + ONE: 49, + + TWO: 50, + + THREE: 51, + + FOUR: 52, + + FIVE: 53, + + SIX: 54, + + SEVEN: 55, + + EIGHT: 56, + + NINE: 57, + + A: 65, + + B: 66, + + C: 67, + + D: 68, + + E: 69, + + F: 70, + + G: 71, + + H: 72, + + I: 73, + + J: 74, + + K: 75, + + L: 76, + + M: 77, + + N: 78, + + O: 79, + + P: 80, + + Q: 81, + + R: 82, + + S: 83, + + T: 84, + + U: 85, + + V: 86, + + W: 87, + + X: 88, + + Y: 89, + + Z: 90, + + CONTEXT_MENU: 93, + + NUM_ZERO: 96, + + NUM_ONE: 97, + + NUM_TWO: 98, + + NUM_THREE: 99, + + NUM_FOUR: 100, + + NUM_FIVE: 101, + + NUM_SIX: 102, + + NUM_SEVEN: 103, + + NUM_EIGHT: 104, + + NUM_NINE: 105, + + NUM_MULTIPLY: 106, + + NUM_PLUS: 107, + + NUM_MINUS: 109, + + NUM_PERIOD: 110, + + NUM_DIVISION: 111, + + F1: 112, + + F2: 113, + + F3: 114, + + F4: 115, + + F5: 116, + + F6: 117, + + F7: 118, + + F8: 119, + + F9: 120, + + F10: 121, + + F11: 122, + + F12: 123, + + + isNavKeyPress : function(){ + var me = this, + k = this.normalizeKey(me.keyCode); + return (k >= 33 && k <= 40) || + k == me.RETURN || + k == me.TAB || + k == me.ESC; + }, + + isSpecialKey : function(){ + var k = this.normalizeKey(this.keyCode); + return (this.type == 'keypress' && this.ctrlKey) || + this.isNavKeyPress() || + (k == this.BACKSPACE) || + (k >= 16 && k <= 20) || + (k >= 44 && k <= 46); + }, + + getPoint : function(){ + return new Ext.lib.Point(this.xy[0], this.xy[1]); + }, + + + hasModifier : function(){ + return ((this.ctrlKey || this.altKey) || this.shiftKey); + } +}); +Ext.Element.addMethods({ + + swallowEvent : function(eventName, preventDefault) { + var me = this; + function fn(e) { + e.stopPropagation(); + if (preventDefault) { + e.preventDefault(); + } + } + + if (Ext.isArray(eventName)) { + Ext.each(eventName, function(e) { + me.on(e, fn); + }); + return me; + } + me.on(eventName, fn); + return me; + }, + + + relayEvent : function(eventName, observable) { + this.on(eventName, function(e) { + observable.fireEvent(eventName, e); + }); + }, + + + clean : function(forceReclean) { + var me = this, + dom = me.dom, + n = dom.firstChild, + ni = -1; + + if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) { + return me; + } + + while (n) { + var nx = n.nextSibling; + if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) { + dom.removeChild(n); + } else { + n.nodeIndex = ++ni; + } + n = nx; + } + + Ext.Element.data(dom, 'isCleaned', true); + return me; + }, + + + load : function() { + var updateManager = this.getUpdater(); + updateManager.update.apply(updateManager, arguments); + + return this; + }, + + + getUpdater : function() { + return this.updateManager || (this.updateManager = new Ext.Updater(this)); + }, + + + update : function(html, loadScripts, callback) { + if (!this.dom) { + return this; + } + html = html || ""; + + if (loadScripts !== true) { + this.dom.innerHTML = html; + if (typeof callback == 'function') { + callback(); + } + return this; + } + + var id = Ext.id(), + dom = this.dom; + + html += ''; + + Ext.lib.Event.onAvailable(id, function() { + var DOC = document, + hd = DOC.getElementsByTagName("head")[0], + re = /(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig, + srcRe = /\ssrc=([\'\"])(.*?)\1/i, + typeRe = /\stype=([\'\"])(.*?)\1/i, + match, + attrs, + srcMatch, + typeMatch, + el, + s; + + while ((match = re.exec(html))) { + attrs = match[1]; + srcMatch = attrs ? attrs.match(srcRe) : false; + if (srcMatch && srcMatch[2]) { + s = DOC.createElement("script"); + s.src = srcMatch[2]; + typeMatch = attrs.match(typeRe); + if (typeMatch && typeMatch[2]) { + s.type = typeMatch[2]; + } + hd.appendChild(s); + } else if (match[2] && match[2].length > 0) { + if (window.execScript) { + window.execScript(match[2]); + } else { + window.eval(match[2]); + } + } + } + + el = DOC.getElementById(id); + if (el) { + Ext.removeNode(el); + } + + if (typeof callback == 'function') { + callback(); + } + }); + dom.innerHTML = html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig, ""); + return this; + }, + + + removeAllListeners : function() { + this.removeAnchor(); + Ext.EventManager.removeAll(this.dom); + return this; + }, + + + createProxy : function(config, renderTo, matchBox) { + config = (typeof config == 'object') ? config : {tag : "div", cls: config}; + + var me = this, + proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : + Ext.DomHelper.insertBefore(me.dom, config, true); + + if (matchBox && me.setBox && me.getBox) { + proxy.setBox(me.getBox()); + } + return proxy; + } +}); + +Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater; + +Ext.Element.addMethods({ + + getAnchorXY : function(anchor, local, s){ + + + anchor = (anchor || "tl").toLowerCase(); + s = s || {}; + + var me = this, + vp = me.dom == document.body || me.dom == document, + w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(), + h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(), + xy, + r = Math.round, + o = me.getXY(), + scroll = me.getScroll(), + extraX = vp ? scroll.left : !local ? o[0] : 0, + extraY = vp ? scroll.top : !local ? o[1] : 0, + hash = { + c : [r(w * 0.5), r(h * 0.5)], + t : [r(w * 0.5), 0], + l : [0, r(h * 0.5)], + r : [w, r(h * 0.5)], + b : [r(w * 0.5), h], + tl : [0, 0], + bl : [0, h], + br : [w, h], + tr : [w, 0] + }; + + xy = hash[anchor]; + return [xy[0] + extraX, xy[1] + extraY]; + }, + + + anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){ + var me = this, + dom = me.dom, + scroll = !Ext.isEmpty(monitorScroll), + action = function(){ + Ext.fly(dom).alignTo(el, alignment, offsets, animate); + Ext.callback(callback, Ext.fly(dom)); + }, + anchor = this.getAnchor(); + + + this.removeAnchor(); + Ext.apply(anchor, { + fn: action, + scroll: scroll + }); + + Ext.EventManager.onWindowResize(action, null); + + if(scroll){ + Ext.EventManager.on(window, 'scroll', action, null, + {buffer: !isNaN(monitorScroll) ? monitorScroll : 50}); + } + action.call(me); + return me; + }, + + + removeAnchor : function(){ + var me = this, + anchor = this.getAnchor(); + + if(anchor && anchor.fn){ + Ext.EventManager.removeResizeListener(anchor.fn); + if(anchor.scroll){ + Ext.EventManager.un(window, 'scroll', anchor.fn); + } + delete anchor.fn; + } + return me; + }, + + + getAnchor : function(){ + var data = Ext.Element.data, + dom = this.dom; + if (!dom) { + return; + } + var anchor = data(dom, '_anchor'); + + if(!anchor){ + anchor = data(dom, '_anchor', {}); + } + return anchor; + }, + + + getAlignToXY : function(el, p, o){ + el = Ext.get(el); + + if(!el || !el.dom){ + throw "Element.alignToXY with an element that doesn't exist"; + } + + o = o || [0,0]; + p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase(); + + var me = this, + d = me.dom, + a1, + a2, + x, + y, + + w, + h, + r, + dw = Ext.lib.Dom.getViewWidth() -10, + dh = Ext.lib.Dom.getViewHeight()-10, + p1y, + p1x, + p2y, + p2x, + swapY, + swapX, + doc = document, + docElement = doc.documentElement, + docBody = doc.body, + scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5, + scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5, + c = false, + p1 = "", + p2 = "", + m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/); + + if(!m){ + throw "Element.alignTo with an invalid alignment " + p; + } + + p1 = m[1]; + p2 = m[2]; + c = !!m[3]; + + + + a1 = me.getAnchorXY(p1, true); + a2 = el.getAnchorXY(p2, false); + + x = a2[0] - a1[0] + o[0]; + y = a2[1] - a1[1] + o[1]; + + if(c){ + w = me.getWidth(); + h = me.getHeight(); + r = el.getRegion(); + + + + p1y = p1.charAt(0); + p1x = p1.charAt(p1.length-1); + p2y = p2.charAt(0); + p2x = p2.charAt(p2.length-1); + swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t")); + swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r")); + + + if (x + w > dw + scrollX) { + x = swapX ? r.left-w : dw+scrollX-w; + } + if (x < scrollX) { + x = swapX ? r.right : scrollX; + } + if (y + h > dh + scrollY) { + y = swapY ? r.top-h : dh+scrollY-h; + } + if (y < scrollY){ + y = swapY ? r.bottom : scrollY; + } + } + return [x,y]; + }, + + + alignTo : function(element, position, offsets, animate){ + var me = this; + return me.setXY(me.getAlignToXY(element, position, offsets), + me.preanim && !!animate ? me.preanim(arguments, 3) : false); + }, + + + adjustForConstraints : function(xy, parent, offsets){ + return this.getConstrainToXY(parent || document, false, offsets, xy) || xy; + }, + + + getConstrainToXY : function(el, local, offsets, proposedXY){ + var os = {top:0, left:0, bottom:0, right: 0}; + + return function(el, local, offsets, proposedXY){ + el = Ext.get(el); + offsets = offsets ? Ext.applyIf(offsets, os) : os; + + var vw, vh, vx = 0, vy = 0; + if(el.dom == document.body || el.dom == document){ + vw =Ext.lib.Dom.getViewWidth(); + vh = Ext.lib.Dom.getViewHeight(); + }else{ + vw = el.dom.clientWidth; + vh = el.dom.clientHeight; + if(!local){ + var vxy = el.getXY(); + vx = vxy[0]; + vy = vxy[1]; + } + } + + var s = el.getScroll(); + + vx += offsets.left + s.left; + vy += offsets.top + s.top; + + vw -= offsets.right; + vh -= offsets.bottom; + + var vr = vx + vw, + vb = vy + vh, + xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]), + x = xy[0], y = xy[1], + offset = this.getConstrainOffset(), + w = this.dom.offsetWidth + offset, + h = this.dom.offsetHeight + offset; + + + var moved = false; + + + if((x + w) > vr){ + x = vr - w; + moved = true; + } + if((y + h) > vb){ + y = vb - h; + moved = true; + } + + if(x < vx){ + x = vx; + moved = true; + } + if(y < vy){ + y = vy; + moved = true; + } + return moved ? [x, y] : false; + }; + }(), + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getConstrainOffset : function(){ + return 0; + }, + + + getCenterXY : function(){ + return this.getAlignToXY(document, 'c-c'); + }, + + + center : function(centerIn){ + return this.alignTo(centerIn || document, 'c-c'); + } +}); + +Ext.Element.addMethods({ + + select : function(selector, unique){ + return Ext.Element.select(selector, unique, this.dom); + } +}); +Ext.apply(Ext.Element.prototype, function() { + var GETDOM = Ext.getDom, + GET = Ext.get, + DH = Ext.DomHelper; + + return { + + insertSibling: function(el, where, returnDom){ + var me = this, + rt, + isAfter = (where || 'before').toLowerCase() == 'after', + insertEl; + + if(Ext.isArray(el)){ + insertEl = me; + Ext.each(el, function(e) { + rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom); + if(isAfter){ + insertEl = rt; + } + }); + return rt; + } + + el = el || {}; + + if(el.nodeType || el.dom){ + rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom); + if (!returnDom) { + rt = GET(rt); + } + }else{ + if (isAfter && !me.dom.nextSibling) { + rt = DH.append(me.dom.parentNode, el, !returnDom); + } else { + rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); + } + } + return rt; + } + }; +}()); + + +Ext.Element.boxMarkup = '
'; + +Ext.Element.addMethods(function(){ + var INTERNAL = "_internal", + pxMatch = /(\d+\.?\d+)px/; + return { + + applyStyles : function(style){ + Ext.DomHelper.applyStyles(this.dom, style); + return this; + }, + + + getStyles : function(){ + var ret = {}; + Ext.each(arguments, function(v) { + ret[v] = this.getStyle(v); + }, + this); + return ret; + }, + + + setOverflow : function(v){ + var dom = this.dom; + if(v=='auto' && Ext.isMac && Ext.isGecko2){ + dom.style.overflow = 'hidden'; + (function(){dom.style.overflow = 'auto';}).defer(1); + }else{ + dom.style.overflow = v; + } + }, + + + boxWrap : function(cls){ + cls = cls || 'x-box'; + var el = Ext.get(this.insertHtml("beforeBegin", "
" + String.format(Ext.Element.boxMarkup, cls) + "
")); + Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom); + return el; + }, + + + setSize : function(width, height, animate){ + var me = this; + if(typeof width == 'object'){ + height = width.height; + width = width.width; + } + width = me.adjustWidth(width); + height = me.adjustHeight(height); + if(!animate || !me.anim){ + me.dom.style.width = me.addUnits(width); + me.dom.style.height = me.addUnits(height); + }else{ + me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2)); + } + return me; + }, + + + getComputedHeight : function(){ + var me = this, + h = Math.max(me.dom.offsetHeight, me.dom.clientHeight); + if(!h){ + h = parseFloat(me.getStyle('height')) || 0; + if(!me.isBorderBox()){ + h += me.getFrameWidth('tb'); + } + } + return h; + }, + + + getComputedWidth : function(){ + var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth); + if(!w){ + w = parseFloat(this.getStyle('width')) || 0; + if(!this.isBorderBox()){ + w += this.getFrameWidth('lr'); + } + } + return w; + }, + + + getFrameWidth : function(sides, onlyContentBox){ + return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides)); + }, + + + addClassOnOver : function(className){ + this.hover( + function(){ + Ext.fly(this, INTERNAL).addClass(className); + }, + function(){ + Ext.fly(this, INTERNAL).removeClass(className); + } + ); + return this; + }, + + + addClassOnFocus : function(className){ + this.on("focus", function(){ + Ext.fly(this, INTERNAL).addClass(className); + }, this.dom); + this.on("blur", function(){ + Ext.fly(this, INTERNAL).removeClass(className); + }, this.dom); + return this; + }, + + + addClassOnClick : function(className){ + var dom = this.dom; + this.on("mousedown", function(){ + Ext.fly(dom, INTERNAL).addClass(className); + var d = Ext.getDoc(), + fn = function(){ + Ext.fly(dom, INTERNAL).removeClass(className); + d.removeListener("mouseup", fn); + }; + d.on("mouseup", fn); + }); + return this; + }, + + + + getViewSize : function(){ + var doc = document, + d = this.dom, + isDoc = (d == doc || d == doc.body); + + + if (isDoc) { + var extdom = Ext.lib.Dom; + return { + width : extdom.getViewWidth(), + height : extdom.getViewHeight() + }; + + + } else { + return { + width : d.clientWidth, + height : d.clientHeight + }; + } + }, + + + + getStyleSize : function(){ + var me = this, + w, h, + doc = document, + d = this.dom, + isDoc = (d == doc || d == doc.body), + s = d.style; + + + if (isDoc) { + var extdom = Ext.lib.Dom; + return { + width : extdom.getViewWidth(), + height : extdom.getViewHeight() + }; + } + + if(s.width && s.width != 'auto'){ + w = parseFloat(s.width); + if(me.isBorderBox()){ + w -= me.getFrameWidth('lr'); + } + } + + if(s.height && s.height != 'auto'){ + h = parseFloat(s.height); + if(me.isBorderBox()){ + h -= me.getFrameWidth('tb'); + } + } + + return {width: w || me.getWidth(true), height: h || me.getHeight(true)}; + }, + + + getSize : function(contentSize){ + return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)}; + }, + + + repaint : function(){ + var dom = this.dom; + this.addClass("x-repaint"); + setTimeout(function(){ + Ext.fly(dom).removeClass("x-repaint"); + }, 1); + return this; + }, + + + unselectable : function(){ + this.dom.unselectable = "on"; + return this.swallowEvent("selectstart", true). + addClass("x-unselectable"); + }, + + + getMargins : function(side){ + var me = this, + key, + hash = {t:"top", l:"left", r:"right", b: "bottom"}, + o = {}; + + if (!side) { + for (key in me.margins){ + o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0; + } + return o; + } else { + return me.addStyles.call(me, side, me.margins); + } + } + }; +}()); + +Ext.Element.addMethods({ + + setBox : function(box, adjust, animate){ + var me = this, + w = box.width, + h = box.height; + if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){ + w -= (me.getBorderWidth("lr") + me.getPadding("lr")); + h -= (me.getBorderWidth("tb") + me.getPadding("tb")); + } + me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2)); + return me; + }, + + + getBox : function(contentBox, local) { + var me = this, + xy, + left, + top, + getBorderWidth = me.getBorderWidth, + getPadding = me.getPadding, + l, + r, + t, + b; + if(!local){ + xy = me.getXY(); + }else{ + left = parseInt(me.getStyle("left"), 10) || 0; + top = parseInt(me.getStyle("top"), 10) || 0; + xy = [left, top]; + } + var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx; + if(!contentBox){ + bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h}; + }else{ + l = getBorderWidth.call(me, "l") + getPadding.call(me, "l"); + r = getBorderWidth.call(me, "r") + getPadding.call(me, "r"); + t = getBorderWidth.call(me, "t") + getPadding.call(me, "t"); + b = getBorderWidth.call(me, "b") + getPadding.call(me, "b"); + bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)}; + } + bx.right = bx.x + bx.width; + bx.bottom = bx.y + bx.height; + return bx; + }, + + + move : function(direction, distance, animate){ + var me = this, + xy = me.getXY(), + x = xy[0], + y = xy[1], + left = [x - distance, y], + right = [x + distance, y], + top = [x, y - distance], + bottom = [x, y + distance], + hash = { + l : left, + left : left, + r : right, + right : right, + t : top, + top : top, + up : top, + b : bottom, + bottom : bottom, + down : bottom + }; + + direction = direction.toLowerCase(); + me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2)); + }, + + + setLeftTop : function(left, top){ + var me = this, + style = me.dom.style; + style.left = me.addUnits(left); + style.top = me.addUnits(top); + return me; + }, + + + getRegion : function(){ + return Ext.lib.Dom.getRegion(this.dom); + }, + + + setBounds : function(x, y, width, height, animate){ + var me = this; + if (!animate || !me.anim) { + me.setSize(width, height); + me.setLocation(x, y); + } else { + me.anim({points: {to: [x, y]}, + width: {to: me.adjustWidth(width)}, + height: {to: me.adjustHeight(height)}}, + me.preanim(arguments, 4), + 'motion'); + } + return me; + }, + + + setRegion : function(region, animate) { + return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1)); + } +}); +Ext.Element.addMethods({ + + scrollTo : function(side, value, animate) { + + var top = /top/i.test(side), + me = this, + dom = me.dom, + prop; + if (!animate || !me.anim) { + + prop = 'scroll' + (top ? 'Top' : 'Left'); + dom[prop] = value; + } + else { + + prop = 'scroll' + (top ? 'Left' : 'Top'); + me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll'); + } + return me; + }, + + + scrollIntoView : function(container, hscroll) { + var c = Ext.getDom(container) || Ext.getBody().dom, + el = this.dom, + o = this.getOffsetsTo(c), + l = o[0] + c.scrollLeft, + t = o[1] + c.scrollTop, + b = t + el.offsetHeight, + r = l + el.offsetWidth, + ch = c.clientHeight, + ct = parseInt(c.scrollTop, 10), + cl = parseInt(c.scrollLeft, 10), + cb = ct + ch, + cr = cl + c.clientWidth; + + if (el.offsetHeight > ch || t < ct) { + c.scrollTop = t; + } + else if (b > cb) { + c.scrollTop = b-ch; + } + + c.scrollTop = c.scrollTop; + + if (hscroll !== false) { + if (el.offsetWidth > c.clientWidth || l < cl) { + c.scrollLeft = l; + } + else if (r > cr) { + c.scrollLeft = r - c.clientWidth; + } + c.scrollLeft = c.scrollLeft; + } + return this; + }, + + + scrollChildIntoView : function(child, hscroll) { + Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll); + }, + + + scroll : function(direction, distance, animate) { + if (!this.isScrollable()) { + return false; + } + var el = this.dom, + l = el.scrollLeft, t = el.scrollTop, + w = el.scrollWidth, h = el.scrollHeight, + cw = el.clientWidth, ch = el.clientHeight, + scrolled = false, v, + hash = { + l: Math.min(l + distance, w-cw), + r: v = Math.max(l - distance, 0), + t: Math.max(t - distance, 0), + b: Math.min(t + distance, h-ch) + }; + hash.d = hash.b; + hash.u = hash.t; + + direction = direction.substr(0, 1); + if ((v = hash[direction]) > -1) { + scrolled = true; + this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2)); + } + return scrolled; + } +}); +Ext.Element.addMethods( + function() { + var VISIBILITY = "visibility", + DISPLAY = "display", + HIDDEN = "hidden", + NONE = "none", + XMASKED = "x-masked", + XMASKEDRELATIVE = "x-masked-relative", + data = Ext.Element.data; + + return { + + isVisible : function(deep) { + var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE), + p = this.dom.parentNode; + + if (deep !== true || !vis) { + return vis; + } + + while (p && !(/^body/i.test(p.tagName))) { + if (!Ext.fly(p, '_isVisible').isVisible()) { + return false; + } + p = p.parentNode; + } + return true; + }, + + + isDisplayed : function() { + return !this.isStyle(DISPLAY, NONE); + }, + + + enableDisplayMode : function(display) { + this.setVisibilityMode(Ext.Element.DISPLAY); + + if (!Ext.isEmpty(display)) { + data(this.dom, 'originalDisplay', display); + } + + return this; + }, + + + mask : function(msg, msgCls) { + var me = this, + dom = me.dom, + dh = Ext.DomHelper, + EXTELMASKMSG = "ext-el-mask-msg", + el, + mask; + + if (!/^body/i.test(dom.tagName) && me.getStyle('position') == 'static') { + me.addClass(XMASKEDRELATIVE); + } + if (el = data(dom, 'maskMsg')) { + el.remove(); + } + if (el = data(dom, 'mask')) { + el.remove(); + } + + mask = dh.append(dom, {cls : "ext-el-mask"}, true); + data(dom, 'mask', mask); + + me.addClass(XMASKED); + mask.setDisplayed(true); + + if (typeof msg == 'string') { + var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true); + data(dom, 'maskMsg', mm); + mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG; + mm.dom.firstChild.innerHTML = msg; + mm.setDisplayed(true); + mm.center(me); + } + + + if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') { + mask.setSize(undefined, me.getHeight()); + } + + return mask; + }, + + + unmask : function() { + var me = this, + dom = me.dom, + mask = data(dom, 'mask'), + maskMsg = data(dom, 'maskMsg'); + + if (mask) { + if (maskMsg) { + maskMsg.remove(); + data(dom, 'maskMsg', undefined); + } + + mask.remove(); + data(dom, 'mask', undefined); + me.removeClass([XMASKED, XMASKEDRELATIVE]); + } + }, + + + isMasked : function() { + var m = data(this.dom, 'mask'); + return m && m.isVisible(); + }, + + + createShim : function() { + var el = document.createElement('iframe'), + shim; + + el.frameBorder = '0'; + el.className = 'ext-shim'; + el.src = Ext.SSL_SECURE_URL; + shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom)); + shim.autoBoxAdjust = false; + return shim; + } + }; + }() +); +Ext.Element.addMethods({ + + addKeyListener : function(key, fn, scope){ + var config; + if(typeof key != 'object' || Ext.isArray(key)){ + config = { + key: key, + fn: fn, + scope: scope + }; + }else{ + config = { + key : key.key, + shift : key.shift, + ctrl : key.ctrl, + alt : key.alt, + fn: fn, + scope: scope + }; + } + return new Ext.KeyMap(this, config); + }, + + + addKeyMap : function(config){ + return new Ext.KeyMap(this, config); + } +}); + + + +Ext.CompositeElementLite.importElementMethods(); +Ext.apply(Ext.CompositeElementLite.prototype, { + addElements : function(els, root){ + if(!els){ + return this; + } + if(typeof els == "string"){ + els = Ext.Element.selectorFunction(els, root); + } + var yels = this.elements; + Ext.each(els, function(e) { + yels.push(Ext.get(e)); + }); + return this; + }, + + + first : function(){ + return this.item(0); + }, + + + last : function(){ + return this.item(this.getCount()-1); + }, + + + contains : function(el){ + return this.indexOf(el) != -1; + }, + + + removeElement : function(keys, removeDom){ + var me = this, + els = this.elements, + el; + Ext.each(keys, function(val){ + if ((el = (els[val] || els[val = me.indexOf(val)]))) { + if(removeDom){ + if(el.dom){ + el.remove(); + }else{ + Ext.removeNode(el); + } + } + els.splice(val, 1); + } + }); + return this; + } +}); + +Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, { + + constructor : function(els, root){ + this.elements = []; + this.add(els, root); + }, + + + getElement : function(el){ + + return el; + }, + + + transformElement : function(el){ + return Ext.get(el); + } + + + + + + +}); + + +Ext.Element.select = function(selector, unique, root){ + var els; + if(typeof selector == "string"){ + els = Ext.Element.selectorFunction(selector, root); + }else if(selector.length !== undefined){ + els = selector; + }else{ + throw "Invalid selector"; + } + + return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els); +}; + + +Ext.select = Ext.Element.select; +Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable, +function() { + var BEFOREUPDATE = "beforeupdate", + UPDATE = "update", + FAILURE = "failure"; + + + function processSuccess(response){ + var me = this; + me.transaction = null; + if (response.argument.form && response.argument.reset) { + try { + response.argument.form.reset(); + } catch(e){} + } + if (me.loadScripts) { + me.renderer.render(me.el, response, me, + updateComplete.createDelegate(me, [response])); + } else { + me.renderer.render(me.el, response, me); + updateComplete.call(me, response); + } + } + + + function updateComplete(response, type, success){ + this.fireEvent(type || UPDATE, this.el, response); + if(Ext.isFunction(response.argument.callback)){ + response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options); + } + } + + + function processFailure(response){ + updateComplete.call(this, response, FAILURE, !!(this.transaction = null)); + } + + return { + constructor: function(el, forceNew){ + var me = this; + el = Ext.get(el); + if(!forceNew && el.updateManager){ + return el.updateManager; + } + + me.el = el; + + me.defaultUrl = null; + + me.addEvents( + + BEFOREUPDATE, + + UPDATE, + + FAILURE + ); + + Ext.apply(me, Ext.Updater.defaults); + + + + + + + + + me.transaction = null; + + me.refreshDelegate = me.refresh.createDelegate(me); + + me.updateDelegate = me.update.createDelegate(me); + + me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me); + + + me.renderer = me.renderer || me.getDefaultRenderer(); + + Ext.Updater.superclass.constructor.call(me); + }, + + + setRenderer : function(renderer){ + this.renderer = renderer; + }, + + + getRenderer : function(){ + return this.renderer; + }, + + + getDefaultRenderer: function() { + return new Ext.Updater.BasicRenderer(); + }, + + + setDefaultUrl : function(defaultUrl){ + this.defaultUrl = defaultUrl; + }, + + + getEl : function(){ + return this.el; + }, + + + update : function(url, params, callback, discardUrl){ + var me = this, + cfg, + callerScope; + + if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){ + if(Ext.isObject(url)){ + cfg = url; + url = cfg.url; + params = params || cfg.params; + callback = callback || cfg.callback; + discardUrl = discardUrl || cfg.discardUrl; + callerScope = cfg.scope; + if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;}; + if(!Ext.isEmpty(cfg.text)){me.indicatorText = '
'+cfg.text+"
";}; + if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;}; + if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;}; + } + me.showLoading(); + + if(!discardUrl){ + me.defaultUrl = url; + } + if(Ext.isFunction(url)){ + url = url.call(me); + } + + var o = Ext.apply({}, { + url : url, + params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params, + success: processSuccess, + failure: processFailure, + scope: me, + callback: undefined, + timeout: (me.timeout*1000), + disableCaching: me.disableCaching, + argument: { + "options": cfg, + "url": url, + "form": null, + "callback": callback, + "scope": callerScope || window, + "params": params + } + }, cfg); + + me.transaction = Ext.Ajax.request(o); + } + }, + + + formUpdate : function(form, url, reset, callback){ + var me = this; + if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){ + if(Ext.isFunction(url)){ + url = url.call(me); + } + form = Ext.getDom(form); + me.transaction = Ext.Ajax.request({ + form: form, + url:url, + success: processSuccess, + failure: processFailure, + scope: me, + timeout: (me.timeout*1000), + argument: { + "url": url, + "form": form, + "callback": callback, + "reset": reset + } + }); + me.showLoading.defer(1, me); + } + }, + + + startAutoRefresh : function(interval, url, params, callback, refreshNow){ + var me = this; + if(refreshNow){ + me.update(url || me.defaultUrl, params, callback, true); + } + if(me.autoRefreshProcId){ + clearInterval(me.autoRefreshProcId); + } + me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000); + }, + + + stopAutoRefresh : function(){ + if(this.autoRefreshProcId){ + clearInterval(this.autoRefreshProcId); + delete this.autoRefreshProcId; + } + }, + + + isAutoRefreshing : function(){ + return !!this.autoRefreshProcId; + }, + + + showLoading : function(){ + if(this.showLoadIndicator){ + this.el.dom.innerHTML = this.indicatorText; + } + }, + + + abort : function(){ + if(this.transaction){ + Ext.Ajax.abort(this.transaction); + } + }, + + + isUpdating : function(){ + return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false; + }, + + + refresh : function(callback){ + if(this.defaultUrl){ + this.update(this.defaultUrl, null, callback, true); + } + } + }; +}()); + + +Ext.Updater.defaults = { + + timeout : 30, + + disableCaching : false, + + showLoadIndicator : true, + + indicatorText : '
Loading...
', + + loadScripts : false, + + sslBlankUrl : Ext.SSL_SECURE_URL +}; + + + +Ext.Updater.updateElement = function(el, url, params, options){ + var um = Ext.get(el).getUpdater(); + Ext.apply(um, options); + um.update(url, params, options ? options.callback : null); +}; + + +Ext.Updater.BasicRenderer = function(){}; + +Ext.Updater.BasicRenderer.prototype = { + + render : function(el, response, updateManager, callback){ + el.update(response.responseText, updateManager.loadScripts, callback); + } +}; + + + +(function() { + + +Date.useStrict = false; + + + + + +function xf(format) { + var args = Array.prototype.slice.call(arguments, 1); + return format.replace(/\{(\d+)\}/g, function(m, i) { + return args[i]; + }); +} + + + +Date.formatCodeToRegex = function(character, currentGroup) { + + var p = Date.parseCodes[character]; + + if (p) { + p = typeof p == 'function'? p() : p; + Date.parseCodes[character] = p; + } + + return p ? Ext.applyIf({ + c: p.c ? xf(p.c, currentGroup || "{0}") : p.c + }, p) : { + g:0, + c:null, + s:Ext.escapeRe(character) + }; +}; + + +var $f = Date.formatCodeToRegex; + +Ext.apply(Date, { + + parseFunctions: { + "M$": function(input, strict) { + + + var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'); + var r = (input || '').match(re); + return r? new Date(((r[1] || '') + r[2]) * 1) : null; + } + }, + parseRegexes: [], + + + formatFunctions: { + "M$": function() { + + return '\\/Date(' + this.getTime() + ')\\/'; + } + }, + + y2kYear : 50, + + + MILLI : "ms", + + + SECOND : "s", + + + MINUTE : "mi", + + + HOUR : "h", + + + DAY : "d", + + + MONTH : "mo", + + + YEAR : "y", + + + defaults: {}, + + + dayNames : [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ], + + + monthNames : [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ], + + + monthNumbers : { + Jan:0, + Feb:1, + Mar:2, + Apr:3, + May:4, + Jun:5, + Jul:6, + Aug:7, + Sep:8, + Oct:9, + Nov:10, + Dec:11 + }, + + + getShortMonthName : function(month) { + return Date.monthNames[month].substring(0, 3); + }, + + + getShortDayName : function(day) { + return Date.dayNames[day].substring(0, 3); + }, + + + getMonthNumber : function(name) { + + return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()]; + }, + + + formatContainsHourInfo : (function(){ + var stripEscapeRe = /(\\.)/g, + hourInfoRe = /([gGhHisucUOPZ]|M\$)/; + return function(format){ + return hourInfoRe.test(format.replace(stripEscapeRe, '')); + }; + })(), + + + formatCodes : { + d: "String.leftPad(this.getDate(), 2, '0')", + D: "Date.getShortDayName(this.getDay())", + j: "this.getDate()", + l: "Date.dayNames[this.getDay()]", + N: "(this.getDay() ? this.getDay() : 7)", + S: "this.getSuffix()", + w: "this.getDay()", + z: "this.getDayOfYear()", + W: "String.leftPad(this.getWeekOfYear(), 2, '0')", + F: "Date.monthNames[this.getMonth()]", + m: "String.leftPad(this.getMonth() + 1, 2, '0')", + M: "Date.getShortMonthName(this.getMonth())", + n: "(this.getMonth() + 1)", + t: "this.getDaysInMonth()", + L: "(this.isLeapYear() ? 1 : 0)", + o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))", + Y: "String.leftPad(this.getFullYear(), 4, '0')", + y: "('' + this.getFullYear()).substring(2, 4)", + a: "(this.getHours() < 12 ? 'am' : 'pm')", + A: "(this.getHours() < 12 ? 'AM' : 'PM')", + g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)", + G: "this.getHours()", + h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')", + H: "String.leftPad(this.getHours(), 2, '0')", + i: "String.leftPad(this.getMinutes(), 2, '0')", + s: "String.leftPad(this.getSeconds(), 2, '0')", + u: "String.leftPad(this.getMilliseconds(), 3, '0')", + O: "this.getGMTOffset()", + P: "this.getGMTOffset(true)", + T: "this.getTimezone()", + Z: "(this.getTimezoneOffset() * -60)", + + c: function() { + for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) { + var e = c.charAt(i); + code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); + } + return code.join(" + "); + }, + + + U: "Math.round(this.getTime() / 1000)" + }, + + + isValid : function(y, m, d, h, i, s, ms) { + + h = h || 0; + i = i || 0; + s = s || 0; + ms = ms || 0; + + + var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0); + + return y == dt.getFullYear() && + m == dt.getMonth() + 1 && + d == dt.getDate() && + h == dt.getHours() && + i == dt.getMinutes() && + s == dt.getSeconds() && + ms == dt.getMilliseconds(); + }, + + + parseDate : function(input, format, strict) { + var p = Date.parseFunctions; + if (p[format] == null) { + Date.createParser(format); + } + return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict); + }, + + + getFormatCode : function(character) { + var f = Date.formatCodes[character]; + + if (f) { + f = typeof f == 'function'? f() : f; + Date.formatCodes[character] = f; + } + + + return f || ("'" + String.escape(character) + "'"); + }, + + + createFormat : function(format) { + var code = [], + special = false, + ch = ''; + + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } else if (special) { + special = false; + code.push("'" + String.escape(ch) + "'"); + } else { + code.push(Date.getFormatCode(ch)); + } + } + Date.formatFunctions[format] = new Function("return " + code.join('+')); + }, + + + createParser : function() { + var code = [ + "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,", + "def = Date.defaults,", + "results = String(input).match(Date.parseRegexes[{0}]);", + + "if(results){", + "{1}", + + "if(u != null){", + "v = new Date(u * 1000);", + "}else{", + + + + "dt = (new Date()).clearTime();", + + + "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));", + "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));", + "d = Ext.num(d, Ext.num(def.d, dt.getDate()));", + + + "h = Ext.num(h, Ext.num(def.h, dt.getHours()));", + "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));", + "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));", + "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));", + + "if(z >= 0 && y >= 0){", + + + + + + "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);", + + + "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);", + "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", + "v = null;", + "}else{", + + + "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);", + "}", + "}", + "}", + + "if(v){", + + "if(zz != null){", + + "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);", + "}else if(o){", + + "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));", + "}", + "}", + + "return v;" + ].join('\n'); + + return function(format) { + var regexNum = Date.parseRegexes.length, + currentGroup = 1, + calc = [], + regex = [], + special = false, + ch = "", + i = 0, + obj, + last; + + for (; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } else if (special) { + special = false; + regex.push(String.escape(ch)); + } else { + obj = $f(ch, currentGroup); + currentGroup += obj.g; + regex.push(obj.s); + if (obj.g && obj.c) { + if (obj.calcLast) { + last = obj.c; + } else { + calc.push(obj.c); + } + } + } + } + + if (last) { + calc.push(last); + } + + Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i'); + Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join(''))); + }; + }(), + + + parseCodes : { + + d: { + g:1, + c:"d = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + j: { + g:1, + c:"d = parseInt(results[{0}], 10);\n", + s:"(\\d{1,2})" + }, + D: function() { + for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); + return { + g:0, + c:null, + s:"(?:" + a.join("|") +")" + }; + }, + l: function() { + return { + g:0, + c:null, + s:"(?:" + Date.dayNames.join("|") + ")" + }; + }, + N: { + g:0, + c:null, + s:"[1-7]" + }, + S: { + g:0, + c:null, + s:"(?:st|nd|rd|th)" + }, + w: { + g:0, + c:null, + s:"[0-6]" + }, + z: { + g:1, + c:"z = parseInt(results[{0}], 10);\n", + s:"(\\d{1,3})" + }, + W: { + g:0, + c:null, + s:"(?:\\d{2})" + }, + F: function() { + return { + g:1, + c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", + s:"(" + Date.monthNames.join("|") + ")" + }; + }, + M: function() { + for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); + return Ext.applyIf({ + s:"(" + a.join("|") + ")" + }, $f("F")); + }, + m: { + g:1, + c:"m = parseInt(results[{0}], 10) - 1;\n", + s:"(\\d{2})" + }, + n: { + g:1, + c:"m = parseInt(results[{0}], 10) - 1;\n", + s:"(\\d{1,2})" + }, + t: { + g:0, + c:null, + s:"(?:\\d{2})" + }, + L: { + g:0, + c:null, + s:"(?:1|0)" + }, + o: function() { + return $f("Y"); + }, + Y: { + g:1, + c:"y = parseInt(results[{0}], 10);\n", + s:"(\\d{4})" + }, + y: { + g:1, + c:"var ty = parseInt(results[{0}], 10);\n" + + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", + s:"(\\d{1,2})" + }, + + a: function(){ + return $f("A"); + }, + A: { + + calcLast: true, + g:1, + c:"if (/(am)/i.test(results[{0}])) {\n" + + "if (!h || h == 12) { h = 0; }\n" + + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}", + s:"(AM|PM|am|pm)" + }, + g: function() { + return $f("G"); + }, + G: { + g:1, + c:"h = parseInt(results[{0}], 10);\n", + s:"(\\d{1,2})" + }, + h: function() { + return $f("H"); + }, + H: { + g:1, + c:"h = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + i: { + g:1, + c:"i = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + s: { + g:1, + c:"s = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + u: { + g:1, + c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n", + s:"(\\d+)" + }, + O: { + g:1, + c:[ + "o = results[{0}];", + "var sn = o.substring(0,1),", + "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", + "mn = o.substring(3,5) % 60;", + "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" + ].join("\n"), + s: "([+\-]\\d{4})" + }, + P: { + g:1, + c:[ + "o = results[{0}];", + "var sn = o.substring(0,1),", + "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", + "mn = o.substring(4,6) % 60;", + "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" + ].join("\n"), + s: "([+\-]\\d{2}:\\d{2})" + }, + T: { + g:0, + c:null, + s:"[A-Z]{1,4}" + }, + Z: { + g:1, + c:"zz = results[{0}] * 1;\n" + + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n", + s:"([+\-]?\\d{1,5})" + }, + c: function() { + var calc = [], + arr = [ + $f("Y", 1), + $f("m", 2), + $f("d", 3), + $f("h", 4), + $f("i", 5), + $f("s", 6), + {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, + {c:[ + "if(results[8]) {", + "if(results[8] == 'Z'){", + "zz = 0;", + "}else if (results[8].indexOf(':') > -1){", + $f("P", 8).c, + "}else{", + $f("O", 8).c, + "}", + "}" + ].join('\n')} + ]; + + for (var i = 0, l = arr.length; i < l; ++i) { + calc.push(arr[i].c); + } + + return { + g:1, + c:calc.join(""), + s:[ + arr[0].s, + "(?:", "-", arr[1].s, + "(?:", "-", arr[2].s, + "(?:", + "(?:T| )?", + arr[3].s, ":", arr[4].s, + "(?::", arr[5].s, ")?", + "(?:(?:\\.|,)(\\d+))?", + "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", + ")?", + ")?", + ")?" + ].join("") + }; + }, + U: { + g:1, + c:"u = parseInt(results[{0}], 10);\n", + s:"(-?\\d+)" + } + } +}); + +}()); + +Ext.apply(Date.prototype, { + + dateFormat : function(format) { + if (Date.formatFunctions[format] == null) { + Date.createFormat(format); + } + return Date.formatFunctions[format].call(this); + }, + + + getTimezone : function() { + + + + + + + + + + + + + return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, ""); + }, + + + getGMTOffset : function(colon) { + return (this.getTimezoneOffset() > 0 ? "-" : "+") + + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0") + + (colon ? ":" : "") + + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0"); + }, + + + getDayOfYear: function() { + var num = 0, + d = this.clone(), + m = this.getMonth(), + i; + + for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) { + num += d.getDaysInMonth(); + } + return num + this.getDate() - 1; + }, + + + getWeekOfYear : function() { + + var ms1d = 864e5, + ms7d = 7 * ms1d; + + return function() { + var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, + AWN = Math.floor(DC3 / 7), + Wyr = new Date(AWN * ms7d).getUTCFullYear(); + + return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1; + }; + }(), + + + isLeapYear : function() { + var year = this.getFullYear(); + return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); + }, + + + getFirstDayOfMonth : function() { + var day = (this.getDay() - (this.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; + }, + + + getLastDayOfMonth : function() { + return this.getLastDateOfMonth().getDay(); + }, + + + + getFirstDateOfMonth : function() { + return new Date(this.getFullYear(), this.getMonth(), 1); + }, + + + getLastDateOfMonth : function() { + return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth()); + }, + + + getDaysInMonth: function() { + var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + + return function() { + var m = this.getMonth(); + + return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m]; + }; + }(), + + + getSuffix : function() { + switch (this.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } + }, + + + clone : function() { + return new Date(this.getTime()); + }, + + + isDST : function() { + + + return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset(); + }, + + + clearTime : function(clone) { + if (clone) { + return this.clone().clearTime(); + } + + + var d = this.getDate(); + + + this.setHours(0); + this.setMinutes(0); + this.setSeconds(0); + this.setMilliseconds(0); + + if (this.getDate() != d) { + + + + + for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr)); + + this.setDate(d); + this.setHours(c.getHours()); + } + + return this; + }, + + + add : function(interval, value) { + var d = this.clone(); + if (!interval || value === 0) return d; + + switch(interval.toLowerCase()) { + case Date.MILLI: + d.setMilliseconds(this.getMilliseconds() + value); + break; + case Date.SECOND: + d.setSeconds(this.getSeconds() + value); + break; + case Date.MINUTE: + d.setMinutes(this.getMinutes() + value); + break; + case Date.HOUR: + d.setHours(this.getHours() + value); + break; + case Date.DAY: + d.setDate(this.getDate() + value); + break; + case Date.MONTH: + var day = this.getDate(); + if (day > 28) { + day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate()); + } + d.setDate(day); + d.setMonth(this.getMonth() + value); + break; + case Date.YEAR: + d.setFullYear(this.getFullYear() + value); + break; + } + return d; + }, + + + between : function(start, end) { + var t = this.getTime(); + return start.getTime() <= t && t <= end.getTime(); + } +}); + + + +Date.prototype.format = Date.prototype.dateFormat; + + + +if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) { + Ext.apply(Date.prototype, { + _xMonth : Date.prototype.setMonth, + _xDate : Date.prototype.setDate, + + + + setMonth : function(num) { + if (num <= -1) { + var n = Math.ceil(-num), + back_year = Math.ceil(n / 12), + month = (n % 12) ? 12 - n % 12 : 0; + + this.setFullYear(this.getFullYear() - back_year); + + return this._xMonth(month); + } else { + return this._xMonth(num); + } + }, + + + + + setDate : function(d) { + + + return this.setTime(this.getTime() - (this.getDate() - d) * 864e5); + } + }); +} + + + + + +Ext.util.MixedCollection = function(allowFunctions, keyFn){ + this.items = []; + this.map = {}; + this.keys = []; + this.length = 0; + this.addEvents( + + 'clear', + + 'add', + + 'replace', + + 'remove', + 'sort' + ); + this.allowFunctions = allowFunctions === true; + if(keyFn){ + this.getKey = keyFn; + } + Ext.util.MixedCollection.superclass.constructor.call(this); +}; + +Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, { + + + allowFunctions : false, + + + add : function(key, o){ + if(arguments.length == 1){ + o = arguments[0]; + key = this.getKey(o); + } + if(typeof key != 'undefined' && key !== null){ + var old = this.map[key]; + if(typeof old != 'undefined'){ + return this.replace(key, o); + } + this.map[key] = o; + } + this.length++; + this.items.push(o); + this.keys.push(key); + this.fireEvent('add', this.length-1, o, key); + return o; + }, + + + getKey : function(o){ + return o.id; + }, + + + replace : function(key, o){ + if(arguments.length == 1){ + o = arguments[0]; + key = this.getKey(o); + } + var old = this.map[key]; + if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){ + return this.add(key, o); + } + var index = this.indexOfKey(key); + this.items[index] = o; + this.map[key] = o; + this.fireEvent('replace', key, old, o); + return o; + }, + + + addAll : function(objs){ + if(arguments.length > 1 || Ext.isArray(objs)){ + var args = arguments.length > 1 ? arguments : objs; + for(var i = 0, len = args.length; i < len; i++){ + this.add(args[i]); + } + }else{ + for(var key in objs){ + if(this.allowFunctions || typeof objs[key] != 'function'){ + this.add(key, objs[key]); + } + } + } + }, + + + each : function(fn, scope){ + var items = [].concat(this.items); + for(var i = 0, len = items.length; i < len; i++){ + if(fn.call(scope || items[i], items[i], i, len) === false){ + break; + } + } + }, + + + eachKey : function(fn, scope){ + for(var i = 0, len = this.keys.length; i < len; i++){ + fn.call(scope || window, this.keys[i], this.items[i], i, len); + } + }, + + + find : function(fn, scope){ + for(var i = 0, len = this.items.length; i < len; i++){ + if(fn.call(scope || window, this.items[i], this.keys[i])){ + return this.items[i]; + } + } + return null; + }, + + + insert : function(index, key, o){ + if(arguments.length == 2){ + o = arguments[1]; + key = this.getKey(o); + } + if(this.containsKey(key)){ + this.suspendEvents(); + this.removeKey(key); + this.resumeEvents(); + } + if(index >= this.length){ + return this.add(key, o); + } + this.length++; + this.items.splice(index, 0, o); + if(typeof key != 'undefined' && key !== null){ + this.map[key] = o; + } + this.keys.splice(index, 0, key); + this.fireEvent('add', index, o, key); + return o; + }, + + + remove : function(o){ + return this.removeAt(this.indexOf(o)); + }, + + + removeAt : function(index){ + if(index < this.length && index >= 0){ + this.length--; + var o = this.items[index]; + this.items.splice(index, 1); + var key = this.keys[index]; + if(typeof key != 'undefined'){ + delete this.map[key]; + } + this.keys.splice(index, 1); + this.fireEvent('remove', o, key); + return o; + } + return false; + }, + + + removeKey : function(key){ + return this.removeAt(this.indexOfKey(key)); + }, + + + getCount : function(){ + return this.length; + }, + + + indexOf : function(o){ + return this.items.indexOf(o); + }, + + + indexOfKey : function(key){ + return this.keys.indexOf(key); + }, + + + item : function(key){ + var mk = this.map[key], + item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined; + return typeof item != 'function' || this.allowFunctions ? item : null; + }, + + + itemAt : function(index){ + return this.items[index]; + }, + + + key : function(key){ + return this.map[key]; + }, + + + contains : function(o){ + return this.indexOf(o) != -1; + }, + + + containsKey : function(key){ + return typeof this.map[key] != 'undefined'; + }, + + + clear : function(){ + this.length = 0; + this.items = []; + this.keys = []; + this.map = {}; + this.fireEvent('clear'); + }, + + + first : function(){ + return this.items[0]; + }, + + + last : function(){ + return this.items[this.length-1]; + }, + + + _sort : function(property, dir, fn){ + var i, len, + dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + + + c = [], + keys = this.keys, + items = this.items; + + + fn = fn || function(a, b) { + return a - b; + }; + + + for(i = 0, len = items.length; i < len; i++){ + c[c.length] = { + key : keys[i], + value: items[i], + index: i + }; + } + + + c.sort(function(a, b){ + var v = fn(a[property], b[property]) * dsc; + if(v === 0){ + v = (a.index < b.index ? -1 : 1); + } + return v; + }); + + + for(i = 0, len = c.length; i < len; i++){ + items[i] = c[i].value; + keys[i] = c[i].key; + } + + this.fireEvent('sort', this); + }, + + + sort : function(dir, fn){ + this._sort('value', dir, fn); + }, + + + reorder: function(mapping) { + this.suspendEvents(); + + var items = this.items, + index = 0, + length = items.length, + order = [], + remaining = [], + oldIndex; + + + for (oldIndex in mapping) { + order[mapping[oldIndex]] = items[oldIndex]; + } + + for (index = 0; index < length; index++) { + if (mapping[index] == undefined) { + remaining.push(items[index]); + } + } + + for (index = 0; index < length; index++) { + if (order[index] == undefined) { + order[index] = remaining.shift(); + } + } + + this.clear(); + this.addAll(order); + + this.resumeEvents(); + this.fireEvent('sort', this); + }, + + + keySort : function(dir, fn){ + this._sort('key', dir, fn || function(a, b){ + var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase(); + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + }); + }, + + + getRange : function(start, end){ + var items = this.items; + if(items.length < 1){ + return []; + } + start = start || 0; + end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1); + var i, r = []; + if(start <= end){ + for(i = start; i <= end; i++) { + r[r.length] = items[i]; + } + }else{ + for(i = start; i >= end; i--) { + r[r.length] = items[i]; + } + } + return r; + }, + + + filter : function(property, value, anyMatch, caseSensitive){ + if(Ext.isEmpty(value, false)){ + return this.clone(); + } + value = this.createValueMatcher(value, anyMatch, caseSensitive); + return this.filterBy(function(o){ + return o && value.test(o[property]); + }); + }, + + + filterBy : function(fn, scope){ + var r = new Ext.util.MixedCollection(); + r.getKey = this.getKey; + var k = this.keys, it = this.items; + for(var i = 0, len = it.length; i < len; i++){ + if(fn.call(scope||this, it[i], k[i])){ + r.add(k[i], it[i]); + } + } + return r; + }, + + + findIndex : function(property, value, start, anyMatch, caseSensitive){ + if(Ext.isEmpty(value, false)){ + return -1; + } + value = this.createValueMatcher(value, anyMatch, caseSensitive); + return this.findIndexBy(function(o){ + return o && value.test(o[property]); + }, null, start); + }, + + + findIndexBy : function(fn, scope, start){ + var k = this.keys, it = this.items; + for(var i = (start||0), len = it.length; i < len; i++){ + if(fn.call(scope||this, it[i], k[i])){ + return i; + } + } + return -1; + }, + + + createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { + if (!value.exec) { + var er = Ext.escapeRe; + value = String(value); + + if (anyMatch === true) { + value = er(value); + } else { + value = '^' + er(value); + if (exactMatch === true) { + value += '$'; + } + } + value = new RegExp(value, caseSensitive ? '' : 'i'); + } + return value; + }, + + + clone : function(){ + var r = new Ext.util.MixedCollection(); + var k = this.keys, it = this.items; + for(var i = 0, len = it.length; i < len; i++){ + r.add(k[i], it[i]); + } + r.getKey = this.getKey; + return r; + } +}); + +Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item; + +Ext.AbstractManager = Ext.extend(Object, { + typeName: 'type', + + constructor: function(config) { + Ext.apply(this, config || {}); + + + this.all = new Ext.util.MixedCollection(); + + this.types = {}; + }, + + + get : function(id){ + return this.all.get(id); + }, + + + register: function(item) { + this.all.add(item); + }, + + + unregister: function(item) { + this.all.remove(item); + }, + + + registerType : function(type, cls){ + this.types[type] = cls; + cls[this.typeName] = type; + }, + + + isRegistered : function(type){ + return this.types[type] !== undefined; + }, + + + create: function(config, defaultType) { + var type = config[this.typeName] || config.type || defaultType, + Constructor = this.types[type]; + + if (Constructor == undefined) { + throw new Error(String.format("The '{0}' type has not been registered with this manager", type)); + } + + return new Constructor(config); + }, + + + onAvailable : function(id, fn, scope){ + var all = this.all; + + all.on("add", function(index, o){ + if (o.id == id) { + fn.call(scope || o, o); + all.un("add", fn, scope); + } + }); + } +}); +Ext.util.Format = function() { + var trimRe = /^\s+|\s+$/g, + stripTagsRE = /<\/?[^>]+>/gi, + stripScriptsRe = /(?:)((\n|\r|.)*?)(?:<\/script>)/ig, + nl2brRe = /\r?\n/g; + + return { + + ellipsis : function(value, len, word) { + if (value && value.length > len) { + if (word) { + var vs = value.substr(0, len - 2), + index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?')); + if (index == -1 || index < (len - 15)) { + return value.substr(0, len - 3) + "..."; + } else { + return vs.substr(0, index) + "..."; + } + } else { + return value.substr(0, len - 3) + "..."; + } + } + return value; + }, + + + undef : function(value) { + return value !== undefined ? value : ""; + }, + + + defaultValue : function(value, defaultValue) { + if (!defaultValue && defaultValue !== 0) { + defaultValue = ''; + } + return value !== undefined && value !== '' ? value : defaultValue; + }, + + + htmlEncode : function(value) { + return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&"); + }, + + + trim : function(value) { + return String(value).replace(trimRe, ""); + }, + + + substr : function(value, start, length) { + return String(value).substr(start, length); + }, + + + lowercase : function(value) { + return String(value).toLowerCase(); + }, + + + uppercase : function(value) { + return String(value).toUpperCase(); + }, + + + capitalize : function(value) { + return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase(); + }, + + + call : function(value, fn) { + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + args.unshift(value); + return eval(fn).apply(window, args); + } else { + return eval(fn).call(window, value); + } + }, + + + usMoney : function(v) { + v = (Math.round((v-0)*100))/100; + v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v); + v = String(v); + var ps = v.split('.'), + whole = ps[0], + sub = ps[1] ? '.'+ ps[1] : '.00', + r = /(\d+)(\d{3})/; + while (r.test(whole)) { + whole = whole.replace(r, '$1' + ',' + '$2'); + } + v = whole + sub; + if (v.charAt(0) == '-') { + return '-$' + v.substr(1); + } + return "$" + v; + }, + + + date : function(v, format) { + if (!v) { + return ""; + } + if (!Ext.isDate(v)) { + v = new Date(Date.parse(v)); + } + return v.dateFormat(format || "m/d/Y"); + }, + + + dateRenderer : function(format) { + return function(v) { + return Ext.util.Format.date(v, format); + }; + }, + + + stripTags : function(v) { + return !v ? v : String(v).replace(stripTagsRE, ""); + }, + + + stripScripts : function(v) { + return !v ? v : String(v).replace(stripScriptsRe, ""); + }, + + + fileSize : function(size) { + if (size < 1024) { + return size + " bytes"; + } else if (size < 1048576) { + return (Math.round(((size*10) / 1024))/10) + " KB"; + } else { + return (Math.round(((size*10) / 1048576))/10) + " MB"; + } + }, + + + math : function(){ + var fns = {}; + + return function(v, a){ + if (!fns[a]) { + fns[a] = new Function('v', 'return v ' + a + ';'); + } + return fns[a](v); + }; + }(), + + + round : function(value, precision) { + var result = Number(value); + if (typeof precision == 'number') { + precision = Math.pow(10, precision); + result = Math.round(value * precision) / precision; + } + return result; + }, + + + number: function(v, format) { + if (!format) { + return v; + } + v = Ext.num(v, NaN); + if (isNaN(v)) { + return ''; + } + var comma = ',', + dec = '.', + i18n = false, + neg = v < 0; + + v = Math.abs(v); + if (format.substr(format.length - 2) == '/i') { + format = format.substr(0, format.length - 2); + i18n = true; + comma = '.'; + dec = ','; + } + + var hasComma = format.indexOf(comma) != -1, + psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec); + + if (1 < psplit.length) { + v = v.toFixed(psplit[1].length); + } else if(2 < psplit.length) { + throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format); + } else { + v = v.toFixed(0); + } + + var fnum = v.toString(); + + psplit = fnum.split('.'); + + if (hasComma) { + var cnum = psplit[0], + parr = [], + j = cnum.length, + m = Math.floor(j / 3), + n = cnum.length % 3 || 3, + i; + + for (i = 0; i < j; i += n) { + if (i != 0) { + n = 3; + } + + parr[parr.length] = cnum.substr(i, n); + m -= 1; + } + fnum = parr.join(comma); + if (psplit[1]) { + fnum += dec + psplit[1]; + } + } else { + if (psplit[1]) { + fnum = psplit[0] + dec + psplit[1]; + } + } + + return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum); + }, + + + numberRenderer : function(format) { + return function(v) { + return Ext.util.Format.number(v, format); + }; + }, + + + plural : function(v, s, p) { + return v +' ' + (v == 1 ? s : (p ? p : s+'s')); + }, + + + nl2br : function(v) { + return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '
'); + } + }; +}(); + +Ext.XTemplate = function(){ + Ext.XTemplate.superclass.constructor.apply(this, arguments); + + var me = this, + s = me.html, + re = /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, + nameRe = /^]*?for="(.*?)"/, + ifRe = /^]*?if="(.*?)"/, + execRe = /^]*?exec="(.*?)"/, + m, + id = 0, + tpls = [], + VALUES = 'values', + PARENT = 'parent', + XINDEX = 'xindex', + XCOUNT = 'xcount', + RETURN = 'return ', + WITHVALUES = 'with(values){ '; + + s = ['', s, ''].join(''); + + while((m = s.match(re))){ + var m2 = m[0].match(nameRe), + m3 = m[0].match(ifRe), + m4 = m[0].match(execRe), + exp = null, + fn = null, + exec = null, + name = m2 && m2[1] ? m2[1] : ''; + + if (m3) { + exp = m3 && m3[1] ? m3[1] : null; + if(exp){ + fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }'); + } + } + if (m4) { + exp = m4 && m4[1] ? m4[1] : null; + if(exp){ + exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }'); + } + } + if(name){ + switch(name){ + case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break; + case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break; + default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }'); + } + } + tpls.push({ + id: id, + target: name, + exec: exec, + test: fn, + body: m[1]||'' + }); + s = s.replace(m[0], '{xtpl'+ id + '}'); + ++id; + } + for(var i = tpls.length-1; i >= 0; --i){ + me.compileTpl(tpls[i]); + } + me.master = tpls[tpls.length-1]; + me.tpls = tpls; +}; +Ext.extend(Ext.XTemplate, Ext.Template, { + + re : /\{([\w\-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g, + + codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g, + + + applySubTemplate : function(id, values, parent, xindex, xcount){ + var me = this, + len, + t = me.tpls[id], + vs, + buf = []; + if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) || + (t.exec && t.exec.call(me, values, parent, xindex, xcount))) { + return ''; + } + vs = t.target ? t.target.call(me, values, parent) : values; + len = vs.length; + parent = t.target ? values : parent; + if(t.target && Ext.isArray(vs)){ + for(var i = 0, len = vs.length; i < len; i++){ + buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len); + } + return buf.join(''); + } + return t.compiled.call(me, vs, parent, xindex, xcount); + }, + + + compileTpl : function(tpl){ + var fm = Ext.util.Format, + useF = this.disableFormats !== true, + sep = Ext.isGecko ? "+" : ",", + body; + + function fn(m, name, format, args, math){ + if(name.substr(0, 4) == 'xtpl'){ + return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'"; + } + var v; + if(name === '.'){ + v = 'values'; + }else if(name === '#'){ + v = 'xindex'; + }else if(name.indexOf('.') != -1){ + v = name; + }else{ + v = "values['" + name + "']"; + } + if(math){ + v = '(' + v + math + ')'; + } + if (format && useF) { + args = args ? ',' + args : ""; + if(format.substr(0, 5) != "this."){ + format = "fm." + format + '('; + }else{ + format = 'this.call("'+ format.substr(5) + '", '; + args = ", values"; + } + } else { + args= ''; format = "("+v+" === undefined ? '' : "; + } + return "'"+ sep + format + v + args + ")"+sep+"'"; + } + + function codeFn(m, code){ + + return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'"; + } + + + if(Ext.isGecko){ + body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" + + tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) + + "';};"; + }else{ + body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"]; + body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn)); + body.push("'].join('');};"); + body = body.join(''); + } + eval(body); + return this; + }, + + + applyTemplate : function(values){ + return this.master.compiled.call(this, values, {}, 1, 1); + }, + + + compile : function(){return this;} + + + + + +}); + +Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate; + + +Ext.XTemplate.from = function(el){ + el = Ext.getDom(el); + return new Ext.XTemplate(el.value || el.innerHTML); +}; + +Ext.util.CSS = function(){ + var rules = null; + var doc = document; + + var camelRe = /(-[a-z])/gi; + var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); }; + + return { + + createStyleSheet : function(cssText, id){ + var ss; + var head = doc.getElementsByTagName("head")[0]; + var rules = doc.createElement("style"); + rules.setAttribute("type", "text/css"); + if(id){ + rules.setAttribute("id", id); + } + if(Ext.isIE){ + head.appendChild(rules); + ss = rules.styleSheet; + ss.cssText = cssText; + }else{ + try{ + rules.appendChild(doc.createTextNode(cssText)); + }catch(e){ + rules.cssText = cssText; + } + head.appendChild(rules); + ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]); + } + this.cacheStyleSheet(ss); + return ss; + }, + + + removeStyleSheet : function(id){ + var existing = doc.getElementById(id); + if(existing){ + existing.parentNode.removeChild(existing); + } + }, + + + swapStyleSheet : function(id, url){ + this.removeStyleSheet(id); + var ss = doc.createElement("link"); + ss.setAttribute("rel", "stylesheet"); + ss.setAttribute("type", "text/css"); + ss.setAttribute("id", id); + ss.setAttribute("href", url); + doc.getElementsByTagName("head")[0].appendChild(ss); + }, + + + refreshCache : function(){ + return this.getRules(true); + }, + + + cacheStyleSheet : function(ss){ + if(!rules){ + rules = {}; + } + try{ + var ssRules = ss.cssRules || ss.rules; + for(var j = ssRules.length-1; j >= 0; --j){ + rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j]; + } + }catch(e){} + }, + + + getRules : function(refreshCache){ + if(rules === null || refreshCache){ + rules = {}; + var ds = doc.styleSheets; + for(var i =0, len = ds.length; i < len; i++){ + try{ + this.cacheStyleSheet(ds[i]); + }catch(e){} + } + } + return rules; + }, + + + getRule : function(selector, refreshCache){ + var rs = this.getRules(refreshCache); + if(!Ext.isArray(selector)){ + return rs[selector.toLowerCase()]; + } + for(var i = 0; i < selector.length; i++){ + if(rs[selector[i]]){ + return rs[selector[i].toLowerCase()]; + } + } + return null; + }, + + + + updateRule : function(selector, property, value){ + if(!Ext.isArray(selector)){ + var rule = this.getRule(selector); + if(rule){ + rule.style[property.replace(camelRe, camelFn)] = value; + return true; + } + }else{ + for(var i = 0; i < selector.length; i++){ + if(this.updateRule(selector[i], property, value)){ + return true; + } + } + } + return false; + } + }; +}(); +Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, { + + constructor : function(el, config){ + this.el = Ext.get(el); + this.el.unselectable(); + + Ext.apply(this, config); + + this.addEvents( + + "mousedown", + + "click", + + "mouseup" + ); + + if(!this.disabled){ + this.disabled = true; + this.enable(); + } + + + if(this.handler){ + this.on("click", this.handler, this.scope || this); + } + + Ext.util.ClickRepeater.superclass.constructor.call(this); + }, + + interval : 20, + delay: 250, + preventDefault : true, + stopDefault : false, + timer : 0, + + + enable: function(){ + if(this.disabled){ + this.el.on('mousedown', this.handleMouseDown, this); + if (Ext.isIE){ + this.el.on('dblclick', this.handleDblClick, this); + } + if(this.preventDefault || this.stopDefault){ + this.el.on('click', this.eventOptions, this); + } + } + this.disabled = false; + }, + + + disable: function( force){ + if(force || !this.disabled){ + clearTimeout(this.timer); + if(this.pressClass){ + this.el.removeClass(this.pressClass); + } + Ext.getDoc().un('mouseup', this.handleMouseUp, this); + this.el.removeAllListeners(); + } + this.disabled = true; + }, + + + setDisabled: function(disabled){ + this[disabled ? 'disable' : 'enable'](); + }, + + eventOptions: function(e){ + if(this.preventDefault){ + e.preventDefault(); + } + if(this.stopDefault){ + e.stopEvent(); + } + }, + + + destroy : function() { + this.disable(true); + Ext.destroy(this.el); + this.purgeListeners(); + }, + + handleDblClick : function(e){ + clearTimeout(this.timer); + this.el.blur(); + + this.fireEvent("mousedown", this, e); + this.fireEvent("click", this, e); + }, + + + handleMouseDown : function(e){ + clearTimeout(this.timer); + this.el.blur(); + if(this.pressClass){ + this.el.addClass(this.pressClass); + } + this.mousedownTime = new Date(); + + Ext.getDoc().on("mouseup", this.handleMouseUp, this); + this.el.on("mouseout", this.handleMouseOut, this); + + this.fireEvent("mousedown", this, e); + this.fireEvent("click", this, e); + + + if (this.accelerate) { + this.delay = 400; + } + this.timer = this.click.defer(this.delay || this.interval, this, [e]); + }, + + + click : function(e){ + this.fireEvent("click", this, e); + this.timer = this.click.defer(this.accelerate ? + this.easeOutExpo(this.mousedownTime.getElapsed(), + 400, + -390, + 12000) : + this.interval, this, [e]); + }, + + easeOutExpo : function (t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; + }, + + + handleMouseOut : function(){ + clearTimeout(this.timer); + if(this.pressClass){ + this.el.removeClass(this.pressClass); + } + this.el.on("mouseover", this.handleMouseReturn, this); + }, + + + handleMouseReturn : function(){ + this.el.un("mouseover", this.handleMouseReturn, this); + if(this.pressClass){ + this.el.addClass(this.pressClass); + } + this.click(); + }, + + + handleMouseUp : function(e){ + clearTimeout(this.timer); + this.el.un("mouseover", this.handleMouseReturn, this); + this.el.un("mouseout", this.handleMouseOut, this); + Ext.getDoc().un("mouseup", this.handleMouseUp, this); + this.el.removeClass(this.pressClass); + this.fireEvent("mouseup", this, e); + } +}); +Ext.KeyNav = function(el, config){ + this.el = Ext.get(el); + Ext.apply(this, config); + if(!this.disabled){ + this.disabled = true; + this.enable(); + } +}; + +Ext.KeyNav.prototype = { + + disabled : false, + + defaultEventAction: "stopEvent", + + forceKeyDown : false, + + + relay : function(e){ + var k = e.getKey(), + h = this.keyToHandler[k]; + if(h && this[h]){ + if(this.doRelay(e, this[h], h) !== true){ + e[this.defaultEventAction](); + } + } + }, + + + doRelay : function(e, h, hname){ + return h.call(this.scope || this, e, hname); + }, + + + enter : false, + left : false, + right : false, + up : false, + down : false, + tab : false, + esc : false, + pageUp : false, + pageDown : false, + del : false, + home : false, + end : false, + space : false, + + + keyToHandler : { + 37 : "left", + 39 : "right", + 38 : "up", + 40 : "down", + 33 : "pageUp", + 34 : "pageDown", + 46 : "del", + 36 : "home", + 35 : "end", + 13 : "enter", + 27 : "esc", + 9 : "tab", + 32 : "space" + }, + + stopKeyUp: function(e) { + var k = e.getKey(); + + if (k >= 37 && k <= 40) { + + + e.stopEvent(); + } + }, + + + destroy: function(){ + this.disable(); + }, + + + enable: function() { + if (this.disabled) { + if (Ext.isSafari2) { + + this.el.on('keyup', this.stopKeyUp, this); + } + + this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this); + this.disabled = false; + } + }, + + + disable: function() { + if (!this.disabled) { + if (Ext.isSafari2) { + + this.el.un('keyup', this.stopKeyUp, this); + } + + this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this); + this.disabled = true; + } + }, + + + setDisabled : function(disabled){ + this[disabled ? "disable" : "enable"](); + }, + + + isKeydown: function(){ + return this.forceKeyDown || Ext.EventManager.useKeydown; + } +}; + +Ext.KeyMap = function(el, config, eventName){ + this.el = Ext.get(el); + this.eventName = eventName || "keydown"; + this.bindings = []; + if(config){ + this.addBinding(config); + } + this.enable(); +}; + +Ext.KeyMap.prototype = { + + stopEvent : false, + + + addBinding : function(config){ + if(Ext.isArray(config)){ + Ext.each(config, function(c){ + this.addBinding(c); + }, this); + return; + } + var keyCode = config.key, + fn = config.fn || config.handler, + scope = config.scope; + + if (config.stopEvent) { + this.stopEvent = config.stopEvent; + } + + if(typeof keyCode == "string"){ + var ks = []; + var keyString = keyCode.toUpperCase(); + for(var j = 0, len = keyString.length; j < len; j++){ + ks.push(keyString.charCodeAt(j)); + } + keyCode = ks; + } + var keyArray = Ext.isArray(keyCode); + + var handler = function(e){ + if(this.checkModifiers(config, e)){ + var k = e.getKey(); + if(keyArray){ + for(var i = 0, len = keyCode.length; i < len; i++){ + if(keyCode[i] == k){ + if(this.stopEvent){ + e.stopEvent(); + } + fn.call(scope || window, k, e); + return; + } + } + }else{ + if(k == keyCode){ + if(this.stopEvent){ + e.stopEvent(); + } + fn.call(scope || window, k, e); + } + } + } + }; + this.bindings.push(handler); + }, + + + checkModifiers: function(config, e){ + var val, key, keys = ['shift', 'ctrl', 'alt']; + for (var i = 0, len = keys.length; i < len; ++i){ + key = keys[i]; + val = config[key]; + if(!(val === undefined || (val === e[key + 'Key']))){ + return false; + } + } + return true; + }, + + + on : function(key, fn, scope){ + var keyCode, shift, ctrl, alt; + if(typeof key == "object" && !Ext.isArray(key)){ + keyCode = key.key; + shift = key.shift; + ctrl = key.ctrl; + alt = key.alt; + }else{ + keyCode = key; + } + this.addBinding({ + key: keyCode, + shift: shift, + ctrl: ctrl, + alt: alt, + fn: fn, + scope: scope + }); + }, + + + handleKeyDown : function(e){ + if(this.enabled){ + var b = this.bindings; + for(var i = 0, len = b.length; i < len; i++){ + b[i].call(this, e); + } + } + }, + + + isEnabled : function(){ + return this.enabled; + }, + + + enable: function(){ + if(!this.enabled){ + this.el.on(this.eventName, this.handleKeyDown, this); + this.enabled = true; + } + }, + + + disable: function(){ + if(this.enabled){ + this.el.removeListener(this.eventName, this.handleKeyDown, this); + this.enabled = false; + } + }, + + + setDisabled : function(disabled){ + this[disabled ? "disable" : "enable"](); + } +}; +Ext.util.TextMetrics = function(){ + var shared; + return { + + measure : function(el, text, fixedWidth){ + if(!shared){ + shared = Ext.util.TextMetrics.Instance(el, fixedWidth); + } + shared.bind(el); + shared.setFixedWidth(fixedWidth || 'auto'); + return shared.getSize(text); + }, + + + createInstance : function(el, fixedWidth){ + return Ext.util.TextMetrics.Instance(el, fixedWidth); + } + }; +}(); + +Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){ + var ml = new Ext.Element(document.createElement('div')); + document.body.appendChild(ml.dom); + ml.position('absolute'); + ml.setLeftTop(-1000, -1000); + ml.hide(); + + if(fixedWidth){ + ml.setWidth(fixedWidth); + } + + var instance = { + + getSize : function(text){ + ml.update(text); + var s = ml.getSize(); + ml.update(''); + return s; + }, + + + bind : function(el){ + ml.setStyle( + Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing') + ); + }, + + + setFixedWidth : function(width){ + ml.setWidth(width); + }, + + + getWidth : function(text){ + ml.dom.style.width = 'auto'; + return this.getSize(text).width; + }, + + + getHeight : function(text){ + return this.getSize(text).height; + } + }; + + instance.bind(bindTo); + + return instance; +}; + +Ext.Element.addMethods({ + + getTextWidth : function(text, min, max){ + return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000); + } +}); + +Ext.util.Cookies = { + + set : function(name, value){ + var argv = arguments; + var argc = arguments.length; + var expires = (argc > 2) ? argv[2] : null; + var path = (argc > 3) ? argv[3] : '/'; + var domain = (argc > 4) ? argv[4] : null; + var secure = (argc > 5) ? argv[5] : false; + document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : ""); + }, + + + get : function(name){ + var arg = name + "="; + var alen = arg.length; + var clen = document.cookie.length; + var i = 0; + var j = 0; + while(i < clen){ + j = i + alen; + if(document.cookie.substring(i, j) == arg){ + return Ext.util.Cookies.getCookieVal(j); + } + i = document.cookie.indexOf(" ", i) + 1; + if(i === 0){ + break; + } + } + return null; + }, + + + clear : function(name){ + if(Ext.util.Cookies.get(name)){ + document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; + } + }, + + getCookieVal : function(offset){ + var endstr = document.cookie.indexOf(";", offset); + if(endstr == -1){ + endstr = document.cookie.length; + } + return unescape(document.cookie.substring(offset, endstr)); + } +}; +Ext.handleError = function(e) { + throw e; +}; + + +Ext.Error = function(message) { + + this.message = (this.lang[message]) ? this.lang[message] : message; +}; + +Ext.Error.prototype = new Error(); +Ext.apply(Ext.Error.prototype, { + + lang: {}, + + name: 'Ext.Error', + + getName : function() { + return this.name; + }, + + getMessage : function() { + return this.message; + }, + + toJson : function() { + return Ext.encode(this); + } +}); + +Ext.ComponentMgr = function(){ + var all = new Ext.util.MixedCollection(); + var types = {}; + var ptypes = {}; + + return { + + register : function(c){ + all.add(c); + }, + + + unregister : function(c){ + all.remove(c); + }, + + + get : function(id){ + return all.get(id); + }, + + + onAvailable : function(id, fn, scope){ + all.on("add", function(index, o){ + if(o.id == id){ + fn.call(scope || o, o); + all.un("add", fn, scope); + } + }); + }, + + + all : all, + + + types : types, + + + ptypes: ptypes, + + + isRegistered : function(xtype){ + return types[xtype] !== undefined; + }, + + + isPluginRegistered : function(ptype){ + return ptypes[ptype] !== undefined; + }, + + + registerType : function(xtype, cls){ + types[xtype] = cls; + cls.xtype = xtype; + }, + + + create : function(config, defaultType){ + return config.render ? config : new types[config.xtype || defaultType](config); + }, + + + registerPlugin : function(ptype, cls){ + ptypes[ptype] = cls; + cls.ptype = ptype; + }, + + + createPlugin : function(config, defaultType){ + var PluginCls = ptypes[config.ptype || defaultType]; + if (PluginCls.init) { + return PluginCls; + } else { + return new PluginCls(config); + } + } + }; +}(); + + +Ext.reg = Ext.ComponentMgr.registerType; + +Ext.preg = Ext.ComponentMgr.registerPlugin; + +Ext.create = Ext.ComponentMgr.create; +Ext.Component = function(config){ + config = config || {}; + if(config.initialConfig){ + if(config.isAction){ + this.baseAction = config; + } + config = config.initialConfig; + }else if(config.tagName || config.dom || Ext.isString(config)){ + config = {applyTo: config, id: config.id || config}; + } + + + this.initialConfig = config; + + Ext.apply(this, config); + this.addEvents( + + 'added', + + 'disable', + + 'enable', + + 'beforeshow', + + 'show', + + 'beforehide', + + 'hide', + + 'removed', + + 'beforerender', + + 'render', + + 'afterrender', + + 'beforedestroy', + + 'destroy', + + 'beforestaterestore', + + 'staterestore', + + 'beforestatesave', + + 'statesave' + ); + this.getId(); + Ext.ComponentMgr.register(this); + Ext.Component.superclass.constructor.call(this); + + if(this.baseAction){ + this.baseAction.addComponent(this); + } + + this.initComponent(); + + if(this.plugins){ + if(Ext.isArray(this.plugins)){ + for(var i = 0, len = this.plugins.length; i < len; i++){ + this.plugins[i] = this.initPlugin(this.plugins[i]); + } + }else{ + this.plugins = this.initPlugin(this.plugins); + } + } + + if(this.stateful !== false){ + this.initState(); + } + + if(this.applyTo){ + this.applyToMarkup(this.applyTo); + delete this.applyTo; + }else if(this.renderTo){ + this.render(this.renderTo); + delete this.renderTo; + } +}; + + +Ext.Component.AUTO_ID = 1000; + +Ext.extend(Ext.Component, Ext.util.Observable, { + + + + + + + + + + + + + + + + + + disabled : false, + + hidden : false, + + + + + + + + autoEl : 'div', + + + disabledClass : 'x-item-disabled', + + allowDomMove : true, + + autoShow : false, + + hideMode : 'display', + + hideParent : false, + + + + + + rendered : false, + + + + + + + + tplWriteMode : 'overwrite', + + + + + bubbleEvents: [], + + + + ctype : 'Ext.Component', + + + actionMode : 'el', + + + getActionEl : function(){ + return this[this.actionMode]; + }, + + initPlugin : function(p){ + if(p.ptype && !Ext.isFunction(p.init)){ + p = Ext.ComponentMgr.createPlugin(p); + }else if(Ext.isString(p)){ + p = Ext.ComponentMgr.createPlugin({ + ptype: p + }); + } + p.init(this); + return p; + }, + + + initComponent : function(){ + + if(this.listeners){ + this.on(this.listeners); + delete this.listeners; + } + this.enableBubble(this.bubbleEvents); + }, + + + render : function(container, position){ + if(!this.rendered && this.fireEvent('beforerender', this) !== false){ + if(!container && this.el){ + this.el = Ext.get(this.el); + container = this.el.dom.parentNode; + this.allowDomMove = false; + } + this.container = Ext.get(container); + if(this.ctCls){ + this.container.addClass(this.ctCls); + } + this.rendered = true; + if(position !== undefined){ + if(Ext.isNumber(position)){ + position = this.container.dom.childNodes[position]; + }else{ + position = Ext.getDom(position); + } + } + this.onRender(this.container, position || null); + if(this.autoShow){ + this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); + } + if(this.cls){ + this.el.addClass(this.cls); + delete this.cls; + } + if(this.style){ + this.el.applyStyles(this.style); + delete this.style; + } + if(this.overCls){ + this.el.addClassOnOver(this.overCls); + } + this.fireEvent('render', this); + + + + + var contentTarget = this.getContentTarget(); + if (this.html){ + contentTarget.update(Ext.DomHelper.markup(this.html)); + delete this.html; + } + if (this.contentEl){ + var ce = Ext.getDom(this.contentEl); + Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); + contentTarget.appendChild(ce); + } + if (this.tpl) { + if (!this.tpl.compile) { + this.tpl = new Ext.XTemplate(this.tpl); + } + if (this.data) { + this.tpl[this.tplWriteMode](contentTarget, this.data); + delete this.data; + } + } + this.afterRender(this.container); + + + if(this.hidden){ + + this.doHide(); + } + if(this.disabled){ + + this.disable(true); + } + + if(this.stateful !== false){ + this.initStateEvents(); + } + this.fireEvent('afterrender', this); + } + return this; + }, + + + + update: function(htmlOrData, loadScripts, cb) { + var contentTarget = this.getContentTarget(); + if (this.tpl && typeof htmlOrData !== "string") { + this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {}); + } else { + var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; + contentTarget.update(html, loadScripts, cb); + } + }, + + + + onAdded : function(container, pos) { + this.ownerCt = container; + this.initRef(); + this.fireEvent('added', this, container, pos); + }, + + + onRemoved : function() { + this.removeRef(); + this.fireEvent('removed', this, this.ownerCt); + delete this.ownerCt; + }, + + + initRef : function() { + + if(this.ref && !this.refOwner){ + var levels = this.ref.split('/'), + last = levels.length, + i = 0, + t = this; + + while(t && i < last){ + t = t.ownerCt; + ++i; + } + if(t){ + t[this.refName = levels[--i]] = this; + + this.refOwner = t; + } + } + }, + + removeRef : function() { + if (this.refOwner && this.refName) { + delete this.refOwner[this.refName]; + delete this.refOwner; + } + }, + + + initState : function(){ + if(Ext.state.Manager){ + var id = this.getStateId(); + if(id){ + var state = Ext.state.Manager.get(id); + if(state){ + if(this.fireEvent('beforestaterestore', this, state) !== false){ + this.applyState(Ext.apply({}, state)); + this.fireEvent('staterestore', this, state); + } + } + } + } + }, + + + getStateId : function(){ + return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id); + }, + + + initStateEvents : function(){ + if(this.stateEvents){ + for(var i = 0, e; e = this.stateEvents[i]; i++){ + this.on(e, this.saveState, this, {delay:100}); + } + } + }, + + + applyState : function(state){ + if(state){ + Ext.apply(this, state); + } + }, + + + getState : function(){ + return null; + }, + + + saveState : function(){ + if(Ext.state.Manager && this.stateful !== false){ + var id = this.getStateId(); + if(id){ + var state = this.getState(); + if(this.fireEvent('beforestatesave', this, state) !== false){ + Ext.state.Manager.set(id, state); + this.fireEvent('statesave', this, state); + } + } + } + }, + + + applyToMarkup : function(el){ + this.allowDomMove = false; + this.el = Ext.get(el); + this.render(this.el.dom.parentNode); + }, + + + addClass : function(cls){ + if(this.el){ + this.el.addClass(cls); + }else{ + this.cls = this.cls ? this.cls + ' ' + cls : cls; + } + return this; + }, + + + removeClass : function(cls){ + if(this.el){ + this.el.removeClass(cls); + }else if(this.cls){ + this.cls = this.cls.split(' ').remove(cls).join(' '); + } + return this; + }, + + + + onRender : function(ct, position){ + if(!this.el && this.autoEl){ + if(Ext.isString(this.autoEl)){ + this.el = document.createElement(this.autoEl); + }else{ + var div = document.createElement('div'); + Ext.DomHelper.overwrite(div, this.autoEl); + this.el = div.firstChild; + } + if (!this.el.id) { + this.el.id = this.getId(); + } + } + if(this.el){ + this.el = Ext.get(this.el); + if(this.allowDomMove !== false){ + ct.dom.insertBefore(this.el.dom, position); + if (div) { + Ext.removeNode(div); + div = null; + } + } + } + }, + + + getAutoCreate : function(){ + var cfg = Ext.isObject(this.autoCreate) ? + this.autoCreate : Ext.apply({}, this.defaultAutoCreate); + if(this.id && !cfg.id){ + cfg.id = this.id; + } + return cfg; + }, + + + afterRender : Ext.emptyFn, + + + destroy : function(){ + if(!this.isDestroyed){ + if(this.fireEvent('beforedestroy', this) !== false){ + this.destroying = true; + this.beforeDestroy(); + if(this.ownerCt && this.ownerCt.remove){ + this.ownerCt.remove(this, false); + } + if(this.rendered){ + this.el.remove(); + if(this.actionMode == 'container' || this.removeMode == 'container'){ + this.container.remove(); + } + } + + if(this.focusTask && this.focusTask.cancel){ + this.focusTask.cancel(); + } + this.onDestroy(); + Ext.ComponentMgr.unregister(this); + this.fireEvent('destroy', this); + this.purgeListeners(); + this.destroying = false; + this.isDestroyed = true; + } + } + }, + + deleteMembers : function(){ + var args = arguments; + for(var i = 0, len = args.length; i < len; ++i){ + delete this[args[i]]; + } + }, + + + beforeDestroy : Ext.emptyFn, + + + onDestroy : Ext.emptyFn, + + + getEl : function(){ + return this.el; + }, + + + getContentTarget : function(){ + return this.el; + }, + + + getId : function(){ + return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID)); + }, + + + getItemId : function(){ + return this.itemId || this.getId(); + }, + + + focus : function(selectText, delay){ + if(delay){ + this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]); + this.focusTask.delay(Ext.isNumber(delay) ? delay : 10); + return this; + } + if(this.rendered && !this.isDestroyed){ + this.el.focus(); + if(selectText === true){ + this.el.dom.select(); + } + } + return this; + }, + + + blur : function(){ + if(this.rendered){ + this.el.blur(); + } + return this; + }, + + + disable : function( silent){ + if(this.rendered){ + this.onDisable(); + } + this.disabled = true; + if(silent !== true){ + this.fireEvent('disable', this); + } + return this; + }, + + + onDisable : function(){ + this.getActionEl().addClass(this.disabledClass); + this.el.dom.disabled = true; + }, + + + enable : function(){ + if(this.rendered){ + this.onEnable(); + } + this.disabled = false; + this.fireEvent('enable', this); + return this; + }, + + + onEnable : function(){ + this.getActionEl().removeClass(this.disabledClass); + this.el.dom.disabled = false; + }, + + + setDisabled : function(disabled){ + return this[disabled ? 'disable' : 'enable'](); + }, + + + show : function(){ + if(this.fireEvent('beforeshow', this) !== false){ + this.hidden = false; + if(this.autoRender){ + this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender); + } + if(this.rendered){ + this.onShow(); + } + this.fireEvent('show', this); + } + return this; + }, + + + onShow : function(){ + this.getVisibilityEl().removeClass('x-hide-' + this.hideMode); + }, + + + hide : function(){ + if(this.fireEvent('beforehide', this) !== false){ + this.doHide(); + this.fireEvent('hide', this); + } + return this; + }, + + + doHide: function(){ + this.hidden = true; + if(this.rendered){ + this.onHide(); + } + }, + + + onHide : function(){ + this.getVisibilityEl().addClass('x-hide-' + this.hideMode); + }, + + + getVisibilityEl : function(){ + return this.hideParent ? this.container : this.getActionEl(); + }, + + + setVisible : function(visible){ + return this[visible ? 'show' : 'hide'](); + }, + + + isVisible : function(){ + return this.rendered && this.getVisibilityEl().isVisible(); + }, + + + cloneConfig : function(overrides){ + overrides = overrides || {}; + var id = overrides.id || Ext.id(); + var cfg = Ext.applyIf(overrides, this.initialConfig); + cfg.id = id; + return new this.constructor(cfg); + }, + + + getXType : function(){ + return this.constructor.xtype; + }, + + + isXType : function(xtype, shallow){ + + if (Ext.isFunction(xtype)){ + xtype = xtype.xtype; + }else if (Ext.isObject(xtype)){ + xtype = xtype.constructor.xtype; + } + + return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype; + }, + + + getXTypes : function(){ + var tc = this.constructor; + if(!tc.xtypes){ + var c = [], sc = this; + while(sc && sc.constructor.xtype){ + c.unshift(sc.constructor.xtype); + sc = sc.constructor.superclass; + } + tc.xtypeChain = c; + tc.xtypes = c.join('/'); + } + return tc.xtypes; + }, + + + findParentBy : function(fn) { + for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt); + return p || null; + }, + + + findParentByType : function(xtype, shallow){ + return this.findParentBy(function(c){ + return c.isXType(xtype, shallow); + }); + }, + + + bubble : function(fn, scope, args){ + var p = this; + while(p){ + if(fn.apply(scope || p, args || [p]) === false){ + break; + } + p = p.ownerCt; + } + return this; + }, + + + getPositionEl : function(){ + return this.positionEl || this.el; + }, + + + purgeListeners : function(){ + Ext.Component.superclass.purgeListeners.call(this); + if(this.mons){ + this.on('beforedestroy', this.clearMons, this, {single: true}); + } + }, + + + clearMons : function(){ + Ext.each(this.mons, function(m){ + m.item.un(m.ename, m.fn, m.scope); + }, this); + this.mons = []; + }, + + + createMons: function(){ + if(!this.mons){ + this.mons = []; + this.on('beforedestroy', this.clearMons, this, {single: true}); + } + }, + + + mon : function(item, ename, fn, scope, opt){ + this.createMons(); + if(Ext.isObject(ename)){ + var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/; + + var o = ename; + for(var e in o){ + if(propRe.test(e)){ + continue; + } + if(Ext.isFunction(o[e])){ + + this.mons.push({ + item: item, ename: e, fn: o[e], scope: o.scope + }); + item.on(e, o[e], o.scope, o); + }else{ + + this.mons.push({ + item: item, ename: e, fn: o[e], scope: o.scope + }); + item.on(e, o[e]); + } + } + return; + } + + this.mons.push({ + item: item, ename: ename, fn: fn, scope: scope + }); + item.on(ename, fn, scope, opt); + }, + + + mun : function(item, ename, fn, scope){ + var found, mon; + this.createMons(); + for(var i = 0, len = this.mons.length; i < len; ++i){ + mon = this.mons[i]; + if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){ + this.mons.splice(i, 1); + item.un(ename, fn, scope); + found = true; + break; + } + } + return found; + }, + + + nextSibling : function(){ + if(this.ownerCt){ + var index = this.ownerCt.items.indexOf(this); + if(index != -1 && index+1 < this.ownerCt.items.getCount()){ + return this.ownerCt.items.itemAt(index+1); + } + } + return null; + }, + + + previousSibling : function(){ + if(this.ownerCt){ + var index = this.ownerCt.items.indexOf(this); + if(index > 0){ + return this.ownerCt.items.itemAt(index-1); + } + } + return null; + }, + + + getBubbleTarget : function(){ + return this.ownerCt; + } +}); + +Ext.reg('component', Ext.Component); + +Ext.Action = Ext.extend(Object, { + + + + + + + + + constructor : function(config){ + this.initialConfig = config; + this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); + this.items = []; + }, + + + isAction : true, + + + setText : function(text){ + this.initialConfig.text = text; + this.callEach('setText', [text]); + }, + + + getText : function(){ + return this.initialConfig.text; + }, + + + setIconClass : function(cls){ + this.initialConfig.iconCls = cls; + this.callEach('setIconClass', [cls]); + }, + + + getIconClass : function(){ + return this.initialConfig.iconCls; + }, + + + setDisabled : function(v){ + this.initialConfig.disabled = v; + this.callEach('setDisabled', [v]); + }, + + + enable : function(){ + this.setDisabled(false); + }, + + + disable : function(){ + this.setDisabled(true); + }, + + + isDisabled : function(){ + return this.initialConfig.disabled; + }, + + + setHidden : function(v){ + this.initialConfig.hidden = v; + this.callEach('setVisible', [!v]); + }, + + + show : function(){ + this.setHidden(false); + }, + + + hide : function(){ + this.setHidden(true); + }, + + + isHidden : function(){ + return this.initialConfig.hidden; + }, + + + setHandler : function(fn, scope){ + this.initialConfig.handler = fn; + this.initialConfig.scope = scope; + this.callEach('setHandler', [fn, scope]); + }, + + + each : function(fn, scope){ + Ext.each(this.items, fn, scope); + }, + + + callEach : function(fnName, args){ + var cs = this.items; + for(var i = 0, len = cs.length; i < len; i++){ + cs[i][fnName].apply(cs[i], args); + } + }, + + + addComponent : function(comp){ + this.items.push(comp); + comp.on('destroy', this.removeComponent, this); + }, + + + removeComponent : function(comp){ + this.items.remove(comp); + }, + + + execute : function(){ + this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments); + } +}); + +(function(){ +Ext.Layer = function(config, existingEl){ + config = config || {}; + var dh = Ext.DomHelper, + cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body; + + if (existingEl) { + this.dom = Ext.getDom(existingEl); + } + if(!this.dom){ + var o = config.dh || {tag: 'div', cls: 'x-layer'}; + this.dom = dh.append(pel, o); + } + if(config.cls){ + this.addClass(config.cls); + } + this.constrain = config.constrain !== false; + this.setVisibilityMode(Ext.Element.VISIBILITY); + if(config.id){ + this.id = this.dom.id = config.id; + }else{ + this.id = Ext.id(this.dom); + } + this.zindex = config.zindex || this.getZIndex(); + this.position('absolute', this.zindex); + if(config.shadow){ + this.shadowOffset = config.shadowOffset || 4; + this.shadow = new Ext.Shadow({ + offset : this.shadowOffset, + mode : config.shadow + }); + }else{ + this.shadowOffset = 0; + } + this.useShim = config.shim !== false && Ext.useShims; + this.useDisplay = config.useDisplay; + this.hide(); +}; + +var supr = Ext.Element.prototype; + + +var shims = []; + +Ext.extend(Ext.Layer, Ext.Element, { + + getZIndex : function(){ + return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000; + }, + + getShim : function(){ + if(!this.useShim){ + return null; + } + if(this.shim){ + return this.shim; + } + var shim = shims.shift(); + if(!shim){ + shim = this.createShim(); + shim.enableDisplayMode('block'); + shim.dom.style.display = 'none'; + shim.dom.style.visibility = 'visible'; + } + var pn = this.dom.parentNode; + if(shim.dom.parentNode != pn){ + pn.insertBefore(shim.dom, this.dom); + } + shim.setStyle('z-index', this.getZIndex()-2); + this.shim = shim; + return shim; + }, + + hideShim : function(){ + if(this.shim){ + this.shim.setDisplayed(false); + shims.push(this.shim); + delete this.shim; + } + }, + + disableShadow : function(){ + if(this.shadow){ + this.shadowDisabled = true; + this.shadow.hide(); + this.lastShadowOffset = this.shadowOffset; + this.shadowOffset = 0; + } + }, + + enableShadow : function(show){ + if(this.shadow){ + this.shadowDisabled = false; + if(Ext.isDefined(this.lastShadowOffset)) { + this.shadowOffset = this.lastShadowOffset; + delete this.lastShadowOffset; + } + if(show){ + this.sync(true); + } + } + }, + + + + + sync : function(doShow){ + var shadow = this.shadow; + if(!this.updating && this.isVisible() && (shadow || this.useShim)){ + var shim = this.getShim(), + w = this.getWidth(), + h = this.getHeight(), + l = this.getLeft(true), + t = this.getTop(true); + + if(shadow && !this.shadowDisabled){ + if(doShow && !shadow.isVisible()){ + shadow.show(this); + }else{ + shadow.realign(l, t, w, h); + } + if(shim){ + if(doShow){ + shim.show(); + } + + var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style, + shadowSize = shadow.el.getSize(); + shimStyle.left = (shadowAdj[0])+'px'; + shimStyle.top = (shadowAdj[1])+'px'; + shimStyle.width = (shadowSize.width)+'px'; + shimStyle.height = (shadowSize.height)+'px'; + } + }else if(shim){ + if(doShow){ + shim.show(); + } + shim.setSize(w, h); + shim.setLeftTop(l, t); + } + } + }, + + + destroy : function(){ + this.hideShim(); + if(this.shadow){ + this.shadow.hide(); + } + this.removeAllListeners(); + Ext.removeNode(this.dom); + delete this.dom; + }, + + remove : function(){ + this.destroy(); + }, + + + beginUpdate : function(){ + this.updating = true; + }, + + + endUpdate : function(){ + this.updating = false; + this.sync(true); + }, + + + hideUnders : function(negOffset){ + if(this.shadow){ + this.shadow.hide(); + } + this.hideShim(); + }, + + + constrainXY : function(){ + if(this.constrain){ + var vw = Ext.lib.Dom.getViewWidth(), + vh = Ext.lib.Dom.getViewHeight(); + var s = Ext.getDoc().getScroll(); + + var xy = this.getXY(); + var x = xy[0], y = xy[1]; + var so = this.shadowOffset; + var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so; + + var moved = false; + + if((x + w) > vw+s.left){ + x = vw - w - so; + moved = true; + } + if((y + h) > vh+s.top){ + y = vh - h - so; + moved = true; + } + + if(x < s.left){ + x = s.left; + moved = true; + } + if(y < s.top){ + y = s.top; + moved = true; + } + if(moved){ + if(this.avoidY){ + var ay = this.avoidY; + if(y <= ay && (y+h) >= ay){ + y = ay-h-5; + } + } + xy = [x, y]; + this.storeXY(xy); + supr.setXY.call(this, xy); + this.sync(); + } + } + return this; + }, + + getConstrainOffset : function(){ + return this.shadowOffset; + }, + + isVisible : function(){ + return this.visible; + }, + + + showAction : function(){ + this.visible = true; + if(this.useDisplay === true){ + this.setDisplayed(''); + }else if(this.lastXY){ + supr.setXY.call(this, this.lastXY); + }else if(this.lastLT){ + supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]); + } + }, + + + hideAction : function(){ + this.visible = false; + if(this.useDisplay === true){ + this.setDisplayed(false); + }else{ + this.setLeftTop(-10000,-10000); + } + }, + + + setVisible : function(v, a, d, c, e){ + if(v){ + this.showAction(); + } + if(a && v){ + var cb = function(){ + this.sync(true); + if(c){ + c(); + } + }.createDelegate(this); + supr.setVisible.call(this, true, true, d, cb, e); + }else{ + if(!v){ + this.hideUnders(true); + } + var cb = c; + if(a){ + cb = function(){ + this.hideAction(); + if(c){ + c(); + } + }.createDelegate(this); + } + supr.setVisible.call(this, v, a, d, cb, e); + if(v){ + this.sync(true); + }else if(!a){ + this.hideAction(); + } + } + return this; + }, + + storeXY : function(xy){ + delete this.lastLT; + this.lastXY = xy; + }, + + storeLeftTop : function(left, top){ + delete this.lastXY; + this.lastLT = [left, top]; + }, + + + beforeFx : function(){ + this.beforeAction(); + return Ext.Layer.superclass.beforeFx.apply(this, arguments); + }, + + + afterFx : function(){ + Ext.Layer.superclass.afterFx.apply(this, arguments); + this.sync(this.isVisible()); + }, + + + beforeAction : function(){ + if(!this.updating && this.shadow){ + this.shadow.hide(); + } + }, + + + setLeft : function(left){ + this.storeLeftTop(left, this.getTop(true)); + supr.setLeft.apply(this, arguments); + this.sync(); + return this; + }, + + setTop : function(top){ + this.storeLeftTop(this.getLeft(true), top); + supr.setTop.apply(this, arguments); + this.sync(); + return this; + }, + + setLeftTop : function(left, top){ + this.storeLeftTop(left, top); + supr.setLeftTop.apply(this, arguments); + this.sync(); + return this; + }, + + setXY : function(xy, a, d, c, e){ + this.fixDisplay(); + this.beforeAction(); + this.storeXY(xy); + var cb = this.createCB(c); + supr.setXY.call(this, xy, a, d, cb, e); + if(!a){ + cb(); + } + return this; + }, + + + createCB : function(c){ + var el = this; + return function(){ + el.constrainXY(); + el.sync(true); + if(c){ + c(); + } + }; + }, + + + setX : function(x, a, d, c, e){ + this.setXY([x, this.getY()], a, d, c, e); + return this; + }, + + + setY : function(y, a, d, c, e){ + this.setXY([this.getX(), y], a, d, c, e); + return this; + }, + + + setSize : function(w, h, a, d, c, e){ + this.beforeAction(); + var cb = this.createCB(c); + supr.setSize.call(this, w, h, a, d, cb, e); + if(!a){ + cb(); + } + return this; + }, + + + setWidth : function(w, a, d, c, e){ + this.beforeAction(); + var cb = this.createCB(c); + supr.setWidth.call(this, w, a, d, cb, e); + if(!a){ + cb(); + } + return this; + }, + + + setHeight : function(h, a, d, c, e){ + this.beforeAction(); + var cb = this.createCB(c); + supr.setHeight.call(this, h, a, d, cb, e); + if(!a){ + cb(); + } + return this; + }, + + + setBounds : function(x, y, w, h, a, d, c, e){ + this.beforeAction(); + var cb = this.createCB(c); + if(!a){ + this.storeXY([x, y]); + supr.setXY.call(this, [x, y]); + supr.setSize.call(this, w, h, a, d, cb, e); + cb(); + }else{ + supr.setBounds.call(this, x, y, w, h, a, d, cb, e); + } + return this; + }, + + + setZIndex : function(zindex){ + this.zindex = zindex; + this.setStyle('z-index', zindex + 2); + if(this.shadow){ + this.shadow.setZIndex(zindex + 1); + } + if(this.shim){ + this.shim.setStyle('z-index', zindex); + } + return this; + } +}); +})(); + +Ext.Shadow = function(config) { + Ext.apply(this, config); + if (typeof this.mode != "string") { + this.mode = this.defaultMode; + } + var o = this.offset, + a = { + h: 0 + }, + rad = Math.floor(this.offset / 2); + switch (this.mode.toLowerCase()) { + + case "drop": + a.w = 0; + a.l = a.t = o; + a.t -= 1; + if (Ext.isIE9m) { + a.l -= this.offset + rad; + a.t -= this.offset + rad; + a.w -= rad; + a.h -= rad; + a.t += 1; + } + break; + case "sides": + a.w = (o * 2); + a.l = -o; + a.t = o - 1; + if (Ext.isIE9m) { + a.l -= (this.offset - rad); + a.t -= this.offset + rad; + a.l += 1; + a.w -= (this.offset - rad) * 2; + a.w -= rad + 1; + a.h -= 1; + } + break; + case "frame": + a.w = a.h = (o * 2); + a.l = a.t = -o; + a.t += 1; + a.h -= 2; + if (Ext.isIE9m) { + a.l -= (this.offset - rad); + a.t -= (this.offset - rad); + a.l += 1; + a.w -= (this.offset + rad + 1); + a.h -= (this.offset + rad); + a.h += 1; + } + break; + }; + + this.adjusts = a; +}; + +Ext.Shadow.prototype = { + + + offset: 4, + + + defaultMode: "drop", + + + show: function(target) { + target = Ext.get(target); + if (!this.el) { + this.el = Ext.Shadow.Pool.pull(); + if (this.el.dom.nextSibling != target.dom) { + this.el.insertBefore(target); + } + } + this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1); + if (Ext.isIE9m) { + this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")"; + } + this.realign( + target.getLeft(true), + target.getTop(true), + target.getWidth(), + target.getHeight() + ); + this.el.dom.style.display = "block"; + }, + + + isVisible: function() { + return this.el ? true: false; + }, + + + realign: function(l, t, w, h) { + if (!this.el) { + return; + } + var a = this.adjusts, + d = this.el.dom, + s = d.style, + iea = 0, + sw = (w + a.w), + sh = (h + a.h), + sws = sw + "px", + shs = sh + "px", + cn, + sww; + s.left = (l + a.l) + "px"; + s.top = (t + a.t) + "px"; + if (s.width != sws || s.height != shs) { + s.width = sws; + s.height = shs; + if (!Ext.isIE9m) { + cn = d.childNodes; + sww = Math.max(0, (sw - 12)) + "px"; + cn[0].childNodes[1].style.width = sww; + cn[1].childNodes[1].style.width = sww; + cn[2].childNodes[1].style.width = sww; + cn[1].style.height = Math.max(0, (sh - 12)) + "px"; + } + } + }, + + + hide: function() { + if (this.el) { + this.el.dom.style.display = "none"; + Ext.Shadow.Pool.push(this.el); + delete this.el; + } + }, + + + setZIndex: function(z) { + this.zIndex = z; + if (this.el) { + this.el.setStyle("z-index", z); + } + } +}; + + +Ext.Shadow.Pool = function() { + var p = [], + markup = Ext.isIE9m ? + '
': + '
'; + return { + pull: function() { + var sh = p.shift(); + if (!sh) { + sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup)); + sh.autoBoxAdjust = false; + } + return sh; + }, + + push: function(sh) { + p.push(sh); + } + }; +}(); +Ext.BoxComponent = Ext.extend(Ext.Component, { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + initComponent : function(){ + Ext.BoxComponent.superclass.initComponent.call(this); + this.addEvents( + + 'resize', + + 'move' + ); + }, + + + boxReady : false, + + deferHeight: false, + + + setSize : function(w, h){ + + + if(typeof w == 'object'){ + h = w.height; + w = w.width; + } + if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) { + w = this.boxMinWidth; + } + if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) { + h = this.boxMinHeight; + } + if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) { + w = this.boxMaxWidth; + } + if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) { + h = this.boxMaxHeight; + } + + if(!this.boxReady){ + this.width = w; + this.height = h; + return this; + } + + + if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){ + return this; + } + this.lastSize = {width: w, height: h}; + var adj = this.adjustSize(w, h), + aw = adj.width, + ah = adj.height, + rz; + if(aw !== undefined || ah !== undefined){ + rz = this.getResizeEl(); + if(!this.deferHeight && aw !== undefined && ah !== undefined){ + rz.setSize(aw, ah); + }else if(!this.deferHeight && ah !== undefined){ + rz.setHeight(ah); + }else if(aw !== undefined){ + rz.setWidth(aw); + } + this.onResize(aw, ah, w, h); + this.fireEvent('resize', this, aw, ah, w, h); + } + return this; + }, + + + setWidth : function(width){ + return this.setSize(width); + }, + + + setHeight : function(height){ + return this.setSize(undefined, height); + }, + + + getSize : function(){ + return this.getResizeEl().getSize(); + }, + + + getWidth : function(){ + return this.getResizeEl().getWidth(); + }, + + + getHeight : function(){ + return this.getResizeEl().getHeight(); + }, + + + getOuterSize : function(){ + var el = this.getResizeEl(); + return {width: el.getWidth() + el.getMargins('lr'), + height: el.getHeight() + el.getMargins('tb')}; + }, + + + getPosition : function(local){ + var el = this.getPositionEl(); + if(local === true){ + return [el.getLeft(true), el.getTop(true)]; + } + return this.xy || el.getXY(); + }, + + + getBox : function(local){ + var pos = this.getPosition(local); + var s = this.getSize(); + s.x = pos[0]; + s.y = pos[1]; + return s; + }, + + + updateBox : function(box){ + this.setSize(box.width, box.height); + this.setPagePosition(box.x, box.y); + return this; + }, + + + getResizeEl : function(){ + return this.resizeEl || this.el; + }, + + + setAutoScroll : function(scroll){ + if(this.rendered){ + this.getContentTarget().setOverflow(scroll ? 'auto' : ''); + } + this.autoScroll = scroll; + return this; + }, + + + setPosition : function(x, y){ + if(x && typeof x[1] == 'number'){ + y = x[1]; + x = x[0]; + } + this.x = x; + this.y = y; + if(!this.boxReady){ + return this; + } + var adj = this.adjustPosition(x, y); + var ax = adj.x, ay = adj.y; + + var el = this.getPositionEl(); + if(ax !== undefined || ay !== undefined){ + if(ax !== undefined && ay !== undefined){ + el.setLeftTop(ax, ay); + }else if(ax !== undefined){ + el.setLeft(ax); + }else if(ay !== undefined){ + el.setTop(ay); + } + this.onPosition(ax, ay); + this.fireEvent('move', this, ax, ay); + } + return this; + }, + + + setPagePosition : function(x, y){ + if(x && typeof x[1] == 'number'){ + y = x[1]; + x = x[0]; + } + this.pageX = x; + this.pageY = y; + if(!this.boxReady){ + return; + } + if(x === undefined || y === undefined){ + return; + } + var p = this.getPositionEl().translatePoints(x, y); + this.setPosition(p.left, p.top); + return this; + }, + + + afterRender : function(){ + Ext.BoxComponent.superclass.afterRender.call(this); + if(this.resizeEl){ + this.resizeEl = Ext.get(this.resizeEl); + } + if(this.positionEl){ + this.positionEl = Ext.get(this.positionEl); + } + this.boxReady = true; + Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll); + this.setSize(this.width, this.height); + if(this.x || this.y){ + this.setPosition(this.x, this.y); + }else if(this.pageX || this.pageY){ + this.setPagePosition(this.pageX, this.pageY); + } + }, + + + syncSize : function(){ + delete this.lastSize; + this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight()); + return this; + }, + + + onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ + }, + + + onPosition : function(x, y){ + + }, + + + adjustSize : function(w, h){ + if(this.autoWidth){ + w = 'auto'; + } + if(this.autoHeight){ + h = 'auto'; + } + return {width : w, height: h}; + }, + + + adjustPosition : function(x, y){ + return {x : x, y: y}; + } +}); +Ext.reg('box', Ext.BoxComponent); + + + +Ext.Spacer = Ext.extend(Ext.BoxComponent, { + autoEl:'div' +}); +Ext.reg('spacer', Ext.Spacer); +Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){ + + + this.el = Ext.get(dragElement, true); + this.el.unselectable(); + + this.resizingEl = Ext.get(resizingElement, true); + + + this.orientation = orientation || Ext.SplitBar.HORIZONTAL; + + + + this.minSize = 0; + + + this.maxSize = 2000; + + + this.animate = false; + + + this.useShim = false; + + + this.shim = null; + + if(!existingProxy){ + + this.proxy = Ext.SplitBar.createProxy(this.orientation); + }else{ + this.proxy = Ext.get(existingProxy).dom; + } + + this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id}); + + + this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this); + + + this.dd.endDrag = this.onEndProxyDrag.createDelegate(this); + + + this.dragSpecs = {}; + + + this.adapter = new Ext.SplitBar.BasicLayoutAdapter(); + this.adapter.init(this); + + if(this.orientation == Ext.SplitBar.HORIZONTAL){ + + this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT); + this.el.addClass("x-splitbar-h"); + }else{ + + this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM); + this.el.addClass("x-splitbar-v"); + } + + this.addEvents( + + "resize", + + "moved", + + "beforeresize", + + "beforeapply" + ); + + Ext.SplitBar.superclass.constructor.call(this); +}; + +Ext.extend(Ext.SplitBar, Ext.util.Observable, { + onStartProxyDrag : function(x, y){ + this.fireEvent("beforeresize", this); + this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true); + this.overlay.unselectable(); + this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); + this.overlay.show(); + Ext.get(this.proxy).setDisplayed("block"); + var size = this.adapter.getElementSize(this); + this.activeMinSize = this.getMinimumSize(); + this.activeMaxSize = this.getMaximumSize(); + var c1 = size - this.activeMinSize; + var c2 = Math.max(this.activeMaxSize - size, 0); + if(this.orientation == Ext.SplitBar.HORIZONTAL){ + this.dd.resetConstraints(); + this.dd.setXConstraint( + this.placement == Ext.SplitBar.LEFT ? c1 : c2, + this.placement == Ext.SplitBar.LEFT ? c2 : c1, + this.tickSize + ); + this.dd.setYConstraint(0, 0); + }else{ + this.dd.resetConstraints(); + this.dd.setXConstraint(0, 0); + this.dd.setYConstraint( + this.placement == Ext.SplitBar.TOP ? c1 : c2, + this.placement == Ext.SplitBar.TOP ? c2 : c1, + this.tickSize + ); + } + this.dragSpecs.startSize = size; + this.dragSpecs.startPoint = [x, y]; + Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y); + }, + + + onEndProxyDrag : function(e){ + Ext.get(this.proxy).setDisplayed(false); + var endPoint = Ext.lib.Event.getXY(e); + if(this.overlay){ + Ext.destroy(this.overlay); + delete this.overlay; + } + var newSize; + if(this.orientation == Ext.SplitBar.HORIZONTAL){ + newSize = this.dragSpecs.startSize + + (this.placement == Ext.SplitBar.LEFT ? + endPoint[0] - this.dragSpecs.startPoint[0] : + this.dragSpecs.startPoint[0] - endPoint[0] + ); + }else{ + newSize = this.dragSpecs.startSize + + (this.placement == Ext.SplitBar.TOP ? + endPoint[1] - this.dragSpecs.startPoint[1] : + this.dragSpecs.startPoint[1] - endPoint[1] + ); + } + newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize); + if(newSize != this.dragSpecs.startSize){ + if(this.fireEvent('beforeapply', this, newSize) !== false){ + this.adapter.setElementSize(this, newSize); + this.fireEvent("moved", this, newSize); + this.fireEvent("resize", this, newSize); + } + } + }, + + + getAdapter : function(){ + return this.adapter; + }, + + + setAdapter : function(adapter){ + this.adapter = adapter; + this.adapter.init(this); + }, + + + getMinimumSize : function(){ + return this.minSize; + }, + + + setMinimumSize : function(minSize){ + this.minSize = minSize; + }, + + + getMaximumSize : function(){ + return this.maxSize; + }, + + + setMaximumSize : function(maxSize){ + this.maxSize = maxSize; + }, + + + setCurrentSize : function(size){ + var oldAnimate = this.animate; + this.animate = false; + this.adapter.setElementSize(this, size); + this.animate = oldAnimate; + }, + + + destroy : function(removeEl){ + Ext.destroy(this.shim, Ext.get(this.proxy)); + this.dd.unreg(); + if(removeEl){ + this.el.remove(); + } + this.purgeListeners(); + } +}); + + +Ext.SplitBar.createProxy = function(dir){ + var proxy = new Ext.Element(document.createElement("div")); + document.body.appendChild(proxy.dom); + proxy.unselectable(); + var cls = 'x-splitbar-proxy'; + proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v')); + return proxy.dom; +}; + + +Ext.SplitBar.BasicLayoutAdapter = function(){ +}; + +Ext.SplitBar.BasicLayoutAdapter.prototype = { + + init : function(s){ + + }, + + getElementSize : function(s){ + if(s.orientation == Ext.SplitBar.HORIZONTAL){ + return s.resizingEl.getWidth(); + }else{ + return s.resizingEl.getHeight(); + } + }, + + + setElementSize : function(s, newSize, onComplete){ + if(s.orientation == Ext.SplitBar.HORIZONTAL){ + if(!s.animate){ + s.resizingEl.setWidth(newSize); + if(onComplete){ + onComplete(s, newSize); + } + }else{ + s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut'); + } + }else{ + + if(!s.animate){ + s.resizingEl.setHeight(newSize); + if(onComplete){ + onComplete(s, newSize); + } + }else{ + s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut'); + } + } + } +}; + + +Ext.SplitBar.AbsoluteLayoutAdapter = function(container){ + this.basic = new Ext.SplitBar.BasicLayoutAdapter(); + this.container = Ext.get(container); +}; + +Ext.SplitBar.AbsoluteLayoutAdapter.prototype = { + init : function(s){ + this.basic.init(s); + }, + + getElementSize : function(s){ + return this.basic.getElementSize(s); + }, + + setElementSize : function(s, newSize, onComplete){ + this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s])); + }, + + moveSplitter : function(s){ + var yes = Ext.SplitBar; + switch(s.placement){ + case yes.LEFT: + s.el.setX(s.resizingEl.getRight()); + break; + case yes.RIGHT: + s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px"); + break; + case yes.TOP: + s.el.setY(s.resizingEl.getBottom()); + break; + case yes.BOTTOM: + s.el.setY(s.resizingEl.getTop() - s.el.getHeight()); + break; + } + } +}; + + +Ext.SplitBar.VERTICAL = 1; + + +Ext.SplitBar.HORIZONTAL = 2; + + +Ext.SplitBar.LEFT = 1; + + +Ext.SplitBar.RIGHT = 2; + + +Ext.SplitBar.TOP = 3; + + +Ext.SplitBar.BOTTOM = 4; + +Ext.Container = Ext.extend(Ext.BoxComponent, { + + + + + bufferResize: 50, + + + + + + + + autoDestroy : true, + + + forceLayout: false, + + + + defaultType : 'panel', + + + resizeEvent: 'resize', + + + bubbleEvents: ['add', 'remove'], + + + initComponent : function(){ + Ext.Container.superclass.initComponent.call(this); + + this.addEvents( + + 'afterlayout', + + 'beforeadd', + + 'beforeremove', + + 'add', + + 'remove' + ); + + + var items = this.items; + if(items){ + delete this.items; + this.add(items); + } + }, + + + initItems : function(){ + if(!this.items){ + this.items = new Ext.util.MixedCollection(false, this.getComponentId); + this.getLayout(); + } + }, + + + setLayout : function(layout){ + if(this.layout && this.layout != layout){ + this.layout.setContainer(null); + } + this.layout = layout; + this.initItems(); + layout.setContainer(this); + }, + + afterRender: function(){ + + + Ext.Container.superclass.afterRender.call(this); + if(!this.layout){ + this.layout = 'auto'; + } + if(Ext.isObject(this.layout) && !this.layout.layout){ + this.layoutConfig = this.layout; + this.layout = this.layoutConfig.type; + } + if(Ext.isString(this.layout)){ + this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig); + } + this.setLayout(this.layout); + + + if(this.activeItem !== undefined && this.layout.setActiveItem){ + var item = this.activeItem; + delete this.activeItem; + this.layout.setActiveItem(item); + } + + + if(!this.ownerCt){ + this.doLayout(false, true); + } + + + + if(this.monitorResize === true){ + Ext.EventManager.onWindowResize(this.doLayout, this, [false]); + } + }, + + + getLayoutTarget : function(){ + return this.el; + }, + + + getComponentId : function(comp){ + return comp.getItemId(); + }, + + + add : function(comp){ + this.initItems(); + var args = arguments.length > 1; + if(args || Ext.isArray(comp)){ + var result = []; + Ext.each(args ? arguments : comp, function(c){ + result.push(this.add(c)); + }, this); + return result; + } + var c = this.lookupComponent(this.applyDefaults(comp)); + var index = this.items.length; + if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){ + this.items.add(c); + + c.onAdded(this, index); + this.onAdd(c); + this.fireEvent('add', this, c, index); + } + return c; + }, + + onAdd : function(c){ + + }, + + + onAdded : function(container, pos) { + + this.ownerCt = container; + this.initRef(); + + this.cascade(function(c){ + c.initRef(); + }); + this.fireEvent('added', this, container, pos); + }, + + + insert : function(index, comp) { + var args = arguments, + length = args.length, + result = [], + i, c; + + this.initItems(); + + if (length > 2) { + for (i = length - 1; i >= 1; --i) { + result.push(this.insert(index, args[i])); + } + return result; + } + + c = this.lookupComponent(this.applyDefaults(comp)); + index = Math.min(index, this.items.length); + + if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) { + if (c.ownerCt == this) { + this.items.remove(c); + } + this.items.insert(index, c); + c.onAdded(this, index); + this.onAdd(c); + this.fireEvent('add', this, c, index); + } + + return c; + }, + + + applyDefaults : function(c){ + var d = this.defaults; + if(d){ + if(Ext.isFunction(d)){ + d = d.call(this, c); + } + if(Ext.isString(c)){ + c = Ext.ComponentMgr.get(c); + Ext.apply(c, d); + }else if(!c.events){ + Ext.applyIf(c.isAction ? c.initialConfig : c, d); + }else{ + Ext.apply(c, d); + } + } + return c; + }, + + + onBeforeAdd : function(item){ + if(item.ownerCt){ + item.ownerCt.remove(item, false); + } + if(this.hideBorders === true){ + item.border = (item.border === true); + } + }, + + + remove : function(comp, autoDestroy){ + this.initItems(); + var c = this.getComponent(comp); + if(c && this.fireEvent('beforeremove', this, c) !== false){ + this.doRemove(c, autoDestroy); + this.fireEvent('remove', this, c); + } + return c; + }, + + onRemove: function(c){ + + }, + + + doRemove: function(c, autoDestroy){ + var l = this.layout, + hasLayout = l && this.rendered; + + if(hasLayout){ + l.onRemove(c); + } + this.items.remove(c); + c.onRemoved(); + this.onRemove(c); + if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){ + c.destroy(); + } + if(hasLayout){ + l.afterRemove(c); + } + }, + + + removeAll: function(autoDestroy){ + this.initItems(); + var item, rem = [], items = []; + this.items.each(function(i){ + rem.push(i); + }); + for (var i = 0, len = rem.length; i < len; ++i){ + item = rem[i]; + this.remove(item, autoDestroy); + if(item.ownerCt !== this){ + items.push(item); + } + } + return items; + }, + + + getComponent : function(comp){ + if(Ext.isObject(comp)){ + comp = comp.getItemId(); + } + return this.items.get(comp); + }, + + + lookupComponent : function(comp){ + if(Ext.isString(comp)){ + return Ext.ComponentMgr.get(comp); + }else if(!comp.events){ + return this.createComponent(comp); + } + return comp; + }, + + + createComponent : function(config, defaultType){ + if (config.render) { + return config; + } + + + var c = Ext.create(Ext.apply({ + ownerCt: this + }, config), defaultType || this.defaultType); + delete c.initialConfig.ownerCt; + delete c.ownerCt; + return c; + }, + + + canLayout : function() { + var el = this.getVisibilityEl(); + return el && el.dom && !el.isStyle("display", "none"); + }, + + + + doLayout : function(shallow, force){ + var rendered = this.rendered, + forceLayout = force || this.forceLayout; + + if(this.collapsed || !this.canLayout()){ + this.deferLayout = this.deferLayout || !shallow; + if(!forceLayout){ + return; + } + shallow = shallow && !this.deferLayout; + } else { + delete this.deferLayout; + } + if(rendered && this.layout){ + this.layout.layout(); + } + if(shallow !== true && this.items){ + var cs = this.items.items; + for(var i = 0, len = cs.length; i < len; i++){ + var c = cs[i]; + if(c.doLayout){ + c.doLayout(false, forceLayout); + } + } + } + if(rendered){ + this.onLayout(shallow, forceLayout); + } + + this.hasLayout = true; + delete this.forceLayout; + }, + + onLayout : Ext.emptyFn, + + + shouldBufferLayout: function(){ + + var hl = this.hasLayout; + if(this.ownerCt){ + + return hl ? !this.hasLayoutPending() : false; + } + + return hl; + }, + + + hasLayoutPending: function(){ + + var pending = false; + this.ownerCt.bubble(function(c){ + if(c.layoutPending){ + pending = true; + return false; + } + }); + return pending; + }, + + onShow : function(){ + + Ext.Container.superclass.onShow.call(this); + + if(Ext.isDefined(this.deferLayout)){ + delete this.deferLayout; + this.doLayout(true); + } + }, + + + getLayout : function(){ + if(!this.layout){ + var layout = new Ext.layout.AutoLayout(this.layoutConfig); + this.setLayout(layout); + } + return this.layout; + }, + + + beforeDestroy : function(){ + var c; + if(this.items){ + while(c = this.items.first()){ + this.doRemove(c, true); + } + } + if(this.monitorResize){ + Ext.EventManager.removeResizeListener(this.doLayout, this); + } + Ext.destroy(this.layout); + Ext.Container.superclass.beforeDestroy.call(this); + }, + + + cascade : function(fn, scope, args){ + if(fn.apply(scope || this, args || [this]) !== false){ + if(this.items){ + var cs = this.items.items; + for(var i = 0, len = cs.length; i < len; i++){ + if(cs[i].cascade){ + cs[i].cascade(fn, scope, args); + }else{ + fn.apply(scope || cs[i], args || [cs[i]]); + } + } + } + } + return this; + }, + + + findById : function(id){ + var m = null, + ct = this; + this.cascade(function(c){ + if(ct != c && c.id === id){ + m = c; + return false; + } + }); + return m; + }, + + + findByType : function(xtype, shallow){ + return this.findBy(function(c){ + return c.isXType(xtype, shallow); + }); + }, + + + find : function(prop, value){ + return this.findBy(function(c){ + return c[prop] === value; + }); + }, + + + findBy : function(fn, scope){ + var m = [], ct = this; + this.cascade(function(c){ + if(ct != c && fn.call(scope || c, c, ct) === true){ + m.push(c); + } + }); + return m; + }, + + + get : function(key){ + return this.getComponent(key); + } +}); + +Ext.Container.LAYOUTS = {}; +Ext.reg('container', Ext.Container); + +Ext.layout.ContainerLayout = Ext.extend(Object, { + + + + + + + monitorResize:false, + + activeItem : null, + + constructor : function(config){ + this.id = Ext.id(null, 'ext-layout-'); + Ext.apply(this, config); + }, + + type: 'container', + + + IEMeasureHack : function(target, viewFlag) { + var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret; + for (i = 0 ; i < tLen ; i++) { + c = tChildren[i]; + e = Ext.get(c); + if (e) { + d[i] = e.getStyle('display'); + e.setStyle({display: 'none'}); + } + } + ret = target ? target.getViewSize(viewFlag) : {}; + for (i = 0 ; i < tLen ; i++) { + c = tChildren[i]; + e = Ext.get(c); + if (e) { + e.setStyle({display: d[i]}); + } + } + return ret; + }, + + + getLayoutTargetSize : Ext.EmptyFn, + + + layout : function(){ + var ct = this.container, target = ct.getLayoutTarget(); + if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){ + target.addClass(this.targetCls); + } + this.onLayout(ct, target); + ct.fireEvent('afterlayout', ct, this); + }, + + + onLayout : function(ct, target){ + this.renderAll(ct, target); + }, + + + isValidParent : function(c, target){ + return target && c.getPositionEl().dom.parentNode == (target.dom || target); + }, + + + renderAll : function(ct, target){ + var items = ct.items.items, i, c, len = items.length; + for(i = 0; i < len; i++) { + c = items[i]; + if(c && (!c.rendered || !this.isValidParent(c, target))){ + this.renderItem(c, i, target); + } + } + }, + + + renderItem : function(c, position, target){ + if (c) { + if (!c.rendered) { + c.render(target, position); + this.configureItem(c); + } else if (!this.isValidParent(c, target)) { + if (Ext.isNumber(position)) { + position = target.dom.childNodes[position]; + } + + target.dom.insertBefore(c.getPositionEl().dom, position || null); + c.container = target; + this.configureItem(c); + } + } + }, + + + + getRenderedItems: function(ct){ + var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = []; + for (i = 0; i < len; i++) { + if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){ + items.push(c); + } + }; + return items; + }, + + + configureItem: function(c){ + if (this.extraCls) { + var t = c.getPositionEl ? c.getPositionEl() : c; + t.addClass(this.extraCls); + } + + + if (c.doLayout && this.forceLayout) { + c.doLayout(); + } + if (this.renderHidden && c != this.activeItem) { + c.hide(); + } + }, + + onRemove: function(c){ + if(this.activeItem == c){ + delete this.activeItem; + } + if(c.rendered && this.extraCls){ + var t = c.getPositionEl ? c.getPositionEl() : c; + t.removeClass(this.extraCls); + } + }, + + afterRemove: function(c){ + if(c.removeRestore){ + c.removeMode = 'container'; + delete c.removeRestore; + } + }, + + + onResize: function(){ + var ct = this.container, + b; + if(ct.collapsed){ + return; + } + if(b = ct.bufferResize && ct.shouldBufferLayout()){ + if(!this.resizeTask){ + this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this); + this.resizeBuffer = Ext.isNumber(b) ? b : 50; + } + ct.layoutPending = true; + this.resizeTask.delay(this.resizeBuffer); + }else{ + this.runLayout(); + } + }, + + runLayout: function(){ + var ct = this.container; + this.layout(); + ct.onLayout(); + delete ct.layoutPending; + }, + + + setContainer : function(ct){ + + if(this.monitorResize && ct != this.container){ + var old = this.container; + if(old){ + old.un(old.resizeEvent, this.onResize, this); + } + if(ct){ + ct.on(ct.resizeEvent, this.onResize, this); + } + } + this.container = ct; + }, + + + parseMargins : function(v){ + if (Ext.isNumber(v)) { + v = v.toString(); + } + var ms = v.split(' '), + len = ms.length; + + if (len == 1) { + ms[1] = ms[2] = ms[3] = ms[0]; + } else if(len == 2) { + ms[2] = ms[0]; + ms[3] = ms[1]; + } else if(len == 3) { + ms[3] = ms[1]; + } + + return { + top :parseInt(ms[0], 10) || 0, + right :parseInt(ms[1], 10) || 0, + bottom:parseInt(ms[2], 10) || 0, + left :parseInt(ms[3], 10) || 0 + }; + }, + + + fieldTpl: (function() { + var t = new Ext.Template( + '
', + '', + '
', + '
', + '
' + ); + t.disableFormats = true; + return t.compile(); + })(), + + + destroy : function(){ + + if(this.resizeTask && this.resizeTask.cancel){ + this.resizeTask.cancel(); + } + if(this.container) { + this.container.un(this.container.resizeEvent, this.onResize, this); + } + if(!Ext.isEmpty(this.targetCls)){ + var target = this.container.getLayoutTarget(); + if(target){ + target.removeClass(this.targetCls); + } + } + } +}); +Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, { + type: 'auto', + + monitorResize: true, + + onLayout : function(ct, target){ + Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target); + var cs = this.getRenderedItems(ct), len = cs.length, i, c; + for(i = 0; i < len; i++){ + c = cs[i]; + if (c.doLayout){ + + c.doLayout(true); + } + } + } +}); + +Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout; + +Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, { + + monitorResize:true, + + type: 'fit', + + getLayoutTargetSize : function() { + var target = this.container.getLayoutTarget(); + if (!target) { + return {}; + } + + return target.getStyleSize(); + }, + + + onLayout : function(ct, target){ + Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target); + if(!ct.collapsed){ + this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize()); + } + }, + + + setItemSize : function(item, size){ + if(item && size.height > 0){ + item.setSize(size); + } + } +}); +Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout; +Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, { + + deferredRender : false, + + + layoutOnCardChange : false, + + + + renderHidden : true, + + type: 'card', + + + setActiveItem : function(item){ + var ai = this.activeItem, + ct = this.container; + item = ct.getComponent(item); + + + if(item && ai != item){ + + + if(ai){ + ai.hide(); + if (ai.hidden !== true) { + return false; + } + ai.fireEvent('deactivate', ai); + } + + var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered); + + + this.activeItem = item; + + + + delete item.deferLayout; + + + item.show(); + + this.layout(); + + if(layout){ + item.doLayout(); + } + item.fireEvent('activate', item); + } + }, + + + renderAll : function(ct, target){ + if(this.deferredRender){ + this.renderItem(this.activeItem, undefined, target); + }else{ + Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target); + } + } +}); +Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout; + +Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, { + + + + monitorResize : true, + + type : 'anchor', + + + defaultAnchor : '100%', + + parseAnchorRE : /^(r|right|b|bottom)$/i, + + + getLayoutTargetSize : function() { + var target = this.container.getLayoutTarget(), ret = {}; + if (target) { + ret = target.getViewSize(); + + + + + if (Ext.isIE9m && Ext.isStrict && ret.width == 0){ + ret = target.getStyleSize(); + } + ret.width -= target.getPadding('lr'); + ret.height -= target.getPadding('tb'); + } + return ret; + }, + + + onLayout : function(container, target) { + Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target); + + var size = this.getLayoutTargetSize(), + containerWidth = size.width, + containerHeight = size.height, + overflow = target.getStyle('overflow'), + components = this.getRenderedItems(container), + len = components.length, + boxes = [], + box, + anchorWidth, + anchorHeight, + component, + anchorSpec, + calcWidth, + calcHeight, + anchorsArray, + totalHeight = 0, + i, + el; + + if(containerWidth < 20 && containerHeight < 20){ + return; + } + + + if(container.anchorSize) { + if(typeof container.anchorSize == 'number') { + anchorWidth = container.anchorSize; + } else { + anchorWidth = container.anchorSize.width; + anchorHeight = container.anchorSize.height; + } + } else { + anchorWidth = container.initialConfig.width; + anchorHeight = container.initialConfig.height; + } + + for(i = 0; i < len; i++) { + component = components[i]; + el = component.getPositionEl(); + + + if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){ + component.anchor = this.defaultAnchor; + } + + if(component.anchor) { + anchorSpec = component.anchorSpec; + + if(!anchorSpec){ + anchorsArray = component.anchor.split(' '); + component.anchorSpec = anchorSpec = { + right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth), + bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight) + }; + } + calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined; + calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined; + + if(calcWidth || calcHeight) { + boxes.push({ + component: component, + width: calcWidth || undefined, + height: calcHeight || undefined + }); + } + } + } + for (i = 0, len = boxes.length; i < len; i++) { + box = boxes[i]; + box.component.setSize(box.width, box.height); + } + + if (overflow && overflow != 'hidden' && !this.adjustmentPass) { + var newTargetSize = this.getLayoutTargetSize(); + if (newTargetSize.width != size.width || newTargetSize.height != size.height){ + this.adjustmentPass = true; + this.onLayout(container, target); + } + } + + delete this.adjustmentPass; + }, + + + parseAnchor : function(a, start, cstart) { + if (a && a != 'none') { + var last; + + if (this.parseAnchorRE.test(a)) { + var diff = cstart - start; + return function(v){ + if(v !== last){ + last = v; + return v - diff; + } + }; + + } else if(a.indexOf('%') != -1) { + var ratio = parseFloat(a.replace('%', ''))*.01; + return function(v){ + if(v !== last){ + last = v; + return Math.floor(v*ratio); + } + }; + + } else { + a = parseInt(a, 10); + if (!isNaN(a)) { + return function(v) { + if (v !== last) { + last = v; + return v + a; + } + }; + } + } + } + return false; + }, + + + adjustWidthAnchor : function(value, comp){ + return value; + }, + + + adjustHeightAnchor : function(value, comp){ + return value; + } + + +}); +Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout; + +Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, { + + monitorResize:true, + + type: 'column', + + extraCls: 'x-column', + + scrollOffset : 0, + + + + targetCls: 'x-column-layout-ct', + + isValidParent : function(c, target){ + return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; + }, + + getLayoutTargetSize : function() { + var target = this.container.getLayoutTarget(), ret; + if (target) { + ret = target.getViewSize(); + + + + + if (Ext.isIE9m && Ext.isStrict && ret.width == 0){ + ret = target.getStyleSize(); + } + + ret.width -= target.getPadding('lr'); + ret.height -= target.getPadding('tb'); + } + return ret; + }, + + renderAll : function(ct, target) { + if(!this.innerCt){ + + + this.innerCt = target.createChild({cls:'x-column-inner'}); + this.innerCt.createChild({cls:'x-clear'}); + } + Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt); + }, + + + onLayout : function(ct, target){ + var cs = ct.items.items, + len = cs.length, + c, + i, + m, + margins = []; + + this.renderAll(ct, target); + + var size = this.getLayoutTargetSize(); + + if (Ext.isIE9m && (size.width < 1 && size.height < 1)) { + return; + } + + var w = size.width - this.scrollOffset, + h = size.height, + pw = w; + + this.innerCt.setWidth(w); + + + + + for(i = 0; i < len; i++){ + c = cs[i]; + m = c.getPositionEl().getMargins('lr'); + margins[i] = m; + if(!c.columnWidth){ + pw -= (c.getWidth() + m); + } + } + + pw = pw < 0 ? 0 : pw; + + for(i = 0; i < len; i++){ + c = cs[i]; + m = margins[i]; + if(c.columnWidth){ + c.setSize(Math.floor(c.columnWidth * pw) - m); + } + } + + + + if (Ext.isIE9m) { + if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { + var ts = this.getLayoutTargetSize(); + if (ts.width != size.width){ + this.adjustmentPass = true; + this.onLayout(ct, target); + } + } + } + delete this.adjustmentPass; + } + + +}); + +Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout; + +Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, { + + monitorResize:true, + + rendered : false, + + type: 'border', + + targetCls: 'x-border-layout-ct', + + getLayoutTargetSize : function() { + var target = this.container.getLayoutTarget(); + return target ? target.getViewSize() : {}; + }, + + + onLayout : function(ct, target){ + var collapsed, i, c, pos, items = ct.items.items, len = items.length; + if(!this.rendered){ + collapsed = []; + for(i = 0; i < len; i++) { + c = items[i]; + pos = c.region; + if(c.collapsed){ + collapsed.push(c); + } + c.collapsed = false; + if(!c.rendered){ + c.render(target, i); + c.getPositionEl().addClass('x-border-panel'); + } + this[pos] = pos != 'center' && c.split ? + new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) : + new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos); + this[pos].render(target, c); + } + this.rendered = true; + } + + var size = this.getLayoutTargetSize(); + if(size.width < 20 || size.height < 20){ + if(collapsed){ + this.restoreCollapsed = collapsed; + } + return; + }else if(this.restoreCollapsed){ + collapsed = this.restoreCollapsed; + delete this.restoreCollapsed; + } + + var w = size.width, h = size.height, + centerW = w, centerH = h, centerY = 0, centerX = 0, + n = this.north, s = this.south, west = this.west, e = this.east, c = this.center, + b, m, totalWidth, totalHeight; + if(!c && Ext.layout.BorderLayout.WARN !== false){ + throw 'No center region defined in BorderLayout ' + ct.id; + } + + if(n && n.isVisible()){ + b = n.getSize(); + m = n.getMargins(); + b.width = w - (m.left+m.right); + b.x = m.left; + b.y = m.top; + centerY = b.height + b.y + m.bottom; + centerH -= centerY; + n.applyLayout(b); + } + if(s && s.isVisible()){ + b = s.getSize(); + m = s.getMargins(); + b.width = w - (m.left+m.right); + b.x = m.left; + totalHeight = (b.height + m.top + m.bottom); + b.y = h - totalHeight + m.top; + centerH -= totalHeight; + s.applyLayout(b); + } + if(west && west.isVisible()){ + b = west.getSize(); + m = west.getMargins(); + b.height = centerH - (m.top+m.bottom); + b.x = m.left; + b.y = centerY + m.top; + totalWidth = (b.width + m.left + m.right); + centerX += totalWidth; + centerW -= totalWidth; + west.applyLayout(b); + } + if(e && e.isVisible()){ + b = e.getSize(); + m = e.getMargins(); + b.height = centerH - (m.top+m.bottom); + totalWidth = (b.width + m.left + m.right); + b.x = w - totalWidth + m.left; + b.y = centerY + m.top; + centerW -= totalWidth; + e.applyLayout(b); + } + if(c){ + m = c.getMargins(); + var centerBox = { + x: centerX + m.left, + y: centerY + m.top, + width: centerW - (m.left+m.right), + height: centerH - (m.top+m.bottom) + }; + c.applyLayout(centerBox); + } + if(collapsed){ + for(i = 0, len = collapsed.length; i < len; i++){ + collapsed[i].collapse(false); + } + } + if(Ext.isIE9m && Ext.isStrict){ + target.repaint(); + } + + if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { + var ts = this.getLayoutTargetSize(); + if (ts.width != size.width || ts.height != size.height){ + this.adjustmentPass = true; + this.onLayout(ct, target); + } + } + delete this.adjustmentPass; + }, + + destroy: function() { + var r = ['north', 'south', 'east', 'west'], i, region; + for (i = 0; i < r.length; i++) { + region = this[r[i]]; + if(region){ + if(region.destroy){ + region.destroy(); + }else if (region.split){ + region.split.destroy(true); + } + } + } + Ext.layout.BorderLayout.superclass.destroy.call(this); + } + + +}); + + +Ext.layout.BorderLayout.Region = function(layout, config, pos){ + Ext.apply(this, config); + this.layout = layout; + this.position = pos; + this.state = {}; + if(typeof this.margins == 'string'){ + this.margins = this.layout.parseMargins(this.margins); + } + this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins); + if(this.collapsible){ + if(typeof this.cmargins == 'string'){ + this.cmargins = this.layout.parseMargins(this.cmargins); + } + if(this.collapseMode == 'mini' && !this.cmargins){ + this.cmargins = {left:0,top:0,right:0,bottom:0}; + }else{ + this.cmargins = Ext.applyIf(this.cmargins || {}, + pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins); + } + } +}; + +Ext.layout.BorderLayout.Region.prototype = { + + + + + + + collapsible : false, + + split:false, + + floatable: true, + + minWidth:50, + + minHeight:50, + + + defaultMargins : {left:0,top:0,right:0,bottom:0}, + + defaultNSCMargins : {left:5,top:5,right:5,bottom:5}, + + defaultEWCMargins : {left:5,top:0,right:5,bottom:0}, + floatingZIndex: 100, + + + isCollapsed : false, + + + + + + + render : function(ct, p){ + this.panel = p; + p.el.enableDisplayMode(); + this.targetEl = ct; + this.el = p.el; + + var gs = p.getState, ps = this.position; + p.getState = function(){ + return Ext.apply(gs.call(p) || {}, this.state); + }.createDelegate(this); + + if(ps != 'center'){ + p.allowQueuedExpand = false; + p.on({ + beforecollapse: this.beforeCollapse, + collapse: this.onCollapse, + beforeexpand: this.beforeExpand, + expand: this.onExpand, + hide: this.onHide, + show: this.onShow, + scope: this + }); + if(this.collapsible || this.floatable){ + p.collapseEl = 'el'; + p.slideAnchor = this.getSlideAnchor(); + } + if(p.tools && p.tools.toggle){ + p.tools.toggle.addClass('x-tool-collapse-'+ps); + p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over'); + } + } + }, + + + getCollapsedEl : function(){ + if(!this.collapsedEl){ + if(!this.toolTemplate){ + var tt = new Ext.Template( + '
 
' + ); + tt.disableFormats = true; + tt.compile(); + Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt; + } + this.collapsedEl = this.targetEl.createChild({ + cls: "x-layout-collapsed x-layout-collapsed-"+this.position, + id: this.panel.id + '-xcollapsed' + }); + this.collapsedEl.enableDisplayMode('block'); + + if(this.collapseMode == 'mini'){ + this.collapsedEl.addClass('x-layout-cmini-'+this.position); + this.miniCollapsedEl = this.collapsedEl.createChild({ + cls: "x-layout-mini x-layout-mini-"+this.position, html: " " + }); + this.miniCollapsedEl.addClassOnOver('x-layout-mini-over'); + this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); + this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true}); + }else { + if(this.collapsible !== false && !this.hideCollapseTool) { + var t = this.expandToolEl = this.toolTemplate.append( + this.collapsedEl.dom, + {id:'expand-'+this.position}, true); + t.addClassOnOver('x-tool-expand-'+this.position+'-over'); + t.on('click', this.onExpandClick, this, {stopEvent:true}); + } + if(this.floatable !== false || this.titleCollapse){ + this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); + this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this); + } + } + } + return this.collapsedEl; + }, + + + onExpandClick : function(e){ + if(this.isSlid){ + this.panel.expand(false); + }else{ + this.panel.expand(); + } + }, + + + onCollapseClick : function(e){ + this.panel.collapse(); + }, + + + beforeCollapse : function(p, animate){ + this.lastAnim = animate; + if(this.splitEl){ + this.splitEl.hide(); + } + this.getCollapsedEl().show(); + var el = this.panel.getEl(); + this.originalZIndex = el.getStyle('z-index'); + el.setStyle('z-index', 100); + this.isCollapsed = true; + this.layout.layout(); + }, + + + onCollapse : function(animate){ + this.panel.el.setStyle('z-index', 1); + if(this.lastAnim === false || this.panel.animCollapse === false){ + this.getCollapsedEl().dom.style.visibility = 'visible'; + }else{ + this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2}); + } + this.state.collapsed = true; + this.panel.saveState(); + }, + + + beforeExpand : function(animate){ + if(this.isSlid){ + this.afterSlideIn(); + } + var c = this.getCollapsedEl(); + this.el.show(); + if(this.position == 'east' || this.position == 'west'){ + this.panel.setSize(undefined, c.getHeight()); + }else{ + this.panel.setSize(c.getWidth(), undefined); + } + c.hide(); + c.dom.style.visibility = 'hidden'; + this.panel.el.setStyle('z-index', this.floatingZIndex); + }, + + + onExpand : function(){ + this.isCollapsed = false; + if(this.splitEl){ + this.splitEl.show(); + } + this.layout.layout(); + this.panel.el.setStyle('z-index', this.originalZIndex); + this.state.collapsed = false; + this.panel.saveState(); + }, + + + collapseClick : function(e){ + if(this.isSlid){ + e.stopPropagation(); + this.slideIn(); + }else{ + e.stopPropagation(); + this.slideOut(); + } + }, + + + onHide : function(){ + if(this.isCollapsed){ + this.getCollapsedEl().hide(); + }else if(this.splitEl){ + this.splitEl.hide(); + } + }, + + + onShow : function(){ + if(this.isCollapsed){ + this.getCollapsedEl().show(); + }else if(this.splitEl){ + this.splitEl.show(); + } + }, + + + isVisible : function(){ + return !this.panel.hidden; + }, + + + getMargins : function(){ + return this.isCollapsed && this.cmargins ? this.cmargins : this.margins; + }, + + + getSize : function(){ + return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize(); + }, + + + setPanel : function(panel){ + this.panel = panel; + }, + + + getMinWidth: function(){ + return this.minWidth; + }, + + + getMinHeight: function(){ + return this.minHeight; + }, + + + applyLayoutCollapsed : function(box){ + var ce = this.getCollapsedEl(); + ce.setLeftTop(box.x, box.y); + ce.setSize(box.width, box.height); + }, + + + applyLayout : function(box){ + if(this.isCollapsed){ + this.applyLayoutCollapsed(box); + }else{ + this.panel.setPosition(box.x, box.y); + this.panel.setSize(box.width, box.height); + } + }, + + + beforeSlide: function(){ + this.panel.beforeEffect(); + }, + + + afterSlide : function(){ + this.panel.afterEffect(); + }, + + + initAutoHide : function(){ + if(this.autoHide !== false){ + if(!this.autoHideHd){ + this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this); + this.autoHideHd = { + "mouseout": function(e){ + if(!e.within(this.el, true)){ + this.autoHideSlideTask.delay(500); + } + }, + "mouseover" : function(e){ + this.autoHideSlideTask.cancel(); + }, + scope : this + }; + } + this.el.on(this.autoHideHd); + this.collapsedEl.on(this.autoHideHd); + } + }, + + + clearAutoHide : function(){ + if(this.autoHide !== false){ + this.el.un("mouseout", this.autoHideHd.mouseout); + this.el.un("mouseover", this.autoHideHd.mouseover); + this.collapsedEl.un("mouseout", this.autoHideHd.mouseout); + this.collapsedEl.un("mouseover", this.autoHideHd.mouseover); + } + }, + + + clearMonitor : function(){ + Ext.getDoc().un("click", this.slideInIf, this); + }, + + + slideOut : function(){ + if(this.isSlid || this.el.hasActiveFx()){ + return; + } + this.isSlid = true; + var ts = this.panel.tools, dh, pc; + if(ts && ts.toggle){ + ts.toggle.hide(); + } + this.el.show(); + + + pc = this.panel.collapsed; + this.panel.collapsed = false; + + if(this.position == 'east' || this.position == 'west'){ + + dh = this.panel.deferHeight; + this.panel.deferHeight = false; + + this.panel.setSize(undefined, this.collapsedEl.getHeight()); + + + this.panel.deferHeight = dh; + }else{ + this.panel.setSize(this.collapsedEl.getWidth(), undefined); + } + + + this.panel.collapsed = pc; + + this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top]; + this.el.alignTo(this.collapsedEl, this.getCollapseAnchor()); + this.el.setStyle("z-index", this.floatingZIndex+2); + this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating'); + if(this.animFloat !== false){ + this.beforeSlide(); + this.el.slideIn(this.getSlideAnchor(), { + callback: function(){ + this.afterSlide(); + this.initAutoHide(); + Ext.getDoc().on("click", this.slideInIf, this); + }, + scope: this, + block: true + }); + }else{ + this.initAutoHide(); + Ext.getDoc().on("click", this.slideInIf, this); + } + }, + + + afterSlideIn : function(){ + this.clearAutoHide(); + this.isSlid = false; + this.clearMonitor(); + this.el.setStyle("z-index", ""); + this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed'); + this.el.dom.style.left = this.restoreLT[0]; + this.el.dom.style.top = this.restoreLT[1]; + + var ts = this.panel.tools; + if(ts && ts.toggle){ + ts.toggle.show(); + } + }, + + + slideIn : function(cb){ + if(!this.isSlid || this.el.hasActiveFx()){ + Ext.callback(cb); + return; + } + this.isSlid = false; + if(this.animFloat !== false){ + this.beforeSlide(); + this.el.slideOut(this.getSlideAnchor(), { + callback: function(){ + this.el.hide(); + this.afterSlide(); + this.afterSlideIn(); + Ext.callback(cb); + }, + scope: this, + block: true + }); + }else{ + this.el.hide(); + this.afterSlideIn(); + } + }, + + + slideInIf : function(e){ + if(!e.within(this.el)){ + this.slideIn(); + } + }, + + + anchors : { + "west" : "left", + "east" : "right", + "north" : "top", + "south" : "bottom" + }, + + + sanchors : { + "west" : "l", + "east" : "r", + "north" : "t", + "south" : "b" + }, + + + canchors : { + "west" : "tl-tr", + "east" : "tr-tl", + "north" : "tl-bl", + "south" : "bl-tl" + }, + + + getAnchor : function(){ + return this.anchors[this.position]; + }, + + + getCollapseAnchor : function(){ + return this.canchors[this.position]; + }, + + + getSlideAnchor : function(){ + return this.sanchors[this.position]; + }, + + + getAlignAdj : function(){ + var cm = this.cmargins; + switch(this.position){ + case "west": + return [0, 0]; + break; + case "east": + return [0, 0]; + break; + case "north": + return [0, 0]; + break; + case "south": + return [0, 0]; + break; + } + }, + + + getExpandAdj : function(){ + var c = this.collapsedEl, cm = this.cmargins; + switch(this.position){ + case "west": + return [-(cm.right+c.getWidth()+cm.left), 0]; + break; + case "east": + return [cm.right+c.getWidth()+cm.left, 0]; + break; + case "north": + return [0, -(cm.top+cm.bottom+c.getHeight())]; + break; + case "south": + return [0, cm.top+cm.bottom+c.getHeight()]; + break; + } + }, + + destroy : function(){ + if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){ + this.autoHideSlideTask.cancel(); + } + Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl'); + } +}; + + +Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){ + Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos); + + this.applyLayout = this.applyFns[pos]; +}; + +Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, { + + + splitTip : "Drag to resize.", + + collapsibleSplitTip : "Drag to resize. Double click to hide.", + + useSplitTips : false, + + + splitSettings : { + north : { + orientation: Ext.SplitBar.VERTICAL, + placement: Ext.SplitBar.TOP, + maxFn : 'getVMaxSize', + minProp: 'minHeight', + maxProp: 'maxHeight' + }, + south : { + orientation: Ext.SplitBar.VERTICAL, + placement: Ext.SplitBar.BOTTOM, + maxFn : 'getVMaxSize', + minProp: 'minHeight', + maxProp: 'maxHeight' + }, + east : { + orientation: Ext.SplitBar.HORIZONTAL, + placement: Ext.SplitBar.RIGHT, + maxFn : 'getHMaxSize', + minProp: 'minWidth', + maxProp: 'maxWidth' + }, + west : { + orientation: Ext.SplitBar.HORIZONTAL, + placement: Ext.SplitBar.LEFT, + maxFn : 'getHMaxSize', + minProp: 'minWidth', + maxProp: 'maxWidth' + } + }, + + + applyFns : { + west : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + this.panel.setPosition(box.x, box.y); + var sw = sd.offsetWidth; + s.left = (box.x+box.width-sw)+'px'; + s.top = (box.y)+'px'; + s.height = Math.max(0, box.height)+'px'; + this.panel.setSize(box.width-sw, box.height); + }, + east : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sw = sd.offsetWidth; + this.panel.setPosition(box.x+sw, box.y); + s.left = (box.x)+'px'; + s.top = (box.y)+'px'; + s.height = Math.max(0, box.height)+'px'; + this.panel.setSize(box.width-sw, box.height); + }, + north : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sh = sd.offsetHeight; + this.panel.setPosition(box.x, box.y); + s.left = (box.x)+'px'; + s.top = (box.y+box.height-sh)+'px'; + s.width = Math.max(0, box.width)+'px'; + this.panel.setSize(box.width, box.height-sh); + }, + south : function(box){ + if(this.isCollapsed){ + return this.applyLayoutCollapsed(box); + } + var sd = this.splitEl.dom, s = sd.style; + var sh = sd.offsetHeight; + this.panel.setPosition(box.x, box.y+sh); + s.left = (box.x)+'px'; + s.top = (box.y)+'px'; + s.width = Math.max(0, box.width)+'px'; + this.panel.setSize(box.width, box.height-sh); + } + }, + + + render : function(ct, p){ + Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p); + + var ps = this.position; + + this.splitEl = ct.createChild({ + cls: "x-layout-split x-layout-split-"+ps, html: " ", + id: this.panel.id + '-xsplit' + }); + + if(this.collapseMode == 'mini'){ + this.miniSplitEl = this.splitEl.createChild({ + cls: "x-layout-mini x-layout-mini-"+ps, html: " " + }); + this.miniSplitEl.addClassOnOver('x-layout-mini-over'); + this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true}); + } + + var s = this.splitSettings[ps]; + + this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation); + this.split.tickSize = this.tickSize; + this.split.placement = s.placement; + this.split.getMaximumSize = this[s.maxFn].createDelegate(this); + this.split.minSize = this.minSize || this[s.minProp]; + this.split.on("beforeapply", this.onSplitMove, this); + this.split.useShim = this.useShim === true; + this.maxSize = this.maxSize || this[s.maxProp]; + + if(p.hidden){ + this.splitEl.hide(); + } + + if(this.useSplitTips){ + this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip; + } + if(this.collapsible){ + this.splitEl.on("dblclick", this.onCollapseClick, this); + } + }, + + + getSize : function(){ + if(this.isCollapsed){ + return this.collapsedEl.getSize(); + } + var s = this.panel.getSize(); + if(this.position == 'north' || this.position == 'south'){ + s.height += this.splitEl.dom.offsetHeight; + }else{ + s.width += this.splitEl.dom.offsetWidth; + } + return s; + }, + + + getHMaxSize : function(){ + var cmax = this.maxSize || 10000; + var center = this.layout.center; + return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth()); + }, + + + getVMaxSize : function(){ + var cmax = this.maxSize || 10000; + var center = this.layout.center; + return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight()); + }, + + + onSplitMove : function(split, newSize){ + var s = this.panel.getSize(); + this.lastSplitSize = newSize; + if(this.position == 'north' || this.position == 'south'){ + this.panel.setSize(s.width, newSize); + this.state.height = newSize; + }else{ + this.panel.setSize(newSize, s.height); + this.state.width = newSize; + } + this.layout.layout(); + this.panel.saveState(); + return false; + }, + + + getSplitBar : function(){ + return this.split; + }, + + + destroy : function() { + Ext.destroy(this.miniSplitEl, this.split, this.splitEl); + Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this); + } +}); + +Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout; + +Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, { + + + labelSeparator : ':', + + + + + trackLabels: true, + + type: 'form', + + onRemove: function(c){ + Ext.layout.FormLayout.superclass.onRemove.call(this, c); + if(this.trackLabels){ + c.un('show', this.onFieldShow, this); + c.un('hide', this.onFieldHide, this); + } + + var el = c.getPositionEl(), + ct = c.getItemCt && c.getItemCt(); + if (c.rendered && ct) { + if (el && el.dom) { + el.insertAfter(ct); + } + Ext.destroy(ct); + Ext.destroyMembers(c, 'label', 'itemCt'); + if (c.customItemCt) { + Ext.destroyMembers(c, 'getItemCt', 'customItemCt'); + } + } + }, + + + setContainer : function(ct){ + Ext.layout.FormLayout.superclass.setContainer.call(this, ct); + ct.labelAlign = ct.labelAlign || this.labelAlign; + if (ct.labelAlign) { + ct.addClass('x-form-label-' + ct.labelAlign); + } + + if (ct.hideLabels || this.hideLabels) { + Ext.apply(this, { + labelStyle: 'display:none', + elementStyle: 'padding-left:0;', + labelAdjust: 0 + }); + } else { + this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator; + ct.labelWidth = ct.labelWidth || this.labelWidth || 100; + if(Ext.isNumber(ct.labelWidth)){ + var pad = ct.labelPad || this.labelPad; + pad = Ext.isNumber(pad) ? pad : 5; + Ext.apply(this, { + labelAdjust: ct.labelWidth + pad, + labelStyle: 'width:' + ct.labelWidth + 'px;', + elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px' + }); + } + if(ct.labelAlign == 'top'){ + Ext.apply(this, { + labelStyle: 'width:auto;', + labelAdjust: 0, + elementStyle: 'padding-left:0;' + }); + } + } + }, + + + isHide: function(c){ + return c.hideLabel || this.container.hideLabels; + }, + + onFieldShow: function(c){ + c.getItemCt().removeClass('x-hide-' + c.hideMode); + + + if (c.isComposite) { + c.doLayout(); + } + }, + + onFieldHide: function(c){ + c.getItemCt().addClass('x-hide-' + c.hideMode); + }, + + + getLabelStyle: function(s){ + var ls = '', items = [this.labelStyle, s]; + for (var i = 0, len = items.length; i < len; ++i){ + if (items[i]){ + ls += items[i]; + if (ls.substr(-1, 1) != ';'){ + ls += ';'; + } + } + } + return ls; + }, + + + + + renderItem : function(c, position, target){ + if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){ + var args = this.getTemplateArgs(c); + if(Ext.isNumber(position)){ + position = target.dom.childNodes[position] || null; + } + if(position){ + c.itemCt = this.fieldTpl.insertBefore(position, args, true); + }else{ + c.itemCt = this.fieldTpl.append(target, args, true); + } + if(!c.getItemCt){ + + + Ext.apply(c, { + getItemCt: function(){ + return c.itemCt; + }, + customItemCt: true + }); + } + c.label = c.getItemCt().child('label.x-form-item-label'); + if(!c.rendered){ + c.render('x-form-el-' + c.id); + }else if(!this.isValidParent(c, target)){ + Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl()); + } + if(this.trackLabels){ + if(c.hidden){ + this.onFieldHide(c); + } + c.on({ + scope: this, + show: this.onFieldShow, + hide: this.onFieldHide + }); + } + this.configureItem(c); + }else { + Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments); + } + }, + + + getTemplateArgs: function(field) { + var noLabelSep = !field.fieldLabel || field.hideLabel, + itemCls = (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''); + + + if (Ext.isIE9 && Ext.isIEQuirks && field instanceof Ext.form.TextField) { + itemCls += ' x-input-wrapper'; + } + + return { + id : field.id, + label : field.fieldLabel, + itemCls : itemCls, + clearCls : field.clearCls || 'x-form-clear-left', + labelStyle : this.getLabelStyle(field.labelStyle), + elementStyle : this.elementStyle || '', + labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator) + }; + }, + + + adjustWidthAnchor: function(value, c){ + if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){ + var adjust = Ext.isIE6 || Ext.isIEQuirks; + return value - this.labelAdjust + (adjust ? -3 : 0); + } + return value; + }, + + adjustHeightAnchor : function(value, c){ + if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){ + return value - c.label.getHeight(); + } + return value; + }, + + + isValidParent : function(c, target){ + return target && this.container.getEl().contains(c.getPositionEl()); + } + + +}); + +Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout; + +Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, { + + fill : true, + + autoWidth : true, + + titleCollapse : true, + + hideCollapseTool : false, + + collapseFirst : false, + + animate : false, + + sequence : false, + + activeOnTop : false, + + type: 'accordion', + + renderItem : function(c){ + if(this.animate === false){ + c.animCollapse = false; + } + c.collapsible = true; + if(this.autoWidth){ + c.autoWidth = true; + } + if(this.titleCollapse){ + c.titleCollapse = true; + } + if(this.hideCollapseTool){ + c.hideCollapseTool = true; + } + if(this.collapseFirst !== undefined){ + c.collapseFirst = this.collapseFirst; + } + if(!this.activeItem && !c.collapsed){ + this.setActiveItem(c, true); + }else if(this.activeItem && this.activeItem != c){ + c.collapsed = true; + } + Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments); + c.header.addClass('x-accordion-hd'); + c.on('beforeexpand', this.beforeExpand, this); + }, + + onRemove: function(c){ + Ext.layout.AccordionLayout.superclass.onRemove.call(this, c); + if(c.rendered){ + c.header.removeClass('x-accordion-hd'); + } + c.un('beforeexpand', this.beforeExpand, this); + }, + + + beforeExpand : function(p, anim){ + var ai = this.activeItem; + if(ai){ + if(this.sequence){ + delete this.activeItem; + if (!ai.collapsed){ + ai.collapse({callback:function(){ + p.expand(anim || true); + }, scope: this}); + return false; + } + }else{ + ai.collapse(this.animate); + } + } + this.setActive(p); + if(this.activeOnTop){ + p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild); + } + + this.layout(); + }, + + + setItemSize : function(item, size){ + if(this.fill && item){ + var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p; + + for (i = 0; i < len; i++) { + if((p = ct[i]) != item && !p.hidden){ + hh += p.header.getHeight(); + } + }; + + size.height -= hh; + + + item.setSize(size); + } + }, + + + setActiveItem : function(item){ + this.setActive(item, true); + }, + + + setActive : function(item, expand){ + var ai = this.activeItem; + item = this.container.getComponent(item); + if(ai != item){ + if(item.rendered && item.collapsed && expand){ + item.expand(); + }else{ + if(ai){ + ai.fireEvent('deactivate', ai); + } + this.activeItem = item; + item.fireEvent('activate', item); + } + } + } +}); +Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout; + + +Ext.layout.Accordion = Ext.layout.AccordionLayout; +Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, { + + + + monitorResize:false, + + type: 'table', + + targetCls: 'x-table-layout-ct', + + + tableAttrs:null, + + + setContainer : function(ct){ + Ext.layout.TableLayout.superclass.setContainer.call(this, ct); + + this.currentRow = 0; + this.currentColumn = 0; + this.cells = []; + }, + + + onLayout : function(ct, target){ + var cs = ct.items.items, len = cs.length, c, i; + + if(!this.table){ + target.addClass('x-table-layout-ct'); + + this.table = target.createChild( + Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); + } + this.renderAll(ct, target); + }, + + + getRow : function(index){ + var row = this.table.tBodies[0].childNodes[index]; + if(!row){ + row = document.createElement('tr'); + this.table.tBodies[0].appendChild(row); + } + return row; + }, + + + getNextCell : function(c){ + var cell = this.getNextNonSpan(this.currentColumn, this.currentRow); + var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1]; + for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){ + if(!this.cells[rowIndex]){ + this.cells[rowIndex] = []; + } + for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){ + this.cells[rowIndex][colIndex] = true; + } + } + var td = document.createElement('td'); + if(c.cellId){ + td.id = c.cellId; + } + var cls = 'x-table-layout-cell'; + if(c.cellCls){ + cls += ' ' + c.cellCls; + } + td.className = cls; + if(c.colspan){ + td.colSpan = c.colspan; + } + if(c.rowspan){ + td.rowSpan = c.rowspan; + } + this.getRow(curRow).appendChild(td); + return td; + }, + + + getNextNonSpan: function(colIndex, rowIndex){ + var cols = this.columns; + while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) { + if(cols && colIndex >= cols){ + rowIndex++; + colIndex = 0; + }else{ + colIndex++; + } + } + return [colIndex, rowIndex]; + }, + + + renderItem : function(c, position, target){ + + if(!this.table){ + this.table = target.createChild( + Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); + } + if(c && !c.rendered){ + c.render(this.getNextCell(c)); + this.configureItem(c); + }else if(c && !this.isValidParent(c, target)){ + var container = this.getNextCell(c); + container.insertBefore(c.getPositionEl().dom, null); + c.container = Ext.get(container); + this.configureItem(c); + } + }, + + + isValidParent : function(c, target){ + return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target); + }, + + destroy: function(){ + delete this.table; + Ext.layout.TableLayout.superclass.destroy.call(this); + } + + +}); + +Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout; +Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, { + + extraCls: 'x-abs-layout-item', + + type: 'absolute', + + onLayout : function(ct, target){ + target.position(); + this.paddingLeft = target.getPadding('l'); + this.paddingTop = target.getPadding('t'); + Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target); + }, + + + adjustWidthAnchor : function(value, comp){ + return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value; + }, + + + adjustHeightAnchor : function(value, comp){ + return value ? value - comp.getPosition(true)[1] + this.paddingTop : value; + } + +}); +Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout; + +Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, { + + defaultMargins : {left:0,top:0,right:0,bottom:0}, + + padding : '0', + + pack : 'start', + + + monitorResize : true, + type: 'box', + scrollOffset : 0, + extraCls : 'x-box-item', + targetCls : 'x-box-layout-ct', + innerCls : 'x-box-inner', + + constructor : function(config){ + Ext.layout.BoxLayout.superclass.constructor.call(this, config); + + if (Ext.isString(this.defaultMargins)) { + this.defaultMargins = this.parseMargins(this.defaultMargins); + } + + var handler = this.overflowHandler; + + if (typeof handler == 'string') { + handler = { + type: handler + }; + } + + var handlerType = 'none'; + if (handler && handler.type != undefined) { + handlerType = handler.type; + } + + var constructor = Ext.layout.boxOverflow[handlerType]; + if (constructor[this.type]) { + constructor = constructor[this.type]; + } + + this.overflowHandler = new constructor(this, handler); + }, + + + onLayout: function(container, target) { + Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target); + + var tSize = this.getLayoutTargetSize(), + items = this.getVisibleItems(container), + calcs = this.calculateChildBoxes(items, tSize), + boxes = calcs.boxes, + meta = calcs.meta; + + + if (tSize.width > 0) { + var handler = this.overflowHandler, + method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow'; + + var results = handler[method](calcs, tSize); + + if (results) { + if (results.targetSize) { + tSize = results.targetSize; + } + + if (results.recalculate) { + items = this.getVisibleItems(container); + calcs = this.calculateChildBoxes(items, tSize); + boxes = calcs.boxes; + } + } + } + + + this.layoutTargetLastSize = tSize; + + + this.childBoxCache = calcs; + + this.updateInnerCtSize(tSize, calcs); + this.updateChildBoxes(boxes); + + + this.handleTargetOverflow(tSize, container, target); + }, + + + updateChildBoxes: function(boxes) { + for (var i = 0, length = boxes.length; i < length; i++) { + var box = boxes[i], + comp = box.component; + + if (box.dirtySize) { + comp.setSize(box.width, box.height); + } + + if (isNaN(box.left) || isNaN(box.top)) { + continue; + } + + comp.setPosition(box.left, box.top); + } + }, + + + updateInnerCtSize: function(tSize, calcs) { + var align = this.align, + padding = this.padding, + width = tSize.width, + height = tSize.height; + + if (this.type == 'hbox') { + var innerCtWidth = width, + innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom; + + if (align == 'stretch') { + innerCtHeight = height; + } else if (align == 'middle') { + innerCtHeight = Math.max(height, innerCtHeight); + } + } else { + var innerCtHeight = height, + innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right; + + if (align == 'stretch') { + innerCtWidth = width; + } else if (align == 'center') { + innerCtWidth = Math.max(width, innerCtWidth); + } + } + + this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined); + }, + + + handleTargetOverflow: function(previousTargetSize, container, target) { + var overflow = target.getStyle('overflow'); + + if (overflow && overflow != 'hidden' &&!this.adjustmentPass) { + var newTargetSize = this.getLayoutTargetSize(); + if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){ + this.adjustmentPass = true; + this.onLayout(container, target); + } + } + + delete this.adjustmentPass; + }, + + + isValidParent : function(c, target) { + return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; + }, + + + getVisibleItems: function(ct) { + var ct = ct || this.container, + t = ct.getLayoutTarget(), + cti = ct.items.items, + len = cti.length, + + i, c, items = []; + + for (i = 0; i < len; i++) { + if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){ + items.push(c); + } + } + + return items; + }, + + + renderAll : function(ct, target) { + if (!this.innerCt) { + + this.innerCt = target.createChild({cls:this.innerCls}); + this.padding = this.parseMargins(this.padding); + } + Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt); + }, + + getLayoutTargetSize : function() { + var target = this.container.getLayoutTarget(), ret; + + if (target) { + ret = target.getViewSize(); + + + + + if (Ext.isIE9m && Ext.isStrict && ret.width == 0){ + ret = target.getStyleSize(); + } + + ret.width -= target.getPadding('lr'); + ret.height -= target.getPadding('tb'); + } + + return ret; + }, + + + renderItem : function(c) { + if(Ext.isString(c.margins)){ + c.margins = this.parseMargins(c.margins); + }else if(!c.margins){ + c.margins = this.defaultMargins; + } + Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments); + }, + + + destroy: function() { + Ext.destroy(this.overflowHandler); + + Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments); + } +}); + + + +Ext.layout.boxOverflow.None = Ext.extend(Object, { + constructor: function(layout, config) { + this.layout = layout; + + Ext.apply(this, config || {}); + }, + + handleOverflow: Ext.emptyFn, + + clearOverflow: Ext.emptyFn +}); + + +Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None; + +Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, { + + afterCls: 'x-strip-right', + + + noItemsMenuText : '
(None)
', + + constructor: function(layout) { + Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments); + + + this.menuItems = []; + }, + + + createInnerElements: function() { + if (!this.afterCt) { + this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before'); + } + }, + + + clearOverflow: function(calculations, targetSize) { + var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0), + items = this.menuItems; + + this.hideTrigger(); + + for (var index = 0, length = items.length; index < length; index++) { + items.pop().component.show(); + } + + return { + targetSize: { + height: targetSize.height, + width : newWidth + } + }; + }, + + + showTrigger: function() { + this.createMenu(); + this.menuTrigger.show(); + }, + + + hideTrigger: function() { + if (this.menuTrigger != undefined) { + this.menuTrigger.hide(); + } + }, + + + beforeMenuShow: function(menu) { + var items = this.menuItems, + len = items.length, + item, + prev; + + var needsSep = function(group, item){ + return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); + }; + + this.clearMenu(); + menu.removeAll(); + + for (var i = 0; i < len; i++) { + item = items[i].component; + + if (prev && (needsSep(item, prev) || needsSep(prev, item))) { + menu.add('-'); + } + + this.addComponentToMenu(menu, item); + prev = item; + } + + + if (menu.items.length < 1) { + menu.add(this.noItemsMenuText); + } + }, + + + createMenuConfig : function(component, hideOnClick){ + var config = Ext.apply({}, component.initialConfig), + group = component.toggleGroup; + + Ext.copyTo(config, component, [ + 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' + ]); + + Ext.apply(config, { + text : component.overflowText || component.text, + hideOnClick: hideOnClick + }); + + if (group || component.enableToggle) { + Ext.apply(config, { + group : group, + checked: component.pressed, + listeners: { + checkchange: function(item, checked){ + component.toggle(checked); + } + } + }); + } + + delete config.ownerCt; + delete config.xtype; + delete config.id; + + return config; + }, + + + addComponentToMenu : function(menu, component) { + if (component instanceof Ext.Toolbar.Separator) { + menu.add('-'); + + } else if (Ext.isFunction(component.isXType)) { + if (component.isXType('splitbutton')) { + menu.add(this.createMenuConfig(component, true)); + + } else if (component.isXType('button')) { + menu.add(this.createMenuConfig(component, !component.menu)); + + } else if (component.isXType('buttongroup')) { + component.items.each(function(item){ + this.addComponentToMenu(menu, item); + }, this); + } + } + }, + + + clearMenu : function(){ + var menu = this.moreMenu; + if (menu && menu.items) { + menu.items.each(function(item){ + delete item.menu; + }); + } + }, + + + createMenu: function() { + if (!this.menuTrigger) { + this.createInnerElements(); + + + this.menu = new Ext.menu.Menu({ + ownerCt : this.layout.container, + listeners: { + scope: this, + beforeshow: this.beforeMenuShow + } + }); + + + this.menuTrigger = new Ext.Button({ + iconCls : 'x-toolbar-more-icon', + cls : 'x-toolbar-more', + menu : this.menu, + renderTo: this.afterCt + }); + } + }, + + + destroy: function() { + Ext.destroy(this.menu, this.menuTrigger); + } +}); + +Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu; + + + +Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, { + + constructor: function() { + Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments); + + var me = this, + layout = me.layout, + origFunction = layout.calculateChildBoxes; + + layout.calculateChildBoxes = function(visibleItems, targetSize) { + var calcs = origFunction.apply(layout, arguments), + meta = calcs.meta, + items = me.menuItems; + + + + var hiddenWidth = 0; + for (var index = 0, length = items.length; index < length; index++) { + hiddenWidth += items[index].width; + } + + meta.minimumWidth += hiddenWidth; + meta.tooNarrow = meta.minimumWidth > targetSize.width; + + return calcs; + }; + }, + + handleOverflow: function(calculations, targetSize) { + this.showTrigger(); + + var newWidth = targetSize.width - this.afterCt.getWidth(), + boxes = calculations.boxes, + usedWidth = 0, + recalculate = false; + + + for (var index = 0, length = boxes.length; index < length; index++) { + usedWidth += boxes[index].width; + } + + var spareWidth = newWidth - usedWidth, + showCount = 0; + + + for (var index = 0, length = this.menuItems.length; index < length; index++) { + var hidden = this.menuItems[index], + comp = hidden.component, + width = hidden.width; + + if (width < spareWidth) { + comp.show(); + + spareWidth -= width; + showCount ++; + recalculate = true; + } else { + break; + } + } + + if (recalculate) { + this.menuItems = this.menuItems.slice(showCount); + } else { + for (var i = boxes.length - 1; i >= 0; i--) { + var item = boxes[i].component, + right = boxes[i].left + boxes[i].width; + + if (right >= newWidth) { + this.menuItems.unshift({ + component: item, + width : boxes[i].width + }); + + item.hide(); + } else { + break; + } + } + } + + if (this.menuItems.length == 0) { + this.hideTrigger(); + } + + return { + targetSize: { + height: targetSize.height, + width : newWidth + }, + recalculate: recalculate + }; + } +}); + +Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu; +Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, { + + animateScroll: true, + + + scrollIncrement: 100, + + + wheelIncrement: 3, + + + scrollRepeatInterval: 400, + + + scrollDuration: 0.4, + + + beforeCls: 'x-strip-left', + + + afterCls: 'x-strip-right', + + + scrollerCls: 'x-strip-scroller', + + + beforeScrollerCls: 'x-strip-scroller-left', + + + afterScrollerCls: 'x-strip-scroller-right', + + + createWheelListener: function() { + this.layout.innerCt.on({ + scope : this, + mousewheel: function(e) { + e.stopEvent(); + + this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); + } + }); + }, + + + handleOverflow: function(calculations, targetSize) { + this.createInnerElements(); + this.showScrollers(); + }, + + + clearOverflow: function() { + this.hideScrollers(); + }, + + + showScrollers: function() { + this.createScrollers(); + + this.beforeScroller.show(); + this.afterScroller.show(); + + this.updateScrollButtons(); + }, + + + hideScrollers: function() { + if (this.beforeScroller != undefined) { + this.beforeScroller.hide(); + this.afterScroller.hide(); + } + }, + + + createScrollers: function() { + if (!this.beforeScroller && !this.afterScroller) { + var before = this.beforeCt.createChild({ + cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls) + }); + + var after = this.afterCt.createChild({ + cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls) + }); + + before.addClassOnOver(this.beforeScrollerCls + '-hover'); + after.addClassOnOver(this.afterScrollerCls + '-hover'); + + before.setVisibilityMode(Ext.Element.DISPLAY); + after.setVisibilityMode(Ext.Element.DISPLAY); + + this.beforeRepeater = new Ext.util.ClickRepeater(before, { + interval: this.scrollRepeatInterval, + handler : this.scrollLeft, + scope : this + }); + + this.afterRepeater = new Ext.util.ClickRepeater(after, { + interval: this.scrollRepeatInterval, + handler : this.scrollRight, + scope : this + }); + + + this.beforeScroller = before; + + + this.afterScroller = after; + } + }, + + + destroy: function() { + Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt); + }, + + + scrollBy: function(delta, animate) { + this.scrollTo(this.getScrollPosition() + delta, animate); + }, + + + getItem: function(item) { + if (Ext.isString(item)) { + item = Ext.getCmp(item); + } else if (Ext.isNumber(item)) { + item = this.items[item]; + } + + return item; + }, + + + getScrollAnim: function() { + return { + duration: this.scrollDuration, + callback: this.updateScrollButtons, + scope : this + }; + }, + + + updateScrollButtons: function() { + if (this.beforeScroller == undefined || this.afterScroller == undefined) { + return; + } + + var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass', + afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass', + beforeCls = this.beforeScrollerCls + '-disabled', + afterCls = this.afterScrollerCls + '-disabled'; + + this.beforeScroller[beforeMeth](beforeCls); + this.afterScroller[afterMeth](afterCls); + this.scrolling = false; + }, + + + atExtremeBefore: function() { + return this.getScrollPosition() === 0; + }, + + + scrollLeft: function(animate) { + this.scrollBy(-this.scrollIncrement, animate); + }, + + + scrollRight: function(animate) { + this.scrollBy(this.scrollIncrement, animate); + }, + + + scrollToItem: function(item, animate) { + item = this.getItem(item); + + if (item != undefined) { + var visibility = this.getItemVisibility(item); + + if (!visibility.fullyVisible) { + var box = item.getBox(true, true), + newX = box.x; + + if (visibility.hiddenRight) { + newX -= (this.layout.innerCt.getWidth() - box.width); + } + + this.scrollTo(newX, animate); + } + } + }, + + + getItemVisibility: function(item) { + var box = this.getItem(item).getBox(true, true), + itemLeft = box.x, + itemRight = box.x + box.width, + scrollLeft = this.getScrollPosition(), + scrollRight = this.layout.innerCt.getWidth() + scrollLeft; + + return { + hiddenLeft : itemLeft < scrollLeft, + hiddenRight : itemRight > scrollRight, + fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight + }; + } +}); + +Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller; + + + +Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { + scrollIncrement: 75, + wheelIncrement : 2, + + handleOverflow: function(calculations, targetSize) { + Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments); + + return { + targetSize: { + height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()), + width : targetSize.width + } + }; + }, + + + createInnerElements: function() { + var target = this.layout.innerCt; + + + + if (!this.beforeCt) { + this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); + this.afterCt = target.insertSibling({cls: this.afterCls}, 'after'); + + this.createWheelListener(); + } + }, + + + scrollTo: function(position, animate) { + var oldPosition = this.getScrollPosition(), + newPosition = position.constrain(0, this.getMaxScrollBottom()); + + if (newPosition != oldPosition && !this.scrolling) { + if (animate == undefined) { + animate = this.animateScroll; + } + + this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false); + + if (animate) { + this.scrolling = true; + } else { + this.scrolling = false; + this.updateScrollButtons(); + } + } + }, + + + getScrollPosition: function(){ + return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0; + }, + + + getMaxScrollBottom: function() { + return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight(); + }, + + + atExtremeAfter: function() { + return this.getScrollPosition() >= this.getMaxScrollBottom(); + } +}); + +Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller; + + + +Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { + handleOverflow: function(calculations, targetSize) { + Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments); + + return { + targetSize: { + height: targetSize.height, + width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth()) + } + }; + }, + + + createInnerElements: function() { + var target = this.layout.innerCt; + + + + if (!this.beforeCt) { + this.afterCt = target.insertSibling({cls: this.afterCls}, 'before'); + this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); + + this.createWheelListener(); + } + }, + + + scrollTo: function(position, animate) { + var oldPosition = this.getScrollPosition(), + newPosition = position.constrain(0, this.getMaxScrollRight()); + + if (newPosition != oldPosition && !this.scrolling) { + if (animate == undefined) { + animate = this.animateScroll; + } + + this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false); + + if (animate) { + this.scrolling = true; + } else { + this.scrolling = false; + this.updateScrollButtons(); + } + } + }, + + + getScrollPosition: function(){ + return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0; + }, + + + getMaxScrollRight: function() { + return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth(); + }, + + + atExtremeAfter: function() { + return this.getScrollPosition() >= this.getMaxScrollRight(); + } +}); + +Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller; +Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, { + + align: 'top', + + type : 'hbox', + + + + + + calculateChildBoxes: function(visibleItems, targetSize) { + var visibleCount = visibleItems.length, + + padding = this.padding, + topOffset = padding.top, + leftOffset = padding.left, + paddingVert = topOffset + padding.bottom, + paddingHoriz = leftOffset + padding.right, + + width = targetSize.width - this.scrollOffset, + height = targetSize.height, + availHeight = Math.max(0, height - paddingVert), + + isStart = this.pack == 'start', + isCenter = this.pack == 'center', + isEnd = this.pack == 'end', + + nonFlexWidth = 0, + maxHeight = 0, + totalFlex = 0, + desiredWidth = 0, + minimumWidth = 0, + + + boxes = [], + + + child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, + horizMargins, vertMargins, stretchHeight; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + childHeight = child.height; + childWidth = child.width; + canLayout = !child.hasLayout && typeof child.doLayout == 'function'; + + + if (typeof childWidth != 'number') { + + + if (child.flex && !childWidth) { + totalFlex += child.flex; + + + } else { + + + if (!childWidth && canLayout) { + child.doLayout(); + } + + childSize = child.getSize(); + childWidth = childSize.width; + childHeight = childSize.height; + } + } + + childMargins = child.margins; + horizMargins = childMargins.left + childMargins.right; + + nonFlexWidth += horizMargins + (childWidth || 0); + desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth); + minimumWidth += horizMargins + (child.minWidth || childWidth || 0); + + + if (typeof childHeight != 'number') { + if (canLayout) { + child.doLayout(); + } + childHeight = child.getHeight(); + } + + maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom); + + + boxes.push({ + component: child, + height : childHeight || undefined, + width : childWidth || undefined + }); + } + + var shortfall = desiredWidth - width, + tooNarrow = minimumWidth > width; + + + var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz); + + if (tooNarrow) { + for (i = 0; i < visibleCount; i++) { + boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width; + } + } else { + + + if (shortfall > 0) { + var minWidths = []; + + + + + for (var index = 0, length = visibleCount; index < length; index++) { + var item = visibleItems[index], + minWidth = item.minWidth || 0; + + + + if (item.flex) { + boxes[index].width = minWidth; + } else { + minWidths.push({ + minWidth : minWidth, + available: boxes[index].width - minWidth, + index : index + }); + } + } + + + minWidths.sort(function(a, b) { + return a.available > b.available ? 1 : -1; + }); + + + for (var i = 0, length = minWidths.length; i < length; i++) { + var itemIndex = minWidths[i].index; + + if (itemIndex == undefined) { + continue; + } + + var item = visibleItems[itemIndex], + box = boxes[itemIndex], + oldWidth = box.width, + minWidth = item.minWidth, + newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))), + reduction = oldWidth - newWidth; + + boxes[itemIndex].width = newWidth; + shortfall -= reduction; + } + } else { + + var remainingWidth = availableWidth, + remainingFlex = totalFlex; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + vertMargins = childMargins.top + childMargins.bottom; + + if (isStart && child.flex && !child.width) { + flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth); + remainingWidth -= flexedWidth; + remainingFlex -= child.flex; + + calcs.width = flexedWidth; + calcs.dirtySize = true; + } + } + } + } + + if (isCenter) { + leftOffset += availableWidth / 2; + } else if (isEnd) { + leftOffset += availableWidth; + } + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + leftOffset += childMargins.left; + vertMargins = childMargins.top + childMargins.bottom; + + calcs.left = leftOffset; + calcs.top = topOffset + childMargins.top; + + switch (this.align) { + case 'stretch': + stretchHeight = availHeight - vertMargins; + calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); + calcs.dirtySize = true; + break; + case 'stretchmax': + stretchHeight = maxHeight - vertMargins; + calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); + calcs.dirtySize = true; + break; + case 'middle': + var diff = availHeight - calcs.height - vertMargins; + if (diff > 0) { + calcs.top = topOffset + vertMargins + (diff / 2); + } + } + + leftOffset += calcs.width + childMargins.right; + } + + return { + boxes: boxes, + meta : { + maxHeight : maxHeight, + nonFlexWidth: nonFlexWidth, + desiredWidth: desiredWidth, + minimumWidth: minimumWidth, + shortfall : desiredWidth - width, + tooNarrow : tooNarrow + } + }; + } +}); + +Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout; +Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, { + + align : 'left', + type: 'vbox', + + + + + + + calculateChildBoxes: function(visibleItems, targetSize) { + var visibleCount = visibleItems.length, + + padding = this.padding, + topOffset = padding.top, + leftOffset = padding.left, + paddingVert = topOffset + padding.bottom, + paddingHoriz = leftOffset + padding.right, + + width = targetSize.width - this.scrollOffset, + height = targetSize.height, + availWidth = Math.max(0, width - paddingHoriz), + + isStart = this.pack == 'start', + isCenter = this.pack == 'center', + isEnd = this.pack == 'end', + + nonFlexHeight= 0, + maxWidth = 0, + totalFlex = 0, + desiredHeight= 0, + minimumHeight= 0, + + + boxes = [], + + + child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, + horizMargins, vertMargins, stretchWidth, length; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + childHeight = child.height; + childWidth = child.width; + canLayout = !child.hasLayout && typeof child.doLayout == 'function'; + + + if (typeof childHeight != 'number') { + + + if (child.flex && !childHeight) { + totalFlex += child.flex; + + + } else { + + + if (!childHeight && canLayout) { + child.doLayout(); + } + + childSize = child.getSize(); + childWidth = childSize.width; + childHeight = childSize.height; + } + } + + childMargins = child.margins; + vertMargins = childMargins.top + childMargins.bottom; + + nonFlexHeight += vertMargins + (childHeight || 0); + desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight); + minimumHeight += vertMargins + (child.minHeight || childHeight || 0); + + + if (typeof childWidth != 'number') { + if (canLayout) { + child.doLayout(); + } + childWidth = child.getWidth(); + } + + maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right); + + + boxes.push({ + component: child, + height : childHeight || undefined, + width : childWidth || undefined + }); + } + + var shortfall = desiredHeight - height, + tooNarrow = minimumHeight > height; + + + var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert)); + + if (tooNarrow) { + for (i = 0, length = visibleCount; i < length; i++) { + boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height; + } + } else { + + + if (shortfall > 0) { + var minHeights = []; + + + + + for (var index = 0, length = visibleCount; index < length; index++) { + var item = visibleItems[index], + minHeight = item.minHeight || 0; + + + + if (item.flex) { + boxes[index].height = minHeight; + } else { + minHeights.push({ + minHeight: minHeight, + available: boxes[index].height - minHeight, + index : index + }); + } + } + + + minHeights.sort(function(a, b) { + return a.available > b.available ? 1 : -1; + }); + + + for (var i = 0, length = minHeights.length; i < length; i++) { + var itemIndex = minHeights[i].index; + + if (itemIndex == undefined) { + continue; + } + + var item = visibleItems[itemIndex], + box = boxes[itemIndex], + oldHeight = box.height, + minHeight = item.minHeight, + newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))), + reduction = oldHeight - newHeight; + + boxes[itemIndex].height = newHeight; + shortfall -= reduction; + } + } else { + + var remainingHeight = availableHeight, + remainingFlex = totalFlex; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + horizMargins = childMargins.left + childMargins.right; + + if (isStart && child.flex && !child.height) { + flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight); + remainingHeight -= flexedHeight; + remainingFlex -= child.flex; + + calcs.height = flexedHeight; + calcs.dirtySize = true; + } + } + } + } + + if (isCenter) { + topOffset += availableHeight / 2; + } else if (isEnd) { + topOffset += availableHeight; + } + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + topOffset += childMargins.top; + horizMargins = childMargins.left + childMargins.right; + + + calcs.left = leftOffset + childMargins.left; + calcs.top = topOffset; + + switch (this.align) { + case 'stretch': + stretchWidth = availWidth - horizMargins; + calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); + calcs.dirtySize = true; + break; + case 'stretchmax': + stretchWidth = maxWidth - horizMargins; + calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); + calcs.dirtySize = true; + break; + case 'center': + var diff = availWidth - calcs.width - horizMargins; + if (diff > 0) { + calcs.left = leftOffset + horizMargins + (diff / 2); + } + } + + topOffset += calcs.height + childMargins.bottom; + } + + return { + boxes: boxes, + meta : { + maxWidth : maxWidth, + nonFlexHeight: nonFlexHeight, + desiredHeight: desiredHeight, + minimumHeight: minimumHeight, + shortfall : desiredHeight - height, + tooNarrow : tooNarrow + } + }; + } +}); + +Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout; + +Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, { + monitorResize : true, + + type: 'toolbar', + + + triggerWidth: 18, + + + noItemsMenuText : '
(None)
', + + + lastOverflow: false, + + + tableHTML: [ + '', + '', + '', + '', + '', + '', + '', + '
', + '', + '', + '', + '', + '
', + '
', + '', + '', + '', + '', + '', + '', + '', + '
', + '', + '', + '', + '', + '
', + '
', + '', + '', + '', + '', + '
', + '
', + '
' + ].join(""), + + + onLayout : function(ct, target) { + + if (!this.leftTr) { + var align = ct.buttonAlign == 'center' ? 'center' : 'left'; + + target.addClass('x-toolbar-layout-ct'); + target.insertHtml('beforeEnd', String.format(this.tableHTML, align)); + + this.leftTr = target.child('tr.x-toolbar-left-row', true); + this.rightTr = target.child('tr.x-toolbar-right-row', true); + this.extrasTr = target.child('tr.x-toolbar-extras-row', true); + + if (this.hiddenItem == undefined) { + + this.hiddenItems = []; + } + } + + var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr, + items = ct.items.items, + position = 0; + + + for (var i = 0, len = items.length, c; i < len; i++, position++) { + c = items[i]; + + if (c.isFill) { + side = this.rightTr; + position = -1; + } else if (!c.rendered) { + c.render(this.insertCell(c, side, position)); + this.configureItem(c); + } else { + if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) { + var td = this.insertCell(c, side, position); + td.appendChild(c.getPositionEl().dom); + c.container = Ext.get(td); + } + } + } + + + this.cleanup(this.leftTr); + this.cleanup(this.rightTr); + this.cleanup(this.extrasTr); + this.fitToSize(target); + }, + + + cleanup : function(el) { + var cn = el.childNodes, i, c; + + for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) { + if (!c.firstChild) { + el.removeChild(c); + } + } + }, + + + insertCell : function(c, target, position) { + var td = document.createElement('td'); + td.className = 'x-toolbar-cell'; + + target.insertBefore(td, target.childNodes[position] || null); + + return td; + }, + + + hideItem : function(item) { + this.hiddenItems.push(item); + + item.xtbHidden = true; + item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth; + item.hide(); + }, + + + unhideItem : function(item) { + item.show(); + item.xtbHidden = false; + this.hiddenItems.remove(item); + }, + + + getItemWidth : function(c) { + return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth; + }, + + + fitToSize : function(target) { + if (this.container.enableOverflow === false) { + return; + } + + var width = target.dom.clientWidth, + tableWidth = target.dom.firstChild.offsetWidth, + clipWidth = width - this.triggerWidth, + lastWidth = this.lastWidth || 0, + + hiddenItems = this.hiddenItems, + hasHiddens = hiddenItems.length != 0, + isLarger = width >= lastWidth; + + this.lastWidth = width; + + if (tableWidth > width || (hasHiddens && isLarger)) { + var items = this.container.items.items, + len = items.length, + loopWidth = 0, + item; + + for (var i = 0; i < len; i++) { + item = items[i]; + + if (!item.isFill) { + loopWidth += this.getItemWidth(item); + if (loopWidth > clipWidth) { + if (!(item.hidden || item.xtbHidden)) { + this.hideItem(item); + } + } else if (item.xtbHidden) { + this.unhideItem(item); + } + } + } + } + + + hasHiddens = hiddenItems.length != 0; + + if (hasHiddens) { + this.initMore(); + + if (!this.lastOverflow) { + this.container.fireEvent('overflowchange', this.container, true); + this.lastOverflow = true; + } + } else if (this.more) { + this.clearMenu(); + this.more.destroy(); + delete this.more; + + if (this.lastOverflow) { + this.container.fireEvent('overflowchange', this.container, false); + this.lastOverflow = false; + } + } + }, + + + createMenuConfig : function(component, hideOnClick){ + var config = Ext.apply({}, component.initialConfig), + group = component.toggleGroup; + + Ext.copyTo(config, component, [ + 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' + ]); + + Ext.apply(config, { + text : component.overflowText || component.text, + hideOnClick: hideOnClick + }); + + if (group || component.enableToggle) { + Ext.apply(config, { + group : group, + checked: component.pressed, + listeners: { + checkchange: function(item, checked){ + component.toggle(checked); + } + } + }); + } + + delete config.ownerCt; + delete config.xtype; + delete config.id; + + return config; + }, + + + addComponentToMenu : function(menu, component) { + if (component instanceof Ext.Toolbar.Separator) { + menu.add('-'); + + } else if (Ext.isFunction(component.isXType)) { + if (component.isXType('splitbutton')) { + menu.add(this.createMenuConfig(component, true)); + + } else if (component.isXType('button')) { + menu.add(this.createMenuConfig(component, !component.menu)); + + } else if (component.isXType('buttongroup')) { + component.items.each(function(item){ + this.addComponentToMenu(menu, item); + }, this); + } + } + }, + + + clearMenu : function(){ + var menu = this.moreMenu; + if (menu && menu.items) { + menu.items.each(function(item){ + delete item.menu; + }); + } + }, + + + beforeMoreShow : function(menu) { + var items = this.container.items.items, + len = items.length, + item, + prev; + + var needsSep = function(group, item){ + return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); + }; + + this.clearMenu(); + menu.removeAll(); + for (var i = 0; i < len; i++) { + item = items[i]; + if (item.xtbHidden) { + if (prev && (needsSep(item, prev) || needsSep(prev, item))) { + menu.add('-'); + } + this.addComponentToMenu(menu, item); + prev = item; + } + } + + + if (menu.items.length < 1) { + menu.add(this.noItemsMenuText); + } + }, + + + initMore : function(){ + if (!this.more) { + + this.moreMenu = new Ext.menu.Menu({ + ownerCt : this.container, + listeners: { + beforeshow: this.beforeMoreShow, + scope: this + } + }); + + + this.more = new Ext.Button({ + iconCls: 'x-toolbar-more-icon', + cls : 'x-toolbar-more', + menu : this.moreMenu, + ownerCt: this.container + }); + + var td = this.insertCell(this.more, this.extrasTr, 100); + this.more.render(td); + } + }, + + destroy : function(){ + Ext.destroy(this.more, this.moreMenu); + delete this.leftTr; + delete this.rightTr; + delete this.extrasTr; + Ext.layout.ToolbarLayout.superclass.destroy.call(this); + } +}); + +Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout; + + Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, { + monitorResize : true, + + type: 'menu', + + setContainer : function(ct){ + this.monitorResize = !ct.floating; + + + ct.on('autosize', this.doAutoSize, this); + Ext.layout.MenuLayout.superclass.setContainer.call(this, ct); + }, + + renderItem : function(c, position, target){ + if (!this.itemTpl) { + this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate( + '
  • ', + '', + '{altText}', + '', + '
  • ' + ); + } + + if(c && !c.rendered){ + if(Ext.isNumber(position)){ + position = target.dom.childNodes[position]; + } + var a = this.getItemArgs(c); + + + c.render(c.positionEl = position ? + this.itemTpl.insertBefore(position, a, true) : + this.itemTpl.append(target, a, true)); + + + c.positionEl.menuItemId = c.getItemId(); + + + + if (!a.isMenuItem && a.needsIcon) { + c.positionEl.addClass('x-menu-list-item-indent'); + } + this.configureItem(c); + }else if(c && !this.isValidParent(c, target)){ + if(Ext.isNumber(position)){ + position = target.dom.childNodes[position]; + } + target.dom.insertBefore(c.getActionEl().dom, position || null); + } + }, + + getItemArgs : function(c) { + var isMenuItem = c instanceof Ext.menu.Item, + canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator); + + return { + isMenuItem: isMenuItem, + needsIcon: canHaveIcon && (c.icon || c.iconCls), + icon: c.icon || Ext.BLANK_IMAGE_URL, + iconCls: 'x-menu-item-icon ' + (c.iconCls || ''), + itemId: 'x-menu-el-' + c.id, + itemCls: 'x-menu-list-item ', + altText: c.altText || '' + }; + }, + + + isValidParent : function(c, target) { + return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target); + }, + + onLayout : function(ct, target){ + Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target); + this.doAutoSize(); + }, + + doAutoSize : function(){ + var ct = this.container, w = ct.width; + if(ct.floating){ + if(w){ + ct.setWidth(w); + }else if(Ext.isIE9m){ + ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8 || Ext.isIE9) ? 'auto' : ct.minWidth); + var el = ct.getEl(), t = el.dom.offsetWidth; + ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr')); + } + } + } +}); +Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout; + +Ext.Viewport = Ext.extend(Ext.Container, { + + + + + + + + + + + + + initComponent : function() { + Ext.Viewport.superclass.initComponent.call(this); + document.getElementsByTagName('html')[0].className += ' x-viewport'; + this.el = Ext.getBody(); + this.el.setHeight = Ext.emptyFn; + this.el.setWidth = Ext.emptyFn; + this.el.setSize = Ext.emptyFn; + this.el.dom.scroll = 'no'; + this.allowDomMove = false; + this.autoWidth = true; + this.autoHeight = true; + Ext.EventManager.onWindowResize(this.fireResize, this); + this.renderTo = this.el; + }, + + fireResize : function(w, h){ + this.fireEvent('resize', this, w, h, w, h); + } +}); +Ext.reg('viewport', Ext.Viewport); + +Ext.Panel = Ext.extend(Ext.Container, { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + baseCls : 'x-panel', + + collapsedCls : 'x-panel-collapsed', + + maskDisabled : true, + + animCollapse : Ext.enableFx, + + headerAsText : true, + + buttonAlign : 'right', + + collapsed : false, + + collapseFirst : true, + + minButtonWidth : 75, + + + elements : 'body', + + preventBodyReset : false, + + + padding: undefined, + + + resizeEvent: 'bodyresize', + + + + + toolTarget : 'header', + collapseEl : 'bwrap', + slideAnchor : 't', + disabledClass : '', + + + deferHeight : true, + + expandDefaults: { + duration : 0.25 + }, + + collapseDefaults : { + duration : 0.25 + }, + + + initComponent : function(){ + Ext.Panel.superclass.initComponent.call(this); + + this.addEvents( + + 'bodyresize', + + 'titlechange', + + 'iconchange', + + 'collapse', + + 'expand', + + 'beforecollapse', + + 'beforeexpand', + + 'beforeclose', + + 'close', + + 'activate', + + 'deactivate' + ); + + if(this.unstyled){ + this.baseCls = 'x-plain'; + } + + + this.toolbars = []; + + if(this.tbar){ + this.elements += ',tbar'; + this.topToolbar = this.createToolbar(this.tbar); + this.tbar = null; + + } + if(this.bbar){ + this.elements += ',bbar'; + this.bottomToolbar = this.createToolbar(this.bbar); + this.bbar = null; + } + + if(this.header === true){ + this.elements += ',header'; + this.header = null; + }else if(this.headerCfg || (this.title && this.header !== false)){ + this.elements += ',header'; + } + + if(this.footerCfg || this.footer === true){ + this.elements += ',footer'; + this.footer = null; + } + + if(this.buttons){ + this.fbar = this.buttons; + this.buttons = null; + } + if(this.fbar){ + this.createFbar(this.fbar); + } + if(this.autoLoad){ + this.on('render', this.doAutoLoad, this, {delay:10}); + } + }, + + + createFbar : function(fbar){ + var min = this.minButtonWidth; + this.elements += ',footer'; + this.fbar = this.createToolbar(fbar, { + buttonAlign: this.buttonAlign, + toolbarCls: 'x-panel-fbar', + enableOverflow: false, + defaults: function(c){ + return { + minWidth: c.minWidth || min + }; + } + }); + + + + this.fbar.items.each(function(c){ + c.minWidth = c.minWidth || this.minButtonWidth; + }, this); + this.buttons = this.fbar.items.items; + }, + + + createToolbar: function(tb, options){ + var result; + + if(Ext.isArray(tb)){ + tb = { + items: tb + }; + } + result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar'); + this.toolbars.push(result); + return result; + }, + + + createElement : function(name, pnode){ + if(this[name]){ + pnode.appendChild(this[name].dom); + return; + } + + if(name === 'bwrap' || this.elements.indexOf(name) != -1){ + if(this[name+'Cfg']){ + this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']); + }else{ + var el = document.createElement('div'); + el.className = this[name+'Cls']; + this[name] = Ext.get(pnode.appendChild(el)); + } + if(this[name+'CssClass']){ + this[name].addClass(this[name+'CssClass']); + } + if(this[name+'Style']){ + this[name].applyStyles(this[name+'Style']); + } + } + }, + + + onRender : function(ct, position){ + Ext.Panel.superclass.onRender.call(this, ct, position); + this.createClasses(); + + var el = this.el, + d = el.dom, + bw, + ts; + + + if(this.collapsible && !this.hideCollapseTool){ + this.tools = this.tools ? this.tools.slice(0) : []; + this.tools[this.collapseFirst?'unshift':'push']({ + id: 'toggle', + handler : this.toggleCollapse, + scope: this + }); + } + + if(this.tools){ + ts = this.tools; + this.elements += (this.header !== false) ? ',header' : ''; + } + this.tools = {}; + + el.addClass(this.baseCls); + if(d.firstChild){ + this.header = el.down('.'+this.headerCls); + this.bwrap = el.down('.'+this.bwrapCls); + var cp = this.bwrap ? this.bwrap : el; + this.tbar = cp.down('.'+this.tbarCls); + this.body = cp.down('.'+this.bodyCls); + this.bbar = cp.down('.'+this.bbarCls); + this.footer = cp.down('.'+this.footerCls); + this.fromMarkup = true; + } + if (this.preventBodyReset === true) { + el.addClass('x-panel-reset'); + } + if(this.cls){ + el.addClass(this.cls); + } + + if(this.buttons){ + this.elements += ',footer'; + } + + + + + if(this.frame){ + el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls)); + + this.createElement('header', d.firstChild.firstChild.firstChild); + this.createElement('bwrap', d); + + + bw = this.bwrap.dom; + var ml = d.childNodes[1], bl = d.childNodes[2]; + bw.appendChild(ml); + bw.appendChild(bl); + + var mc = bw.firstChild.firstChild.firstChild; + this.createElement('tbar', mc); + this.createElement('body', mc); + this.createElement('bbar', mc); + this.createElement('footer', bw.lastChild.firstChild.firstChild); + + if(!this.footer){ + this.bwrap.dom.lastChild.className += ' x-panel-nofooter'; + } + + this.ft = Ext.get(this.bwrap.dom.lastChild); + this.mc = Ext.get(mc); + }else{ + this.createElement('header', d); + this.createElement('bwrap', d); + + + bw = this.bwrap.dom; + this.createElement('tbar', bw); + this.createElement('body', bw); + this.createElement('bbar', bw); + this.createElement('footer', bw); + + if(!this.header){ + this.body.addClass(this.bodyCls + '-noheader'); + if(this.tbar){ + this.tbar.addClass(this.tbarCls + '-noheader'); + } + } + } + + if(Ext.isDefined(this.padding)){ + this.body.setStyle('padding', this.body.addUnits(this.padding)); + } + + if(this.border === false){ + this.el.addClass(this.baseCls + '-noborder'); + this.body.addClass(this.bodyCls + '-noborder'); + if(this.header){ + this.header.addClass(this.headerCls + '-noborder'); + } + if(this.footer){ + this.footer.addClass(this.footerCls + '-noborder'); + } + if(this.tbar){ + this.tbar.addClass(this.tbarCls + '-noborder'); + } + if(this.bbar){ + this.bbar.addClass(this.bbarCls + '-noborder'); + } + } + + if(this.bodyBorder === false){ + this.body.addClass(this.bodyCls + '-noborder'); + } + + this.bwrap.enableDisplayMode('block'); + + if(this.header){ + this.header.unselectable(); + + + if(this.headerAsText){ + this.header.dom.innerHTML = + ''+this.header.dom.innerHTML+''; + + if(this.iconCls){ + this.setIconClass(this.iconCls); + } + } + } + + if(this.floating){ + this.makeFloating(this.floating); + } + + if(this.collapsible && this.titleCollapse && this.header){ + this.mon(this.header, 'click', this.toggleCollapse, this); + this.header.setStyle('cursor', 'pointer'); + } + if(ts){ + this.addTool.apply(this, ts); + } + + + if(this.fbar){ + this.footer.addClass('x-panel-btns'); + this.fbar.ownerCt = this; + this.fbar.render(this.footer); + this.footer.createChild({cls:'x-clear'}); + } + if(this.tbar && this.topToolbar){ + this.topToolbar.ownerCt = this; + this.topToolbar.render(this.tbar); + } + if(this.bbar && this.bottomToolbar){ + this.bottomToolbar.ownerCt = this; + this.bottomToolbar.render(this.bbar); + } + }, + + + setIconClass : function(cls){ + var old = this.iconCls; + this.iconCls = cls; + if(this.rendered && this.header){ + if(this.frame){ + this.header.addClass('x-panel-icon'); + this.header.replaceClass(old, this.iconCls); + }else{ + var hd = this.header, + img = hd.child('img.x-panel-inline-icon'); + if(img){ + Ext.fly(img).replaceClass(old, this.iconCls); + }else{ + var hdspan = hd.child('span.' + this.headerTextCls); + if (hdspan) { + Ext.DomHelper.insertBefore(hdspan.dom, { + tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls + }); + } + } + } + } + this.fireEvent('iconchange', this, cls, old); + }, + + + makeFloating : function(cfg){ + this.floating = true; + this.el = new Ext.Layer(Ext.apply({}, cfg, { + shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', + shadowOffset: this.shadowOffset, + constrain:false, + shim: this.shim === false ? false : undefined + }), this.el); + }, + + + getTopToolbar : function(){ + return this.topToolbar; + }, + + + getBottomToolbar : function(){ + return this.bottomToolbar; + }, + + + getFooterToolbar : function() { + return this.fbar; + }, + + + addButton : function(config, handler, scope){ + if(!this.fbar){ + this.createFbar([]); + } + if(handler){ + if(Ext.isString(config)){ + config = {text: config}; + } + config = Ext.apply({ + handler: handler, + scope: scope + }, config); + } + return this.fbar.add(config); + }, + + + addTool : function(){ + if(!this.rendered){ + if(!this.tools){ + this.tools = []; + } + Ext.each(arguments, function(arg){ + this.tools.push(arg); + }, this); + return; + } + + if(!this[this.toolTarget]){ + return; + } + if(!this.toolTemplate){ + + var tt = new Ext.Template( + '
     
    ' + ); + tt.disableFormats = true; + tt.compile(); + Ext.Panel.prototype.toolTemplate = tt; + } + for(var i = 0, a = arguments, len = a.length; i < len; i++) { + var tc = a[i]; + if(!this.tools[tc.id]){ + var overCls = 'x-tool-'+tc.id+'-over'; + var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true); + this.tools[tc.id] = t; + t.enableDisplayMode('block'); + this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this)); + if(tc.on){ + this.mon(t, tc.on); + } + if(tc.hidden){ + t.hide(); + } + if(tc.qtip){ + if(Ext.isObject(tc.qtip)){ + Ext.QuickTips.register(Ext.apply({ + target: t.id + }, tc.qtip)); + } else { + t.dom.qtip = tc.qtip; + } + } + t.addClassOnOver(overCls); + } + } + }, + + onLayout : function(shallow, force){ + Ext.Panel.superclass.onLayout.apply(this, arguments); + if(this.hasLayout && this.toolbars.length > 0){ + Ext.each(this.toolbars, function(tb){ + tb.doLayout(undefined, force); + }); + this.syncHeight(); + } + }, + + syncHeight : function(){ + var h = this.toolbarHeight, + bd = this.body, + lsh = this.lastSize.height, + sz; + + if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){ + return; + } + + + if(h != this.getToolbarHeight()){ + h = Math.max(0, lsh - this.getFrameHeight()); + bd.setHeight(h); + sz = bd.getSize(); + this.toolbarHeight = this.getToolbarHeight(); + this.onBodyResize(sz.width, sz.height); + } + }, + + + onShow : function(){ + if(this.floating){ + return this.el.show(); + } + Ext.Panel.superclass.onShow.call(this); + }, + + + onHide : function(){ + if(this.floating){ + return this.el.hide(); + } + Ext.Panel.superclass.onHide.call(this); + }, + + + createToolHandler : function(t, tc, overCls, panel){ + return function(e){ + t.removeClass(overCls); + if(tc.stopEvent !== false){ + e.stopEvent(); + } + if(tc.handler){ + tc.handler.call(tc.scope || t, e, t, panel, tc); + } + }; + }, + + + afterRender : function(){ + if(this.floating && !this.hidden){ + this.el.show(); + } + if(this.title){ + this.setTitle(this.title); + } + Ext.Panel.superclass.afterRender.call(this); + if (this.collapsed) { + this.collapsed = false; + this.collapse(false); + } + this.initEvents(); + }, + + + getKeyMap : function(){ + if(!this.keyMap){ + this.keyMap = new Ext.KeyMap(this.el, this.keys); + } + return this.keyMap; + }, + + + initEvents : function(){ + if(this.keys){ + this.getKeyMap(); + } + if(this.draggable){ + this.initDraggable(); + } + if(this.toolbars.length > 0){ + Ext.each(this.toolbars, function(tb){ + tb.doLayout(); + tb.on({ + scope: this, + afterlayout: this.syncHeight, + remove: this.syncHeight + }); + }, this); + this.syncHeight(); + } + + }, + + + initDraggable : function(){ + + this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable); + }, + + + beforeEffect : function(anim){ + if(this.floating){ + this.el.beforeAction(); + } + if(anim !== false){ + this.el.addClass('x-panel-animated'); + } + }, + + + afterEffect : function(anim){ + this.syncShadow(); + this.el.removeClass('x-panel-animated'); + }, + + + createEffect : function(a, cb, scope){ + var o = { + scope:scope, + block:true + }; + if(a === true){ + o.callback = cb; + return o; + }else if(!a.callback){ + o.callback = cb; + }else { + o.callback = function(){ + cb.call(scope); + Ext.callback(a.callback, a.scope); + }; + } + return Ext.applyIf(o, a); + }, + + + collapse : function(animate){ + if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){ + return; + } + var doAnim = animate === true || (animate !== false && this.animCollapse); + this.beforeEffect(doAnim); + this.onCollapse(doAnim, animate); + return this; + }, + + + onCollapse : function(doAnim, animArg){ + if(doAnim){ + this[this.collapseEl].slideOut(this.slideAnchor, + Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this), + this.collapseDefaults)); + }else{ + this[this.collapseEl].hide(this.hideMode); + this.afterCollapse(false); + } + }, + + + afterCollapse : function(anim){ + this.collapsed = true; + this.el.addClass(this.collapsedCls); + if(anim !== false){ + this[this.collapseEl].hide(this.hideMode); + } + this.afterEffect(anim); + + + this.cascade(function(c) { + if (c.lastSize) { + c.lastSize = { width: undefined, height: undefined }; + } + }); + this.fireEvent('collapse', this); + }, + + + expand : function(animate){ + if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){ + return; + } + var doAnim = animate === true || (animate !== false && this.animCollapse); + this.el.removeClass(this.collapsedCls); + this.beforeEffect(doAnim); + this.onExpand(doAnim, animate); + return this; + }, + + + onExpand : function(doAnim, animArg){ + if(doAnim){ + this[this.collapseEl].slideIn(this.slideAnchor, + Ext.apply(this.createEffect(animArg||true, this.afterExpand, this), + this.expandDefaults)); + }else{ + this[this.collapseEl].show(this.hideMode); + this.afterExpand(false); + } + }, + + + afterExpand : function(anim){ + this.collapsed = false; + if(anim !== false){ + this[this.collapseEl].show(this.hideMode); + } + this.afterEffect(anim); + if (this.deferLayout) { + delete this.deferLayout; + this.doLayout(true); + } + this.fireEvent('expand', this); + }, + + + toggleCollapse : function(animate){ + this[this.collapsed ? 'expand' : 'collapse'](animate); + return this; + }, + + + onDisable : function(){ + if(this.rendered && this.maskDisabled){ + this.el.mask(); + } + Ext.Panel.superclass.onDisable.call(this); + }, + + + onEnable : function(){ + if(this.rendered && this.maskDisabled){ + this.el.unmask(); + } + Ext.Panel.superclass.onEnable.call(this); + }, + + + onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ + var w = adjWidth, + h = adjHeight; + + if(Ext.isDefined(w) || Ext.isDefined(h)){ + if(!this.collapsed){ + + + + + if(Ext.isNumber(w)){ + this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth())); + } else if (w == 'auto') { + w = this.body.setWidth('auto').dom.offsetWidth; + } else { + w = this.body.dom.offsetWidth; + } + + if(this.tbar){ + this.tbar.setWidth(w); + if(this.topToolbar){ + this.topToolbar.setSize(w); + } + } + if(this.bbar){ + this.bbar.setWidth(w); + if(this.bottomToolbar){ + this.bottomToolbar.setSize(w); + + if (Ext.isIE9m) { + this.bbar.setStyle('position', 'static'); + this.bbar.setStyle('position', ''); + } + } + } + if(this.footer){ + this.footer.setWidth(w); + if(this.fbar){ + this.fbar.setSize(Ext.isIE9m ? (w - this.footer.getFrameWidth('lr')) : 'auto'); + } + } + + + if(Ext.isNumber(h)){ + h = Math.max(0, h - this.getFrameHeight()); + + this.body.setHeight(h); + }else if(h == 'auto'){ + this.body.setHeight(h); + } + + if(this.disabled && this.el._mask){ + this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight()); + } + }else{ + + this.queuedBodySize = {width: w, height: h}; + if(!this.queuedExpand && this.allowQueuedExpand !== false){ + this.queuedExpand = true; + this.on('expand', function(){ + delete this.queuedExpand; + this.onResize(this.queuedBodySize.width, this.queuedBodySize.height); + }, this, {single:true}); + } + } + this.onBodyResize(w, h); + } + this.syncShadow(); + Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight); + + }, + + + onBodyResize: function(w, h){ + this.fireEvent('bodyresize', this, w, h); + }, + + + getToolbarHeight: function(){ + var h = 0; + if(this.rendered){ + Ext.each(this.toolbars, function(tb){ + h += tb.getHeight(); + }, this); + } + return h; + }, + + + adjustBodyHeight : function(h){ + return h; + }, + + + adjustBodyWidth : function(w){ + return w; + }, + + + onPosition : function(){ + this.syncShadow(); + }, + + + getFrameWidth : function(){ + var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr'); + + if(this.frame){ + var l = this.bwrap.dom.firstChild; + w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r')); + w += this.mc.getFrameWidth('lr'); + } + return w; + }, + + + getFrameHeight : function() { + var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb'); + h += (this.tbar ? this.tbar.getHeight() : 0) + + (this.bbar ? this.bbar.getHeight() : 0); + + if(this.frame){ + h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb'); + }else{ + h += (this.header ? this.header.getHeight() : 0) + + (this.footer ? this.footer.getHeight() : 0); + } + return h; + }, + + + getInnerWidth : function(){ + return this.getSize().width - this.getFrameWidth(); + }, + + + getInnerHeight : function(){ + return this.body.getHeight(); + + }, + + + syncShadow : function(){ + if(this.floating){ + this.el.sync(true); + } + }, + + + getLayoutTarget : function(){ + return this.body; + }, + + + getContentTarget : function(){ + return this.body; + }, + + + setTitle : function(title, iconCls){ + this.title = title; + if(this.header && this.headerAsText){ + this.header.child('span').update(title); + } + if(iconCls){ + this.setIconClass(iconCls); + } + this.fireEvent('titlechange', this, title); + return this; + }, + + + getUpdater : function(){ + return this.body.getUpdater(); + }, + + + load : function(){ + var um = this.body.getUpdater(); + um.update.apply(um, arguments); + return this; + }, + + + beforeDestroy : function(){ + Ext.Panel.superclass.beforeDestroy.call(this); + if(this.header){ + this.header.removeAllListeners(); + } + if(this.tools){ + for(var k in this.tools){ + Ext.destroy(this.tools[k]); + } + } + if(this.toolbars.length > 0){ + Ext.each(this.toolbars, function(tb){ + tb.un('afterlayout', this.syncHeight, this); + tb.un('remove', this.syncHeight, this); + }, this); + } + if(Ext.isArray(this.buttons)){ + while(this.buttons.length) { + Ext.destroy(this.buttons[0]); + } + } + if(this.rendered){ + Ext.destroy( + this.ft, + this.header, + this.footer, + this.tbar, + this.bbar, + this.body, + this.mc, + this.bwrap, + this.dd + ); + if (this.fbar) { + Ext.destroy( + this.fbar, + this.fbar.el + ); + } + } + Ext.destroy(this.toolbars); + }, + + + createClasses : function(){ + this.headerCls = this.baseCls + '-header'; + this.headerTextCls = this.baseCls + '-header-text'; + this.bwrapCls = this.baseCls + '-bwrap'; + this.tbarCls = this.baseCls + '-tbar'; + this.bodyCls = this.baseCls + '-body'; + this.bbarCls = this.baseCls + '-bbar'; + this.footerCls = this.baseCls + '-footer'; + }, + + + createGhost : function(cls, useShim, appendTo){ + var el = document.createElement('div'); + el.className = 'x-panel-ghost ' + (cls ? cls : ''); + if(this.header){ + el.appendChild(this.el.dom.firstChild.cloneNode(true)); + } + Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight()); + el.style.width = this.el.dom.offsetWidth + 'px';; + if(!appendTo){ + this.container.dom.appendChild(el); + }else{ + Ext.getDom(appendTo).appendChild(el); + } + if(useShim !== false && this.el.useShim !== false){ + var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el); + layer.show(); + return layer; + }else{ + return new Ext.Element(el); + } + }, + + + doAutoLoad : function(){ + var u = this.body.getUpdater(); + if(this.renderer){ + u.setRenderer(this.renderer); + } + u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad}); + }, + + + getTool : function(id) { + return this.tools[id]; + } + + +}); +Ext.reg('panel', Ext.Panel); + +Ext.Editor = function(field, config){ + if(field.field){ + this.field = Ext.create(field.field, 'textfield'); + config = Ext.apply({}, field); + delete config.field; + }else{ + this.field = field; + } + Ext.Editor.superclass.constructor.call(this, config); +}; + +Ext.extend(Ext.Editor, Ext.Component, { + + + allowBlur: true, + + + + + + value : "", + + alignment: "c-c?", + + offsets: [0, 0], + + shadow : "frame", + + constrain : false, + + swallowKeys : true, + + completeOnEnter : true, + + cancelOnEsc : true, + + updateEl : false, + + initComponent : function(){ + Ext.Editor.superclass.initComponent.call(this); + this.addEvents( + + "beforestartedit", + + "startedit", + + "beforecomplete", + + "complete", + + "canceledit", + + "specialkey" + ); + }, + + + onRender : function(ct, position){ + this.el = new Ext.Layer({ + shadow: this.shadow, + cls: "x-editor", + parentEl : ct, + shim : this.shim, + shadowOffset: this.shadowOffset || 4, + id: this.id, + constrain: this.constrain + }); + if(this.zIndex){ + this.el.setZIndex(this.zIndex); + } + this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden"); + if(this.field.msgTarget != 'title'){ + this.field.msgTarget = 'qtip'; + } + this.field.inEditor = true; + this.mon(this.field, { + scope: this, + blur: this.onBlur, + specialkey: this.onSpecialKey + }); + if(this.field.grow){ + this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1}); + } + this.field.render(this.el).show(); + this.field.getEl().dom.name = ''; + if(this.swallowKeys){ + this.field.el.swallowEvent([ + 'keypress', + 'keydown' + ]); + } + }, + + + onSpecialKey : function(field, e){ + var key = e.getKey(), + complete = this.completeOnEnter && key == e.ENTER, + cancel = this.cancelOnEsc && key == e.ESC; + if(complete || cancel){ + e.stopEvent(); + if(complete){ + this.completeEdit(); + }else{ + this.cancelEdit(); + } + if(field.triggerBlur){ + field.triggerBlur(); + } + } + this.fireEvent('specialkey', field, e); + }, + + + startEdit : function(el, value){ + if(this.editing){ + this.completeEdit(); + } + this.boundEl = Ext.get(el); + var v = value !== undefined ? value : this.boundEl.dom.innerHTML; + if(!this.rendered){ + this.render(this.parentEl || document.body); + } + if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){ + this.startValue = v; + this.field.reset(); + this.field.setValue(v); + this.realign(true); + this.editing = true; + this.show(); + } + }, + + + doAutoSize : function(){ + if(this.autoSize){ + var sz = this.boundEl.getSize(), + fs = this.field.getSize(); + + switch(this.autoSize){ + case "width": + this.setSize(sz.width, fs.height); + break; + case "height": + this.setSize(fs.width, sz.height); + break; + case "none": + this.setSize(fs.width, fs.height); + break; + default: + this.setSize(sz.width, sz.height); + } + } + }, + + + setSize : function(w, h){ + delete this.field.lastSize; + this.field.setSize(w, h); + if(this.el){ + + if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){ + + this.el.setSize(w, h); + } + this.el.sync(); + } + }, + + + realign : function(autoSize){ + if(autoSize === true){ + this.doAutoSize(); + } + this.el.alignTo(this.boundEl, this.alignment, this.offsets); + }, + + + completeEdit : function(remainVisible){ + if(!this.editing){ + return; + } + + if (this.field.assertValue) { + this.field.assertValue(); + } + var v = this.getValue(); + if(!this.field.isValid()){ + if(this.revertInvalid !== false){ + this.cancelEdit(remainVisible); + } + return; + } + if(String(v) === String(this.startValue) && this.ignoreNoChange){ + this.hideEdit(remainVisible); + return; + } + if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){ + v = this.getValue(); + if(this.updateEl && this.boundEl){ + this.boundEl.update(v); + } + this.hideEdit(remainVisible); + this.fireEvent("complete", this, v, this.startValue); + } + }, + + + onShow : function(){ + this.el.show(); + if(this.hideEl !== false){ + this.boundEl.hide(); + } + this.field.show().focus(false, true); + this.fireEvent("startedit", this.boundEl, this.startValue); + }, + + + cancelEdit : function(remainVisible){ + if(this.editing){ + var v = this.getValue(); + this.setValue(this.startValue); + this.hideEdit(remainVisible); + this.fireEvent("canceledit", this, v, this.startValue); + } + }, + + + hideEdit: function(remainVisible){ + if(remainVisible !== true){ + this.editing = false; + this.hide(); + } + }, + + + onBlur : function(){ + + if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){ + this.completeEdit(); + } + }, + + + onHide : function(){ + if(this.editing){ + this.completeEdit(); + return; + } + this.field.blur(); + if(this.field.collapse){ + this.field.collapse(); + } + this.el.hide(); + if(this.hideEl !== false){ + this.boundEl.show(); + } + }, + + + setValue : function(v){ + this.field.setValue(v); + }, + + + getValue : function(){ + return this.field.getValue(); + }, + + beforeDestroy : function(){ + Ext.destroyMembers(this, 'field'); + + delete this.parentEl; + delete this.boundEl; + } +}); +Ext.reg('editor', Ext.Editor); + +Ext.ColorPalette = Ext.extend(Ext.Component, { + + + itemCls : 'x-color-palette', + + value : null, + + clickEvent :'click', + + ctype : 'Ext.ColorPalette', + + + allowReselect : false, + + + colors : [ + '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333', + '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080', + 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696', + 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0', + 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF' + ], + + + + + + initComponent : function(){ + Ext.ColorPalette.superclass.initComponent.call(this); + this.addEvents( + + 'select' + ); + + if(this.handler){ + this.on('select', this.handler, this.scope, true); + } + }, + + + onRender : function(container, position){ + this.autoEl = { + tag: 'div', + cls: this.itemCls + }; + Ext.ColorPalette.superclass.onRender.call(this, container, position); + var t = this.tpl || new Ext.XTemplate( + ' ' + ); + t.overwrite(this.el, this.colors); + this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'}); + if(this.clickEvent != 'click'){ + this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true}); + } + }, + + + afterRender : function(){ + Ext.ColorPalette.superclass.afterRender.call(this); + if(this.value){ + var s = this.value; + this.value = null; + this.select(s, true); + } + }, + + + handleClick : function(e, t){ + e.preventDefault(); + if(!this.disabled){ + var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1]; + this.select(c.toUpperCase()); + } + }, + + + select : function(color, suppressEvent){ + color = color.replace('#', ''); + if(color != this.value || this.allowReselect){ + var el = this.el; + if(this.value){ + el.child('a.color-'+this.value).removeClass('x-color-palette-sel'); + } + el.child('a.color-'+color).addClass('x-color-palette-sel'); + this.value = color; + if(suppressEvent !== true){ + this.fireEvent('select', this, color); + } + } + } + + +}); +Ext.reg('colorpalette', Ext.ColorPalette); +Ext.DatePicker = Ext.extend(Ext.BoxComponent, { + + todayText : 'Today', + + okText : ' OK ', + + cancelText : 'Cancel', + + + + todayTip : '{0} (Spacebar)', + + minText : 'This date is before the minimum date', + + maxText : 'This date is after the maximum date', + + format : 'm/d/y', + + disabledDaysText : 'Disabled', + + disabledDatesText : 'Disabled', + + monthNames : Date.monthNames, + + dayNames : Date.dayNames, + + nextText : 'Next Month (Control+Right)', + + prevText : 'Previous Month (Control+Left)', + + monthYearText : 'Choose a month (Control+Up/Down to move years)', + + startDay : 0, + + showToday : true, + + + + + + + + + focusOnSelect: true, + + + + initHour: 12, + + + initComponent : function(){ + Ext.DatePicker.superclass.initComponent.call(this); + + this.value = this.value ? + this.value.clearTime(true) : new Date().clearTime(); + + this.addEvents( + + 'select' + ); + + if(this.handler){ + this.on('select', this.handler, this.scope || this); + } + + this.initDisabledDays(); + }, + + + initDisabledDays : function(){ + if(!this.disabledDatesRE && this.disabledDates){ + var dd = this.disabledDates, + len = dd.length - 1, + re = '(?:'; + + Ext.each(dd, function(d, i){ + re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i]; + if(i != len){ + re += '|'; + } + }, this); + this.disabledDatesRE = new RegExp(re + ')'); + } + }, + + + setDisabledDates : function(dd){ + if(Ext.isArray(dd)){ + this.disabledDates = dd; + this.disabledDatesRE = null; + }else{ + this.disabledDatesRE = dd; + } + this.initDisabledDays(); + this.update(this.value, true); + }, + + + setDisabledDays : function(dd){ + this.disabledDays = dd; + this.update(this.value, true); + }, + + + setMinDate : function(dt){ + this.minDate = dt; + this.update(this.value, true); + }, + + + setMaxDate : function(dt){ + this.maxDate = dt; + this.update(this.value, true); + }, + + + setValue : function(value){ + this.value = value.clearTime(true); + this.update(this.value); + }, + + + getValue : function(){ + return this.value; + }, + + + focus : function(){ + this.update(this.activeDate); + }, + + + onEnable: function(initial){ + Ext.DatePicker.superclass.onEnable.call(this); + this.doDisabled(false); + this.update(initial ? this.value : this.activeDate); + if(Ext.isIE9m){ + this.el.repaint(); + } + + }, + + + onDisable : function(){ + Ext.DatePicker.superclass.onDisable.call(this); + this.doDisabled(true); + if(Ext.isIE9m && !Ext.isIE8){ + + Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){ + Ext.fly(el).repaint(); + }); + } + }, + + + doDisabled : function(disabled){ + this.keyNav.setDisabled(disabled); + this.prevRepeater.setDisabled(disabled); + this.nextRepeater.setDisabled(disabled); + if(this.showToday){ + this.todayKeyListener.setDisabled(disabled); + this.todayBtn.setDisabled(disabled); + } + }, + + + onRender : function(container, position){ + var m = [ + '', + '', + '', + this.showToday ? '' : '', + '
      
    '], + dn = this.dayNames, + i; + for(i = 0; i < 7; i++){ + var d = this.startDay+i; + if(d > 6){ + d = d-7; + } + m.push(''); + } + m[m.length] = ''; + for(i = 0; i < 42; i++) { + if(i % 7 === 0 && i !== 0){ + m[m.length] = ''; + } + m[m.length] = ''; + } + m.push('
    ', dn[d].substr(0,1), '
    '); + + var el = document.createElement('div'); + el.className = 'x-date-picker'; + el.innerHTML = m.join(''); + + container.dom.insertBefore(el, position); + + this.el = Ext.get(el); + this.eventEl = Ext.get(el.firstChild); + + this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), { + handler: this.showPrevMonth, + scope: this, + preventDefault:true, + stopDefault:true + }); + + this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), { + handler: this.showNextMonth, + scope: this, + preventDefault:true, + stopDefault:true + }); + + this.monthPicker = this.el.down('div.x-date-mp'); + this.monthPicker.enableDisplayMode('block'); + + this.keyNav = new Ext.KeyNav(this.eventEl, { + 'left' : function(e){ + if(e.ctrlKey){ + this.showPrevMonth(); + }else{ + this.update(this.activeDate.add('d', -1)); + } + }, + + 'right' : function(e){ + if(e.ctrlKey){ + this.showNextMonth(); + }else{ + this.update(this.activeDate.add('d', 1)); + } + }, + + 'up' : function(e){ + if(e.ctrlKey){ + this.showNextYear(); + }else{ + this.update(this.activeDate.add('d', -7)); + } + }, + + 'down' : function(e){ + if(e.ctrlKey){ + this.showPrevYear(); + }else{ + this.update(this.activeDate.add('d', 7)); + } + }, + + 'pageUp' : function(e){ + this.showNextMonth(); + }, + + 'pageDown' : function(e){ + this.showPrevMonth(); + }, + + 'enter' : function(e){ + e.stopPropagation(); + return true; + }, + + scope : this + }); + + this.el.unselectable(); + + this.cells = this.el.select('table.x-date-inner tbody td'); + this.textNodes = this.el.query('table.x-date-inner tbody span'); + + this.mbtn = new Ext.Button({ + text: ' ', + tooltip: this.monthYearText, + renderTo: this.el.child('td.x-date-middle', true) + }); + this.mbtn.el.child('em').addClass('x-btn-arrow'); + + if(this.showToday){ + this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this); + var today = (new Date()).dateFormat(this.format); + this.todayBtn = new Ext.Button({ + renderTo: this.el.child('td.x-date-bottom', true), + text: String.format(this.todayText, today), + tooltip: String.format(this.todayTip, today), + handler: this.selectToday, + scope: this + }); + } + this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this); + this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'}); + this.mon(this.mbtn, 'click', this.showMonthPicker, this); + this.onEnable(true); + }, + + + createMonthPicker : function(){ + if(!this.monthPicker.dom.firstChild){ + var buf = ['']; + for(var i = 0; i < 6; i++){ + buf.push( + '', + '', + i === 0 ? + '' : + '' + ); + } + buf.push( + '', + '
    ', Date.getShortMonthName(i), '', Date.getShortMonthName(i + 6), '
    ' + ); + this.monthPicker.update(buf.join('')); + + this.mon(this.monthPicker, 'click', this.onMonthClick, this); + this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this); + + this.mpMonths = this.monthPicker.select('td.x-date-mp-month'); + this.mpYears = this.monthPicker.select('td.x-date-mp-year'); + + this.mpMonths.each(function(m, a, i){ + i += 1; + if((i%2) === 0){ + m.dom.xmonth = 5 + Math.round(i * 0.5); + }else{ + m.dom.xmonth = Math.round((i-1) * 0.5); + } + }); + } + }, + + + showMonthPicker : function(){ + if(!this.disabled){ + this.createMonthPicker(); + var size = this.el.getSize(); + this.monthPicker.setSize(size); + this.monthPicker.child('table').setSize(size); + + this.mpSelMonth = (this.activeDate || this.value).getMonth(); + this.updateMPMonth(this.mpSelMonth); + this.mpSelYear = (this.activeDate || this.value).getFullYear(); + this.updateMPYear(this.mpSelYear); + + this.monthPicker.slideIn('t', {duration:0.2}); + } + }, + + + updateMPYear : function(y){ + this.mpyear = y; + var ys = this.mpYears.elements; + for(var i = 1; i <= 10; i++){ + var td = ys[i-1], y2; + if((i%2) === 0){ + y2 = y + Math.round(i * 0.5); + td.firstChild.innerHTML = y2; + td.xyear = y2; + }else{ + y2 = y - (5-Math.round(i * 0.5)); + td.firstChild.innerHTML = y2; + td.xyear = y2; + } + this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel'); + } + }, + + + updateMPMonth : function(sm){ + this.mpMonths.each(function(m, a, i){ + m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel'); + }); + }, + + + selectMPMonth : function(m){ + + }, + + + onMonthClick : function(e, t){ + e.stopEvent(); + var el = new Ext.Element(t), pn; + if(el.is('button.x-date-mp-cancel')){ + this.hideMonthPicker(); + } + else if(el.is('button.x-date-mp-ok')){ + var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate()); + if(d.getMonth() != this.mpSelMonth){ + + d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth(); + } + this.update(d); + this.hideMonthPicker(); + } + else if((pn = el.up('td.x-date-mp-month', 2))){ + this.mpMonths.removeClass('x-date-mp-sel'); + pn.addClass('x-date-mp-sel'); + this.mpSelMonth = pn.dom.xmonth; + } + else if((pn = el.up('td.x-date-mp-year', 2))){ + this.mpYears.removeClass('x-date-mp-sel'); + pn.addClass('x-date-mp-sel'); + this.mpSelYear = pn.dom.xyear; + } + else if(el.is('a.x-date-mp-prev')){ + this.updateMPYear(this.mpyear-10); + } + else if(el.is('a.x-date-mp-next')){ + this.updateMPYear(this.mpyear+10); + } + }, + + + onMonthDblClick : function(e, t){ + e.stopEvent(); + var el = new Ext.Element(t), pn; + if((pn = el.up('td.x-date-mp-month', 2))){ + this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate())); + this.hideMonthPicker(); + } + else if((pn = el.up('td.x-date-mp-year', 2))){ + this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate())); + this.hideMonthPicker(); + } + }, + + + hideMonthPicker : function(disableAnim){ + if(this.monthPicker){ + if(disableAnim === true){ + this.monthPicker.hide(); + }else{ + this.monthPicker.slideOut('t', {duration:0.2}); + } + } + }, + + + showPrevMonth : function(e){ + this.update(this.activeDate.add('mo', -1)); + }, + + + showNextMonth : function(e){ + this.update(this.activeDate.add('mo', 1)); + }, + + + showPrevYear : function(){ + this.update(this.activeDate.add('y', -1)); + }, + + + showNextYear : function(){ + this.update(this.activeDate.add('y', 1)); + }, + + + handleMouseWheel : function(e){ + e.stopEvent(); + if(!this.disabled){ + var delta = e.getWheelDelta(); + if(delta > 0){ + this.showPrevMonth(); + } else if(delta < 0){ + this.showNextMonth(); + } + } + }, + + + handleDateClick : function(e, t){ + e.stopEvent(); + if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){ + this.cancelFocus = this.focusOnSelect === false; + this.setValue(new Date(t.dateValue)); + delete this.cancelFocus; + this.fireEvent('select', this, this.value); + } + }, + + + selectToday : function(){ + if(this.todayBtn && !this.todayBtn.disabled){ + this.setValue(new Date().clearTime()); + this.fireEvent('select', this, this.value); + } + }, + + + update : function(date, forceRefresh){ + if(this.rendered){ + var vd = this.activeDate, vis = this.isVisible(); + this.activeDate = date; + if(!forceRefresh && vd && this.el){ + var t = date.getTime(); + if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){ + this.cells.removeClass('x-date-selected'); + this.cells.each(function(c){ + if(c.dom.firstChild.dateValue == t){ + c.addClass('x-date-selected'); + if(vis && !this.cancelFocus){ + Ext.fly(c.dom.firstChild).focus(50); + } + return false; + } + }, this); + return; + } + } + var days = date.getDaysInMonth(), + firstOfMonth = date.getFirstDateOfMonth(), + startingPos = firstOfMonth.getDay()-this.startDay; + + if(startingPos < 0){ + startingPos += 7; + } + days += startingPos; + + var pm = date.add('mo', -1), + prevStart = pm.getDaysInMonth()-startingPos, + cells = this.cells.elements, + textEls = this.textNodes, + + d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)), + today = new Date().clearTime().getTime(), + sel = date.clearTime(true).getTime(), + min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY, + max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY, + ddMatch = this.disabledDatesRE, + ddText = this.disabledDatesText, + ddays = this.disabledDays ? this.disabledDays.join('') : false, + ddaysText = this.disabledDaysText, + format = this.format; + + if(this.showToday){ + var td = new Date().clearTime(), + disable = (td < min || td > max || + (ddMatch && format && ddMatch.test(td.dateFormat(format))) || + (ddays && ddays.indexOf(td.getDay()) != -1)); + + if(!this.disabled){ + this.todayBtn.setDisabled(disable); + this.todayKeyListener[disable ? 'disable' : 'enable'](); + } + } + + var setCellClass = function(cal, cell){ + cell.title = ''; + var t = d.clearTime(true).getTime(); + cell.firstChild.dateValue = t; + if(t == today){ + cell.className += ' x-date-today'; + cell.title = cal.todayText; + } + if(t == sel){ + cell.className += ' x-date-selected'; + if(vis){ + Ext.fly(cell.firstChild).focus(50); + } + } + + if(t < min) { + cell.className = ' x-date-disabled'; + cell.title = cal.minText; + return; + } + if(t > max) { + cell.className = ' x-date-disabled'; + cell.title = cal.maxText; + return; + } + if(ddays){ + if(ddays.indexOf(d.getDay()) != -1){ + cell.title = ddaysText; + cell.className = ' x-date-disabled'; + } + } + if(ddMatch && format){ + var fvalue = d.dateFormat(format); + if(ddMatch.test(fvalue)){ + cell.title = ddText.replace('%0', fvalue); + cell.className = ' x-date-disabled'; + } + } + }; + + var i = 0; + for(; i < startingPos; i++) { + textEls[i].innerHTML = (++prevStart); + d.setDate(d.getDate()+1); + cells[i].className = 'x-date-prevday'; + setCellClass(this, cells[i]); + } + for(; i < days; i++){ + var intDay = i - startingPos + 1; + textEls[i].innerHTML = (intDay); + d.setDate(d.getDate()+1); + cells[i].className = 'x-date-active'; + setCellClass(this, cells[i]); + } + var extraDays = 0; + for(; i < 42; i++) { + textEls[i].innerHTML = (++extraDays); + d.setDate(d.getDate()+1); + cells[i].className = 'x-date-nextday'; + setCellClass(this, cells[i]); + } + + this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear()); + + if(!this.internalRender){ + var main = this.el.dom.firstChild, + w = main.offsetWidth; + this.el.setWidth(w + this.el.getBorderWidth('lr')); + Ext.fly(main).setWidth(w); + this.internalRender = true; + + + + if(Ext.isOpera && !this.secondPass){ + main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px'; + this.secondPass = true; + this.update.defer(10, this, [date]); + } + } + } + }, + + + beforeDestroy : function() { + if(this.rendered){ + Ext.destroy( + this.keyNav, + this.monthPicker, + this.eventEl, + this.mbtn, + this.nextRepeater, + this.prevRepeater, + this.cells.el, + this.todayBtn + ); + delete this.textNodes; + delete this.cells.elements; + } + } + + +}); + +Ext.reg('datepicker', Ext.DatePicker); + +Ext.LoadMask = function(el, config){ + this.el = Ext.get(el); + Ext.apply(this, config); + if(this.store){ + this.store.on({ + scope: this, + beforeload: this.onBeforeLoad, + load: this.onLoad, + exception: this.onLoad + }); + this.removeMask = Ext.value(this.removeMask, false); + }else{ + var um = this.el.getUpdater(); + um.showLoadIndicator = false; + um.on({ + scope: this, + beforeupdate: this.onBeforeLoad, + update: this.onLoad, + failure: this.onLoad + }); + this.removeMask = Ext.value(this.removeMask, true); + } +}; + +Ext.LoadMask.prototype = { + + + + msg : 'Loading...', + + msgCls : 'x-mask-loading', + + + disabled: false, + + + disable : function(){ + this.disabled = true; + }, + + + enable : function(){ + this.disabled = false; + }, + + + onLoad : function(){ + this.el.unmask(this.removeMask); + }, + + + onBeforeLoad : function(){ + if(!this.disabled){ + this.el.mask(this.msg, this.msgCls); + } + }, + + + show: function(){ + this.onBeforeLoad(); + }, + + + hide: function(){ + this.onLoad(); + }, + + + destroy : function(){ + if(this.store){ + this.store.un('beforeload', this.onBeforeLoad, this); + this.store.un('load', this.onLoad, this); + this.store.un('exception', this.onLoad, this); + }else{ + var um = this.el.getUpdater(); + um.un('beforeupdate', this.onBeforeLoad, this); + um.un('update', this.onLoad, this); + um.un('failure', this.onLoad, this); + } + } +}; +Ext.slider.Thumb = Ext.extend(Object, { + + + dragging: false, + + + constructor: function(config) { + + Ext.apply(this, config || {}, { + cls: 'x-slider-thumb', + + + constrain: false + }); + + Ext.slider.Thumb.superclass.constructor.call(this, config); + + if (this.slider.vertical) { + Ext.apply(this, Ext.slider.Thumb.Vertical); + } + }, + + + render: function() { + this.el = this.slider.innerEl.insertFirst({cls: this.cls}); + + this.initEvents(); + }, + + + enable: function() { + this.disabled = false; + this.el.removeClass(this.slider.disabledClass); + }, + + + disable: function() { + this.disabled = true; + this.el.addClass(this.slider.disabledClass); + }, + + + initEvents: function() { + var el = this.el; + + el.addClassOnOver('x-slider-thumb-over'); + + this.tracker = new Ext.dd.DragTracker({ + onBeforeStart: this.onBeforeDragStart.createDelegate(this), + onStart : this.onDragStart.createDelegate(this), + onDrag : this.onDrag.createDelegate(this), + onEnd : this.onDragEnd.createDelegate(this), + tolerance : 3, + autoStart : 300 + }); + + this.tracker.initEl(el); + }, + + + onBeforeDragStart : function(e) { + if (this.disabled) { + return false; + } else { + this.slider.promoteThumb(this); + return true; + } + }, + + + onDragStart: function(e){ + this.el.addClass('x-slider-thumb-drag'); + this.dragging = true; + this.dragStartValue = this.value; + + this.slider.fireEvent('dragstart', this.slider, e, this); + }, + + + onDrag: function(e) { + var slider = this.slider, + index = this.index, + newValue = this.getNewValue(); + + if (this.constrain) { + var above = slider.thumbs[index + 1], + below = slider.thumbs[index - 1]; + + if (below != undefined && newValue <= below.value) newValue = below.value; + if (above != undefined && newValue >= above.value) newValue = above.value; + } + + slider.setValue(index, newValue, false); + slider.fireEvent('drag', slider, e, this); + }, + + getNewValue: function() { + var slider = this.slider, + pos = slider.innerEl.translatePoints(this.tracker.getXY()); + + return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision); + }, + + + onDragEnd: function(e) { + var slider = this.slider, + value = this.value; + + this.el.removeClass('x-slider-thumb-drag'); + + this.dragging = false; + slider.fireEvent('dragend', slider, e); + + if (this.dragStartValue != value) { + slider.fireEvent('changecomplete', slider, value, this); + } + }, + + + destroy: function(){ + Ext.destroyMembers(this, 'tracker', 'el'); + } +}); + + +Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, { + + + vertical: false, + + minValue: 0, + + maxValue: 100, + + decimalPrecision: 0, + + keyIncrement: 1, + + increment: 0, + + + clickRange: [5,15], + + + clickToChange : true, + + animate: true, + + constrainThumbs: true, + + + topThumbZIndex: 10000, + + + initComponent : function(){ + if(!Ext.isDefined(this.value)){ + this.value = this.minValue; + } + + + this.thumbs = []; + + Ext.slider.MultiSlider.superclass.initComponent.call(this); + + this.keyIncrement = Math.max(this.increment, this.keyIncrement); + this.addEvents( + + 'beforechange', + + + 'change', + + + 'changecomplete', + + + 'dragstart', + + + 'drag', + + + 'dragend' + ); + + + if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0]; + + var values = this.values; + + for (var i=0; i < values.length; i++) { + this.addThumb(values[i]); + } + + if(this.vertical){ + Ext.apply(this, Ext.slider.Vertical); + } + }, + + + addThumb: function(value) { + var thumb = new Ext.slider.Thumb({ + value : value, + slider : this, + index : this.thumbs.length, + constrain: this.constrainThumbs + }); + this.thumbs.push(thumb); + + + if (this.rendered) thumb.render(); + }, + + + promoteThumb: function(topThumb) { + var thumbs = this.thumbs, + zIndex, thumb; + + for (var i = 0, j = thumbs.length; i < j; i++) { + thumb = thumbs[i]; + + if (thumb == topThumb) { + zIndex = this.topThumbZIndex; + } else { + zIndex = ''; + } + + thumb.el.setStyle('zIndex', zIndex); + } + }, + + + onRender : function() { + this.autoEl = { + cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'), + cn : { + cls: 'x-slider-end', + cn : { + cls:'x-slider-inner', + cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}] + } + } + }; + + Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments); + + this.endEl = this.el.first(); + this.innerEl = this.endEl.first(); + this.focusEl = this.innerEl.child('.x-slider-focus'); + + + for (var i=0; i < this.thumbs.length; i++) { + this.thumbs[i].render(); + } + + + var thumb = this.innerEl.child('.x-slider-thumb'); + this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2; + + this.initEvents(); + }, + + + initEvents : function(){ + this.mon(this.el, { + scope : this, + mousedown: this.onMouseDown, + keydown : this.onKeyDown + }); + + this.focusEl.swallowEvent("click", true); + }, + + + onMouseDown : function(e){ + if(this.disabled){ + return; + } + + + var thumbClicked = false; + for (var i=0; i < this.thumbs.length; i++) { + thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom; + } + + if (this.clickToChange && !thumbClicked) { + var local = this.innerEl.translatePoints(e.getXY()); + this.onClickChange(local); + } + this.focus(); + }, + + + onClickChange : function(local) { + if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) { + + var thumb = this.getNearest(local, 'left'), + index = thumb.index; + + this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true); + } + }, + + + getNearest: function(local, prop) { + var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop], + clickValue = this.reverseValue(localValue), + nearestDistance = (this.maxValue - this.minValue) + 5, + index = 0, + nearest = null; + + for (var i=0; i < this.thumbs.length; i++) { + var thumb = this.thumbs[i], + value = thumb.value, + dist = Math.abs(value - clickValue); + + if (Math.abs(dist <= nearestDistance)) { + nearest = thumb; + index = i; + nearestDistance = dist; + } + } + return nearest; + }, + + + onKeyDown : function(e){ + + if(this.disabled || this.thumbs.length !== 1){ + e.preventDefault(); + return; + } + var k = e.getKey(), + val; + switch(k){ + case e.UP: + case e.RIGHT: + e.stopEvent(); + val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement; + this.setValue(0, val, undefined, true); + break; + case e.DOWN: + case e.LEFT: + e.stopEvent(); + val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement; + this.setValue(0, val, undefined, true); + break; + default: + e.preventDefault(); + } + }, + + + doSnap : function(value){ + if (!(this.increment && value)) { + return value; + } + var newValue = value, + inc = this.increment, + m = value % inc; + if (m != 0) { + newValue -= m; + if (m * 2 >= inc) { + newValue += inc; + } else if (m * 2 < -inc) { + newValue -= inc; + } + } + return newValue.constrain(this.minValue, this.maxValue); + }, + + + afterRender : function(){ + Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments); + + for (var i=0; i < this.thumbs.length; i++) { + var thumb = this.thumbs[i]; + + if (thumb.value !== undefined) { + var v = this.normalizeValue(thumb.value); + + if (v !== thumb.value) { + + this.setValue(i, v, false); + } else { + this.moveThumb(i, this.translateValue(v), false); + } + } + }; + }, + + + getRatio : function(){ + var w = this.innerEl.getWidth(), + v = this.maxValue - this.minValue; + return v == 0 ? w : (w/v); + }, + + + normalizeValue : function(v){ + v = this.doSnap(v); + v = Ext.util.Format.round(v, this.decimalPrecision); + v = v.constrain(this.minValue, this.maxValue); + return v; + }, + + + setMinValue : function(val){ + this.minValue = val; + var i = 0, + thumbs = this.thumbs, + len = thumbs.length, + t; + + for(; i < len; ++i){ + t = thumbs[i]; + t.value = t.value < val ? val : t.value; + } + this.syncThumb(); + }, + + + setMaxValue : function(val){ + this.maxValue = val; + var i = 0, + thumbs = this.thumbs, + len = thumbs.length, + t; + + for(; i < len; ++i){ + t = thumbs[i]; + t.value = t.value > val ? val : t.value; + } + this.syncThumb(); + }, + + + setValue : function(index, v, animate, changeComplete) { + var thumb = this.thumbs[index], + el = thumb.el; + + v = this.normalizeValue(v); + + if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) { + thumb.value = v; + if(this.rendered){ + this.moveThumb(index, this.translateValue(v), animate !== false); + this.fireEvent('change', this, v, thumb); + if(changeComplete){ + this.fireEvent('changecomplete', this, v, thumb); + } + } + } + }, + + + translateValue : function(v) { + var ratio = this.getRatio(); + return (v * ratio) - (this.minValue * ratio) - this.halfThumb; + }, + + + reverseValue : function(pos){ + var ratio = this.getRatio(); + return (pos + (this.minValue * ratio)) / ratio; + }, + + + moveThumb: function(index, v, animate){ + var thumb = this.thumbs[index].el; + + if(!animate || this.animate === false){ + thumb.setLeft(v); + }else{ + thumb.shift({left: v, stopFx: true, duration:.35}); + } + }, + + + focus : function(){ + this.focusEl.focus(10); + }, + + + onResize : function(w, h){ + var thumbs = this.thumbs, + len = thumbs.length, + i = 0; + + + for(; i < len; ++i){ + thumbs[i].el.stopFx(); + } + + if(Ext.isNumber(w)){ + this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r'))); + } + this.syncThumb(); + Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments); + }, + + + onDisable: function(){ + Ext.slider.MultiSlider.superclass.onDisable.call(this); + + for (var i=0; i < this.thumbs.length; i++) { + var thumb = this.thumbs[i], + el = thumb.el; + + thumb.disable(); + + if(Ext.isIE){ + + + var xy = el.getXY(); + el.hide(); + + this.innerEl.addClass(this.disabledClass).dom.disabled = true; + + if (!this.thumbHolder) { + this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass}); + } + + this.thumbHolder.show().setXY(xy); + } + } + }, + + + onEnable: function(){ + Ext.slider.MultiSlider.superclass.onEnable.call(this); + + for (var i=0; i < this.thumbs.length; i++) { + var thumb = this.thumbs[i], + el = thumb.el; + + thumb.enable(); + + if (Ext.isIE) { + this.innerEl.removeClass(this.disabledClass).dom.disabled = false; + + if (this.thumbHolder) this.thumbHolder.hide(); + + el.show(); + this.syncThumb(); + } + } + }, + + + syncThumb : function() { + if (this.rendered) { + for (var i=0; i < this.thumbs.length; i++) { + this.moveThumb(i, this.translateValue(this.thumbs[i].value)); + } + } + }, + + + getValue : function(index) { + return this.thumbs[index].value; + }, + + + getValues: function() { + var values = []; + + for (var i=0; i < this.thumbs.length; i++) { + values.push(this.thumbs[i].value); + } + + return values; + }, + + + beforeDestroy : function(){ + var thumbs = this.thumbs; + for(var i = 0, len = thumbs.length; i < len; ++i){ + thumbs[i].destroy(); + thumbs[i] = null; + } + Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder'); + Ext.slider.MultiSlider.superclass.beforeDestroy.call(this); + } +}); + +Ext.reg('multislider', Ext.slider.MultiSlider); + + +Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, { + constructor: function(config) { + config = config || {}; + + Ext.applyIf(config, { + values: [config.value || 0] + }); + + Ext.slider.SingleSlider.superclass.constructor.call(this, config); + }, + + + getValue: function() { + + return Ext.slider.SingleSlider.superclass.getValue.call(this, 0); + }, + + + setValue: function(value, animate) { + var args = Ext.toArray(arguments), + len = args.length; + + + + + if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) { + args.unshift(0); + } + + return Ext.slider.SingleSlider.superclass.setValue.apply(this, args); + }, + + + syncThumb : function() { + return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments)); + }, + + + getNearest : function(){ + + return this.thumbs[0]; + } +}); + + +Ext.Slider = Ext.slider.SingleSlider; + +Ext.reg('slider', Ext.slider.SingleSlider); + + +Ext.slider.Vertical = { + onResize : function(w, h){ + this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b'))); + this.syncThumb(); + }, + + getRatio : function(){ + var h = this.innerEl.getHeight(), + v = this.maxValue - this.minValue; + return h/v; + }, + + moveThumb: function(index, v, animate) { + var thumb = this.thumbs[index], + el = thumb.el; + + if (!animate || this.animate === false) { + el.setBottom(v); + } else { + el.shift({bottom: v, stopFx: true, duration:.35}); + } + }, + + onClickChange : function(local) { + if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) { + var thumb = this.getNearest(local, 'top'), + index = thumb.index, + value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top); + + this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true); + } + } +}; + + +Ext.slider.Thumb.Vertical = { + getNewValue: function() { + var slider = this.slider, + innerEl = slider.innerEl, + pos = innerEl.translatePoints(this.tracker.getXY()), + bottom = innerEl.getHeight() - pos.top; + + return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision); + } +}; + +Ext.ProgressBar = Ext.extend(Ext.BoxComponent, { + + baseCls : 'x-progress', + + + animate : false, + + + waitTimer : null, + + + initComponent : function(){ + Ext.ProgressBar.superclass.initComponent.call(this); + this.addEvents( + + "update" + ); + }, + + + onRender : function(ct, position){ + var tpl = new Ext.Template( + '
    ', + '
    ', + '
    ', + '
    ', + '
     
    ', + '
    ', + '
    ', + '
    ', + '
     
    ', + '
    ', + '
    ', + '
    ' + ); + + this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true) + : tpl.append(ct, {cls: this.baseCls}, true); + + if(this.id){ + this.el.dom.id = this.id; + } + var inner = this.el.dom.firstChild; + this.progressBar = Ext.get(inner.firstChild); + + if(this.textEl){ + + this.textEl = Ext.get(this.textEl); + delete this.textTopEl; + }else{ + + this.textTopEl = Ext.get(this.progressBar.dom.firstChild); + var textBackEl = Ext.get(inner.childNodes[1]); + this.textTopEl.setStyle("z-index", 99).addClass('x-hidden'); + this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]); + this.textEl.setWidth(inner.offsetWidth); + } + this.progressBar.setHeight(inner.offsetHeight); + }, + + + afterRender : function(){ + Ext.ProgressBar.superclass.afterRender.call(this); + if(this.value){ + this.updateProgress(this.value, this.text); + }else{ + this.updateText(this.text); + } + }, + + + updateProgress : function(value, text, animate){ + this.value = value || 0; + if(text){ + this.updateText(text); + } + if(this.rendered && !this.isDestroyed){ + var w = Math.floor(value*this.el.dom.firstChild.offsetWidth); + this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate)); + if(this.textTopEl){ + + this.textTopEl.removeClass('x-hidden').setWidth(w); + } + } + this.fireEvent('update', this, value, text); + return this; + }, + + + wait : function(o){ + if(!this.waitTimer){ + var scope = this; + o = o || {}; + this.updateText(o.text); + this.waitTimer = Ext.TaskMgr.start({ + run: function(i){ + var inc = o.increment || 10; + i -= 1; + this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate); + }, + interval: o.interval || 1000, + duration: o.duration, + onStop: function(){ + if(o.fn){ + o.fn.apply(o.scope || this); + } + this.reset(); + }, + scope: scope + }); + } + return this; + }, + + + isWaiting : function(){ + return this.waitTimer !== null; + }, + + + updateText : function(text){ + this.text = text || ' '; + if(this.rendered){ + this.textEl.update(this.text); + } + return this; + }, + + + syncProgressBar : function(){ + if(this.value){ + this.updateProgress(this.value, this.text); + } + return this; + }, + + + setSize : function(w, h){ + Ext.ProgressBar.superclass.setSize.call(this, w, h); + if(this.textTopEl){ + var inner = this.el.dom.firstChild; + this.textEl.setSize(inner.offsetWidth, inner.offsetHeight); + } + this.syncProgressBar(); + return this; + }, + + + reset : function(hide){ + this.updateProgress(0); + if(this.textTopEl){ + this.textTopEl.addClass('x-hidden'); + } + this.clearTimer(); + if(hide === true){ + this.hide(); + } + return this; + }, + + + clearTimer : function(){ + if(this.waitTimer){ + this.waitTimer.onStop = null; + Ext.TaskMgr.stop(this.waitTimer); + this.waitTimer = null; + } + }, + + onDestroy: function(){ + this.clearTimer(); + if(this.rendered){ + if(this.textEl.isComposite){ + this.textEl.clear(); + } + Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl'); + } + Ext.ProgressBar.superclass.onDestroy.call(this); + } +}); +Ext.reg('progress', Ext.ProgressBar); + +(function() { + +var Event=Ext.EventManager; +var Dom=Ext.lib.Dom; + + +Ext.dd.DragDrop = function(id, sGroup, config) { + if(id) { + this.init(id, sGroup, config); + } +}; + +Ext.dd.DragDrop.prototype = { + + + + + id: null, + + + config: null, + + + dragElId: null, + + + handleElId: null, + + + invalidHandleTypes: null, + + + invalidHandleIds: null, + + + invalidHandleClasses: null, + + + startPageX: 0, + + + startPageY: 0, + + + groups: null, + + + locked: false, + + + lock: function() { + this.locked = true; + }, + + + moveOnly: false, + + + unlock: function() { + this.locked = false; + }, + + + isTarget: true, + + + padding: null, + + + _domRef: null, + + + __ygDragDrop: true, + + + constrainX: false, + + + constrainY: false, + + + minX: 0, + + + maxX: 0, + + + minY: 0, + + + maxY: 0, + + + maintainOffset: false, + + + xTicks: null, + + + yTicks: null, + + + primaryButtonOnly: true, + + + available: false, + + + hasOuterHandles: false, + + + b4StartDrag: function(x, y) { }, + + + startDrag: function(x, y) { }, + + + b4Drag: function(e) { }, + + + onDrag: function(e) { }, + + + onDragEnter: function(e, id) { }, + + + b4DragOver: function(e) { }, + + + onDragOver: function(e, id) { }, + + + b4DragOut: function(e) { }, + + + onDragOut: function(e, id) { }, + + + b4DragDrop: function(e) { }, + + + onDragDrop: function(e, id) { }, + + + onInvalidDrop: function(e) { }, + + + b4EndDrag: function(e) { }, + + + endDrag: function(e) { }, + + + b4MouseDown: function(e) { }, + + + onMouseDown: function(e) { }, + + + onMouseUp: function(e) { }, + + + onAvailable: function () { + }, + + + defaultPadding : {left:0, right:0, top:0, bottom:0}, + + + constrainTo : function(constrainTo, pad, inContent){ + if(Ext.isNumber(pad)){ + pad = {left: pad, right:pad, top:pad, bottom:pad}; + } + pad = pad || this.defaultPadding; + var b = Ext.get(this.getEl()).getBox(), + ce = Ext.get(constrainTo), + s = ce.getScroll(), + c, + cd = ce.dom; + if(cd == document.body){ + c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()}; + }else{ + var xy = ce.getXY(); + c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight}; + } + + + var topSpace = b.y - c.y, + leftSpace = b.x - c.x; + + this.resetConstraints(); + this.setXConstraint(leftSpace - (pad.left||0), + c.width - leftSpace - b.width - (pad.right||0), + this.xTickSize + ); + this.setYConstraint(topSpace - (pad.top||0), + c.height - topSpace - b.height - (pad.bottom||0), + this.yTickSize + ); + }, + + + getEl: function() { + if (!this._domRef) { + this._domRef = Ext.getDom(this.id); + } + + return this._domRef; + }, + + + getDragEl: function() { + return Ext.getDom(this.dragElId); + }, + + + init: function(id, sGroup, config) { + this.initTarget(id, sGroup, config); + Event.on(this.id, "mousedown", this.handleMouseDown, this); + + }, + + + initTarget: function(id, sGroup, config) { + + + this.config = config || {}; + + + this.DDM = Ext.dd.DDM; + + this.groups = {}; + + + + if (typeof id !== "string") { + id = Ext.id(id); + } + + + this.id = id; + + + this.addToGroup((sGroup) ? sGroup : "default"); + + + + this.handleElId = id; + + + this.setDragElId(id); + + + this.invalidHandleTypes = { A: "A" }; + this.invalidHandleIds = {}; + this.invalidHandleClasses = []; + + this.applyConfig(); + + this.handleOnAvailable(); + }, + + + applyConfig: function() { + + + + this.padding = this.config.padding || [0, 0, 0, 0]; + this.isTarget = (this.config.isTarget !== false); + this.maintainOffset = (this.config.maintainOffset); + this.primaryButtonOnly = (this.config.primaryButtonOnly !== false); + + }, + + + handleOnAvailable: function() { + this.available = true; + this.resetConstraints(); + this.onAvailable(); + }, + + + setPadding: function(iTop, iRight, iBot, iLeft) { + + if (!iRight && 0 !== iRight) { + this.padding = [iTop, iTop, iTop, iTop]; + } else if (!iBot && 0 !== iBot) { + this.padding = [iTop, iRight, iTop, iRight]; + } else { + this.padding = [iTop, iRight, iBot, iLeft]; + } + }, + + + setInitPosition: function(diffX, diffY) { + var el = this.getEl(); + + if (!this.DDM.verifyEl(el)) { + return; + } + + var dx = diffX || 0; + var dy = diffY || 0; + + var p = Dom.getXY( el ); + + this.initPageX = p[0] - dx; + this.initPageY = p[1] - dy; + + this.lastPageX = p[0]; + this.lastPageY = p[1]; + + this.setStartPosition(p); + }, + + + setStartPosition: function(pos) { + var p = pos || Dom.getXY( this.getEl() ); + this.deltaSetXY = null; + + this.startPageX = p[0]; + this.startPageY = p[1]; + }, + + + addToGroup: function(sGroup) { + this.groups[sGroup] = true; + this.DDM.regDragDrop(this, sGroup); + }, + + + removeFromGroup: function(sGroup) { + if (this.groups[sGroup]) { + delete this.groups[sGroup]; + } + + this.DDM.removeDDFromGroup(this, sGroup); + }, + + + setDragElId: function(id) { + this.dragElId = id; + }, + + + setHandleElId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + this.handleElId = id; + this.DDM.regHandle(this.id, id); + }, + + + setOuterHandleElId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + Event.on(id, "mousedown", + this.handleMouseDown, this); + this.setHandleElId(id); + + this.hasOuterHandles = true; + }, + + + unreg: function() { + Event.un(this.id, "mousedown", + this.handleMouseDown); + this._domRef = null; + this.DDM._remove(this); + }, + + destroy : function(){ + this.unreg(); + }, + + + isLocked: function() { + return (this.DDM.isLocked() || this.locked); + }, + + + handleMouseDown: function(e, oDD){ + if (this.primaryButtonOnly && e.button != 0) { + return; + } + + if (this.isLocked()) { + return; + } + + this.DDM.refreshCache(this.groups); + + var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e)); + if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) { + } else { + if (this.clickValidator(e)) { + + + this.setStartPosition(); + + this.b4MouseDown(e); + this.onMouseDown(e); + + this.DDM.handleMouseDown(e, this); + + if (this.preventDefault || this.stopPropagation) { + if (this.preventDefault) { + e.preventDefault(); + } + if (this.stopPropagation) { + e.stopPropagation(); + } + } else { + this.DDM.stopEvent(e); + } + } else { + + + } + } + }, + + clickValidator: function(e) { + var target = e.getTarget(); + return ( this.isValidHandleChild(target) && + (this.id == this.handleElId || + this.DDM.handleWasClicked(target, this.id)) ); + }, + + + addInvalidHandleType: function(tagName) { + var type = tagName.toUpperCase(); + this.invalidHandleTypes[type] = type; + }, + + + addInvalidHandleId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + this.invalidHandleIds[id] = id; + }, + + + addInvalidHandleClass: function(cssClass) { + this.invalidHandleClasses.push(cssClass); + }, + + + removeInvalidHandleType: function(tagName) { + var type = tagName.toUpperCase(); + + delete this.invalidHandleTypes[type]; + }, + + + removeInvalidHandleId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + delete this.invalidHandleIds[id]; + }, + + + removeInvalidHandleClass: function(cssClass) { + for (var i=0, len=this.invalidHandleClasses.length; i= this.minX; i = i - iTickSize) { + if (!tickMap[i]) { + this.xTicks[this.xTicks.length] = i; + tickMap[i] = true; + } + } + + for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) { + if (!tickMap[i]) { + this.xTicks[this.xTicks.length] = i; + tickMap[i] = true; + } + } + + this.xTicks.sort(this.DDM.numericSort) ; + }, + + + setYTicks: function(iStartY, iTickSize) { + this.yTicks = []; + this.yTickSize = iTickSize; + + var tickMap = {}; + + for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) { + if (!tickMap[i]) { + this.yTicks[this.yTicks.length] = i; + tickMap[i] = true; + } + } + + for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) { + if (!tickMap[i]) { + this.yTicks[this.yTicks.length] = i; + tickMap[i] = true; + } + } + + this.yTicks.sort(this.DDM.numericSort) ; + }, + + + setXConstraint: function(iLeft, iRight, iTickSize) { + this.leftConstraint = iLeft; + this.rightConstraint = iRight; + + this.minX = this.initPageX - iLeft; + this.maxX = this.initPageX + iRight; + if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); } + + this.constrainX = true; + }, + + + clearConstraints: function() { + this.constrainX = false; + this.constrainY = false; + this.clearTicks(); + }, + + + clearTicks: function() { + this.xTicks = null; + this.yTicks = null; + this.xTickSize = 0; + this.yTickSize = 0; + }, + + + setYConstraint: function(iUp, iDown, iTickSize) { + this.topConstraint = iUp; + this.bottomConstraint = iDown; + + this.minY = this.initPageY - iUp; + this.maxY = this.initPageY + iDown; + if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); } + + this.constrainY = true; + + }, + + + resetConstraints: function() { + + if (this.initPageX || this.initPageX === 0) { + + var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0; + var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0; + + this.setInitPosition(dx, dy); + + + } else { + this.setInitPosition(); + } + + if (this.constrainX) { + this.setXConstraint( this.leftConstraint, + this.rightConstraint, + this.xTickSize ); + } + + if (this.constrainY) { + this.setYConstraint( this.topConstraint, + this.bottomConstraint, + this.yTickSize ); + } + }, + + + getTick: function(val, tickArray) { + if (!tickArray) { + + + return val; + } else if (tickArray[0] >= val) { + + + return tickArray[0]; + } else { + for (var i=0, len=tickArray.length; i= val) { + var diff1 = val - tickArray[i]; + var diff2 = tickArray[next] - val; + return (diff2 > diff1) ? tickArray[i] : tickArray[next]; + } + } + + + + return tickArray[tickArray.length - 1]; + } + }, + + + toString: function() { + return ("DragDrop " + this.id); + } + +}; + +})(); + + + + +if (!Ext.dd.DragDropMgr) { + + +Ext.dd.DragDropMgr = function() { + + var Event = Ext.EventManager; + + return { + + + ids: {}, + + + handleIds: {}, + + + dragCurrent: null, + + + dragOvers: {}, + + + deltaX: 0, + + + deltaY: 0, + + + preventDefault: true, + + + stopPropagation: true, + + + initialized: false, + + + locked: false, + + + init: function() { + this.initialized = true; + }, + + + POINT: 0, + + + INTERSECT: 1, + + + mode: 0, + + + notifyOccluded: false, + + + _execOnAll: function(sMethod, args) { + for (var i in this.ids) { + for (var j in this.ids[i]) { + var oDD = this.ids[i][j]; + if (! this.isTypeOfDD(oDD)) { + continue; + } + oDD[sMethod].apply(oDD, args); + } + } + }, + + + _onLoad: function() { + + this.init(); + + + Event.on(document, "mouseup", this.handleMouseUp, this, true); + Event.on(document, "mousemove", this.handleMouseMove, this, true); + Event.on(window, "unload", this._onUnload, this, true); + Event.on(window, "resize", this._onResize, this, true); + + + }, + + + _onResize: function(e) { + this._execOnAll("resetConstraints", []); + }, + + + lock: function() { this.locked = true; }, + + + unlock: function() { this.locked = false; }, + + + isLocked: function() { return this.locked; }, + + + locationCache: {}, + + + useCache: true, + + + clickPixelThresh: 3, + + + clickTimeThresh: 350, + + + dragThreshMet: false, + + + clickTimeout: null, + + + startX: 0, + + + startY: 0, + + + regDragDrop: function(oDD, sGroup) { + if (!this.initialized) { this.init(); } + + if (!this.ids[sGroup]) { + this.ids[sGroup] = {}; + } + this.ids[sGroup][oDD.id] = oDD; + }, + + + removeDDFromGroup: function(oDD, sGroup) { + if (!this.ids[sGroup]) { + this.ids[sGroup] = {}; + } + + var obj = this.ids[sGroup]; + if (obj && obj[oDD.id]) { + delete obj[oDD.id]; + } + }, + + + _remove: function(oDD) { + for (var g in oDD.groups) { + if (g && this.ids[g] && this.ids[g][oDD.id]) { + delete this.ids[g][oDD.id]; + } + } + delete this.handleIds[oDD.id]; + }, + + + regHandle: function(sDDId, sHandleId) { + if (!this.handleIds[sDDId]) { + this.handleIds[sDDId] = {}; + } + this.handleIds[sDDId][sHandleId] = sHandleId; + }, + + + isDragDrop: function(id) { + return ( this.getDDById(id) ) ? true : false; + }, + + + getRelated: function(p_oDD, bTargetsOnly) { + var oDDs = []; + for (var i in p_oDD.groups) { + for (var j in this.ids[i]) { + var dd = this.ids[i][j]; + if (! this.isTypeOfDD(dd)) { + continue; + } + if (!bTargetsOnly || dd.isTarget) { + oDDs[oDDs.length] = dd; + } + } + } + + return oDDs; + }, + + + isLegalTarget: function (oDD, oTargetDD) { + var targets = this.getRelated(oDD, true); + for (var i=0, len=targets.length;i this.clickPixelThresh || + diffY > this.clickPixelThresh) { + this.startDrag(this.startX, this.startY); + } + } + + if (this.dragThreshMet) { + this.dragCurrent.b4Drag(e); + this.dragCurrent.onDrag(e); + if(!this.dragCurrent.moveOnly){ + this.fireEvents(e, false); + } + } + + this.stopEvent(e); + + return true; + }, + + + fireEvents: function(e, isDrop) { + var me = this, + dragCurrent = me.dragCurrent, + mousePoint = e.getPoint(), + overTarget, + overTargetEl, + allTargets = [], + oldOvers = [], + outEvts = [], + overEvts = [], + dropEvts = [], + enterEvts = [], + needsSort, + i, + len, + sGroup; + + + + if (!dragCurrent || dragCurrent.isLocked()) { + return; + } + + + + for (i in me.dragOvers) { + overTarget = me.dragOvers[i]; + + if (! me.isTypeOfDD(overTarget)) { + continue; + } + + if (! this.isOverTarget(mousePoint, overTarget, me.mode)) { + outEvts.push( overTarget ); + } + + oldOvers[i] = true; + delete me.dragOvers[i]; + } + + + + + for (sGroup in dragCurrent.groups) { + + if ("string" != typeof sGroup) { + continue; + } + + + for (i in me.ids[sGroup]) { + overTarget = me.ids[sGroup][i]; + + + + + + + if (me.isTypeOfDD(overTarget) && + (overTargetEl = overTarget.getEl()) && + (overTarget.isTarget) && + (!overTarget.isLocked()) && + ((overTarget != dragCurrent) || (dragCurrent.ignoreSelf === false))) { + + + if ((overTarget.zIndex = me.getZIndex(overTargetEl)) !== -1) { + needsSort = true; + } + allTargets.push(overTarget); + } + } + } + + + if (needsSort) { + allTargets.sort(me.byZIndex); + } + + + + for (i = 0, len = allTargets.length; i < len; i++) { + overTarget = allTargets[i]; + + + if (me.isOverTarget(mousePoint, overTarget, me.mode)) { + + if (isDrop) { + dropEvts.push( overTarget ); + + } else { + + if (!oldOvers[overTarget.id]) { + enterEvts.push( overTarget ); + + } else { + overEvts.push( overTarget ); + } + me.dragOvers[overTarget.id] = overTarget; + } + + + if (!me.notifyOccluded) { + break; + } + } + } + + if (me.mode) { + if (outEvts.length) { + dragCurrent.b4DragOut(e, outEvts); + dragCurrent.onDragOut(e, outEvts); + } + + if (enterEvts.length) { + dragCurrent.onDragEnter(e, enterEvts); + } + + if (overEvts.length) { + dragCurrent.b4DragOver(e, overEvts); + dragCurrent.onDragOver(e, overEvts); + } + + if (dropEvts.length) { + dragCurrent.b4DragDrop(e, dropEvts); + dragCurrent.onDragDrop(e, dropEvts); + } + + } else { + + for (i=0, len=outEvts.length; i 2000) { + } else { + setTimeout(DDM._addListeners, 10); + if (document && document.body) { + DDM._timeoutCount += 1; + } + } + } + }, + + + handleWasClicked: function(node, id) { + if (this.isHandle(id, node.id)) { + return true; + } else { + + var p = node.parentNode; + + while (p) { + if (this.isHandle(id, p.id)) { + return true; + } else { + p = p.parentNode; + } + } + } + + return false; + } + + }; + +}(); + + +Ext.dd.DDM = Ext.dd.DragDropMgr; +Ext.dd.DDM._addListeners(); + +} + + +Ext.dd.DD = function(id, sGroup, config) { + if (id) { + this.init(id, sGroup, config); + } +}; + +Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, { + + + scroll: true, + + + autoOffset: function(iPageX, iPageY) { + var x = iPageX - this.startPageX; + var y = iPageY - this.startPageY; + this.setDelta(x, y); + }, + + + setDelta: function(iDeltaX, iDeltaY) { + this.deltaX = iDeltaX; + this.deltaY = iDeltaY; + }, + + + setDragElPos: function(iPageX, iPageY) { + + + + var el = this.getDragEl(); + this.alignElWithMouse(el, iPageX, iPageY); + }, + + + alignElWithMouse: function(el, iPageX, iPageY) { + var oCoord = this.getTargetCoord(iPageX, iPageY); + var fly = el.dom ? el : Ext.fly(el, '_dd'); + if (!this.deltaSetXY) { + var aCoord = [oCoord.x, oCoord.y]; + fly.setXY(aCoord); + var newLeft = fly.getLeft(true); + var newTop = fly.getTop(true); + this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ]; + } else { + fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]); + } + + this.cachePosition(oCoord.x, oCoord.y); + this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth); + return oCoord; + }, + + + cachePosition: function(iPageX, iPageY) { + if (iPageX) { + this.lastPageX = iPageX; + this.lastPageY = iPageY; + } else { + var aCoord = Ext.lib.Dom.getXY(this.getEl()); + this.lastPageX = aCoord[0]; + this.lastPageY = aCoord[1]; + } + }, + + + autoScroll: function(x, y, h, w) { + + if (this.scroll) { + + var clientH = Ext.lib.Dom.getViewHeight(); + + + var clientW = Ext.lib.Dom.getViewWidth(); + + + var st = this.DDM.getScrollTop(); + + + var sl = this.DDM.getScrollLeft(); + + + var bot = h + y; + + + var right = w + x; + + + + + var toBot = (clientH + st - y - this.deltaY); + + + var toRight = (clientW + sl - x - this.deltaX); + + + + + var thresh = 40; + + + + + var scrAmt = (document.all) ? 80 : 30; + + + + if ( bot > clientH && toBot < thresh ) { + window.scrollTo(sl, st + scrAmt); + } + + + + if ( y < st && st > 0 && y - st < thresh ) { + window.scrollTo(sl, st - scrAmt); + } + + + + if ( right > clientW && toRight < thresh ) { + window.scrollTo(sl + scrAmt, st); + } + + + + if ( x < sl && sl > 0 && x - sl < thresh ) { + window.scrollTo(sl - scrAmt, st); + } + } + }, + + + getTargetCoord: function(iPageX, iPageY) { + var x = iPageX - this.deltaX; + var y = iPageY - this.deltaY; + + if (this.constrainX) { + if (x < this.minX) { x = this.minX; } + if (x > this.maxX) { x = this.maxX; } + } + + if (this.constrainY) { + if (y < this.minY) { y = this.minY; } + if (y > this.maxY) { y = this.maxY; } + } + + x = this.getTick(x, this.xTicks); + y = this.getTick(y, this.yTicks); + + + return {x:x, y:y}; + }, + + + applyConfig: function() { + Ext.dd.DD.superclass.applyConfig.call(this); + this.scroll = (this.config.scroll !== false); + }, + + + b4MouseDown: function(e) { + + this.autoOffset(e.getPageX(), + e.getPageY()); + }, + + + b4Drag: function(e) { + this.setDragElPos(e.getPageX(), + e.getPageY()); + }, + + toString: function() { + return ("DD " + this.id); + } + + + + + + +}); + +Ext.dd.DDProxy = function(id, sGroup, config) { + if (id) { + this.init(id, sGroup, config); + this.initFrame(); + } +}; + + +Ext.dd.DDProxy.dragElId = "ygddfdiv"; + +Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, { + + + resizeFrame: true, + + + centerFrame: false, + + + createFrame: function() { + var self = this; + var body = document.body; + + if (!body || !body.firstChild) { + setTimeout( function() { self.createFrame(); }, 50 ); + return; + } + + var div = this.getDragEl(); + + if (!div) { + div = document.createElement("div"); + div.id = this.dragElId; + var s = div.style; + + s.position = "absolute"; + s.visibility = "hidden"; + s.cursor = "move"; + s.border = "2px solid #aaa"; + s.zIndex = 999; + + + + + body.insertBefore(div, body.firstChild); + } + }, + + + initFrame: function() { + this.createFrame(); + }, + + applyConfig: function() { + Ext.dd.DDProxy.superclass.applyConfig.call(this); + + this.resizeFrame = (this.config.resizeFrame !== false); + this.centerFrame = (this.config.centerFrame); + this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId); + }, + + + showFrame: function(iPageX, iPageY) { + var el = this.getEl(); + var dragEl = this.getDragEl(); + var s = dragEl.style; + + this._resizeProxy(); + + if (this.centerFrame) { + this.setDelta( Math.round(parseInt(s.width, 10)/2), + Math.round(parseInt(s.height, 10)/2) ); + } + + this.setDragElPos(iPageX, iPageY); + + Ext.fly(dragEl).show(); + }, + + + _resizeProxy: function() { + if (this.resizeFrame) { + var el = this.getEl(); + Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight); + } + }, + + + b4MouseDown: function(e) { + var x = e.getPageX(); + var y = e.getPageY(); + this.autoOffset(x, y); + this.setDragElPos(x, y); + }, + + + b4StartDrag: function(x, y) { + + this.showFrame(x, y); + }, + + + b4EndDrag: function(e) { + Ext.fly(this.getDragEl()).hide(); + }, + + + + + endDrag: function(e) { + + var lel = this.getEl(); + var del = this.getDragEl(); + + + del.style.visibility = ""; + + this.beforeMove(); + + + lel.style.visibility = "hidden"; + Ext.dd.DDM.moveToEl(lel, del); + del.style.visibility = "hidden"; + lel.style.visibility = ""; + + this.afterDrag(); + }, + + beforeMove : function(){ + + }, + + afterDrag : function(){ + + }, + + toString: function() { + return ("DDProxy " + this.id); + } + +}); + +Ext.dd.DDTarget = function(id, sGroup, config) { + if (id) { + this.initTarget(id, sGroup, config); + } +}; + + +Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, { + + getDragEl: Ext.emptyFn, + + isValidHandleChild: Ext.emptyFn, + + startDrag: Ext.emptyFn, + + endDrag: Ext.emptyFn, + + onDrag: Ext.emptyFn, + + onDragDrop: Ext.emptyFn, + + onDragEnter: Ext.emptyFn, + + onDragOut: Ext.emptyFn, + + onDragOver: Ext.emptyFn, + + onInvalidDrop: Ext.emptyFn, + + onMouseDown: Ext.emptyFn, + + onMouseUp: Ext.emptyFn, + + setXConstraint: Ext.emptyFn, + + setYConstraint: Ext.emptyFn, + + resetConstraints: Ext.emptyFn, + + clearConstraints: Ext.emptyFn, + + clearTicks: Ext.emptyFn, + + setInitPosition: Ext.emptyFn, + + setDragElId: Ext.emptyFn, + + setHandleElId: Ext.emptyFn, + + setOuterHandleElId: Ext.emptyFn, + + addInvalidHandleClass: Ext.emptyFn, + + addInvalidHandleId: Ext.emptyFn, + + addInvalidHandleType: Ext.emptyFn, + + removeInvalidHandleClass: Ext.emptyFn, + + removeInvalidHandleId: Ext.emptyFn, + + removeInvalidHandleType: Ext.emptyFn, + + toString: function() { + return ("DDTarget " + this.id); + } +}); +Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, { + + active: false, + + tolerance: 5, + + autoStart: false, + + constructor : function(config){ + Ext.apply(this, config); + this.addEvents( + + 'mousedown', + + 'mouseup', + + 'mousemove', + + 'dragstart', + + 'dragend', + + 'drag' + ); + + this.dragRegion = new Ext.lib.Region(0,0,0,0); + + if(this.el){ + this.initEl(this.el); + } + Ext.dd.DragTracker.superclass.constructor.call(this, config); + }, + + initEl: function(el){ + this.el = Ext.get(el); + el.on('mousedown', this.onMouseDown, this, + this.delegate ? {delegate: this.delegate} : undefined); + }, + + destroy : function(){ + this.el.un('mousedown', this.onMouseDown, this); + delete this.el; + }, + + onMouseDown: function(e, target){ + if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){ + this.startXY = this.lastXY = e.getXY(); + this.dragTarget = this.delegate ? target : this.el.dom; + if(this.preventDefault !== false){ + e.preventDefault(); + } + Ext.getDoc().on({ + scope: this, + mouseup: this.onMouseUp, + mousemove: this.onMouseMove, + selectstart: this.stopSelect + }); + if(this.autoStart){ + this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]); + } + } + }, + + onMouseMove: function(e, target){ + + var ieCheck = Ext.isIE6 || Ext.isIE7 || Ext.isIE8; + if(this.active && ieCheck && !e.browserEvent.button){ + e.preventDefault(); + this.onMouseUp(e); + return; + } + + e.preventDefault(); + var xy = e.getXY(), s = this.startXY; + this.lastXY = xy; + if(!this.active){ + if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){ + this.triggerStart(e); + }else{ + return; + } + } + this.fireEvent('mousemove', this, e); + this.onDrag(e); + this.fireEvent('drag', this, e); + }, + + onMouseUp: function(e) { + var doc = Ext.getDoc(), + wasActive = this.active; + + doc.un('mousemove', this.onMouseMove, this); + doc.un('mouseup', this.onMouseUp, this); + doc.un('selectstart', this.stopSelect, this); + e.preventDefault(); + this.clearStart(); + this.active = false; + delete this.elRegion; + this.fireEvent('mouseup', this, e); + if(wasActive){ + this.onEnd(e); + this.fireEvent('dragend', this, e); + } + }, + + triggerStart: function(e) { + this.clearStart(); + this.active = true; + this.onStart(e); + this.fireEvent('dragstart', this, e); + }, + + clearStart : function() { + if(this.timer){ + clearTimeout(this.timer); + delete this.timer; + } + }, + + stopSelect : function(e) { + e.stopEvent(); + return false; + }, + + + onBeforeStart : function(e) { + + }, + + + onStart : function(xy) { + + }, + + + onDrag : function(e) { + + }, + + + onEnd : function(e) { + + }, + + + getDragTarget : function(){ + return this.dragTarget; + }, + + getDragCt : function(){ + return this.el; + }, + + getXY : function(constrain){ + return constrain ? + this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY; + }, + + getOffset : function(constrain){ + var xy = this.getXY(constrain), + s = this.startXY; + return [s[0]-xy[0], s[1]-xy[1]]; + }, + + constrainModes: { + 'point' : function(xy){ + + if(!this.elRegion){ + this.elRegion = this.getDragCt().getRegion(); + } + + var dr = this.dragRegion; + + dr.left = xy[0]; + dr.top = xy[1]; + dr.right = xy[0]; + dr.bottom = xy[1]; + + dr.constrainTo(this.elRegion); + + return [dr.left, dr.top]; + } + } +}); +Ext.dd.ScrollManager = function(){ + var ddm = Ext.dd.DragDropMgr; + var els = {}; + var dragEl = null; + var proc = {}; + + var onStop = function(e){ + dragEl = null; + clearProc(); + }; + + var triggerRefresh = function(){ + if(ddm.dragCurrent){ + ddm.refreshCache(ddm.dragCurrent.groups); + } + }; + + var doScroll = function(){ + if(ddm.dragCurrent){ + var dds = Ext.dd.ScrollManager; + var inc = proc.el.ddScrollConfig ? + proc.el.ddScrollConfig.increment : dds.increment; + if(!dds.animate){ + if(proc.el.scroll(proc.dir, inc)){ + triggerRefresh(); + } + }else{ + proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh); + } + } + }; + + var clearProc = function(){ + if(proc.id){ + clearInterval(proc.id); + } + proc.id = 0; + proc.el = null; + proc.dir = ""; + }; + + var startProc = function(el, dir){ + clearProc(); + proc.el = el; + proc.dir = dir; + var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined, + freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) + ? el.ddScrollConfig.frequency + : Ext.dd.ScrollManager.frequency; + + if (group === undefined || ddm.dragCurrent.ddGroup == group) { + proc.id = setInterval(doScroll, freq); + } + }; + + var onFire = function(e, isDrop){ + if(isDrop || !ddm.dragCurrent){ return; } + var dds = Ext.dd.ScrollManager; + if(!dragEl || dragEl != ddm.dragCurrent){ + dragEl = ddm.dragCurrent; + + dds.refreshCache(); + } + + var xy = Ext.lib.Event.getXY(e); + var pt = new Ext.lib.Point(xy[0], xy[1]); + for(var id in els){ + var el = els[id], r = el._region; + var c = el.ddScrollConfig ? el.ddScrollConfig : dds; + if(r && r.contains(pt) && el.isScrollable()){ + if(r.bottom - pt.y <= c.vthresh){ + if(proc.el != el){ + startProc(el, "down"); + } + return; + }else if(r.right - pt.x <= c.hthresh){ + if(proc.el != el){ + startProc(el, "left"); + } + return; + }else if(pt.y - r.top <= c.vthresh){ + if(proc.el != el){ + startProc(el, "up"); + } + return; + }else if(pt.x - r.left <= c.hthresh){ + if(proc.el != el){ + startProc(el, "right"); + } + return; + } + } + } + clearProc(); + }; + + ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm); + ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm); + + return { + + register : function(el){ + if(Ext.isArray(el)){ + for(var i = 0, len = el.length; i < len; i++) { + this.register(el[i]); + } + }else{ + el = Ext.get(el); + els[el.id] = el; + } + }, + + + unregister : function(el){ + if(Ext.isArray(el)){ + for(var i = 0, len = el.length; i < len; i++) { + this.unregister(el[i]); + } + }else{ + el = Ext.get(el); + delete els[el.id]; + } + }, + + + vthresh : 25, + + hthresh : 25, + + + increment : 100, + + + frequency : 500, + + + animate: true, + + + animDuration: .4, + + + ddGroup: undefined, + + + refreshCache : function(){ + for(var id in els){ + if(typeof els[id] == 'object'){ + els[id]._region = els[id].getRegion(); + } + } + } + }; +}(); +Ext.dd.Registry = function(){ + var elements = {}; + var handles = {}; + var autoIdSeed = 0; + + var getId = function(el, autogen){ + if(typeof el == "string"){ + return el; + } + var id = el.id; + if(!id && autogen !== false){ + id = "extdd-" + (++autoIdSeed); + el.id = id; + } + return id; + }; + + return { + + register : function(el, data){ + data = data || {}; + if(typeof el == "string"){ + el = document.getElementById(el); + } + data.ddel = el; + elements[getId(el)] = data; + if(data.isHandle !== false){ + handles[data.ddel.id] = data; + } + if(data.handles){ + var hs = data.handles; + for(var i = 0, len = hs.length; i < len; i++){ + handles[getId(hs[i])] = data; + } + } + }, + + + unregister : function(el){ + var id = getId(el, false); + var data = elements[id]; + if(data){ + delete elements[id]; + if(data.handles){ + var hs = data.handles; + for(var i = 0, len = hs.length; i < len; i++){ + delete handles[getId(hs[i], false)]; + } + } + } + }, + + + getHandle : function(id){ + if(typeof id != "string"){ + id = id.id; + } + return handles[id]; + }, + + + getHandleFromEvent : function(e){ + var t = Ext.lib.Event.getTarget(e); + return t ? handles[t.id] : null; + }, + + + getTarget : function(id){ + if(typeof id != "string"){ + id = id.id; + } + return elements[id]; + }, + + + getTargetFromEvent : function(e){ + var t = Ext.lib.Event.getTarget(e); + return t ? elements[t.id] || handles[t.id] : null; + } + }; +}(); +Ext.dd.StatusProxy = function(config){ + Ext.apply(this, config); + this.id = this.id || Ext.id(); + this.el = new Ext.Layer({ + dh: { + id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [ + {tag: "div", cls: "x-dd-drop-icon"}, + {tag: "div", cls: "x-dd-drag-ghost"} + ] + }, + shadow: !config || config.shadow !== false + }); + this.ghost = Ext.get(this.el.dom.childNodes[1]); + this.dropStatus = this.dropNotAllowed; +}; + +Ext.dd.StatusProxy.prototype = { + + dropAllowed : "x-dd-drop-ok", + + dropNotAllowed : "x-dd-drop-nodrop", + + + setStatus : function(cssClass){ + cssClass = cssClass || this.dropNotAllowed; + if(this.dropStatus != cssClass){ + this.el.replaceClass(this.dropStatus, cssClass); + this.dropStatus = cssClass; + } + }, + + + reset : function(clearGhost){ + this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed; + this.dropStatus = this.dropNotAllowed; + if(clearGhost){ + this.ghost.update(""); + } + }, + + + update : function(html){ + if(typeof html == "string"){ + this.ghost.update(html); + }else{ + this.ghost.update(""); + html.style.margin = "0"; + this.ghost.dom.appendChild(html); + } + var el = this.ghost.dom.firstChild; + if(el){ + Ext.fly(el).setStyle('float', 'none'); + } + }, + + + getEl : function(){ + return this.el; + }, + + + getGhost : function(){ + return this.ghost; + }, + + + hide : function(clear){ + this.el.hide(); + if(clear){ + this.reset(true); + } + }, + + + stop : function(){ + if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){ + this.anim.stop(); + } + }, + + + show : function(){ + this.el.show(); + }, + + + sync : function(){ + this.el.sync(); + }, + + + repair : function(xy, callback, scope){ + this.callback = callback; + this.scope = scope; + if(xy && this.animRepair !== false){ + this.el.addClass("x-dd-drag-repair"); + this.el.hideUnders(true); + this.anim = this.el.shift({ + duration: this.repairDuration || .5, + easing: 'easeOut', + xy: xy, + stopFx: true, + callback: this.afterRepair, + scope: this + }); + }else{ + this.afterRepair(); + } + }, + + + afterRepair : function(){ + this.hide(true); + if(typeof this.callback == "function"){ + this.callback.call(this.scope || this); + } + this.callback = null; + this.scope = null; + }, + + destroy: function(){ + Ext.destroy(this.ghost, this.el); + } +}; +Ext.dd.DragSource = function(el, config){ + this.el = Ext.get(el); + if(!this.dragData){ + this.dragData = {}; + } + + Ext.apply(this, config); + + if(!this.proxy){ + this.proxy = new Ext.dd.StatusProxy(); + } + Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, + {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true}); + + this.dragging = false; +}; + +Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, { + + + dropAllowed : "x-dd-drop-ok", + + dropNotAllowed : "x-dd-drop-nodrop", + + + getDragData : function(e){ + return this.dragData; + }, + + + onDragEnter : function(e, id){ + var target = Ext.dd.DragDropMgr.getDDById(id); + this.cachedTarget = target; + if(this.beforeDragEnter(target, e, id) !== false){ + if(target.isNotifyTarget){ + var status = target.notifyEnter(this, e, this.dragData); + this.proxy.setStatus(status); + }else{ + this.proxy.setStatus(this.dropAllowed); + } + + if(this.afterDragEnter){ + + this.afterDragEnter(target, e, id); + } + } + }, + + + beforeDragEnter : function(target, e, id){ + return true; + }, + + + alignElWithMouse: function() { + Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments); + this.proxy.sync(); + }, + + + onDragOver : function(e, id){ + var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); + if(this.beforeDragOver(target, e, id) !== false){ + if(target.isNotifyTarget){ + var status = target.notifyOver(this, e, this.dragData); + this.proxy.setStatus(status); + } + + if(this.afterDragOver){ + + this.afterDragOver(target, e, id); + } + } + }, + + + beforeDragOver : function(target, e, id){ + return true; + }, + + + onDragOut : function(e, id){ + var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); + if(this.beforeDragOut(target, e, id) !== false){ + if(target.isNotifyTarget){ + target.notifyOut(this, e, this.dragData); + } + this.proxy.reset(); + if(this.afterDragOut){ + + this.afterDragOut(target, e, id); + } + } + this.cachedTarget = null; + }, + + + beforeDragOut : function(target, e, id){ + return true; + }, + + + onDragDrop : function(e, id){ + var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); + if(this.beforeDragDrop(target, e, id) !== false){ + if(target.isNotifyTarget){ + if(target.notifyDrop(this, e, this.dragData)){ + this.onValidDrop(target, e, id); + }else{ + this.onInvalidDrop(target, e, id); + } + }else{ + this.onValidDrop(target, e, id); + } + + if(this.afterDragDrop){ + + this.afterDragDrop(target, e, id); + } + } + delete this.cachedTarget; + }, + + + beforeDragDrop : function(target, e, id){ + return true; + }, + + + onValidDrop : function(target, e, id){ + this.hideProxy(); + if(this.afterValidDrop){ + + this.afterValidDrop(target, e, id); + } + }, + + + getRepairXY : function(e, data){ + return this.el.getXY(); + }, + + + onInvalidDrop : function(target, e, id){ + this.beforeInvalidDrop(target, e, id); + if(this.cachedTarget){ + if(this.cachedTarget.isNotifyTarget){ + this.cachedTarget.notifyOut(this, e, this.dragData); + } + this.cacheTarget = null; + } + this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this); + + if(this.afterInvalidDrop){ + + this.afterInvalidDrop(e, id); + } + }, + + + afterRepair : function(){ + if(Ext.enableFx){ + this.el.highlight(this.hlColor || "c3daf9"); + } + this.dragging = false; + }, + + + beforeInvalidDrop : function(target, e, id){ + return true; + }, + + + handleMouseDown : function(e){ + if(this.dragging) { + return; + } + var data = this.getDragData(e); + if(data && this.onBeforeDrag(data, e) !== false){ + this.dragData = data; + this.proxy.stop(); + Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments); + } + }, + + + onBeforeDrag : function(data, e){ + return true; + }, + + + onStartDrag : Ext.emptyFn, + + + startDrag : function(x, y){ + this.proxy.reset(); + this.dragging = true; + this.proxy.update(""); + this.onInitDrag(x, y); + this.proxy.show(); + }, + + + onInitDrag : function(x, y){ + var clone = this.el.dom.cloneNode(true); + clone.id = Ext.id(); + this.proxy.update(clone); + this.onStartDrag(x, y); + return true; + }, + + + getProxy : function(){ + return this.proxy; + }, + + + hideProxy : function(){ + this.proxy.hide(); + this.proxy.reset(true); + this.dragging = false; + }, + + + triggerCacheRefresh : function(){ + Ext.dd.DDM.refreshCache(this.groups); + }, + + + b4EndDrag: function(e) { + }, + + + endDrag : function(e){ + this.onEndDrag(this.dragData, e); + }, + + + onEndDrag : function(data, e){ + }, + + + autoOffset : function(x, y) { + this.setDelta(-12, -20); + }, + + destroy: function(){ + Ext.dd.DragSource.superclass.destroy.call(this); + Ext.destroy(this.proxy); + } +}); +Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, { + + constructor : function(el, config){ + this.el = Ext.get(el); + + Ext.apply(this, config); + + if(this.containerScroll){ + Ext.dd.ScrollManager.register(this.el); + } + + Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, + {isTarget: true}); + }, + + + + + dropAllowed : "x-dd-drop-ok", + + dropNotAllowed : "x-dd-drop-nodrop", + + + isTarget : true, + + + isNotifyTarget : true, + + + notifyEnter : function(dd, e, data){ + if(this.overClass){ + this.el.addClass(this.overClass); + } + return this.dropAllowed; + }, + + + notifyOver : function(dd, e, data){ + return this.dropAllowed; + }, + + + notifyOut : function(dd, e, data){ + if(this.overClass){ + this.el.removeClass(this.overClass); + } + }, + + + notifyDrop : function(dd, e, data){ + return false; + }, + + destroy : function(){ + Ext.dd.DropTarget.superclass.destroy.call(this); + if(this.containerScroll){ + Ext.dd.ScrollManager.unregister(this.el); + } + } +}); +Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, { + + constructor : function(el, config){ + Ext.dd.DragZone.superclass.constructor.call(this, el, config); + if(this.containerScroll){ + Ext.dd.ScrollManager.register(this.el); + } + }, + + + + + + + getDragData : function(e){ + return Ext.dd.Registry.getHandleFromEvent(e); + }, + + + onInitDrag : function(x, y){ + this.proxy.update(this.dragData.ddel.cloneNode(true)); + this.onStartDrag(x, y); + return true; + }, + + + afterRepair : function(){ + if(Ext.enableFx){ + Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9"); + } + this.dragging = false; + }, + + + getRepairXY : function(e){ + return Ext.Element.fly(this.dragData.ddel).getXY(); + }, + + destroy : function(){ + Ext.dd.DragZone.superclass.destroy.call(this); + if(this.containerScroll){ + Ext.dd.ScrollManager.unregister(this.el); + } + } +}); +Ext.dd.DropZone = function(el, config){ + Ext.dd.DropZone.superclass.constructor.call(this, el, config); +}; + +Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, { + + getTargetFromEvent : function(e){ + return Ext.dd.Registry.getTargetFromEvent(e); + }, + + + onNodeEnter : function(n, dd, e, data){ + + }, + + + onNodeOver : function(n, dd, e, data){ + return this.dropAllowed; + }, + + + onNodeOut : function(n, dd, e, data){ + + }, + + + onNodeDrop : function(n, dd, e, data){ + return false; + }, + + + onContainerOver : function(dd, e, data){ + return this.dropNotAllowed; + }, + + + onContainerDrop : function(dd, e, data){ + return false; + }, + + + notifyEnter : function(dd, e, data){ + return this.dropNotAllowed; + }, + + + notifyOver : function(dd, e, data){ + var n = this.getTargetFromEvent(e); + if(!n){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; + } + return this.onContainerOver(dd, e, data); + } + if(this.lastOverNode != n){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + } + this.onNodeEnter(n, dd, e, data); + this.lastOverNode = n; + } + return this.onNodeOver(n, dd, e, data); + }, + + + notifyOut : function(dd, e, data){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; + } + }, + + + notifyDrop : function(dd, e, data){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; + } + var n = this.getTargetFromEvent(e); + return n ? + this.onNodeDrop(n, dd, e, data) : + this.onContainerDrop(dd, e, data); + }, + + + triggerCacheRefresh : function(){ + Ext.dd.DDM.refreshCache(this.groups); + } +}); +Ext.Element.addMethods({ + + initDD : function(group, config, overrides){ + var dd = new Ext.dd.DD(Ext.id(this.dom), group, config); + return Ext.apply(dd, overrides); + }, + + + initDDProxy : function(group, config, overrides){ + var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config); + return Ext.apply(dd, overrides); + }, + + + initDDTarget : function(group, config, overrides){ + var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config); + return Ext.apply(dd, overrides); + } +}); + +Ext.data.Api = (function() { + + + + + + var validActions = {}; + + return { + + actions : { + create : 'create', + read : 'read', + update : 'update', + destroy : 'destroy' + }, + + + restActions : { + create : 'POST', + read : 'GET', + update : 'PUT', + destroy : 'DELETE' + }, + + + isAction : function(action) { + return (Ext.data.Api.actions[action]) ? true : false; + }, + + + getVerb : function(name) { + if (validActions[name]) { + return validActions[name]; + } + for (var verb in this.actions) { + if (this.actions[verb] === name) { + validActions[name] = verb; + break; + } + } + return (validActions[name] !== undefined) ? validActions[name] : null; + }, + + + isValid : function(api){ + var invalid = []; + var crud = this.actions; + for (var action in api) { + if (!(action in crud)) { + invalid.push(action); + } + } + return (!invalid.length) ? true : invalid; + }, + + + hasUniqueUrl : function(proxy, verb) { + var url = (proxy.api[verb]) ? proxy.api[verb].url : null; + var unique = true; + for (var action in proxy.api) { + if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) { + break; + } + } + return unique; + }, + + + prepare : function(proxy) { + if (!proxy.api) { + proxy.api = {}; + } + for (var verb in this.actions) { + var action = this.actions[verb]; + proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn; + if (typeof(proxy.api[action]) == 'string') { + proxy.api[action] = { + url: proxy.api[action], + method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined + }; + } + } + }, + + + restify : function(proxy) { + proxy.restful = true; + for (var verb in this.restActions) { + proxy.api[this.actions[verb]].method || + (proxy.api[this.actions[verb]].method = this.restActions[verb]); + } + + + proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) { + var reader = o.reader; + var res = new Ext.data.Response({ + action: action, + raw: response + }); + + switch (response.status) { + case 200: + return true; + break; + case 201: + if (Ext.isEmpty(res.raw.responseText)) { + res.success = true; + } else { + + return true; + } + break; + case 204: + res.success = true; + res.data = null; + break; + default: + return true; + break; + } + if (res.success === true) { + this.fireEvent("write", this, action, res.data, res, rs, o.request.arg); + } else { + this.fireEvent('exception', this, 'remote', action, o, res, rs); + } + o.request.callback.call(o.request.scope, res.data, res, res.success); + + return false; + }, proxy); + } + }; +})(); + + +Ext.data.Response = function(params, response) { + Ext.apply(this, params, { + raw: response + }); +}; +Ext.data.Response.prototype = { + message : null, + success : false, + status : null, + root : null, + raw : null, + + getMessage : function() { + return this.message; + }, + getSuccess : function() { + return this.success; + }, + getStatus : function() { + return this.status; + }, + getRoot : function() { + return this.root; + }, + getRawResponse : function() { + return this.raw; + } +}; + + +Ext.data.Api.Error = Ext.extend(Ext.Error, { + constructor : function(message, arg) { + this.arg = arg; + Ext.Error.call(this, message); + }, + name: 'Ext.data.Api' +}); +Ext.apply(Ext.data.Api.Error.prototype, { + lang: { + 'action-url-undefined': 'No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.', + 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions', + 'invalid-url': 'Invalid url. Please review your proxy configuration.', + 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"' + } +}); + + + + +Ext.data.SortTypes = { + + none : function(s){ + return s; + }, + + + stripTagsRE : /<\/?[^>]+>/gi, + + + asText : function(s){ + return String(s).replace(this.stripTagsRE, ""); + }, + + + asUCText : function(s){ + return String(s).toUpperCase().replace(this.stripTagsRE, ""); + }, + + + asUCString : function(s) { + return String(s).toUpperCase(); + }, + + + asDate : function(s) { + if(!s){ + return 0; + } + if(Ext.isDate(s)){ + return s.getTime(); + } + return Date.parse(String(s)); + }, + + + asFloat : function(s) { + var val = parseFloat(String(s).replace(/,/g, "")); + return isNaN(val) ? 0 : val; + }, + + + asInt : function(s) { + var val = parseInt(String(s).replace(/,/g, ""), 10); + return isNaN(val) ? 0 : val; + } +}; +Ext.data.Record = function(data, id){ + + this.id = (id || id === 0) ? id : Ext.data.Record.id(this); + this.data = data || {}; +}; + + +Ext.data.Record.create = function(o){ + var f = Ext.extend(Ext.data.Record, {}); + var p = f.prototype; + p.fields = new Ext.util.MixedCollection(false, function(field){ + return field.name; + }); + for(var i = 0, len = o.length; i < len; i++){ + p.fields.add(new Ext.data.Field(o[i])); + } + f.getField = function(name){ + return p.fields.get(name); + }; + return f; +}; + +Ext.data.Record.PREFIX = 'ext-record'; +Ext.data.Record.AUTO_ID = 1; +Ext.data.Record.EDIT = 'edit'; +Ext.data.Record.REJECT = 'reject'; +Ext.data.Record.COMMIT = 'commit'; + + + +Ext.data.Record.id = function(rec) { + rec.phantom = true; + return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join(''); +}; + +Ext.data.Record.prototype = { + + + + + + + dirty : false, + editing : false, + error : null, + + modified : null, + + phantom : false, + + + join : function(store){ + + this.store = store; + }, + + + set : function(name, value){ + var encode = Ext.isPrimitive(value) ? String : Ext.encode; + if(encode(this.data[name]) == encode(value)) { + return; + } + this.dirty = true; + if(!this.modified){ + this.modified = {}; + } + if(this.modified[name] === undefined){ + this.modified[name] = this.data[name]; + } + this.data[name] = value; + if(!this.editing){ + this.afterEdit(); + } + }, + + + afterEdit : function(){ + if (this.store != undefined && typeof this.store.afterEdit == "function") { + this.store.afterEdit(this); + } + }, + + + afterReject : function(){ + if(this.store){ + this.store.afterReject(this); + } + }, + + + afterCommit : function(){ + if(this.store){ + this.store.afterCommit(this); + } + }, + + + get : function(name){ + return this.data[name]; + }, + + + beginEdit : function(){ + this.editing = true; + this.modified = this.modified || {}; + }, + + + cancelEdit : function(){ + this.editing = false; + delete this.modified; + }, + + + endEdit : function(){ + this.editing = false; + if(this.dirty){ + this.afterEdit(); + } + }, + + + reject : function(silent){ + var m = this.modified; + for(var n in m){ + if(typeof m[n] != "function"){ + this.data[n] = m[n]; + } + } + this.dirty = false; + delete this.modified; + this.editing = false; + if(silent !== true){ + this.afterReject(); + } + }, + + + commit : function(silent){ + this.dirty = false; + delete this.modified; + this.editing = false; + if(silent !== true){ + this.afterCommit(); + } + }, + + + getChanges : function(){ + var m = this.modified, cs = {}; + for(var n in m){ + if(m.hasOwnProperty(n)){ + cs[n] = this.data[n]; + } + } + return cs; + }, + + + hasError : function(){ + return this.error !== null; + }, + + + clearError : function(){ + this.error = null; + }, + + + copy : function(newId) { + return new this.constructor(Ext.apply({}, this.data), newId || this.id); + }, + + + isModified : function(fieldName){ + return !!(this.modified && this.modified.hasOwnProperty(fieldName)); + }, + + + isValid : function() { + return this.fields.find(function(f) { + return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false; + },this) ? false : true; + }, + + + markDirty : function(){ + this.dirty = true; + if(!this.modified){ + this.modified = {}; + } + this.fields.each(function(f) { + this.modified[f.name] = this.data[f.name]; + },this); + } +}; + +Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), { + + + + register : function(){ + for(var i = 0, s; (s = arguments[i]); i++){ + this.add(s); + } + }, + + + unregister : function(){ + for(var i = 0, s; (s = arguments[i]); i++){ + this.remove(this.lookup(s)); + } + }, + + + lookup : function(id){ + if(Ext.isArray(id)){ + var fields = ['field1'], expand = !Ext.isArray(id[0]); + if(!expand){ + for(var i = 2, len = id[0].length; i <= len; ++i){ + fields.push('field' + i); + } + } + return new Ext.data.ArrayStore({ + fields: fields, + data: id, + expandData: expand, + autoDestroy: true, + autoCreated: true + + }); + } + return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id); + }, + + + getKey : function(o){ + return o.storeId; + } +}); +Ext.data.Store = Ext.extend(Ext.util.Observable, { + + + + + + + + writer : undefined, + + + + remoteSort : false, + + + autoDestroy : false, + + + pruneModifiedRecords : false, + + + lastOptions : null, + + + autoSave : true, + + + batch : true, + + + restful: false, + + + paramNames : undefined, + + + defaultParamNames : { + start : 'start', + limit : 'limit', + sort : 'sort', + dir : 'dir' + }, + + isDestroyed: false, + hasMultiSort: false, + + + batchKey : '_ext_batch_', + + constructor : function(config){ + + + + + this.data = new Ext.util.MixedCollection(false); + this.data.getKey = function(o){ + return o.id; + }; + + + + this.removed = []; + + if(config && config.data){ + this.inlineData = config.data; + delete config.data; + } + + Ext.apply(this, config); + + + this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {}; + + this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames); + + if((this.url || this.api) && !this.proxy){ + this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api}); + } + + if (this.restful === true && this.proxy) { + + + this.batch = false; + Ext.data.Api.restify(this.proxy); + } + + if(this.reader){ + if(!this.recordType){ + this.recordType = this.reader.recordType; + } + if(this.reader.onMetaChange){ + this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this); + } + if (this.writer) { + if (this.writer instanceof(Ext.data.DataWriter) === false) { + this.writer = this.buildWriter(this.writer); + } + this.writer.meta = this.reader.meta; + this.pruneModifiedRecords = true; + } + } + + + + if(this.recordType){ + + this.fields = this.recordType.prototype.fields; + } + this.modified = []; + + this.addEvents( + + 'datachanged', + + 'metachange', + + 'add', + + 'remove', + + 'update', + + 'clear', + + 'exception', + + 'beforeload', + + 'load', + + 'loadexception', + + 'beforewrite', + + 'write', + + 'beforesave', + + 'save' + + ); + + if(this.proxy){ + + this.relayEvents(this.proxy, ['loadexception', 'exception']); + } + + if (this.writer) { + this.on({ + scope: this, + add: this.createRecords, + remove: this.destroyRecord, + update: this.updateRecord, + clear: this.onClear + }); + } + + this.sortToggle = {}; + if(this.sortField){ + this.setDefaultSort(this.sortField, this.sortDir); + }else if(this.sortInfo){ + this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction); + } + + Ext.data.Store.superclass.constructor.call(this); + + if(this.id){ + this.storeId = this.id; + delete this.id; + } + if(this.storeId){ + Ext.StoreMgr.register(this); + } + if(this.inlineData){ + this.loadData(this.inlineData); + delete this.inlineData; + }else if(this.autoLoad){ + this.load.defer(10, this, [ + typeof this.autoLoad == 'object' ? + this.autoLoad : undefined]); + } + + this.batchCounter = 0; + this.batches = {}; + }, + + + buildWriter : function(config) { + var klass = undefined, + type = (config.format || 'json').toLowerCase(); + switch (type) { + case 'json': + klass = Ext.data.JsonWriter; + break; + case 'xml': + klass = Ext.data.XmlWriter; + break; + default: + klass = Ext.data.JsonWriter; + } + return new klass(config); + }, + + + destroy : function(){ + if(!this.isDestroyed){ + if(this.storeId){ + Ext.StoreMgr.unregister(this); + } + this.clearData(); + this.data = null; + Ext.destroy(this.proxy); + this.reader = this.writer = null; + this.purgeListeners(); + this.isDestroyed = true; + } + }, + + + add : function(records) { + var i, len, record, index; + + records = [].concat(records); + if (records.length < 1) { + return; + } + + for (i = 0, len = records.length; i < len; i++) { + record = records[i]; + + record.join(this); + + if (record.dirty || record.phantom) { + this.modified.push(record); + } + } + + index = this.data.length; + this.data.addAll(records); + + if (this.snapshot) { + this.snapshot.addAll(records); + } + + this.fireEvent('add', this, records, index); + }, + + + addSorted : function(record){ + var index = this.findInsertIndex(record); + this.insert(index, record); + }, + + + doUpdate: function(rec){ + var id = rec.id; + + this.getById(id).join(null); + + this.data.replace(id, rec); + if (this.snapshot) { + this.snapshot.replace(id, rec); + } + rec.join(this); + this.fireEvent('update', this, rec, Ext.data.Record.COMMIT); + }, + + + remove : function(record){ + if(Ext.isArray(record)){ + Ext.each(record, function(r){ + this.remove(r); + }, this); + return; + } + var index = this.data.indexOf(record); + if(index > -1){ + record.join(null); + this.data.removeAt(index); + } + if(this.pruneModifiedRecords){ + this.modified.remove(record); + } + if(this.snapshot){ + this.snapshot.remove(record); + } + if(index > -1){ + this.fireEvent('remove', this, record, index); + } + }, + + + removeAt : function(index){ + this.remove(this.getAt(index)); + }, + + + removeAll : function(silent){ + var items = []; + this.each(function(rec){ + items.push(rec); + }); + this.clearData(); + if(this.snapshot){ + this.snapshot.clear(); + } + if(this.pruneModifiedRecords){ + this.modified = []; + } + if (silent !== true) { + this.fireEvent('clear', this, items); + } + }, + + + onClear: function(store, records){ + Ext.each(records, function(rec, index){ + this.destroyRecord(this, rec, index); + }, this); + }, + + + insert : function(index, records) { + var i, len, record; + + records = [].concat(records); + for (i = 0, len = records.length; i < len; i++) { + record = records[i]; + + this.data.insert(index + i, record); + record.join(this); + + if (record.dirty || record.phantom) { + this.modified.push(record); + } + } + + if (this.snapshot) { + this.snapshot.addAll(records); + } + + this.fireEvent('add', this, records, index); + }, + + + indexOf : function(record){ + return this.data.indexOf(record); + }, + + + indexOfId : function(id){ + return this.data.indexOfKey(id); + }, + + + getById : function(id){ + return (this.snapshot || this.data).key(id); + }, + + + getAt : function(index){ + return this.data.itemAt(index); + }, + + + getRange : function(start, end){ + return this.data.getRange(start, end); + }, + + + storeOptions : function(o){ + o = Ext.apply({}, o); + delete o.callback; + delete o.scope; + this.lastOptions = o; + }, + + + clearData: function(){ + this.data.each(function(rec) { + rec.join(null); + }); + this.data.clear(); + }, + + + load : function(options) { + options = Ext.apply({}, options); + this.storeOptions(options); + if(this.sortInfo && this.remoteSort){ + var pn = this.paramNames; + options.params = Ext.apply({}, options.params); + options.params[pn.sort] = this.sortInfo.field; + options.params[pn.dir] = this.sortInfo.direction; + } + try { + return this.execute('read', null, options); + } catch(e) { + this.handleException(e); + return false; + } + }, + + + updateRecord : function(store, record, action) { + if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) { + this.save(); + } + }, + + + createRecords : function(store, records, index) { + var modified = this.modified, + length = records.length, + record, i; + + for (i = 0; i < length; i++) { + record = records[i]; + + if (record.phantom && record.isValid()) { + record.markDirty(); + + if (modified.indexOf(record) == -1) { + modified.push(record); + } + } + } + if (this.autoSave === true) { + this.save(); + } + }, + + + destroyRecord : function(store, record, index) { + if (this.modified.indexOf(record) != -1) { + this.modified.remove(record); + } + if (!record.phantom) { + this.removed.push(record); + + + + + record.lastIndex = index; + + if (this.autoSave === true) { + this.save(); + } + } + }, + + + execute : function(action, rs, options, batch) { + + if (!Ext.data.Api.isAction(action)) { + throw new Ext.data.Api.Error('execute', action); + } + + options = Ext.applyIf(options||{}, { + params: {} + }); + if(batch !== undefined){ + this.addToBatch(batch); + } + + + var doRequest = true; + + if (action === 'read') { + doRequest = this.fireEvent('beforeload', this, options); + Ext.applyIf(options.params, this.baseParams); + } + else { + + + if (this.writer.listful === true && this.restful !== true) { + rs = (Ext.isArray(rs)) ? rs : [rs]; + } + + else if (Ext.isArray(rs) && rs.length == 1) { + rs = rs.shift(); + } + + if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) { + this.writer.apply(options.params, this.baseParams, action, rs); + } + } + if (doRequest !== false) { + + if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) { + options.params.xaction = action; + } + + + + + + this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options); + } + return doRequest; + }, + + + save : function() { + if (!this.writer) { + throw new Ext.data.Store.Error('writer-undefined'); + } + + var queue = [], + len, + trans, + batch, + data = {}, + i; + + if(this.removed.length){ + queue.push(['destroy', this.removed]); + } + + + var rs = [].concat(this.getModifiedRecords()); + if(rs.length){ + + var phantoms = []; + for(i = rs.length-1; i >= 0; i--){ + if(rs[i].phantom === true){ + var rec = rs.splice(i, 1).shift(); + if(rec.isValid()){ + phantoms.push(rec); + } + }else if(!rs[i].isValid()){ + rs.splice(i,1); + } + } + + if(phantoms.length){ + queue.push(['create', phantoms]); + } + + + if(rs.length){ + queue.push(['update', rs]); + } + } + len = queue.length; + if(len){ + batch = ++this.batchCounter; + for(i = 0; i < len; ++i){ + trans = queue[i]; + data[trans[0]] = trans[1]; + } + if(this.fireEvent('beforesave', this, data) !== false){ + for(i = 0; i < len; ++i){ + trans = queue[i]; + this.doTransaction(trans[0], trans[1], batch); + } + return batch; + } + } + return -1; + }, + + + doTransaction : function(action, rs, batch) { + function transaction(records) { + try{ + this.execute(action, records, undefined, batch); + }catch (e){ + this.handleException(e); + } + } + if(this.batch === false){ + for(var i = 0, len = rs.length; i < len; i++){ + transaction.call(this, rs[i]); + } + }else{ + transaction.call(this, rs); + } + }, + + + addToBatch : function(batch){ + var b = this.batches, + key = this.batchKey + batch, + o = b[key]; + + if(!o){ + b[key] = o = { + id: batch, + count: 0, + data: {} + }; + } + ++o.count; + }, + + removeFromBatch : function(batch, action, data){ + var b = this.batches, + key = this.batchKey + batch, + o = b[key], + arr; + + + if(o){ + arr = o.data[action] || []; + o.data[action] = arr.concat(data); + if(o.count === 1){ + data = o.data; + delete b[key]; + this.fireEvent('save', this, batch, data); + }else{ + --o.count; + } + } + }, + + + + createCallback : function(action, rs, batch) { + var actions = Ext.data.Api.actions; + return (action == 'read') ? this.loadRecords : function(data, response, success) { + + this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data)); + + if (success === true) { + this.fireEvent('write', this, action, data, response, rs); + } + this.removeFromBatch(batch, action, data); + }; + }, + + + + + clearModified : function(rs) { + if (Ext.isArray(rs)) { + for (var n=rs.length-1;n>=0;n--) { + this.modified.splice(this.modified.indexOf(rs[n]), 1); + } + } else { + this.modified.splice(this.modified.indexOf(rs), 1); + } + }, + + + reMap : function(record) { + if (Ext.isArray(record)) { + for (var i = 0, len = record.length; i < len; i++) { + this.reMap(record[i]); + } + } else { + delete this.data.map[record._phid]; + this.data.map[record.id] = record; + var index = this.data.keys.indexOf(record._phid); + this.data.keys.splice(index, 1, record.id); + delete record._phid; + } + }, + + + onCreateRecords : function(success, rs, data) { + if (success === true) { + try { + this.reader.realize(rs, data); + } + catch (e) { + this.handleException(e); + if (Ext.isArray(rs)) { + + this.onCreateRecords(success, rs, data); + } + } + } + }, + + + onUpdateRecords : function(success, rs, data) { + if (success === true) { + try { + this.reader.update(rs, data); + } catch (e) { + this.handleException(e); + if (Ext.isArray(rs)) { + + this.onUpdateRecords(success, rs, data); + } + } + } + }, + + + onDestroyRecords : function(success, rs, data) { + + rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs); + for (var i=0,len=rs.length;i=0;i--) { + this.insert(rs[i].lastIndex, rs[i]); + } + } + }, + + + handleException : function(e) { + + Ext.handleError(e); + }, + + + reload : function(options){ + this.load(Ext.applyIf(options||{}, this.lastOptions)); + }, + + + + loadRecords : function(o, options, success){ + var i, len; + + if (this.isDestroyed === true) { + return; + } + if(!o || success === false){ + if(success !== false){ + this.fireEvent('load', this, [], options); + } + if(options.callback){ + options.callback.call(options.scope || this, [], options, false, o); + } + return; + } + var r = o.records, t = o.totalRecords || r.length; + if(!options || options.add !== true){ + if(this.pruneModifiedRecords){ + this.modified = []; + } + for(i = 0, len = r.length; i < len; i++){ + r[i].join(this); + } + if(this.snapshot){ + this.data = this.snapshot; + delete this.snapshot; + } + this.clearData(); + this.data.addAll(r); + this.totalLength = t; + this.applySort(); + this.fireEvent('datachanged', this); + }else{ + var toAdd = [], + rec, + cnt = 0; + for(i = 0, len = r.length; i < len; ++i){ + rec = r[i]; + if(this.indexOfId(rec.id) > -1){ + this.doUpdate(rec); + }else{ + toAdd.push(rec); + ++cnt; + } + } + this.totalLength = Math.max(t, this.data.length + cnt); + this.add(toAdd); + } + this.fireEvent('load', this, r, options); + if(options.callback){ + options.callback.call(options.scope || this, r, options, true); + } + }, + + + loadData : function(o, append){ + var r = this.reader.readRecords(o); + this.loadRecords(r, {add: append}, true); + }, + + + getCount : function(){ + return this.data.length || 0; + }, + + + getTotalCount : function(){ + return this.totalLength || 0; + }, + + + getSortState : function(){ + return this.sortInfo; + }, + + + applySort : function(){ + if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) { + this.sortData(); + } + }, + + + sortData : function() { + var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo, + direction = sortInfo.direction || "ASC", + sorters = sortInfo.sorters, + sortFns = []; + + + if (!this.hasMultiSort) { + sorters = [{direction: direction, field: sortInfo.field}]; + } + + + for (var i=0, j = sorters.length; i < j; i++) { + sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction)); + } + + if (sortFns.length == 0) { + return; + } + + + + var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1; + + + var fn = function(r1, r2) { + var result = sortFns[0].call(this, r1, r2); + + + if (sortFns.length > 1) { + for (var i=1, j = sortFns.length; i < j; i++) { + result = result || sortFns[i].call(this, r1, r2); + } + } + + return directionModifier * result; + }; + + + this.data.sort(direction, fn); + if (this.snapshot && this.snapshot != this.data) { + this.snapshot.sort(direction, fn); + } + }, + + + createSortFunction: function(field, direction) { + direction = direction || "ASC"; + var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1; + + var sortType = this.fields.get(field).sortType; + + + + return function(r1, r2) { + var v1 = sortType(r1.data[field]), + v2 = sortType(r2.data[field]); + + return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0)); + }; + }, + + + setDefaultSort : function(field, dir) { + dir = dir ? dir.toUpperCase() : 'ASC'; + this.sortInfo = {field: field, direction: dir}; + this.sortToggle[field] = dir; + }, + + + sort : function(fieldName, dir) { + if (Ext.isArray(arguments[0])) { + return this.multiSort.call(this, fieldName, dir); + } else { + return this.singleSort(fieldName, dir); + } + }, + + + singleSort: function(fieldName, dir) { + var field = this.fields.get(fieldName); + if (!field) { + return false; + } + + var name = field.name, + sortInfo = this.sortInfo || null, + sortToggle = this.sortToggle ? this.sortToggle[name] : null; + + if (!dir) { + if (sortInfo && sortInfo.field == name) { + dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC'); + } else { + dir = field.sortDir; + } + } + + this.sortToggle[name] = dir; + this.sortInfo = {field: name, direction: dir}; + this.hasMultiSort = false; + + if (this.remoteSort) { + if (!this.load(this.lastOptions)) { + if (sortToggle) { + this.sortToggle[name] = sortToggle; + } + if (sortInfo) { + this.sortInfo = sortInfo; + } + } + } else { + this.applySort(); + this.fireEvent('datachanged', this); + } + return true; + }, + + + multiSort: function(sorters, direction) { + this.hasMultiSort = true; + direction = direction || "ASC"; + + + if (this.multiSortInfo && direction == this.multiSortInfo.direction) { + direction = direction.toggle("ASC", "DESC"); + } + + + this.multiSortInfo = { + sorters : sorters, + direction: direction + }; + + if (this.remoteSort) { + this.singleSort(sorters[0].field, sorters[0].direction); + + } else { + this.applySort(); + this.fireEvent('datachanged', this); + } + }, + + + each : function(fn, scope){ + this.data.each(fn, scope); + }, + + + getModifiedRecords : function(){ + return this.modified; + }, + + + sum : function(property, start, end){ + var rs = this.data.items, v = 0; + start = start || 0; + end = (end || end === 0) ? end : rs.length-1; + + for(var i = start; i <= end; i++){ + v += (rs[i].data[property] || 0); + } + return v; + }, + + + createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){ + if(Ext.isEmpty(value, false)){ + return false; + } + value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch); + return function(r) { + return value.test(r.data[property]); + }; + }, + + + createMultipleFilterFn: function(filters) { + return function(record) { + var isMatch = true; + + for (var i=0, j = filters.length; i < j; i++) { + var filter = filters[i], + fn = filter.fn, + scope = filter.scope; + + isMatch = isMatch && fn.call(scope, record); + } + + return isMatch; + }; + }, + + + filter : function(property, value, anyMatch, caseSensitive, exactMatch){ + var fn; + + if (Ext.isObject(property)) { + property = [property]; + } + + if (Ext.isArray(property)) { + var filters = []; + + + for (var i=0, j = property.length; i < j; i++) { + var filter = property[i], + func = filter.fn, + scope = filter.scope || this; + + + if (!Ext.isFunction(func)) { + func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch); + } + + filters.push({fn: func, scope: scope}); + } + + fn = this.createMultipleFilterFn(filters); + } else { + + fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch); + } + + return fn ? this.filterBy(fn) : this.clearFilter(); + }, + + + filterBy : function(fn, scope){ + this.snapshot = this.snapshot || this.data; + this.data = this.queryBy(fn, scope || this); + this.fireEvent('datachanged', this); + }, + + + clearFilter : function(suppressEvent){ + if(this.isFiltered()){ + this.data = this.snapshot; + delete this.snapshot; + if(suppressEvent !== true){ + this.fireEvent('datachanged', this); + } + } + }, + + + isFiltered : function(){ + return !!this.snapshot && this.snapshot != this.data; + }, + + + query : function(property, value, anyMatch, caseSensitive){ + var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); + return fn ? this.queryBy(fn) : this.data.clone(); + }, + + + queryBy : function(fn, scope){ + var data = this.snapshot || this.data; + return data.filterBy(fn, scope||this); + }, + + + find : function(property, value, start, anyMatch, caseSensitive){ + var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); + return fn ? this.data.findIndexBy(fn, null, start) : -1; + }, + + + findExact: function(property, value, start){ + return this.data.findIndexBy(function(rec){ + return rec.get(property) === value; + }, this, start); + }, + + + findBy : function(fn, scope, start){ + return this.data.findIndexBy(fn, scope, start); + }, + + + collect : function(dataIndex, allowNull, bypassFilter){ + var d = (bypassFilter === true && this.snapshot) ? + this.snapshot.items : this.data.items; + var v, sv, r = [], l = {}; + for(var i = 0, len = d.length; i < len; i++){ + v = d[i].data[dataIndex]; + sv = String(v); + if((allowNull || !Ext.isEmpty(v)) && !l[sv]){ + l[sv] = true; + r[r.length] = v; + } + } + return r; + }, + + + afterEdit : function(record){ + if(this.modified.indexOf(record) == -1){ + this.modified.push(record); + } + this.fireEvent('update', this, record, Ext.data.Record.EDIT); + }, + + + afterReject : function(record){ + this.modified.remove(record); + this.fireEvent('update', this, record, Ext.data.Record.REJECT); + }, + + + afterCommit : function(record){ + this.modified.remove(record); + this.fireEvent('update', this, record, Ext.data.Record.COMMIT); + }, + + + commitChanges : function(){ + var modified = this.modified.slice(0), + length = modified.length, + i; + + for (i = 0; i < length; i++){ + modified[i].commit(); + } + + this.modified = []; + this.removed = []; + }, + + + rejectChanges : function() { + var modified = this.modified.slice(0), + removed = this.removed.slice(0).reverse(), + mLength = modified.length, + rLength = removed.length, + i; + + for (i = 0; i < mLength; i++) { + modified[i].reject(); + } + + for (i = 0; i < rLength; i++) { + this.insert(removed[i].lastIndex || 0, removed[i]); + removed[i].reject(); + } + + this.modified = []; + this.removed = []; + }, + + + onMetaChange : function(meta){ + this.recordType = this.reader.recordType; + this.fields = this.recordType.prototype.fields; + delete this.snapshot; + if(this.reader.meta.sortInfo){ + this.sortInfo = this.reader.meta.sortInfo; + }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){ + delete this.sortInfo; + } + if(this.writer){ + this.writer.meta = this.reader.meta; + } + this.modified = []; + this.fireEvent('metachange', this, this.reader.meta); + }, + + + findInsertIndex : function(record){ + this.suspendEvents(); + var data = this.data.clone(); + this.data.add(record); + this.applySort(); + var index = this.data.indexOf(record); + this.data = data; + this.resumeEvents(); + return index; + }, + + + setBaseParam : function (name, value){ + this.baseParams = this.baseParams || {}; + this.baseParams[name] = value; + } +}); + +Ext.reg('store', Ext.data.Store); + + +Ext.data.Store.Error = Ext.extend(Ext.Error, { + name: 'Ext.data.Store' +}); +Ext.apply(Ext.data.Store.Error.prototype, { + lang: { + 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.' + } +}); + +Ext.data.Field = Ext.extend(Object, { + + constructor : function(config){ + if(Ext.isString(config)){ + config = {name: config}; + } + Ext.apply(this, config); + + var types = Ext.data.Types, + st = this.sortType, + t; + + if(this.type){ + if(Ext.isString(this.type)){ + this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO; + } + }else{ + this.type = types.AUTO; + } + + + if(Ext.isString(st)){ + this.sortType = Ext.data.SortTypes[st]; + }else if(Ext.isEmpty(st)){ + this.sortType = this.type.sortType; + } + + if(!this.convert){ + this.convert = this.type.convert; + } + }, + + + + + + dateFormat: null, + + + useNull: false, + + + defaultValue: "", + + mapping: null, + + sortType : null, + + sortDir : "ASC", + + allowBlank : true +}); + +Ext.data.DataReader = function(meta, recordType){ + + this.meta = meta; + + this.recordType = Ext.isArray(recordType) ? + Ext.data.Record.create(recordType) : recordType; + + + if (this.recordType){ + this.buildExtractors(); + } +}; + +Ext.data.DataReader.prototype = { + + + getTotal: Ext.emptyFn, + + getRoot: Ext.emptyFn, + + getMessage: Ext.emptyFn, + + getSuccess: Ext.emptyFn, + + getId: Ext.emptyFn, + + buildExtractors : Ext.emptyFn, + + extractValues : Ext.emptyFn, + + + realize: function(rs, data){ + if (Ext.isArray(rs)) { + for (var i = rs.length - 1; i >= 0; i--) { + + if (Ext.isArray(data)) { + this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift()); + } + else { + + + this.realize(rs.splice(i,1).shift(), data); + } + } + } + else { + + if (Ext.isArray(data) && data.length == 1) { + data = data.shift(); + } + if (!this.isData(data)) { + + + throw new Ext.data.DataReader.Error('realize', rs); + } + rs.phantom = false; + rs._phid = rs.id; + rs.id = this.getId(data); + rs.data = data; + + rs.commit(); + rs.store.reMap(rs); + } + }, + + + update : function(rs, data) { + if (Ext.isArray(rs)) { + for (var i=rs.length-1; i >= 0; i--) { + if (Ext.isArray(data)) { + this.update(rs.splice(i,1).shift(), data.splice(i,1).shift()); + } + else { + + + this.update(rs.splice(i,1).shift(), data); + } + } + } + else { + + if (Ext.isArray(data) && data.length == 1) { + data = data.shift(); + } + if (this.isData(data)) { + rs.data = Ext.apply(rs.data, data); + } + rs.commit(); + } + }, + + + extractData : function(root, returnRecords) { + + var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node'; + + var rs = []; + + + + if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) { + root = [root]; + } + var f = this.recordType.prototype.fields, + fi = f.items, + fl = f.length, + rs = []; + if (returnRecords === true) { + var Record = this.recordType; + for (var i = 0; i < root.length; i++) { + var n = root[i]; + var record = new Record(this.extractValues(n, fi, fl), this.getId(n)); + record[rawName] = n; + rs.push(record); + } + } + else { + for (var i = 0; i < root.length; i++) { + var data = this.extractValues(root[i], fi, fl); + data[this.meta.idProperty] = this.getId(root[i]); + rs.push(data); + } + } + return rs; + }, + + + isData : function(data) { + return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false; + }, + + + onMetaChange : function(meta){ + delete this.ef; + this.meta = meta; + this.recordType = Ext.data.Record.create(meta.fields); + this.buildExtractors(); + } +}; + + +Ext.data.DataReader.Error = Ext.extend(Ext.Error, { + constructor : function(message, arg) { + this.arg = arg; + Ext.Error.call(this, message); + }, + name: 'Ext.data.DataReader' +}); +Ext.apply(Ext.data.DataReader.Error.prototype, { + lang : { + 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.", + 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.", + 'invalid-response': "#readResponse received an invalid response from the server." + } +}); + +Ext.data.DataWriter = function(config){ + Ext.apply(this, config); +}; +Ext.data.DataWriter.prototype = { + + + writeAllFields : false, + + listful : false, + + + apply : function(params, baseParams, action, rs) { + var data = [], + renderer = action + 'Record'; + + if (Ext.isArray(rs)) { + Ext.each(rs, function(rec){ + data.push(this[renderer](rec)); + }, this); + } + else if (rs instanceof Ext.data.Record) { + data = this[renderer](rs); + } + this.render(params, baseParams, data); + }, + + + render : Ext.emptyFn, + + + updateRecord : Ext.emptyFn, + + + createRecord : Ext.emptyFn, + + + destroyRecord : Ext.emptyFn, + + + toHash : function(rec, config) { + var map = rec.fields.map, + data = {}, + raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data, + m; + Ext.iterate(raw, function(prop, value){ + if((m = map[prop])){ + data[m.mapping ? m.mapping : m.name] = value; + } + }); + + + + if (rec.phantom) { + if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) { + delete data[this.meta.idProperty]; + } + } else { + data[this.meta.idProperty] = rec.id; + } + return data; + }, + + + toArray : function(data) { + var fields = []; + Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this); + return fields; + } +}; +Ext.data.DataProxy = function(conn){ + + + conn = conn || {}; + + + + + + this.api = conn.api; + this.url = conn.url; + this.restful = conn.restful; + this.listeners = conn.listeners; + + + this.prettyUrls = conn.prettyUrls; + + + + this.addEvents( + + 'exception', + + 'beforeload', + + 'load', + + 'loadexception', + + 'beforewrite', + + 'write' + ); + Ext.data.DataProxy.superclass.constructor.call(this); + + + try { + Ext.data.Api.prepare(this); + } catch (e) { + if (e instanceof Ext.data.Api.Error) { + e.toConsole(); + } + } + + Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']); +}; + +Ext.extend(Ext.data.DataProxy, Ext.util.Observable, { + + restful: false, + + + setApi : function() { + if (arguments.length == 1) { + var valid = Ext.data.Api.isValid(arguments[0]); + if (valid === true) { + this.api = arguments[0]; + } + else { + throw new Ext.data.Api.Error('invalid', valid); + } + } + else if (arguments.length == 2) { + if (!Ext.data.Api.isAction(arguments[0])) { + throw new Ext.data.Api.Error('invalid', arguments[0]); + } + this.api[arguments[0]] = arguments[1]; + } + Ext.data.Api.prepare(this); + }, + + + isApiAction : function(action) { + return (this.api[action]) ? true : false; + }, + + + request : function(action, rs, params, reader, callback, scope, options) { + if (!this.api[action] && !this.load) { + throw new Ext.data.DataProxy.Error('action-undefined', action); + } + params = params || {}; + if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) { + this.doRequest.apply(this, arguments); + } + else { + callback.call(scope || this, null, options, false); + } + }, + + + + load : null, + + + doRequest : function(action, rs, params, reader, callback, scope, options) { + + + + this.load(params, reader, callback, scope, options); + }, + + + onRead : Ext.emptyFn, + + onWrite : Ext.emptyFn, + + buildUrl : function(action, record) { + record = record || null; + + + + + var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url; + if (!url) { + throw new Ext.data.Api.Error('invalid-url', action); + } + + + + + + + + var provides = null; + var m = url.match(/(.*)(\.json|\.xml|\.html)$/); + if (m) { + provides = m[2]; + url = m[1]; + } + + if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) { + url += '/' + record.id; + } + return (provides === null) ? url : url + provides; + }, + + + destroy: function(){ + this.purgeListeners(); + } +}); + + + +Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype); +Ext.util.Observable.call(Ext.data.DataProxy); + + +Ext.data.DataProxy.Error = Ext.extend(Ext.Error, { + constructor : function(message, arg) { + this.arg = arg; + Ext.Error.call(this, message); + }, + name: 'Ext.data.DataProxy' +}); +Ext.apply(Ext.data.DataProxy.Error.prototype, { + lang: { + 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.", + 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.' + } +}); + + + +Ext.data.Request = function(params) { + Ext.apply(this, params); +}; +Ext.data.Request.prototype = { + + action : undefined, + + rs : undefined, + + params: undefined, + + callback : Ext.emptyFn, + + scope : undefined, + + reader : undefined +}; + +Ext.data.Response = function(params) { + Ext.apply(this, params); +}; +Ext.data.Response.prototype = { + + action: undefined, + + success : undefined, + + message : undefined, + + data: undefined, + + raw: undefined, + + records: undefined +}; + +Ext.data.ScriptTagProxy = function(config){ + Ext.apply(this, config); + + Ext.data.ScriptTagProxy.superclass.constructor.call(this, config); + + this.head = document.getElementsByTagName("head")[0]; + + +}; + +Ext.data.ScriptTagProxy.TRANS_ID = 1000; + +Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, { + + + timeout : 30000, + + callbackParam : "callback", + + nocache : true, + + + doRequest : function(action, rs, params, reader, callback, scope, arg) { + var p = Ext.urlEncode(Ext.apply(params, this.extraParams)); + + var url = this.buildUrl(action, rs); + if (!url) { + throw new Ext.data.Api.Error('invalid-url', url); + } + url = Ext.urlAppend(url, p); + + if(this.nocache){ + url = Ext.urlAppend(url, '_dc=' + (new Date().getTime())); + } + var transId = ++Ext.data.ScriptTagProxy.TRANS_ID; + var trans = { + id : transId, + action: action, + cb : "stcCallback"+transId, + scriptId : "stcScript"+transId, + params : params, + arg : arg, + url : url, + callback : callback, + scope : scope, + reader : reader + }; + window[trans.cb] = this.createCallback(action, rs, trans); + url += String.format("&{0}={1}", this.callbackParam, trans.cb); + if(this.autoAbort !== false){ + this.abort(); + } + + trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]); + + var script = document.createElement("script"); + script.setAttribute("src", url); + script.setAttribute("type", "text/javascript"); + script.setAttribute("id", trans.scriptId); + this.head.appendChild(script); + + this.trans = trans; + }, + + + createCallback : function(action, rs, trans) { + var self = this; + return function(res) { + self.trans = false; + self.destroyTrans(trans, true); + if (action === Ext.data.Api.actions.read) { + self.onRead.call(self, action, trans, res); + } else { + self.onWrite.call(self, action, trans, res, rs); + } + }; + }, + + onRead : function(action, trans, res) { + var result; + try { + result = trans.reader.readRecords(res); + }catch(e){ + + this.fireEvent("loadexception", this, trans, res, e); + + this.fireEvent('exception', this, 'response', action, trans, res, e); + trans.callback.call(trans.scope||window, null, trans.arg, false); + return; + } + if (result.success === false) { + + this.fireEvent('loadexception', this, trans, res); + + this.fireEvent('exception', this, 'remote', action, trans, res, null); + } else { + this.fireEvent("load", this, res, trans.arg); + } + trans.callback.call(trans.scope||window, result, trans.arg, result.success); + }, + + onWrite : function(action, trans, response, rs) { + var reader = trans.reader; + try { + + var res = reader.readResponse(action, response); + } catch (e) { + this.fireEvent('exception', this, 'response', action, trans, res, e); + trans.callback.call(trans.scope||window, null, res, false); + return; + } + if(!res.success === true){ + this.fireEvent('exception', this, 'remote', action, trans, res, rs); + trans.callback.call(trans.scope||window, null, res, false); + return; + } + this.fireEvent("write", this, action, res.data, res, rs, trans.arg ); + trans.callback.call(trans.scope||window, res.data, res, true); + }, + + + isLoading : function(){ + return this.trans ? true : false; + }, + + + abort : function(){ + if(this.isLoading()){ + this.destroyTrans(this.trans); + } + }, + + + destroyTrans : function(trans, isLoaded){ + this.head.removeChild(document.getElementById(trans.scriptId)); + clearTimeout(trans.timeoutId); + if(isLoaded){ + window[trans.cb] = undefined; + try{ + delete window[trans.cb]; + }catch(e){} + }else{ + + window[trans.cb] = function(){ + window[trans.cb] = undefined; + try{ + delete window[trans.cb]; + }catch(e){} + }; + } + }, + + + handleFailure : function(trans){ + this.trans = false; + this.destroyTrans(trans, false); + if (trans.action === Ext.data.Api.actions.read) { + + this.fireEvent("loadexception", this, null, trans.arg); + } + + this.fireEvent('exception', this, 'response', trans.action, { + response: null, + options: trans.arg + }); + trans.callback.call(trans.scope||window, null, trans.arg, false); + }, + + + destroy: function(){ + this.abort(); + Ext.data.ScriptTagProxy.superclass.destroy.call(this); + } +}); +Ext.data.HttpProxy = function(conn){ + Ext.data.HttpProxy.superclass.constructor.call(this, conn); + + + this.conn = conn; + + + + + + this.conn.url = null; + + this.useAjax = !conn || !conn.events; + + + var actions = Ext.data.Api.actions; + this.activeRequest = {}; + for (var verb in actions) { + this.activeRequest[actions[verb]] = undefined; + } +}; + +Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, { + + getConnection : function() { + return this.useAjax ? Ext.Ajax : this.conn; + }, + + + setUrl : function(url, makePermanent) { + this.conn.url = url; + if (makePermanent === true) { + this.url = url; + this.api = null; + Ext.data.Api.prepare(this); + } + }, + + + doRequest : function(action, rs, params, reader, cb, scope, arg) { + var o = { + method: (this.api[action]) ? this.api[action]['method'] : undefined, + request: { + callback : cb, + scope : scope, + arg : arg + }, + reader: reader, + callback : this.createCallback(action, rs), + scope: this + }; + + + + if (params.jsonData) { + o.jsonData = params.jsonData; + } else if (params.xmlData) { + o.xmlData = params.xmlData; + } else { + o.params = params || {}; + } + + + + this.conn.url = this.buildUrl(action, rs); + + if(this.useAjax){ + + Ext.applyIf(o, this.conn); + + + if (action == Ext.data.Api.actions.read && this.activeRequest[action]) { + Ext.Ajax.abort(this.activeRequest[action]); + } + this.activeRequest[action] = Ext.Ajax.request(o); + }else{ + this.conn.request(o); + } + + this.conn.url = null; + }, + + + createCallback : function(action, rs) { + return function(o, success, response) { + this.activeRequest[action] = undefined; + if (!success) { + if (action === Ext.data.Api.actions.read) { + + + this.fireEvent('loadexception', this, o, response); + } + this.fireEvent('exception', this, 'response', action, o, response); + o.request.callback.call(o.request.scope, null, o.request.arg, false); + return; + } + if (action === Ext.data.Api.actions.read) { + this.onRead(action, o, response); + } else { + this.onWrite(action, o, response, rs); + } + }; + }, + + + onRead : function(action, o, response) { + var result; + try { + result = o.reader.read(response); + }catch(e){ + + + this.fireEvent('loadexception', this, o, response, e); + + this.fireEvent('exception', this, 'response', action, o, response, e); + o.request.callback.call(o.request.scope, null, o.request.arg, false); + return; + } + if (result.success === false) { + + + this.fireEvent('loadexception', this, o, response); + + + var res = o.reader.readResponse(action, response); + this.fireEvent('exception', this, 'remote', action, o, res, null); + } + else { + this.fireEvent('load', this, o, o.request.arg); + } + + + + o.request.callback.call(o.request.scope, result, o.request.arg, result.success); + }, + + onWrite : function(action, o, response, rs) { + var reader = o.reader; + var res; + try { + res = reader.readResponse(action, response); + } catch (e) { + this.fireEvent('exception', this, 'response', action, o, response, e); + o.request.callback.call(o.request.scope, null, o.request.arg, false); + return; + } + if (res.success === true) { + this.fireEvent('write', this, action, res.data, res, rs, o.request.arg); + } else { + this.fireEvent('exception', this, 'remote', action, o, res, rs); + } + + + + o.request.callback.call(o.request.scope, res.data, res, res.success); + }, + + + destroy: function(){ + if(!this.useAjax){ + this.conn.abort(); + }else if(this.activeRequest){ + var actions = Ext.data.Api.actions; + for (var verb in actions) { + if(this.activeRequest[actions[verb]]){ + Ext.Ajax.abort(this.activeRequest[actions[verb]]); + } + } + } + Ext.data.HttpProxy.superclass.destroy.call(this); + } +}); +Ext.data.MemoryProxy = function(data){ + + var api = {}; + api[Ext.data.Api.actions.read] = true; + Ext.data.MemoryProxy.superclass.constructor.call(this, { + api: api + }); + this.data = data; +}; + +Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, { + + + + doRequest : function(action, rs, params, reader, callback, scope, arg) { + + params = params || {}; + var result; + try { + result = reader.readRecords(this.data); + }catch(e){ + + this.fireEvent("loadexception", this, null, arg, e); + + this.fireEvent('exception', this, 'response', action, arg, null, e); + callback.call(scope, null, arg, false); + return; + } + callback.call(scope, result, arg, true); + } +}); +Ext.data.Types = new function(){ + var st = Ext.data.SortTypes; + Ext.apply(this, { + + stripRe: /[\$,%]/g, + + + AUTO: { + convert: function(v){ return v; }, + sortType: st.none, + type: 'auto' + }, + + + STRING: { + convert: function(v){ return (v === undefined || v === null) ? '' : String(v); }, + sortType: st.asUCString, + type: 'string' + }, + + + INT: { + convert: function(v){ + return v !== undefined && v !== null && v !== '' ? + parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); + }, + sortType: st.none, + type: 'int' + }, + + + FLOAT: { + convert: function(v){ + return v !== undefined && v !== null && v !== '' ? + parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); + }, + sortType: st.none, + type: 'float' + }, + + + BOOL: { + convert: function(v){ return v === true || v === 'true' || v == 1; }, + sortType: st.none, + type: 'bool' + }, + + + DATE: { + convert: function(v){ + var df = this.dateFormat; + if(!v){ + return null; + } + if(Ext.isDate(v)){ + return v; + } + if(df){ + if(df == 'timestamp'){ + return new Date(v*1000); + } + if(df == 'time'){ + return new Date(parseInt(v, 10)); + } + return Date.parseDate(v, df); + } + var parsed = Date.parse(v); + return parsed ? new Date(parsed) : null; + }, + sortType: st.asDate, + type: 'date' + } + }); + + Ext.apply(this, { + + BOOLEAN: this.BOOL, + + INTEGER: this.INT, + + NUMBER: this.FLOAT + }); +}; +Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, { + + encode : true, + + encodeDelete: false, + + constructor : function(config){ + Ext.data.JsonWriter.superclass.constructor.call(this, config); + }, + + + render : function(params, baseParams, data) { + if (this.encode === true) { + + Ext.apply(params, baseParams); + params[this.meta.root] = Ext.encode(data); + } else { + + var jdata = Ext.apply({}, baseParams); + jdata[this.meta.root] = data; + params.jsonData = jdata; + } + }, + + createRecord : function(rec) { + return this.toHash(rec); + }, + + updateRecord : function(rec) { + return this.toHash(rec); + + }, + + destroyRecord : function(rec){ + if(this.encodeDelete){ + var data = {}; + data[this.meta.idProperty] = rec.id; + return data; + }else{ + return rec.id; + } + } +}); +Ext.data.JsonReader = function(meta, recordType){ + meta = meta || {}; + + + + + Ext.applyIf(meta, { + idProperty: 'id', + successProperty: 'success', + totalProperty: 'total' + }); + + Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields); +}; +Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, { + + + read : function(response){ + var json = response.responseText; + var o = Ext.decode(json); + if(!o) { + throw {message: 'JsonReader.read: Json object not found'}; + } + return this.readRecords(o); + }, + + + + readResponse : function(action, response) { + var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response; + if(!o) { + throw new Ext.data.JsonReader.Error('response'); + } + + var root = this.getRoot(o), + success = this.getSuccess(o); + if (success && action === Ext.data.Api.actions.create) { + var def = Ext.isDefined(root); + if (def && Ext.isEmpty(root)) { + throw new Ext.data.JsonReader.Error('root-empty', this.meta.root); + } + else if (!def) { + throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root); + } + } + + + var res = new Ext.data.Response({ + action: action, + success: success, + data: (root) ? this.extractData(root, false) : [], + message: this.getMessage(o), + raw: o + }); + + + if (Ext.isEmpty(res.success)) { + throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty); + } + return res; + }, + + + readRecords : function(o){ + + this.jsonData = o; + if(o.metaData){ + this.onMetaChange(o.metaData); + } + var s = this.meta, Record = this.recordType, + f = Record.prototype.fields, fi = f.items, fl = f.length, v; + + var root = this.getRoot(o), c = root.length, totalRecords = c, success = true; + if(s.totalProperty){ + v = parseInt(this.getTotal(o), 10); + if(!isNaN(v)){ + totalRecords = v; + } + } + if(s.successProperty){ + v = this.getSuccess(o); + if(v === false || v === 'false'){ + success = false; + } + } + + + return { + success : success, + records : this.extractData(root, true), + totalRecords : totalRecords + }; + }, + + + buildExtractors : function() { + if(this.ef){ + return; + } + var s = this.meta, Record = this.recordType, + f = Record.prototype.fields, fi = f.items, fl = f.length; + + if(s.totalProperty) { + this.getTotal = this.createAccessor(s.totalProperty); + } + if(s.successProperty) { + this.getSuccess = this.createAccessor(s.successProperty); + } + if (s.messageProperty) { + this.getMessage = this.createAccessor(s.messageProperty); + } + this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;}; + if (s.id || s.idProperty) { + var g = this.createAccessor(s.id || s.idProperty); + this.getId = function(rec) { + var r = g(rec); + return (r === undefined || r === '') ? null : r; + }; + } else { + this.getId = function(){return null;}; + } + var ef = []; + for(var i = 0; i < fl; i++){ + f = fi[i]; + var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; + ef.push(this.createAccessor(map)); + } + this.ef = ef; + }, + + + simpleAccess : function(obj, subsc) { + return obj[subsc]; + }, + + + createAccessor : function(){ + var re = /[\[\.]/; + return function(expr) { + if(Ext.isEmpty(expr)){ + return Ext.emptyFn; + } + if(Ext.isFunction(expr)){ + return expr; + } + var i = String(expr).search(re); + if(i >= 0){ + return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr); + } + return function(obj){ + return obj[expr]; + }; + + }; + }(), + + + extractValues : function(data, items, len) { + var f, values = {}; + for(var j = 0; j < len; j++){ + f = items[j]; + var v = this.ef[j](data); + values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data); + } + return values; + } +}); + + +Ext.data.JsonReader.Error = Ext.extend(Ext.Error, { + constructor : function(message, arg) { + this.arg = arg; + Ext.Error.call(this, message); + }, + name : 'Ext.data.JsonReader' +}); +Ext.apply(Ext.data.JsonReader.Error.prototype, { + lang: { + 'response': 'An error occurred while json-decoding your server response', + 'successProperty-response': 'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.', + 'root-undefined-config': 'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.', + 'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.', + 'root-empty': 'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.' + } +}); + +Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, { + + + + + readRecords : function(o){ + this.arrayData = o; + var s = this.meta, + sid = s ? Ext.num(s.idIndex, s.id) : null, + recordType = this.recordType, + fields = recordType.prototype.fields, + records = [], + success = true, + v; + + var root = this.getRoot(o); + + for(var i = 0, len = root.length; i < len; i++) { + var n = root[i], + values = {}, + id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null); + for(var j = 0, jlen = fields.length; j < jlen; j++) { + var f = fields.items[j], + k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j; + v = n[k] !== undefined ? n[k] : f.defaultValue; + v = f.convert(v, n); + values[f.name] = v; + } + var record = new recordType(values, id); + record.json = n; + records[records.length] = record; + } + + var totalRecords = records.length; + + if(s.totalProperty) { + v = parseInt(this.getTotal(o), 10); + if(!isNaN(v)) { + totalRecords = v; + } + } + if(s.successProperty){ + v = this.getSuccess(o); + if(v === false || v === 'false'){ + success = false; + } + } + + return { + success : success, + records : records, + totalRecords : totalRecords + }; + } +}); +Ext.data.ArrayStore = Ext.extend(Ext.data.Store, { + + constructor: function(config){ + Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, { + reader: new Ext.data.ArrayReader(config) + })); + }, + + loadData : function(data, append){ + if(this.expandData === true){ + var r = []; + for(var i = 0, len = data.length; i < len; i++){ + r[r.length] = [data[i]]; + } + data = r; + } + Ext.data.ArrayStore.superclass.loadData.call(this, data, append); + } +}); +Ext.reg('arraystore', Ext.data.ArrayStore); + + +Ext.data.SimpleStore = Ext.data.ArrayStore; +Ext.reg('simplestore', Ext.data.SimpleStore); +Ext.data.JsonStore = Ext.extend(Ext.data.Store, { + + constructor: function(config){ + Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, { + reader: new Ext.data.JsonReader(config) + })); + } +}); +Ext.reg('jsonstore', Ext.data.JsonStore); +Ext.data.XmlWriter = function(params) { + Ext.data.XmlWriter.superclass.constructor.apply(this, arguments); + + this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile(); +}; +Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, { + + documentRoot: 'xrequest', + + forceDocumentRoot: false, + + root: 'records', + + xmlVersion : '1.0', + + xmlEncoding: 'ISO-8859-15', + + + tpl: '<\u003fxml version="{version}" encoding="{encoding}"\u003f><{documentRoot}><{name}>{value}<{root}><{parent.record}><{name}>{value}', + + + + render : function(params, baseParams, data) { + baseParams = this.toArray(baseParams); + params.xmlData = this.tpl.applyTemplate({ + version: this.xmlVersion, + encoding: this.xmlEncoding, + documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false, + record: this.meta.record, + root: this.root, + baseParams: baseParams, + records: (Ext.isArray(data[0])) ? data : [data] + }); + }, + + + createRecord : function(rec) { + return this.toArray(this.toHash(rec)); + }, + + + updateRecord : function(rec) { + return this.toArray(this.toHash(rec)); + + }, + + destroyRecord : function(rec) { + var data = {}; + data[this.meta.idProperty] = rec.id; + return this.toArray(data); + } +}); + +Ext.data.XmlReader = function(meta, recordType){ + meta = meta || {}; + + + Ext.applyIf(meta, { + idProperty: meta.idProperty || meta.idPath || meta.id, + successProperty: meta.successProperty || meta.success + }); + + Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields); +}; +Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, { + + read : function(response){ + var doc = response.responseXML; + if(!doc) { + throw {message: "XmlReader.read: XML Document not available"}; + } + return this.readRecords(doc); + }, + + + readRecords : function(doc){ + + this.xmlData = doc; + + var root = doc.documentElement || doc, + q = Ext.DomQuery, + totalRecords = 0, + success = true; + + if(this.meta.totalProperty){ + totalRecords = this.getTotal(root, 0); + } + if(this.meta.successProperty){ + success = this.getSuccess(root); + } + + var records = this.extractData(q.select(this.meta.record, root), true); + + + return { + success : success, + records : records, + totalRecords : totalRecords || records.length + }; + }, + + + readResponse : function(action, response) { + var q = Ext.DomQuery, + doc = response.responseXML, + root = doc.documentElement || doc; + + + var res = new Ext.data.Response({ + action: action, + success : this.getSuccess(root), + message: this.getMessage(root), + data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false), + raw: doc + }); + + if (Ext.isEmpty(res.success)) { + throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty); + } + + + if (action === Ext.data.Api.actions.create) { + var def = Ext.isDefined(res.data); + if (def && Ext.isEmpty(res.data)) { + throw new Ext.data.JsonReader.Error('root-empty', this.meta.root); + } + else if (!def) { + throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root); + } + } + return res; + }, + + getSuccess : function() { + return true; + }, + + + buildExtractors : function() { + if(this.ef){ + return; + } + var s = this.meta, + Record = this.recordType, + f = Record.prototype.fields, + fi = f.items, + fl = f.length; + + if(s.totalProperty) { + this.getTotal = this.createAccessor(s.totalProperty); + } + if(s.successProperty) { + this.getSuccess = this.createAccessor(s.successProperty); + } + if (s.messageProperty) { + this.getMessage = this.createAccessor(s.messageProperty); + } + this.getRoot = function(res) { + return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root]; + }; + if (s.idPath || s.idProperty) { + var g = this.createAccessor(s.idPath || s.idProperty); + this.getId = function(rec) { + var id = g(rec) || rec.id; + return (id === undefined || id === '') ? null : id; + }; + } else { + this.getId = function(){return null;}; + } + var ef = []; + for(var i = 0; i < fl; i++){ + f = fi[i]; + var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; + ef.push(this.createAccessor(map)); + } + this.ef = ef; + }, + + + createAccessor : function(){ + var q = Ext.DomQuery; + return function(key) { + if (Ext.isFunction(key)) { + return key; + } + switch(key) { + case this.meta.totalProperty: + return function(root, def){ + return q.selectNumber(key, root, def); + }; + break; + case this.meta.successProperty: + return function(root, def) { + var sv = q.selectValue(key, root, true); + var success = sv !== false && sv !== 'false'; + return success; + }; + break; + default: + return function(root, def) { + return q.selectValue(key, root, def); + }; + break; + } + }; + }(), + + + extractValues : function(data, items, len) { + var f, values = {}; + for(var j = 0; j < len; j++){ + f = items[j]; + var v = this.ef[j](data); + values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data); + } + return values; + } +}); +Ext.data.XmlStore = Ext.extend(Ext.data.Store, { + + constructor: function(config){ + Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, { + reader: new Ext.data.XmlReader(config) + })); + } +}); +Ext.reg('xmlstore', Ext.data.XmlStore); +Ext.data.GroupingStore = Ext.extend(Ext.data.Store, { + + + constructor: function(config) { + config = config || {}; + + + + + + this.hasMultiSort = true; + this.multiSortInfo = this.multiSortInfo || {sorters: []}; + + var sorters = this.multiSortInfo.sorters, + groupField = config.groupField || this.groupField, + sortInfo = config.sortInfo || this.sortInfo, + groupDir = config.groupDir || this.groupDir; + + + if(groupField){ + sorters.push({ + field : groupField, + direction: groupDir + }); + } + + + if (sortInfo) { + sorters.push(sortInfo); + } + + Ext.data.GroupingStore.superclass.constructor.call(this, config); + + this.addEvents( + + 'groupchange' + ); + + this.applyGroupField(); + }, + + + + remoteGroup : false, + + groupOnSort:false, + + + groupDir : 'ASC', + + + clearGrouping : function(){ + this.groupField = false; + + if(this.remoteGroup){ + if(this.baseParams){ + delete this.baseParams.groupBy; + delete this.baseParams.groupDir; + } + var lo = this.lastOptions; + if(lo && lo.params){ + delete lo.params.groupBy; + delete lo.params.groupDir; + } + + this.reload(); + }else{ + this.sort(); + this.fireEvent('datachanged', this); + } + }, + + + groupBy : function(field, forceRegroup, direction) { + direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir; + + if (this.groupField == field && this.groupDir == direction && !forceRegroup) { + return; + } + + + + var sorters = this.multiSortInfo.sorters; + if (sorters.length > 0 && sorters[0].field == this.groupField) { + sorters.shift(); + } + + this.groupField = field; + this.groupDir = direction; + this.applyGroupField(); + + var fireGroupEvent = function() { + this.fireEvent('groupchange', this, this.getGroupState()); + }; + + if (this.groupOnSort) { + this.sort(field, direction); + fireGroupEvent.call(this); + return; + } + + if (this.remoteGroup) { + this.on('load', fireGroupEvent, this, {single: true}); + this.reload(); + } else { + this.sort(sorters); + fireGroupEvent.call(this); + } + }, + + + + sort : function(fieldName, dir) { + if (this.remoteSort) { + return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir); + } + + var sorters = []; + + + if (Ext.isArray(arguments[0])) { + sorters = arguments[0]; + } else if (fieldName == undefined) { + + + sorters = this.sortInfo ? [this.sortInfo] : []; + } else { + + + var field = this.fields.get(fieldName); + if (!field) return false; + + var name = field.name, + sortInfo = this.sortInfo || null, + sortToggle = this.sortToggle ? this.sortToggle[name] : null; + + if (!dir) { + if (sortInfo && sortInfo.field == name) { + dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC'); + } else { + dir = field.sortDir; + } + } + + this.sortToggle[name] = dir; + this.sortInfo = {field: name, direction: dir}; + + sorters = [this.sortInfo]; + } + + + if (this.groupField) { + sorters.unshift({direction: this.groupDir, field: this.groupField}); + } + + return this.multiSort.call(this, sorters, dir); + }, + + + applyGroupField: function(){ + if (this.remoteGroup) { + if(!this.baseParams){ + this.baseParams = {}; + } + + Ext.apply(this.baseParams, { + groupBy : this.groupField, + groupDir: this.groupDir + }); + + var lo = this.lastOptions; + if (lo && lo.params) { + lo.params.groupDir = this.groupDir; + + + delete lo.params.groupBy; + } + } + }, + + + applyGrouping : function(alwaysFireChange){ + if(this.groupField !== false){ + this.groupBy(this.groupField, true, this.groupDir); + return true; + }else{ + if(alwaysFireChange === true){ + this.fireEvent('datachanged', this); + } + return false; + } + }, + + + getGroupState : function(){ + return this.groupOnSort && this.groupField !== false ? + (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField; + } +}); +Ext.reg('groupingstore', Ext.data.GroupingStore); + +Ext.data.DirectProxy = function(config){ + Ext.apply(this, config); + if(typeof this.paramOrder == 'string'){ + this.paramOrder = this.paramOrder.split(/[\s,|]/); + } + Ext.data.DirectProxy.superclass.constructor.call(this, config); +}; + +Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, { + + paramOrder: undefined, + + + paramsAsHash: true, + + + directFn : undefined, + + + doRequest : function(action, rs, params, reader, callback, scope, options) { + var args = [], + directFn = this.api[action] || this.directFn; + + switch (action) { + case Ext.data.Api.actions.create: + args.push(params.jsonData); + break; + case Ext.data.Api.actions.read: + + if(directFn.directCfg.method.len > 0){ + if(this.paramOrder){ + for(var i = 0, len = this.paramOrder.length; i < len; i++){ + args.push(params[this.paramOrder[i]]); + } + }else if(this.paramsAsHash){ + args.push(params); + } + } + break; + case Ext.data.Api.actions.update: + args.push(params.jsonData); + break; + case Ext.data.Api.actions.destroy: + args.push(params.jsonData); + break; + } + + var trans = { + params : params || {}, + request: { + callback : callback, + scope : scope, + arg : options + }, + reader: reader + }; + + args.push(this.createCallback(action, rs, trans), this); + directFn.apply(window, args); + }, + + + createCallback : function(action, rs, trans) { + var me = this; + return function(result, res) { + if (!res.status) { + + if (action === Ext.data.Api.actions.read) { + me.fireEvent("loadexception", me, trans, res, null); + } + me.fireEvent('exception', me, 'remote', action, trans, res, null); + trans.request.callback.call(trans.request.scope, null, trans.request.arg, false); + return; + } + if (action === Ext.data.Api.actions.read) { + me.onRead(action, trans, result, res); + } else { + me.onWrite(action, trans, result, res, rs); + } + }; + }, + + + onRead : function(action, trans, result, res) { + var records; + try { + records = trans.reader.readRecords(result); + } + catch (ex) { + + this.fireEvent("loadexception", this, trans, res, ex); + + this.fireEvent('exception', this, 'response', action, trans, res, ex); + trans.request.callback.call(trans.request.scope, null, trans.request.arg, false); + return; + } + this.fireEvent("load", this, res, trans.request.arg); + trans.request.callback.call(trans.request.scope, records, trans.request.arg, true); + }, + + onWrite : function(action, trans, result, res, rs) { + var data = trans.reader.extractData(trans.reader.getRoot(result), false); + var success = trans.reader.getSuccess(result); + success = (success !== false); + if (success){ + this.fireEvent("write", this, action, data, res, rs, trans.request.arg); + }else{ + this.fireEvent('exception', this, 'remote', action, trans, result, rs); + } + trans.request.callback.call(trans.request.scope, data, res, success); + } +}); + +Ext.data.DirectStore = Ext.extend(Ext.data.Store, { + constructor : function(config){ + + var c = Ext.apply({}, { + batchTransactions: false + }, config); + Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, { + proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')), + reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader + })); + } +}); +Ext.reg('directstore', Ext.data.DirectStore); + +Ext.Direct = Ext.extend(Ext.util.Observable, { + + + + exceptions: { + TRANSPORT: 'xhr', + PARSE: 'parse', + LOGIN: 'login', + SERVER: 'exception' + }, + + + constructor: function(){ + this.addEvents( + + 'event', + + 'exception' + ); + this.transactions = {}; + this.providers = {}; + }, + + + addProvider : function(provider){ + var a = arguments; + if(a.length > 1){ + for(var i = 0, len = a.length; i < len; i++){ + this.addProvider(a[i]); + } + return; + } + + + if(!provider.events){ + provider = new Ext.Direct.PROVIDERS[provider.type](provider); + } + provider.id = provider.id || Ext.id(); + this.providers[provider.id] = provider; + + provider.on('data', this.onProviderData, this); + provider.on('exception', this.onProviderException, this); + + + if(!provider.isConnected()){ + provider.connect(); + } + + return provider; + }, + + + getProvider : function(id){ + return this.providers[id]; + }, + + removeProvider : function(id){ + var provider = id.id ? id : this.providers[id]; + provider.un('data', this.onProviderData, this); + provider.un('exception', this.onProviderException, this); + delete this.providers[provider.id]; + return provider; + }, + + addTransaction: function(t){ + this.transactions[t.tid] = t; + return t; + }, + + removeTransaction: function(t){ + delete this.transactions[t.tid || t]; + return t; + }, + + getTransaction: function(tid){ + return this.transactions[tid.tid || tid]; + }, + + onProviderData : function(provider, e){ + if(Ext.isArray(e)){ + for(var i = 0, len = e.length; i < len; i++){ + this.onProviderData(provider, e[i]); + } + return; + } + if(e.name && e.name != 'event' && e.name != 'exception'){ + this.fireEvent(e.name, e); + }else if(e.type == 'exception'){ + this.fireEvent('exception', e); + } + this.fireEvent('event', e, provider); + }, + + createEvent : function(response, extraProps){ + return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps)); + } +}); + +Ext.Direct = new Ext.Direct(); + +Ext.Direct.TID = 1; +Ext.Direct.PROVIDERS = {}; +Ext.Direct.Transaction = function(config){ + Ext.apply(this, config); + this.tid = ++Ext.Direct.TID; + this.retryCount = 0; +}; +Ext.Direct.Transaction.prototype = { + send: function(){ + this.provider.queueTransaction(this); + }, + + retry: function(){ + this.retryCount++; + this.send(); + }, + + getProvider: function(){ + return this.provider; + } +};Ext.Direct.Event = function(config){ + Ext.apply(this, config); +}; + +Ext.Direct.Event.prototype = { + status: true, + getData: function(){ + return this.data; + } +}; + +Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, { + type: 'rpc', + getTransaction: function(){ + return this.transaction || Ext.Direct.getTransaction(this.tid); + } +}); + +Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, { + status: false, + type: 'exception' +}); + +Ext.Direct.eventTypes = { + 'rpc': Ext.Direct.RemotingEvent, + 'event': Ext.Direct.Event, + 'exception': Ext.Direct.ExceptionEvent +}; + +Ext.direct.Provider = Ext.extend(Ext.util.Observable, { + + + + priority: 1, + + + + + constructor : function(config){ + Ext.apply(this, config); + this.addEvents( + + 'connect', + + 'disconnect', + + 'data', + + 'exception' + ); + Ext.direct.Provider.superclass.constructor.call(this, config); + }, + + + isConnected: function(){ + return false; + }, + + + connect: Ext.emptyFn, + + + disconnect: Ext.emptyFn +}); + +Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, { + parseResponse: function(xhr){ + if(!Ext.isEmpty(xhr.responseText)){ + if(typeof xhr.responseText == 'object'){ + return xhr.responseText; + } + return Ext.decode(xhr.responseText); + } + return null; + }, + + getEvents: function(xhr){ + var data = null; + try{ + data = this.parseResponse(xhr); + }catch(e){ + var event = new Ext.Direct.ExceptionEvent({ + data: e, + xhr: xhr, + code: Ext.Direct.exceptions.PARSE, + message: 'Error parsing json response: \n\n ' + data + }); + return [event]; + } + var events = []; + if(Ext.isArray(data)){ + for(var i = 0, len = data.length; i < len; i++){ + events.push(Ext.Direct.createEvent(data[i])); + } + }else{ + events.push(Ext.Direct.createEvent(data)); + } + return events; + } +}); +Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, { + + + priority: 3, + + + interval: 3000, + + + + + + + constructor : function(config){ + Ext.direct.PollingProvider.superclass.constructor.call(this, config); + this.addEvents( + + 'beforepoll', + + 'poll' + ); + }, + + + isConnected: function(){ + return !!this.pollTask; + }, + + + connect: function(){ + if(this.url && !this.pollTask){ + this.pollTask = Ext.TaskMgr.start({ + run: function(){ + if(this.fireEvent('beforepoll', this) !== false){ + if(typeof this.url == 'function'){ + this.url(this.baseParams); + }else{ + Ext.Ajax.request({ + url: this.url, + callback: this.onData, + scope: this, + params: this.baseParams + }); + } + } + }, + interval: this.interval, + scope: this + }); + this.fireEvent('connect', this); + }else if(!this.url){ + throw 'Error initializing PollingProvider, no url configured.'; + } + }, + + + disconnect: function(){ + if(this.pollTask){ + Ext.TaskMgr.stop(this.pollTask); + delete this.pollTask; + this.fireEvent('disconnect', this); + } + }, + + + onData: function(opt, success, xhr){ + if(success){ + var events = this.getEvents(xhr); + for(var i = 0, len = events.length; i < len; i++){ + var e = events[i]; + this.fireEvent('data', this, e); + } + }else{ + var e = new Ext.Direct.ExceptionEvent({ + data: e, + code: Ext.Direct.exceptions.TRANSPORT, + message: 'Unable to connect to the server.', + xhr: xhr + }); + this.fireEvent('data', this, e); + } + } +}); + +Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider; +Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, { + + + + + + + + + + enableBuffer: 10, + + + maxRetries: 1, + + + timeout: undefined, + + constructor : function(config){ + Ext.direct.RemotingProvider.superclass.constructor.call(this, config); + this.addEvents( + + 'beforecall', + + 'call' + ); + this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window; + this.transactions = {}; + this.callBuffer = []; + }, + + + initAPI : function(){ + var o = this.actions; + for(var c in o){ + var cls = this.namespace[c] || (this.namespace[c] = {}), + ms = o[c]; + for(var i = 0, len = ms.length; i < len; i++){ + var m = ms[i]; + cls[m.name] = this.createMethod(c, m); + } + } + }, + + + isConnected: function(){ + return !!this.connected; + }, + + connect: function(){ + if(this.url){ + this.initAPI(); + this.connected = true; + this.fireEvent('connect', this); + }else if(!this.url){ + throw 'Error initializing RemotingProvider, no url configured.'; + } + }, + + disconnect: function(){ + if(this.connected){ + this.connected = false; + this.fireEvent('disconnect', this); + } + }, + + onData: function(opt, success, xhr){ + if(success){ + var events = this.getEvents(xhr); + for(var i = 0, len = events.length; i < len; i++){ + var e = events[i], + t = this.getTransaction(e); + this.fireEvent('data', this, e); + if(t){ + this.doCallback(t, e, true); + Ext.Direct.removeTransaction(t); + } + } + }else{ + var ts = [].concat(opt.ts); + for(var i = 0, len = ts.length; i < len; i++){ + var t = this.getTransaction(ts[i]); + if(t && t.retryCount < this.maxRetries){ + t.retry(); + }else{ + var e = new Ext.Direct.ExceptionEvent({ + data: e, + transaction: t, + code: Ext.Direct.exceptions.TRANSPORT, + message: 'Unable to connect to the server.', + xhr: xhr + }); + this.fireEvent('data', this, e); + if(t){ + this.doCallback(t, e, false); + Ext.Direct.removeTransaction(t); + } + } + } + } + }, + + getCallData: function(t){ + return { + action: t.action, + method: t.method, + data: t.data, + type: 'rpc', + tid: t.tid + }; + }, + + doSend : function(data){ + var o = { + url: this.url, + callback: this.onData, + scope: this, + ts: data, + timeout: this.timeout + }, callData; + + if(Ext.isArray(data)){ + callData = []; + for(var i = 0, len = data.length; i < len; i++){ + callData.push(this.getCallData(data[i])); + } + }else{ + callData = this.getCallData(data); + } + + if(this.enableUrlEncode){ + var params = {}; + params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData); + o.params = params; + }else{ + o.jsonData = callData; + } + Ext.Ajax.request(o); + }, + + combineAndSend : function(){ + var len = this.callBuffer.length; + if(len > 0){ + this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer); + this.callBuffer = []; + } + }, + + queueTransaction: function(t){ + if(t.form){ + this.processForm(t); + return; + } + this.callBuffer.push(t); + if(this.enableBuffer){ + if(!this.callTask){ + this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this); + } + this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10); + }else{ + this.combineAndSend(); + } + }, + + doCall : function(c, m, args){ + var data = null, hs = args[m.len], scope = args[m.len+1]; + + if(m.len !== 0){ + data = args.slice(0, m.len); + } + + var t = new Ext.Direct.Transaction({ + provider: this, + args: args, + action: c, + method: m.name, + data: data, + cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs + }); + + if(this.fireEvent('beforecall', this, t, m) !== false){ + Ext.Direct.addTransaction(t); + this.queueTransaction(t); + this.fireEvent('call', this, t, m); + } + }, + + doForm : function(c, m, form, callback, scope){ + var t = new Ext.Direct.Transaction({ + provider: this, + action: c, + method: m.name, + args:[form, callback, scope], + cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback, + isForm: true + }); + + if(this.fireEvent('beforecall', this, t, m) !== false){ + Ext.Direct.addTransaction(t); + var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data', + params = { + extTID: t.tid, + extAction: c, + extMethod: m.name, + extType: 'rpc', + extUpload: String(isUpload) + }; + + + + Ext.apply(t, { + form: Ext.getDom(form), + isUpload: isUpload, + params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params + }); + this.fireEvent('call', this, t, m); + this.processForm(t); + } + }, + + processForm: function(t){ + Ext.Ajax.request({ + url: this.url, + params: t.params, + callback: this.onData, + scope: this, + form: t.form, + isUpload: t.isUpload, + ts: t + }); + }, + + createMethod : function(c, m){ + var f; + if(!m.formHandler){ + f = function(){ + this.doCall(c, m, Array.prototype.slice.call(arguments, 0)); + }.createDelegate(this); + }else{ + f = function(form, callback, scope){ + this.doForm(c, m, form, callback, scope); + }.createDelegate(this); + } + f.directCfg = { + action: c, + method: m + }; + return f; + }, + + getTransaction: function(opt){ + return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null; + }, + + doCallback: function(t, e){ + var fn = e.status ? 'success' : 'failure'; + if(t && t.cb){ + var hs = t.cb, + result = Ext.isDefined(e.result) ? e.result : e.data; + if(Ext.isFunction(hs)){ + hs(result, e); + } else{ + Ext.callback(hs[fn], hs.scope, [result, e]); + Ext.callback(hs.callback, hs.scope, [result, e]); + } + } + } +}); +Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider; +Ext.Resizable = Ext.extend(Ext.util.Observable, { + + constructor: function(el, config){ + this.el = Ext.get(el); + if(config && config.wrap){ + config.resizeChild = this.el; + this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'}); + this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap'; + this.el.setStyle('overflow', 'hidden'); + this.el.setPositioning(config.resizeChild.getPositioning()); + config.resizeChild.clearPositioning(); + if(!config.width || !config.height){ + var csize = config.resizeChild.getSize(); + this.el.setSize(csize.width, csize.height); + } + if(config.pinned && !config.adjustments){ + config.adjustments = 'auto'; + } + } + + + this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody()); + this.proxy.unselectable(); + this.proxy.enableDisplayMode('block'); + + Ext.apply(this, config); + + if(this.pinned){ + this.disableTrackOver = true; + this.el.addClass('x-resizable-pinned'); + } + + var position = this.el.getStyle('position'); + if(position != 'absolute' && position != 'fixed'){ + this.el.setStyle('position', 'relative'); + } + if(!this.handles){ + this.handles = 's,e,se'; + if(this.multiDirectional){ + this.handles += ',n,w'; + } + } + if(this.handles == 'all'){ + this.handles = 'n s e w ne nw se sw'; + } + var hs = this.handles.split(/\s*?[,;]\s*?| /); + var ps = Ext.Resizable.positions; + for(var i = 0, len = hs.length; i < len; i++){ + if(hs[i] && ps[hs[i]]){ + var pos = ps[hs[i]]; + this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls); + } + } + + this.corner = this.southeast; + + if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){ + this.updateBox = true; + } + + this.activeHandle = null; + + if(this.resizeChild){ + if(typeof this.resizeChild == 'boolean'){ + this.resizeChild = Ext.get(this.el.dom.firstChild, true); + }else{ + this.resizeChild = Ext.get(this.resizeChild, true); + } + } + + if(this.adjustments == 'auto'){ + var rc = this.resizeChild; + var hw = this.west, he = this.east, hn = this.north, hs = this.south; + if(rc && (hw || hn)){ + rc.position('relative'); + rc.setLeft(hw ? hw.el.getWidth() : 0); + rc.setTop(hn ? hn.el.getHeight() : 0); + } + this.adjustments = [ + (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0), + (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 + ]; + } + + if(this.draggable){ + this.dd = this.dynamic ? + this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id}); + this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id); + if(this.constrainTo){ + this.dd.constrainTo(this.constrainTo); + } + } + + this.addEvents( + + 'beforeresize', + + 'resize' + ); + + if(this.width !== null && this.height !== null){ + this.resizeTo(this.width, this.height); + }else{ + this.updateChildSize(); + } + if(Ext.isIE){ + this.el.dom.style.zoom = 1; + } + Ext.Resizable.superclass.constructor.call(this); + }, + + + adjustments : [0, 0], + + animate : false, + + + disableTrackOver : false, + + draggable: false, + + duration : 0.35, + + dynamic : false, + + easing : 'easeOutStrong', + + enabled : true, + + + handles : false, + + multiDirectional : false, + + height : null, + + width : null, + + heightIncrement : 0, + + widthIncrement : 0, + + minHeight : 5, + + minWidth : 5, + + maxHeight : 10000, + + maxWidth : 10000, + + minX: 0, + + minY: 0, + + pinned : false, + + preserveRatio : false, + + resizeChild : false, + + transparent: false, + + + + + + + resizeTo : function(width, height){ + this.el.setSize(width, height); + this.updateChildSize(); + this.fireEvent('resize', this, width, height, null); + }, + + + startSizing : function(e, handle){ + this.fireEvent('beforeresize', this, e); + if(this.enabled){ + + if(!this.overlay){ + this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody()); + this.overlay.unselectable(); + this.overlay.enableDisplayMode('block'); + this.overlay.on({ + scope: this, + mousemove: this.onMouseMove, + mouseup: this.onMouseUp + }); + } + this.overlay.setStyle('cursor', handle.el.getStyle('cursor')); + + this.resizing = true; + this.startBox = this.el.getBox(); + this.startPoint = e.getXY(); + this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0], + (this.startBox.y + this.startBox.height) - this.startPoint[1]]; + + this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); + this.overlay.show(); + + if(this.constrainTo) { + var ct = Ext.get(this.constrainTo); + this.resizeRegion = ct.getRegion().adjust( + ct.getFrameWidth('t'), + ct.getFrameWidth('l'), + -ct.getFrameWidth('b'), + -ct.getFrameWidth('r') + ); + } + + this.proxy.setStyle('visibility', 'hidden'); + this.proxy.show(); + this.proxy.setBox(this.startBox); + if(!this.dynamic){ + this.proxy.setStyle('visibility', 'visible'); + } + } + }, + + + onMouseDown : function(handle, e){ + if(this.enabled){ + e.stopEvent(); + this.activeHandle = handle; + this.startSizing(e, handle); + } + }, + + + onMouseUp : function(e){ + this.activeHandle = null; + var size = this.resizeElement(); + this.resizing = false; + this.handleOut(); + this.overlay.hide(); + this.proxy.hide(); + this.fireEvent('resize', this, size.width, size.height, e); + }, + + + updateChildSize : function(){ + if(this.resizeChild){ + var el = this.el; + var child = this.resizeChild; + var adj = this.adjustments; + if(el.dom.offsetWidth){ + var b = el.getSize(true); + child.setSize(b.width+adj[0], b.height+adj[1]); + } + + + + + if(Ext.isIE9m){ + setTimeout(function(){ + if(el.dom.offsetWidth){ + var b = el.getSize(true); + child.setSize(b.width+adj[0], b.height+adj[1]); + } + }, 10); + } + } + }, + + + snap : function(value, inc, min){ + if(!inc || !value){ + return value; + } + var newValue = value; + var m = value % inc; + if(m > 0){ + if(m > (inc/2)){ + newValue = value + (inc-m); + }else{ + newValue = value - m; + } + } + return Math.max(min, newValue); + }, + + + resizeElement : function(){ + var box = this.proxy.getBox(); + if(this.updateBox){ + this.el.setBox(box, false, this.animate, this.duration, null, this.easing); + }else{ + this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing); + } + this.updateChildSize(); + if(!this.dynamic){ + this.proxy.hide(); + } + if(this.draggable && this.constrainTo){ + this.dd.resetConstraints(); + this.dd.constrainTo(this.constrainTo); + } + return box; + }, + + + constrain : function(v, diff, m, mx){ + if(v - diff < m){ + diff = v - m; + }else if(v - diff > mx){ + diff = v - mx; + } + return diff; + }, + + + onMouseMove : function(e){ + if(this.enabled && this.activeHandle){ + try{ + + if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) { + return; + } + + + var curSize = this.curSize || this.startBox, + x = this.startBox.x, y = this.startBox.y, + ox = x, + oy = y, + w = curSize.width, + h = curSize.height, + ow = w, + oh = h, + mw = this.minWidth, + mh = this.minHeight, + mxw = this.maxWidth, + mxh = this.maxHeight, + wi = this.widthIncrement, + hi = this.heightIncrement, + eventXY = e.getXY(), + diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])), + diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])), + pos = this.activeHandle.position, + tw, + th; + + switch(pos){ + case 'east': + w += diffX; + w = Math.min(Math.max(mw, w), mxw); + break; + case 'south': + h += diffY; + h = Math.min(Math.max(mh, h), mxh); + break; + case 'southeast': + w += diffX; + h += diffY; + w = Math.min(Math.max(mw, w), mxw); + h = Math.min(Math.max(mh, h), mxh); + break; + case 'north': + diffY = this.constrain(h, diffY, mh, mxh); + y += diffY; + h -= diffY; + break; + case 'west': + diffX = this.constrain(w, diffX, mw, mxw); + x += diffX; + w -= diffX; + break; + case 'northeast': + w += diffX; + w = Math.min(Math.max(mw, w), mxw); + diffY = this.constrain(h, diffY, mh, mxh); + y += diffY; + h -= diffY; + break; + case 'northwest': + diffX = this.constrain(w, diffX, mw, mxw); + diffY = this.constrain(h, diffY, mh, mxh); + y += diffY; + h -= diffY; + x += diffX; + w -= diffX; + break; + case 'southwest': + diffX = this.constrain(w, diffX, mw, mxw); + h += diffY; + h = Math.min(Math.max(mh, h), mxh); + x += diffX; + w -= diffX; + break; + } + + var sw = this.snap(w, wi, mw); + var sh = this.snap(h, hi, mh); + if(sw != w || sh != h){ + switch(pos){ + case 'northeast': + y -= sh - h; + break; + case 'north': + y -= sh - h; + break; + case 'southwest': + x -= sw - w; + break; + case 'west': + x -= sw - w; + break; + case 'northwest': + x -= sw - w; + y -= sh - h; + break; + } + w = sw; + h = sh; + } + + if(this.preserveRatio){ + switch(pos){ + case 'southeast': + case 'east': + h = oh * (w/ow); + h = Math.min(Math.max(mh, h), mxh); + w = ow * (h/oh); + break; + case 'south': + w = ow * (h/oh); + w = Math.min(Math.max(mw, w), mxw); + h = oh * (w/ow); + break; + case 'northeast': + w = ow * (h/oh); + w = Math.min(Math.max(mw, w), mxw); + h = oh * (w/ow); + break; + case 'north': + tw = w; + w = ow * (h/oh); + w = Math.min(Math.max(mw, w), mxw); + h = oh * (w/ow); + x += (tw - w) / 2; + break; + case 'southwest': + h = oh * (w/ow); + h = Math.min(Math.max(mh, h), mxh); + tw = w; + w = ow * (h/oh); + x += tw - w; + break; + case 'west': + th = h; + h = oh * (w/ow); + h = Math.min(Math.max(mh, h), mxh); + y += (th - h) / 2; + tw = w; + w = ow * (h/oh); + x += tw - w; + break; + case 'northwest': + tw = w; + th = h; + h = oh * (w/ow); + h = Math.min(Math.max(mh, h), mxh); + w = ow * (h/oh); + y += th - h; + x += tw - w; + break; + + } + } + this.proxy.setBounds(x, y, w, h); + if(this.dynamic){ + this.resizeElement(); + } + }catch(ex){} + } + }, + + + handleOver : function(){ + if(this.enabled){ + this.el.addClass('x-resizable-over'); + } + }, + + + handleOut : function(){ + if(!this.resizing){ + this.el.removeClass('x-resizable-over'); + } + }, + + + getEl : function(){ + return this.el; + }, + + + getResizeChild : function(){ + return this.resizeChild; + }, + + + destroy : function(removeEl){ + Ext.destroy(this.dd, this.overlay, this.proxy); + this.overlay = null; + this.proxy = null; + + var ps = Ext.Resizable.positions; + for(var k in ps){ + if(typeof ps[k] != 'function' && this[ps[k]]){ + this[ps[k]].destroy(); + } + } + if(removeEl){ + this.el.update(''); + Ext.destroy(this.el); + this.el = null; + } + this.purgeListeners(); + }, + + syncHandleHeight : function(){ + var h = this.el.getHeight(true); + if(this.west){ + this.west.el.setHeight(h); + } + if(this.east){ + this.east.el.setHeight(h); + } + } +}); + + + +Ext.Resizable.positions = { + n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast' +}; + +Ext.Resizable.Handle = Ext.extend(Object, { + constructor : function(rz, pos, disableTrackOver, transparent, cls){ + if(!this.tpl){ + + var tpl = Ext.DomHelper.createTemplate( + {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'} + ); + tpl.compile(); + Ext.Resizable.Handle.prototype.tpl = tpl; + } + this.position = pos; + this.rz = rz; + this.el = this.tpl.append(rz.el.dom, [this.position], true); + this.el.unselectable(); + if(transparent){ + this.el.setOpacity(0); + } + if(!Ext.isEmpty(cls)){ + this.el.addClass(cls); + } + this.el.on('mousedown', this.onMouseDown, this); + if(!disableTrackOver){ + this.el.on({ + scope: this, + mouseover: this.onMouseOver, + mouseout: this.onMouseOut + }); + } + }, + + + afterResize : function(rz){ + + }, + + onMouseDown : function(e){ + this.rz.onMouseDown(this, e); + }, + + onMouseOver : function(e){ + this.rz.handleOver(this, e); + }, + + onMouseOut : function(e){ + this.rz.handleOut(this, e); + }, + + destroy : function(){ + Ext.destroy(this.el); + this.el = null; + } +}); + +Ext.Window = Ext.extend(Ext.Panel, { + + + + + + + + + + + + + baseCls : 'x-window', + + resizable : true, + + draggable : true, + + closable : true, + + closeAction : 'close', + + constrain : false, + + constrainHeader : false, + + plain : false, + + minimizable : false, + + maximizable : false, + + minHeight : 100, + + minWidth : 200, + + expandOnShow : true, + + + showAnimDuration: 0.25, + + + hideAnimDuration: 0.25, + + + collapsible : false, + + + initHidden : undefined, + + + hidden : true, + + + + + + + elements : 'header,body', + + frame : true, + + floating : true, + + + initComponent : function(){ + this.initTools(); + Ext.Window.superclass.initComponent.call(this); + this.addEvents( + + + + 'resize', + + 'maximize', + + 'minimize', + + 'restore' + ); + + if(Ext.isDefined(this.initHidden)){ + this.hidden = this.initHidden; + } + if(this.hidden === false){ + this.hidden = true; + this.show(); + } + }, + + + getState : function(){ + return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true)); + }, + + + onRender : function(ct, position){ + Ext.Window.superclass.onRender.call(this, ct, position); + + if(this.plain){ + this.el.addClass('x-window-plain'); + } + + + this.focusEl = this.el.createChild({ + tag: 'a', href:'#', cls:'x-dlg-focus', + tabIndex:'-1', html: ' '}); + this.focusEl.swallowEvent('click', true); + + this.proxy = this.el.createProxy('x-window-proxy'); + this.proxy.enableDisplayMode('block'); + + if(this.modal){ + this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom); + this.mask.enableDisplayMode('block'); + this.mask.hide(); + this.mon(this.mask, 'click', this.focus, this); + } + if(this.maximizable){ + this.mon(this.header, 'dblclick', this.toggleMaximize, this); + } + }, + + + initEvents : function(){ + Ext.Window.superclass.initEvents.call(this); + if(this.animateTarget){ + this.setAnimateTarget(this.animateTarget); + } + + if(this.resizable){ + this.resizer = new Ext.Resizable(this.el, { + minWidth: this.minWidth, + minHeight:this.minHeight, + handles: this.resizeHandles || 'all', + pinned: true, + resizeElement : this.resizerAction, + handleCls: 'x-window-handle' + }); + this.resizer.window = this; + this.mon(this.resizer, 'beforeresize', this.beforeResize, this); + } + + if(this.draggable){ + this.header.addClass('x-window-draggable'); + } + this.mon(this.el, 'mousedown', this.toFront, this); + this.manager = this.manager || Ext.WindowMgr; + this.manager.register(this); + if(this.maximized){ + this.maximized = false; + this.maximize(); + } + if(this.closable){ + var km = this.getKeyMap(); + km.on(27, this.onEsc, this); + km.disable(); + } + }, + + initDraggable : function(){ + + this.dd = new Ext.Window.DD(this); + }, + + + onEsc : function(k, e){ + if (this.activeGhost) { + this.unghost(); + } + e.stopEvent(); + this[this.closeAction](); + }, + + + beforeDestroy : function(){ + if(this.rendered){ + this.hide(); + this.clearAnchor(); + Ext.destroy( + this.focusEl, + this.resizer, + this.dd, + this.proxy, + this.mask + ); + } + Ext.Window.superclass.beforeDestroy.call(this); + }, + + + onDestroy : function(){ + if(this.manager){ + this.manager.unregister(this); + } + Ext.Window.superclass.onDestroy.call(this); + }, + + + initTools : function(){ + if(this.minimizable){ + this.addTool({ + id: 'minimize', + handler: this.minimize.createDelegate(this, []) + }); + } + if(this.maximizable){ + this.addTool({ + id: 'maximize', + handler: this.maximize.createDelegate(this, []) + }); + this.addTool({ + id: 'restore', + handler: this.restore.createDelegate(this, []), + hidden:true + }); + } + if(this.closable){ + this.addTool({ + id: 'close', + handler: this[this.closeAction].createDelegate(this, []) + }); + } + }, + + + resizerAction : function(){ + var box = this.proxy.getBox(); + this.proxy.hide(); + this.window.handleResize(box); + return box; + }, + + + beforeResize : function(){ + this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); + this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40); + this.resizeBox = this.el.getBox(); + }, + + + updateHandles : function(){ + if(Ext.isIE9m && this.resizer){ + this.resizer.syncHandleHeight(); + this.el.repaint(); + } + }, + + + handleResize : function(box){ + var rz = this.resizeBox; + if(rz.x != box.x || rz.y != box.y){ + this.updateBox(box); + }else{ + this.setSize(box); + if (Ext.isIE6 && Ext.isStrict) { + this.doLayout(); + } + } + this.focus(); + this.updateHandles(); + this.saveState(); + }, + + + focus : function(){ + var f = this.focusEl, + db = this.defaultButton, + t = typeof db, + el, + ct; + if(Ext.isDefined(db)){ + if(Ext.isNumber(db) && this.fbar){ + f = this.fbar.items.get(db); + }else if(Ext.isString(db)){ + f = Ext.getCmp(db); + }else{ + f = db; + } + el = f.getEl(); + ct = Ext.getDom(this.container); + if (el && ct) { + if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){ + return; + } + } + } + f = f || this.focusEl; + f.focus.defer(10, f); + }, + + + setAnimateTarget : function(el){ + el = Ext.get(el); + this.animateTarget = el; + }, + + + beforeShow : function(){ + delete this.el.lastXY; + delete this.el.lastLT; + if(this.x === undefined || this.y === undefined){ + var xy = this.el.getAlignToXY(this.container, 'c-c'); + var pos = this.el.translatePoints(xy[0], xy[1]); + this.x = this.x === undefined? pos.left : this.x; + this.y = this.y === undefined? pos.top : this.y; + } + this.el.setLeftTop(this.x, this.y); + + if(this.expandOnShow){ + this.expand(false); + } + + if(this.modal){ + Ext.getBody().addClass('x-body-masked'); + this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); + this.mask.show(); + } + }, + + + show : function(animateTarget, cb, scope){ + if(!this.rendered){ + this.render(Ext.getBody()); + } + if(this.hidden === false){ + this.toFront(); + return this; + } + if(this.fireEvent('beforeshow', this) === false){ + return this; + } + if(cb){ + this.on('show', cb, scope, {single:true}); + } + this.hidden = false; + if(Ext.isDefined(animateTarget)){ + this.setAnimateTarget(animateTarget); + } + this.beforeShow(); + if(this.animateTarget){ + this.animShow(); + }else{ + this.afterShow(); + } + return this; + }, + + + afterShow : function(isAnim){ + if (this.isDestroyed){ + return false; + } + this.proxy.hide(); + this.el.setStyle('display', 'block'); + this.el.show(); + if(this.maximized){ + this.fitContainer(); + } + if(Ext.isMac && Ext.isGecko2){ + this.cascade(this.setAutoScroll); + } + + if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){ + Ext.EventManager.onWindowResize(this.onWindowResize, this); + } + this.doConstrain(); + this.doLayout(); + if(this.keyMap){ + this.keyMap.enable(); + } + this.toFront(); + this.updateHandles(); + if(isAnim && (Ext.isIE || Ext.isWebKit)){ + var sz = this.getSize(); + this.onResize(sz.width, sz.height); + } + this.onShow(); + this.fireEvent('show', this); + }, + + + animShow : function(){ + this.proxy.show(); + this.proxy.setBox(this.animateTarget.getBox()); + this.proxy.setOpacity(0); + var b = this.getBox(); + this.el.setStyle('display', 'none'); + this.proxy.shift(Ext.apply(b, { + callback: this.afterShow.createDelegate(this, [true], false), + scope: this, + easing: 'easeNone', + duration: this.showAnimDuration, + opacity: 0.5 + })); + }, + + + hide : function(animateTarget, cb, scope){ + if(this.hidden || this.fireEvent('beforehide', this) === false){ + return this; + } + if(cb){ + this.on('hide', cb, scope, {single:true}); + } + this.hidden = true; + if(animateTarget !== undefined){ + this.setAnimateTarget(animateTarget); + } + if(this.modal){ + this.mask.hide(); + Ext.getBody().removeClass('x-body-masked'); + } + if(this.animateTarget){ + this.animHide(); + }else{ + this.el.hide(); + this.afterHide(); + } + return this; + }, + + + afterHide : function(){ + this.proxy.hide(); + if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){ + Ext.EventManager.removeResizeListener(this.onWindowResize, this); + } + if(this.keyMap){ + this.keyMap.disable(); + } + this.onHide(); + this.fireEvent('hide', this); + }, + + + animHide : function(){ + this.proxy.setOpacity(0.5); + this.proxy.show(); + var tb = this.getBox(false); + this.proxy.setBox(tb); + this.el.hide(); + this.proxy.shift(Ext.apply(this.animateTarget.getBox(), { + callback: this.afterHide, + scope: this, + duration: this.hideAnimDuration, + easing: 'easeNone', + opacity: 0 + })); + }, + + + onShow : Ext.emptyFn, + + + onHide : Ext.emptyFn, + + + onWindowResize : function(){ + if(this.maximized){ + this.fitContainer(); + } + if(this.modal){ + this.mask.setSize('100%', '100%'); + var force = this.mask.dom.offsetHeight; + this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); + } + this.doConstrain(); + }, + + + doConstrain : function(){ + if(this.constrain || this.constrainHeader){ + var offsets; + if(this.constrain){ + offsets = { + right:this.el.shadowOffset, + left:this.el.shadowOffset, + bottom:this.el.shadowOffset + }; + }else { + var s = this.getSize(); + offsets = { + right:-(s.width - 100), + bottom:-(s.height - 25 + this.el.getConstrainOffset()) + }; + } + + var xy = this.el.getConstrainToXY(this.container, true, offsets); + if(xy){ + this.setPosition(xy[0], xy[1]); + } + } + }, + + + ghost : function(cls){ + var ghost = this.createGhost(cls); + var box = this.getBox(true); + ghost.setLeftTop(box.x, box.y); + ghost.setWidth(box.width); + this.el.hide(); + this.activeGhost = ghost; + return ghost; + }, + + + unghost : function(show, matchPosition){ + if(!this.activeGhost) { + return; + } + if(show !== false){ + this.el.show(); + this.focus.defer(10, this); + if(Ext.isMac && Ext.isGecko2){ + this.cascade(this.setAutoScroll); + } + } + if(matchPosition !== false){ + this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true)); + } + this.activeGhost.hide(); + this.activeGhost.remove(); + delete this.activeGhost; + }, + + + minimize : function(){ + this.fireEvent('minimize', this); + return this; + }, + + + close : function(){ + if(this.fireEvent('beforeclose', this) !== false){ + if(this.hidden){ + this.doClose(); + }else{ + this.hide(null, this.doClose, this); + } + } + }, + + + doClose : function(){ + this.fireEvent('close', this); + this.destroy(); + }, + + + maximize : function(){ + if(!this.maximized){ + this.expand(false); + this.restoreSize = this.getSize(); + this.restorePos = this.getPosition(true); + if (this.maximizable){ + this.tools.maximize.hide(); + this.tools.restore.show(); + } + this.maximized = true; + this.el.disableShadow(); + + if(this.dd){ + this.dd.lock(); + } + if(this.collapsible){ + this.tools.toggle.hide(); + } + this.el.addClass('x-window-maximized'); + this.container.addClass('x-window-maximized-ct'); + + this.setPosition(0, 0); + this.fitContainer(); + this.fireEvent('maximize', this); + } + return this; + }, + + + restore : function(){ + if(this.maximized){ + var t = this.tools; + this.el.removeClass('x-window-maximized'); + if(t.restore){ + t.restore.hide(); + } + if(t.maximize){ + t.maximize.show(); + } + this.setPosition(this.restorePos[0], this.restorePos[1]); + this.setSize(this.restoreSize.width, this.restoreSize.height); + delete this.restorePos; + delete this.restoreSize; + this.maximized = false; + this.el.enableShadow(true); + + if(this.dd){ + this.dd.unlock(); + } + if(this.collapsible && t.toggle){ + t.toggle.show(); + } + this.container.removeClass('x-window-maximized-ct'); + + this.doConstrain(); + this.fireEvent('restore', this); + } + return this; + }, + + + toggleMaximize : function(){ + return this[this.maximized ? 'restore' : 'maximize'](); + }, + + + fitContainer : function(){ + var vs = this.container.getViewSize(false); + this.setSize(vs.width, vs.height); + }, + + + + setZIndex : function(index){ + if(this.modal){ + this.mask.setStyle('z-index', index); + } + this.el.setZIndex(++index); + index += 5; + + if(this.resizer){ + this.resizer.proxy.setStyle('z-index', ++index); + } + + this.lastZIndex = index; + }, + + + alignTo : function(element, position, offsets){ + var xy = this.el.getAlignToXY(element, position, offsets); + this.setPagePosition(xy[0], xy[1]); + return this; + }, + + + anchorTo : function(el, alignment, offsets, monitorScroll){ + this.clearAnchor(); + this.anchorTarget = { + el: el, + alignment: alignment, + offsets: offsets + }; + + Ext.EventManager.onWindowResize(this.doAnchor, this); + var tm = typeof monitorScroll; + if(tm != 'undefined'){ + Ext.EventManager.on(window, 'scroll', this.doAnchor, this, + {buffer: tm == 'number' ? monitorScroll : 50}); + } + return this.doAnchor(); + }, + + + doAnchor : function(){ + var o = this.anchorTarget; + this.alignTo(o.el, o.alignment, o.offsets); + return this; + }, + + + clearAnchor : function(){ + if(this.anchorTarget){ + Ext.EventManager.removeResizeListener(this.doAnchor, this); + Ext.EventManager.un(window, 'scroll', this.doAnchor, this); + delete this.anchorTarget; + } + return this; + }, + + + toFront : function(e){ + if(this.manager.bringToFront(this)){ + if(!e || !e.getTarget().focus){ + this.focus(); + } + } + return this; + }, + + + setActive : function(active){ + if(active){ + if(!this.maximized){ + this.el.enableShadow(true); + } + this.fireEvent('activate', this); + }else{ + this.el.disableShadow(); + this.fireEvent('deactivate', this); + } + }, + + + toBack : function(){ + this.manager.sendToBack(this); + return this; + }, + + + center : function(){ + var xy = this.el.getAlignToXY(this.container, 'c-c'); + this.setPagePosition(xy[0], xy[1]); + return this; + } + + +}); +Ext.reg('window', Ext.Window); + + +Ext.Window.DD = Ext.extend(Ext.dd.DD, { + + constructor : function(win){ + this.win = win; + Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id); + this.setHandleElId(win.header.id); + this.scroll = false; + }, + + moveOnly:true, + headerOffsets:[100, 25], + startDrag : function(){ + var w = this.win; + this.proxy = w.ghost(w.initialConfig.cls); + if(w.constrain !== false){ + var so = w.el.shadowOffset; + this.constrainTo(w.container, {right: so, left: so, bottom: so}); + }else if(w.constrainHeader !== false){ + var s = this.proxy.getSize(); + this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])}); + } + }, + b4Drag : Ext.emptyFn, + + onDrag : function(e){ + this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY()); + }, + + endDrag : function(e){ + this.win.unghost(); + this.win.saveState(); + } +}); + +Ext.WindowGroup = function(){ + var list = {}; + var accessList = []; + var front = null; + + + var sortWindows = function(d1, d2){ + return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1; + }; + + + var orderWindows = function(){ + var a = accessList, len = a.length; + if(len > 0){ + a.sort(sortWindows); + var seed = a[0].manager.zseed; + for(var i = 0; i < len; i++){ + var win = a[i]; + if(win && !win.hidden){ + win.setZIndex(seed + (i*10)); + } + } + } + activateLast(); + }; + + + var setActiveWin = function(win){ + if(win != front){ + if(front){ + front.setActive(false); + } + front = win; + if(win){ + win.setActive(true); + } + } + }; + + + var activateLast = function(){ + for(var i = accessList.length-1; i >=0; --i) { + if(!accessList[i].hidden){ + setActiveWin(accessList[i]); + return; + } + } + + setActiveWin(null); + }; + + return { + + zseed : 9000, + + + register : function(win){ + if(win.manager){ + win.manager.unregister(win); + } + win.manager = this; + + list[win.id] = win; + accessList.push(win); + win.on('hide', activateLast); + }, + + + unregister : function(win){ + delete win.manager; + delete list[win.id]; + win.un('hide', activateLast); + accessList.remove(win); + }, + + + get : function(id){ + return typeof id == "object" ? id : list[id]; + }, + + + bringToFront : function(win){ + win = this.get(win); + if(win != front){ + win._lastAccess = new Date().getTime(); + orderWindows(); + return true; + } + return false; + }, + + + sendToBack : function(win){ + win = this.get(win); + win._lastAccess = -(new Date().getTime()); + orderWindows(); + return win; + }, + + + hideAll : function(){ + for(var id in list){ + if(list[id] && typeof list[id] != "function" && list[id].isVisible()){ + list[id].hide(); + } + } + }, + + + getActive : function(){ + return front; + }, + + + getBy : function(fn, scope){ + var r = []; + for(var i = accessList.length-1; i >=0; --i) { + var win = accessList[i]; + if(fn.call(scope||win, win) !== false){ + r.push(win); + } + } + return r; + }, + + + each : function(fn, scope){ + for(var id in list){ + if(list[id] && typeof list[id] != "function"){ + if(fn.call(scope || list[id], list[id]) === false){ + return; + } + } + } + } + }; +}; + + + +Ext.WindowMgr = new Ext.WindowGroup(); +Ext.MessageBox = function(){ + var dlg, opt, mask, waitTimer, + bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl, + buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '', + buttonNames = ['ok', 'yes', 'no', 'cancel']; + + + var handleButton = function(button){ + buttons[button].blur(); + if(dlg.isVisible()){ + dlg.hide(); + handleHide(); + Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1); + } + }; + + + var handleHide = function(){ + if(opt && opt.cls){ + dlg.el.removeClass(opt.cls); + } + progressBar.reset(); + }; + + + var handleEsc = function(d, k, e){ + if(opt && opt.closable !== false){ + dlg.hide(); + handleHide(); + } + if(e){ + e.stopEvent(); + } + }; + + + var updateButtons = function(b){ + var width = 0, + cfg; + if(!b){ + Ext.each(buttonNames, function(name){ + buttons[name].hide(); + }); + return width; + } + dlg.footer.dom.style.display = ''; + Ext.iterate(buttons, function(name, btn){ + cfg = b[name]; + if(cfg){ + btn.show(); + btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]); + width += btn.getEl().getWidth() + 15; + }else{ + btn.hide(); + } + }); + return width; + }; + + return { + + getDialog : function(titleText){ + if(!dlg){ + var btns = []; + + buttons = {}; + Ext.each(buttonNames, function(name){ + btns.push(buttons[name] = new Ext.Button({ + text: this.buttonText[name], + handler: handleButton.createCallback(name), + hideMode: 'offsets' + })); + }, this); + dlg = new Ext.Window({ + autoCreate : true, + title:titleText, + resizable:false, + constrain:true, + constrainHeader:true, + minimizable : false, + maximizable : false, + stateful: false, + modal: true, + shim:true, + buttonAlign:"center", + width:400, + height:100, + minHeight: 80, + plain:true, + footer:true, + closable:true, + close : function(){ + if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){ + handleButton("no"); + }else{ + handleButton("cancel"); + } + }, + fbar: new Ext.Toolbar({ + items: btns, + enableOverflow: false + }) + }); + dlg.render(document.body); + dlg.getEl().addClass('x-window-dlg'); + mask = dlg.mask; + bodyEl = dlg.body.createChild({ + html:'

    ' + }); + iconEl = Ext.get(bodyEl.dom.firstChild); + var contentEl = bodyEl.dom.childNodes[1]; + msgEl = Ext.get(contentEl.firstChild); + textboxEl = Ext.get(contentEl.childNodes[2].firstChild); + textboxEl.enableDisplayMode(); + textboxEl.addKeyListener([10,13], function(){ + if(dlg.isVisible() && opt && opt.buttons){ + if(opt.buttons.ok){ + handleButton("ok"); + }else if(opt.buttons.yes){ + handleButton("yes"); + } + } + }); + textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]); + textareaEl.enableDisplayMode(); + progressBar = new Ext.ProgressBar({ + renderTo:bodyEl + }); + bodyEl.createChild({cls:'x-clear'}); + } + return dlg; + }, + + + updateText : function(text){ + if(!dlg.isVisible() && !opt.width){ + dlg.setSize(this.maxWidth, 100); + } + + msgEl.update(text ? text + ' ' : ' '); + + var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0, + mw = msgEl.getWidth() + msgEl.getMargins('lr'), + fw = dlg.getFrameWidth('lr'), + bw = dlg.body.getFrameWidth('lr'), + w; + + w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth), + Math.max(opt.minWidth || this.minWidth, bwidth || 0)); + + if(opt.prompt === true){ + activeTextEl.setWidth(w-iw-fw-bw); + } + if(opt.progress === true || opt.wait === true){ + progressBar.setSize(w-iw-fw-bw); + } + if(Ext.isIE9m && w == bwidth){ + w += 4; + } + msgEl.update(text || ' '); + dlg.setSize(w, 'auto').center(); + return this; + }, + + + updateProgress : function(value, progressText, msg){ + progressBar.updateProgress(value, progressText); + if(msg){ + this.updateText(msg); + } + return this; + }, + + + isVisible : function(){ + return dlg && dlg.isVisible(); + }, + + + hide : function(){ + var proxy = dlg ? dlg.activeGhost : null; + if(this.isVisible() || proxy){ + dlg.hide(); + handleHide(); + if (proxy){ + + + dlg.unghost(false, false); + } + } + return this; + }, + + + show : function(options){ + if(this.isVisible()){ + this.hide(); + } + opt = options; + var d = this.getDialog(opt.title || " "); + + d.setTitle(opt.title || " "); + var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true); + d.tools.close.setDisplayed(allowClose); + activeTextEl = textboxEl; + opt.prompt = opt.prompt || (opt.multiline ? true : false); + if(opt.prompt){ + if(opt.multiline){ + textboxEl.hide(); + textareaEl.show(); + textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight); + activeTextEl = textareaEl; + }else{ + textboxEl.show(); + textareaEl.hide(); + } + }else{ + textboxEl.hide(); + textareaEl.hide(); + } + activeTextEl.dom.value = opt.value || ""; + if(opt.prompt){ + d.focusEl = activeTextEl; + }else{ + var bs = opt.buttons; + var db = null; + if(bs && bs.ok){ + db = buttons["ok"]; + }else if(bs && bs.yes){ + db = buttons["yes"]; + } + if (db){ + d.focusEl = db; + } + } + if(Ext.isDefined(opt.iconCls)){ + d.setIconClass(opt.iconCls); + } + this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon); + bwidth = updateButtons(opt.buttons); + progressBar.setVisible(opt.progress === true || opt.wait === true); + this.updateProgress(0, opt.progressText); + this.updateText(opt.msg); + if(opt.cls){ + d.el.addClass(opt.cls); + } + d.proxyDrag = opt.proxyDrag === true; + d.modal = opt.modal !== false; + d.mask = opt.modal !== false ? mask : false; + if(!d.isVisible()){ + + document.body.appendChild(dlg.el.dom); + d.setAnimateTarget(opt.animEl); + + d.on('show', function(){ + if(allowClose === true){ + d.keyMap.enable(); + }else{ + d.keyMap.disable(); + } + }, this, {single:true}); + d.show(opt.animEl); + } + if(opt.wait === true){ + progressBar.wait(opt.waitConfig); + } + return this; + }, + + + setIcon : function(icon){ + if(!dlg){ + bufferIcon = icon; + return; + } + bufferIcon = undefined; + if(icon && icon != ''){ + iconEl.removeClass('x-hidden'); + iconEl.replaceClass(iconCls, icon); + bodyEl.addClass('x-dlg-icon'); + iconCls = icon; + }else{ + iconEl.replaceClass(iconCls, 'x-hidden'); + bodyEl.removeClass('x-dlg-icon'); + iconCls = ''; + } + return this; + }, + + + progress : function(title, msg, progressText){ + this.show({ + title : title, + msg : msg, + buttons: false, + progress:true, + closable:false, + minWidth: this.minProgressWidth, + progressText: progressText + }); + return this; + }, + + + wait : function(msg, title, config){ + this.show({ + title : title, + msg : msg, + buttons: false, + closable:false, + wait:true, + modal:true, + minWidth: this.minProgressWidth, + waitConfig: config + }); + return this; + }, + + + alert : function(title, msg, fn, scope){ + this.show({ + title : title, + msg : msg, + buttons: this.OK, + fn: fn, + scope : scope, + minWidth: this.minWidth + }); + return this; + }, + + + confirm : function(title, msg, fn, scope){ + this.show({ + title : title, + msg : msg, + buttons: this.YESNO, + fn: fn, + scope : scope, + icon: this.QUESTION, + minWidth: this.minWidth + }); + return this; + }, + + + prompt : function(title, msg, fn, scope, multiline, value){ + this.show({ + title : title, + msg : msg, + buttons: this.OKCANCEL, + fn: fn, + minWidth: this.minPromptWidth, + scope : scope, + prompt:true, + multiline: multiline, + value: value + }); + return this; + }, + + + OK : {ok:true}, + + CANCEL : {cancel:true}, + + OKCANCEL : {ok:true, cancel:true}, + + YESNO : {yes:true, no:true}, + + YESNOCANCEL : {yes:true, no:true, cancel:true}, + + INFO : 'ext-mb-info', + + WARNING : 'ext-mb-warning', + + QUESTION : 'ext-mb-question', + + ERROR : 'ext-mb-error', + + + defaultTextHeight : 75, + + maxWidth : 600, + + minWidth : 100, + + minProgressWidth : 250, + + minPromptWidth: 250, + + buttonText : { + ok : "OK", + cancel : "Cancel", + yes : "Yes", + no : "No" + } + }; +}(); + + +Ext.Msg = Ext.MessageBox; +Ext.dd.PanelProxy = Ext.extend(Object, { + + constructor : function(panel, config){ + this.panel = panel; + this.id = this.panel.id +'-ddproxy'; + Ext.apply(this, config); + }, + + + insertProxy : true, + + + setStatus : Ext.emptyFn, + reset : Ext.emptyFn, + update : Ext.emptyFn, + stop : Ext.emptyFn, + sync: Ext.emptyFn, + + + getEl : function(){ + return this.ghost; + }, + + + getGhost : function(){ + return this.ghost; + }, + + + getProxy : function(){ + return this.proxy; + }, + + + hide : function(){ + if(this.ghost){ + if(this.proxy){ + this.proxy.remove(); + delete this.proxy; + } + this.panel.el.dom.style.display = ''; + this.ghost.remove(); + delete this.ghost; + } + }, + + + show : function(){ + if(!this.ghost){ + this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody()); + this.ghost.setXY(this.panel.el.getXY()); + if(this.insertProxy){ + this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'}); + this.proxy.setSize(this.panel.getSize()); + } + this.panel.el.dom.style.display = 'none'; + } + }, + + + repair : function(xy, callback, scope){ + this.hide(); + if(typeof callback == "function"){ + callback.call(scope || this); + } + }, + + + moveProxy : function(parentNode, before){ + if(this.proxy){ + parentNode.insertBefore(this.proxy.dom, before); + } + } +}); + + +Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, { + + constructor : function(panel, cfg){ + this.panel = panel; + this.dragData = {panel: panel}; + this.proxy = new Ext.dd.PanelProxy(panel, cfg); + Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg); + var h = panel.header, + el = panel.body; + if(h){ + this.setHandleElId(h.id); + el = panel.header; + } + el.setStyle('cursor', 'move'); + this.scroll = false; + }, + + showFrame: Ext.emptyFn, + startDrag: Ext.emptyFn, + b4StartDrag: function(x, y) { + this.proxy.show(); + }, + b4MouseDown: function(e) { + var x = e.getPageX(), + y = e.getPageY(); + this.autoOffset(x, y); + }, + onInitDrag : function(x, y){ + this.onStartDrag(x, y); + return true; + }, + createFrame : Ext.emptyFn, + getDragEl : function(e){ + return this.proxy.ghost.dom; + }, + endDrag : function(e){ + this.proxy.hide(); + this.panel.saveState(); + }, + + autoOffset : function(x, y) { + x -= this.startPageX; + y -= this.startPageY; + this.setDelta(x, y); + } +}); +Ext.state.Provider = Ext.extend(Ext.util.Observable, { + + constructor : function(){ + + this.addEvents("statechange"); + this.state = {}; + Ext.state.Provider.superclass.constructor.call(this); + }, + + + get : function(name, defaultValue){ + return typeof this.state[name] == "undefined" ? + defaultValue : this.state[name]; + }, + + + clear : function(name){ + delete this.state[name]; + this.fireEvent("statechange", this, name, null); + }, + + + set : function(name, value){ + this.state[name] = value; + this.fireEvent("statechange", this, name, value); + }, + + + decodeValue : function(cookie){ + + var re = /^(a|n|d|b|s|o|e)\:(.*)$/, + matches = re.exec(unescape(cookie)), + all, + type, + v, + kv; + if(!matches || !matches[1]){ + return; + } + type = matches[1]; + v = matches[2]; + switch(type){ + case 'e': + return null; + case 'n': + return parseFloat(v); + case 'd': + return new Date(Date.parse(v)); + case 'b': + return (v == '1'); + case 'a': + all = []; + if(v != ''){ + Ext.each(v.split('^'), function(val){ + all.push(this.decodeValue(val)); + }, this); + } + return all; + case 'o': + all = {}; + if(v != ''){ + Ext.each(v.split('^'), function(val){ + kv = val.split('='); + all[kv[0]] = this.decodeValue(kv[1]); + }, this); + } + return all; + default: + return v; + } + }, + + + encodeValue : function(v){ + var enc, + flat = '', + i = 0, + len, + key; + if(v == null){ + return 'e:1'; + }else if(typeof v == 'number'){ + enc = 'n:' + v; + }else if(typeof v == 'boolean'){ + enc = 'b:' + (v ? '1' : '0'); + }else if(Ext.isDate(v)){ + enc = 'd:' + v.toGMTString(); + }else if(Ext.isArray(v)){ + for(len = v.length; i < len; i++){ + flat += this.encodeValue(v[i]); + if(i != len - 1){ + flat += '^'; + } + } + enc = 'a:' + flat; + }else if(typeof v == 'object'){ + for(key in v){ + if(typeof v[key] != 'function' && v[key] !== undefined){ + flat += key + '=' + this.encodeValue(v[key]) + '^'; + } + } + enc = 'o:' + flat.substring(0, flat.length-1); + }else{ + enc = 's:' + v; + } + return escape(enc); + } +}); + +Ext.state.Manager = function(){ + var provider = new Ext.state.Provider(); + + return { + + setProvider : function(stateProvider){ + provider = stateProvider; + }, + + + get : function(key, defaultValue){ + return provider.get(key, defaultValue); + }, + + + set : function(key, value){ + provider.set(key, value); + }, + + + clear : function(key){ + provider.clear(key); + }, + + + getProvider : function(){ + return provider; + } + }; +}(); + +Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, { + + constructor : function(config){ + Ext.state.CookieProvider.superclass.constructor.call(this); + this.path = "/"; + this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); + this.domain = null; + this.secure = false; + Ext.apply(this, config); + this.state = this.readCookies(); + }, + + + set : function(name, value){ + if(typeof value == "undefined" || value === null){ + this.clear(name); + return; + } + this.setCookie(name, value); + Ext.state.CookieProvider.superclass.set.call(this, name, value); + }, + + + clear : function(name){ + this.clearCookie(name); + Ext.state.CookieProvider.superclass.clear.call(this, name); + }, + + + readCookies : function(){ + var cookies = {}, + c = document.cookie + ";", + re = /\s?(.*?)=(.*?);/g, + matches, + name, + value; + while((matches = re.exec(c)) != null){ + name = matches[1]; + value = matches[2]; + if(name && name.substring(0,3) == "ys-"){ + cookies[name.substr(3)] = this.decodeValue(value); + } + } + return cookies; + }, + + + setCookie : function(name, value){ + document.cookie = "ys-"+ name + "=" + this.encodeValue(value) + + ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) + + ((this.path == null) ? "" : ("; path=" + this.path)) + + ((this.domain == null) ? "" : ("; domain=" + this.domain)) + + ((this.secure == true) ? "; secure" : ""); + }, + + + clearCookie : function(name){ + document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" + + ((this.path == null) ? "" : ("; path=" + this.path)) + + ((this.domain == null) ? "" : ("; domain=" + this.domain)) + + ((this.secure == true) ? "; secure" : ""); + } +}); +Ext.DataView = Ext.extend(Ext.BoxComponent, { + + + + + + + + + + selectedClass : "x-view-selected", + + emptyText : "", + + + deferEmptyText: true, + + trackOver: false, + + + blockRefresh: false, + + + last: false, + + + initComponent : function(){ + Ext.DataView.superclass.initComponent.call(this); + if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){ + this.tpl = new Ext.XTemplate(this.tpl); + } + + this.addEvents( + + "beforeclick", + + "click", + + "mouseenter", + + "mouseleave", + + "containerclick", + + "dblclick", + + "contextmenu", + + "containercontextmenu", + + "selectionchange", + + + "beforeselect" + ); + + this.store = Ext.StoreMgr.lookup(this.store); + this.all = new Ext.CompositeElementLite(); + this.selected = new Ext.CompositeElementLite(); + }, + + + afterRender : function(){ + Ext.DataView.superclass.afterRender.call(this); + + this.mon(this.getTemplateTarget(), { + "click": this.onClick, + "dblclick": this.onDblClick, + "contextmenu": this.onContextMenu, + scope:this + }); + + if(this.overClass || this.trackOver){ + this.mon(this.getTemplateTarget(), { + "mouseover": this.onMouseOver, + "mouseout": this.onMouseOut, + scope:this + }); + } + + if(this.store){ + this.bindStore(this.store, true); + } + }, + + + refresh : function() { + this.clearSelections(false, true); + var el = this.getTemplateTarget(), + records = this.store.getRange(); + + el.update(''); + if(records.length < 1){ + if(!this.deferEmptyText || this.hasSkippedEmptyText){ + el.update(this.emptyText); + } + this.all.clear(); + }else{ + this.tpl.overwrite(el, this.collectData(records, 0)); + this.all.fill(Ext.query(this.itemSelector, el.dom)); + this.updateIndexes(0); + } + this.hasSkippedEmptyText = true; + }, + + getTemplateTarget: function(){ + return this.el; + }, + + + prepareData : function(data){ + return data; + }, + + + collectData : function(records, startIndex){ + var r = [], + i = 0, + len = records.length; + for(; i < len; i++){ + r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]); + } + return r; + }, + + + bufferRender : function(records, index){ + var div = document.createElement('div'); + this.tpl.overwrite(div, this.collectData(records, index)); + return Ext.query(this.itemSelector, div); + }, + + + onUpdate : function(ds, record){ + var index = this.store.indexOf(record); + if(index > -1){ + var sel = this.isSelected(index), + original = this.all.elements[index], + node = this.bufferRender([record], index)[0]; + + this.all.replaceElement(index, node, true); + if(sel){ + this.selected.replaceElement(original, node); + this.all.item(index).addClass(this.selectedClass); + } + this.updateIndexes(index, index); + } + }, + + + onAdd : function(ds, records, index){ + if(this.all.getCount() === 0){ + this.refresh(); + return; + } + var nodes = this.bufferRender(records, index), n, a = this.all.elements; + if(index < this.all.getCount()){ + n = this.all.item(index).insertSibling(nodes, 'before', true); + a.splice.apply(a, [index, 0].concat(nodes)); + }else{ + n = this.all.last().insertSibling(nodes, 'after', true); + a.push.apply(a, nodes); + } + this.updateIndexes(index); + }, + + + onRemove : function(ds, record, index){ + this.deselect(index); + this.all.removeElement(index, true); + this.updateIndexes(index); + if (this.store.getCount() === 0){ + this.refresh(); + } + }, + + + refreshNode : function(index){ + this.onUpdate(this.store, this.store.getAt(index)); + }, + + + updateIndexes : function(startIndex, endIndex){ + var ns = this.all.elements; + startIndex = startIndex || 0; + endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1)); + for(var i = startIndex; i <= endIndex; i++){ + ns[i].viewIndex = i; + } + }, + + + getStore : function(){ + return this.store; + }, + + + bindStore : function(store, initial){ + if(!initial && this.store){ + if(store !== this.store && this.store.autoDestroy){ + this.store.destroy(); + }else{ + this.store.un("beforeload", this.onBeforeLoad, this); + this.store.un("datachanged", this.onDataChanged, this); + this.store.un("add", this.onAdd, this); + this.store.un("remove", this.onRemove, this); + this.store.un("update", this.onUpdate, this); + this.store.un("clear", this.refresh, this); + } + if(!store){ + this.store = null; + } + } + if(store){ + store = Ext.StoreMgr.lookup(store); + store.on({ + scope: this, + beforeload: this.onBeforeLoad, + datachanged: this.onDataChanged, + add: this.onAdd, + remove: this.onRemove, + update: this.onUpdate, + clear: this.refresh + }); + } + this.store = store; + if(store){ + this.refresh(); + } + }, + + + onDataChanged: function() { + if (this.blockRefresh !== true) { + this.refresh.apply(this, arguments); + } + }, + + + findItemFromChild : function(node){ + return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget()); + }, + + + onClick : function(e){ + var item = e.getTarget(this.itemSelector, this.getTemplateTarget()), + index; + if(item){ + index = this.indexOf(item); + if(this.onItemClick(item, index, e) !== false){ + this.fireEvent("click", this, index, item, e); + } + }else{ + if(this.fireEvent("containerclick", this, e) !== false){ + this.onContainerClick(e); + } + } + }, + + onContainerClick : function(e){ + this.clearSelections(); + }, + + + onContextMenu : function(e){ + var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); + if(item){ + this.fireEvent("contextmenu", this, this.indexOf(item), item, e); + }else{ + this.fireEvent("containercontextmenu", this, e); + } + }, + + + onDblClick : function(e){ + var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); + if(item){ + this.fireEvent("dblclick", this, this.indexOf(item), item, e); + } + }, + + + onMouseOver : function(e){ + var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); + if(item && item !== this.lastItem){ + this.lastItem = item; + Ext.fly(item).addClass(this.overClass); + this.fireEvent("mouseenter", this, this.indexOf(item), item, e); + } + }, + + + onMouseOut : function(e){ + if(this.lastItem){ + if(!e.within(this.lastItem, true, true)){ + Ext.fly(this.lastItem).removeClass(this.overClass); + this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e); + delete this.lastItem; + } + } + }, + + + onItemClick : function(item, index, e){ + if(this.fireEvent("beforeclick", this, index, item, e) === false){ + return false; + } + if(this.multiSelect){ + this.doMultiSelection(item, index, e); + e.preventDefault(); + }else if(this.singleSelect){ + this.doSingleSelection(item, index, e); + e.preventDefault(); + } + return true; + }, + + + doSingleSelection : function(item, index, e){ + if(e.ctrlKey && this.isSelected(index)){ + this.deselect(index); + }else{ + this.select(index, false); + } + }, + + + doMultiSelection : function(item, index, e){ + if(e.shiftKey && this.last !== false){ + var last = this.last; + this.selectRange(last, index, e.ctrlKey); + this.last = last; + }else{ + if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){ + this.deselect(index); + }else{ + this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect); + } + } + }, + + + getSelectionCount : function(){ + return this.selected.getCount(); + }, + + + getSelectedNodes : function(){ + return this.selected.elements; + }, + + + getSelectedIndexes : function(){ + var indexes = [], + selected = this.selected.elements, + i = 0, + len = selected.length; + + for(; i < len; i++){ + indexes.push(selected[i].viewIndex); + } + return indexes; + }, + + + getSelectedRecords : function(){ + return this.getRecords(this.selected.elements); + }, + + + getRecords : function(nodes){ + var records = [], + i = 0, + len = nodes.length; + + for(; i < len; i++){ + records[records.length] = this.store.getAt(nodes[i].viewIndex); + } + return records; + }, + + + getRecord : function(node){ + return this.store.getAt(node.viewIndex); + }, + + + clearSelections : function(suppressEvent, skipUpdate){ + if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){ + if(!skipUpdate){ + this.selected.removeClass(this.selectedClass); + } + this.selected.clear(); + this.last = false; + if(!suppressEvent){ + this.fireEvent("selectionchange", this, this.selected.elements); + } + } + }, + + + isSelected : function(node){ + return this.selected.contains(this.getNode(node)); + }, + + + deselect : function(node){ + if(this.isSelected(node)){ + node = this.getNode(node); + this.selected.removeElement(node); + if(this.last == node.viewIndex){ + this.last = false; + } + Ext.fly(node).removeClass(this.selectedClass); + this.fireEvent("selectionchange", this, this.selected.elements); + } + }, + + + select : function(nodeInfo, keepExisting, suppressEvent){ + if(Ext.isArray(nodeInfo)){ + if(!keepExisting){ + this.clearSelections(true); + } + for(var i = 0, len = nodeInfo.length; i < len; i++){ + this.select(nodeInfo[i], true, true); + } + if(!suppressEvent){ + this.fireEvent("selectionchange", this, this.selected.elements); + } + } else{ + var node = this.getNode(nodeInfo); + if(!keepExisting){ + this.clearSelections(true); + } + if(node && !this.isSelected(node)){ + if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){ + Ext.fly(node).addClass(this.selectedClass); + this.selected.add(node); + this.last = node.viewIndex; + if(!suppressEvent){ + this.fireEvent("selectionchange", this, this.selected.elements); + } + } + } + } + }, + + + selectRange : function(start, end, keepExisting){ + if(!keepExisting){ + this.clearSelections(true); + } + this.select(this.getNodes(start, end), true); + }, + + + getNode : function(nodeInfo){ + if(Ext.isString(nodeInfo)){ + return document.getElementById(nodeInfo); + }else if(Ext.isNumber(nodeInfo)){ + return this.all.elements[nodeInfo]; + }else if(nodeInfo instanceof Ext.data.Record){ + var idx = this.store.indexOf(nodeInfo); + return this.all.elements[idx]; + } + return nodeInfo; + }, + + + getNodes : function(start, end){ + var ns = this.all.elements, + nodes = [], + i; + + start = start || 0; + end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end; + if(start <= end){ + for(i = start; i <= end && ns[i]; i++){ + nodes.push(ns[i]); + } + } else{ + for(i = start; i >= end && ns[i]; i--){ + nodes.push(ns[i]); + } + } + return nodes; + }, + + + indexOf : function(node){ + node = this.getNode(node); + if(Ext.isNumber(node.viewIndex)){ + return node.viewIndex; + } + return this.all.indexOf(node); + }, + + + onBeforeLoad : function(){ + if(this.loadingText){ + this.clearSelections(false, true); + this.getTemplateTarget().update('
    '+this.loadingText+'
    '); + this.all.clear(); + } + }, + + onDestroy : function(){ + this.all.clear(); + this.selected.clear(); + Ext.DataView.superclass.onDestroy.call(this); + this.bindStore(null); + } +}); + + +Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore; + +Ext.reg('dataview', Ext.DataView); + +Ext.list.ListView = Ext.extend(Ext.DataView, { + + + + itemSelector: 'dl', + + selectedClass:'x-list-selected', + + overClass:'x-list-over', + + + scrollOffset : undefined, + + columnResize: true, + + + columnSort: true, + + + + maxColumnWidth: Ext.isIE9m ? 99 : 100, + + initComponent : function(){ + if(this.columnResize){ + this.colResizer = new Ext.list.ColumnResizer(this.colResizer); + this.colResizer.init(this); + } + if(this.columnSort){ + this.colSorter = new Ext.list.Sorter(this.columnSort); + this.colSorter.init(this); + } + if(!this.internalTpl){ + this.internalTpl = new Ext.XTemplate( + '
    ', + '', + '
    ', + '{header}', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ); + } + if(!this.tpl){ + this.tpl = new Ext.XTemplate( + '', + '
    ', + '', + '
    ', + ' class="{cls}">', + '{[values.tpl.apply(parent)]}', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ); + }; + + var cs = this.columns, + allocatedWidth = 0, + colsWithWidth = 0, + len = cs.length, + columns = []; + + for(var i = 0; i < len; i++){ + var c = cs[i]; + if(!c.isColumn) { + c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn'; + c = Ext.create(c); + } + if(c.width) { + allocatedWidth += c.width*100; + if(allocatedWidth > this.maxColumnWidth){ + c.width -= (allocatedWidth - this.maxColumnWidth) / 100; + } + colsWithWidth++; + } + columns.push(c); + } + + cs = this.columns = columns; + + + if(colsWithWidth < len){ + var remaining = len - colsWithWidth; + if(allocatedWidth < this.maxColumnWidth){ + var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100; + for(var j = 0; j < len; j++){ + var c = cs[j]; + if(!c.width){ + c.width = perCol; + } + } + } + } + Ext.list.ListView.superclass.initComponent.call(this); + }, + + onRender : function(){ + this.autoEl = { + cls: 'x-list-wrap' + }; + Ext.list.ListView.superclass.onRender.apply(this, arguments); + + this.internalTpl.overwrite(this.el, {columns: this.columns}); + + this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild); + this.innerHd = Ext.get(this.el.dom.firstChild.firstChild); + + if(this.hideHeaders){ + this.el.dom.firstChild.style.display = 'none'; + } + }, + + getTemplateTarget : function(){ + return this.innerBody; + }, + + + collectData : function(){ + var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments); + return { + columns: this.columns, + rows: rs + }; + }, + + verifyInternalSize : function(){ + if(this.lastSize){ + this.onResize(this.lastSize.width, this.lastSize.height); + } + }, + + + onResize : function(w, h){ + var body = this.innerBody.dom, + header = this.innerHd.dom, + scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px', + parentNode; + + if(!body){ + return; + } + parentNode = body.parentNode; + if(Ext.isNumber(w)){ + if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){ + body.style.width = scrollWidth; + header.style.width = scrollWidth; + }else{ + body.style.width = w + 'px'; + header.style.width = w + 'px'; + setTimeout(function(){ + if((parentNode.offsetWidth - parentNode.clientWidth) > 10){ + body.style.width = scrollWidth; + header.style.width = scrollWidth; + } + }, 10); + } + } + if(Ext.isNumber(h)){ + parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px'; + } + }, + + updateIndexes : function(){ + Ext.list.ListView.superclass.updateIndexes.apply(this, arguments); + this.verifyInternalSize(); + }, + + findHeaderIndex : function(header){ + header = header.dom || header; + var parentNode = header.parentNode, + children = parentNode.parentNode.childNodes, + i = 0, + c; + for(; c = children[i]; i++){ + if(c == parentNode){ + return i; + } + } + return -1; + }, + + setHdWidths : function(){ + var els = this.innerHd.dom.getElementsByTagName('div'), + i = 0, + columns = this.columns, + len = columns.length; + + for(; i < len; i++){ + els[i].style.width = (columns[i].width*100) + '%'; + } + } +}); + +Ext.reg('listview', Ext.list.ListView); + + +Ext.ListView = Ext.list.ListView; +Ext.list.Column = Ext.extend(Object, { + + isColumn: true, + + + align: 'left', + + header: '', + + + width: null, + + + cls: '', + + + + + + constructor : function(c){ + if(!c.tpl){ + c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}'); + } + else if(Ext.isString(c.tpl)){ + c.tpl = new Ext.XTemplate(c.tpl); + } + + Ext.apply(this, c); + } +}); + +Ext.reg('lvcolumn', Ext.list.Column); + + +Ext.list.NumberColumn = Ext.extend(Ext.list.Column, { + + format: '0,000.00', + + constructor : function(c) { + c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}'); + Ext.list.NumberColumn.superclass.constructor.call(this, c); + } +}); + +Ext.reg('lvnumbercolumn', Ext.list.NumberColumn); + + +Ext.list.DateColumn = Ext.extend(Ext.list.Column, { + format: 'm/d/Y', + constructor : function(c) { + c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}'); + Ext.list.DateColumn.superclass.constructor.call(this, c); + } +}); +Ext.reg('lvdatecolumn', Ext.list.DateColumn); + + +Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, { + + trueText: 'true', + + falseText: 'false', + + undefinedText: ' ', + + constructor : function(c) { + c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}'); + + var t = this.trueText, f = this.falseText, u = this.undefinedText; + c.tpl.format = function(v){ + if(v === undefined){ + return u; + } + if(!v || v === 'false'){ + return f; + } + return t; + }; + + Ext.list.DateColumn.superclass.constructor.call(this, c); + } +}); + +Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn); +Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, { + + minPct: .05, + + constructor: function(config){ + Ext.apply(this, config); + Ext.list.ColumnResizer.superclass.constructor.call(this); + }, + init : function(listView){ + this.view = listView; + listView.on('render', this.initEvents, this); + }, + + initEvents : function(view){ + view.mon(view.innerHd, 'mousemove', this.handleHdMove, this); + this.tracker = new Ext.dd.DragTracker({ + onBeforeStart: this.onBeforeStart.createDelegate(this), + onStart: this.onStart.createDelegate(this), + onDrag: this.onDrag.createDelegate(this), + onEnd: this.onEnd.createDelegate(this), + tolerance: 3, + autoStart: 300 + }); + this.tracker.initEl(view.innerHd); + view.on('beforedestroy', this.tracker.destroy, this.tracker); + }, + + handleHdMove : function(e, t){ + var handleWidth = 5, + x = e.getPageX(), + header = e.getTarget('em', 3, true); + if(header){ + var region = header.getRegion(), + style = header.dom.style, + parentNode = header.dom.parentNode; + + if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){ + this.activeHd = Ext.get(parentNode.previousSibling.firstChild); + style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize'; + } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){ + this.activeHd = header; + style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize'; + } else{ + delete this.activeHd; + style.cursor = ''; + } + } + }, + + onBeforeStart : function(e){ + this.dragHd = this.activeHd; + return !!this.dragHd; + }, + + onStart: function(e){ + + var me = this, + view = me.view, + dragHeader = me.dragHd, + x = me.tracker.getXY()[0]; + + me.proxy = view.el.createChild({cls:'x-list-resizer'}); + me.dragX = dragHeader.getX(); + me.headerIndex = view.findHeaderIndex(dragHeader); + + me.headersDisabled = view.disableHeaders; + view.disableHeaders = true; + + me.proxy.setHeight(view.el.getHeight()); + me.proxy.setX(me.dragX); + me.proxy.setWidth(x - me.dragX); + + this.setBoundaries(); + + }, + + + setBoundaries: function(relativeX){ + var view = this.view, + headerIndex = this.headerIndex, + width = view.innerHd.getWidth(), + relativeX = view.innerHd.getX(), + minWidth = Math.ceil(width * this.minPct), + maxWidth = width - minWidth, + numColumns = view.columns.length, + headers = view.innerHd.select('em', true), + minX = minWidth + relativeX, + maxX = maxWidth + relativeX, + header; + + if (numColumns == 2) { + this.minX = minX; + this.maxX = maxX; + }else{ + header = headers.item(headerIndex + 2); + this.minX = headers.item(headerIndex).getX() + minWidth; + this.maxX = header ? header.getX() - minWidth : maxX; + if (headerIndex == 0) { + + this.minX = minX; + } else if (headerIndex == numColumns - 2) { + + this.maxX = maxX; + } + } + }, + + onDrag: function(e){ + var me = this, + cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX); + + me.proxy.setWidth(cursorX - this.dragX); + }, + + onEnd: function(e){ + + var newWidth = this.proxy.getWidth(), + index = this.headerIndex, + view = this.view, + columns = view.columns, + width = view.innerHd.getWidth(), + newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100, + disabled = this.headersDisabled, + headerCol = columns[index], + otherCol = columns[index + 1], + totalPercent = headerCol.width + otherCol.width; + + this.proxy.remove(); + + headerCol.width = newPercent; + otherCol.width = totalPercent - newPercent; + + delete this.dragHd; + view.setHdWidths(); + view.refresh(); + + setTimeout(function(){ + view.disableHeaders = disabled; + }, 100); + } +}); + + +Ext.ListView.ColumnResizer = Ext.list.ColumnResizer; +Ext.list.Sorter = Ext.extend(Ext.util.Observable, { + + sortClasses : ["sort-asc", "sort-desc"], + + constructor: function(config){ + Ext.apply(this, config); + Ext.list.Sorter.superclass.constructor.call(this); + }, + + init : function(listView){ + this.view = listView; + listView.on('render', this.initEvents, this); + }, + + initEvents : function(view){ + view.mon(view.innerHd, 'click', this.onHdClick, this); + view.innerHd.setStyle('cursor', 'pointer'); + view.mon(view.store, 'datachanged', this.updateSortState, this); + this.updateSortState.defer(10, this, [view.store]); + }, + + updateSortState : function(store){ + var state = store.getSortState(); + if(!state){ + return; + } + this.sortState = state; + var cs = this.view.columns, sortColumn = -1; + for(var i = 0, len = cs.length; i < len; i++){ + if(cs[i].dataIndex == state.field){ + sortColumn = i; + break; + } + } + if(sortColumn != -1){ + var sortDir = state.direction; + this.updateSortIcon(sortColumn, sortDir); + } + }, + + updateSortIcon : function(col, dir){ + var sc = this.sortClasses; + var hds = this.view.innerHd.select('em').removeClass(sc); + hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]); + }, + + onHdClick : function(e){ + var hd = e.getTarget('em', 3); + if(hd && !this.view.disableHeaders){ + var index = this.view.findHeaderIndex(hd); + this.view.store.sort(this.view.columns[index].dataIndex); + } + } +}); + + +Ext.ListView.Sorter = Ext.list.Sorter; +Ext.TabPanel = Ext.extend(Ext.Panel, { + + + + deferredRender : true, + + tabWidth : 120, + + minTabWidth : 30, + + resizeTabs : false, + + enableTabScroll : false, + + scrollIncrement : 0, + + scrollRepeatInterval : 400, + + scrollDuration : 0.35, + + animScroll : true, + + tabPosition : 'top', + + baseCls : 'x-tab-panel', + + autoTabs : false, + + autoTabSelector : 'div.x-tab', + + activeTab : undefined, + + tabMargin : 2, + + plain : false, + + wheelIncrement : 20, + + + idDelimiter : '__', + + + itemCls : 'x-tab-item', + + + elements : 'body', + headerAsText : false, + frame : false, + hideBorders :true, + + + initComponent : function(){ + this.frame = false; + Ext.TabPanel.superclass.initComponent.call(this); + this.addEvents( + + 'beforetabchange', + + 'tabchange', + + 'contextmenu' + ); + + this.setLayout(new Ext.layout.CardLayout(Ext.apply({ + layoutOnCardChange: this.layoutOnTabChange, + deferredRender: this.deferredRender + }, this.layoutConfig))); + + if(this.tabPosition == 'top'){ + this.elements += ',header'; + this.stripTarget = 'header'; + }else { + this.elements += ',footer'; + this.stripTarget = 'footer'; + } + if(!this.stack){ + this.stack = Ext.TabPanel.AccessStack(); + } + this.initItems(); + }, + + + onRender : function(ct, position){ + Ext.TabPanel.superclass.onRender.call(this, ct, position); + + if(this.plain){ + var pos = this.tabPosition == 'top' ? 'header' : 'footer'; + this[pos].addClass('x-tab-panel-'+pos+'-plain'); + } + + var st = this[this.stripTarget]; + + this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{ + tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}}); + + var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null); + st.createChild({cls:'x-tab-strip-spacer'}, beforeEl); + this.strip = new Ext.Element(this.stripWrap.dom.firstChild); + + + this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]}); + this.strip.createChild({cls:'x-clear'}); + + this.body.addClass('x-tab-panel-body-'+this.tabPosition); + + + if(!this.itemTpl){ + var tt = new Ext.Template( + '
  • ', + '', + '{text}', + '
  • ' + ); + tt.disableFormats = true; + tt.compile(); + Ext.TabPanel.prototype.itemTpl = tt; + } + + this.items.each(this.initTab, this); + }, + + + afterRender : function(){ + Ext.TabPanel.superclass.afterRender.call(this); + if(this.autoTabs){ + this.readTabs(false); + } + if(this.activeTab !== undefined){ + var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab); + delete this.activeTab; + this.setActiveTab(item); + } + }, + + + initEvents : function(){ + Ext.TabPanel.superclass.initEvents.call(this); + this.mon(this.strip, { + scope: this, + mousedown: this.onStripMouseDown, + contextmenu: this.onStripContextMenu + }); + if(this.enableTabScroll){ + this.mon(this.strip, 'mousewheel', this.onWheel, this); + } + }, + + + findTargets : function(e){ + var item = null, + itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip); + + if(itemEl){ + item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]); + if(item.disabled){ + return { + close : null, + item : null, + el : null + }; + } + } + return { + close : e.getTarget('.x-tab-strip-close', this.strip), + item : item, + el : itemEl + }; + }, + + + onStripMouseDown : function(e){ + if(e.button !== 0){ + return; + } + e.preventDefault(); + var t = this.findTargets(e); + if(t.close){ + if (t.item.fireEvent('beforeclose', t.item) !== false) { + t.item.fireEvent('close', t.item); + this.remove(t.item); + } + return; + } + if(t.item && t.item != this.activeTab){ + this.setActiveTab(t.item); + } + }, + + + onStripContextMenu : function(e){ + e.preventDefault(); + var t = this.findTargets(e); + if(t.item){ + this.fireEvent('contextmenu', this, t.item, e); + } + }, + + + readTabs : function(removeExisting){ + if(removeExisting === true){ + this.items.each(function(item){ + this.remove(item); + }, this); + } + var tabs = this.el.query(this.autoTabSelector); + for(var i = 0, len = tabs.length; i < len; i++){ + var tab = tabs[i], + title = tab.getAttribute('title'); + tab.removeAttribute('title'); + this.add({ + title: title, + contentEl: tab + }); + } + }, + + + initTab : function(item, index){ + var before = this.strip.dom.childNodes[index], + p = this.getTemplateArgs(item), + el = before ? + this.itemTpl.insertBefore(before, p) : + this.itemTpl.append(this.strip, p), + cls = 'x-tab-strip-over', + tabEl = Ext.get(el); + + tabEl.hover(function(){ + if(!item.disabled){ + tabEl.addClass(cls); + } + }, function(){ + tabEl.removeClass(cls); + }); + + if(item.tabTip){ + tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip; + } + item.tabEl = el; + + + tabEl.select('a').on('click', function(e){ + if(!e.getPageX()){ + this.onStripMouseDown(e); + } + }, this, {preventDefault: true}); + + item.on({ + scope: this, + disable: this.onItemDisabled, + enable: this.onItemEnabled, + titlechange: this.onItemTitleChanged, + iconchange: this.onItemIconChanged, + beforeshow: this.onBeforeShowItem + }); + }, + + + + + getTemplateArgs : function(item) { + var cls = item.closable ? 'x-tab-strip-closable' : ''; + if(item.disabled){ + cls += ' x-item-disabled'; + } + if(item.iconCls){ + cls += ' x-tab-with-icon'; + } + if(item.tabCls){ + cls += ' ' + item.tabCls; + } + + return { + id: this.id + this.idDelimiter + item.getItemId(), + text: item.title, + cls: cls, + iconCls: item.iconCls || '' + }; + }, + + + onAdd : function(c){ + Ext.TabPanel.superclass.onAdd.call(this, c); + if(this.rendered){ + var items = this.items; + this.initTab(c, items.indexOf(c)); + this.delegateUpdates(); + } + }, + + + onBeforeAdd : function(item){ + var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item); + if(existing){ + this.setActiveTab(item); + return false; + } + Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments); + var es = item.elements; + item.elements = es ? es.replace(',header', '') : es; + item.border = (item.border === true); + }, + + + onRemove : function(c){ + var te = Ext.get(c.tabEl); + + if(te){ + te.select('a').removeAllListeners(); + Ext.destroy(te); + } + Ext.TabPanel.superclass.onRemove.call(this, c); + this.stack.remove(c); + delete c.tabEl; + c.un('disable', this.onItemDisabled, this); + c.un('enable', this.onItemEnabled, this); + c.un('titlechange', this.onItemTitleChanged, this); + c.un('iconchange', this.onItemIconChanged, this); + c.un('beforeshow', this.onBeforeShowItem, this); + if(c == this.activeTab){ + var next = this.stack.next(); + if(next){ + this.setActiveTab(next); + }else if(this.items.getCount() > 0){ + this.setActiveTab(0); + }else{ + this.setActiveTab(null); + } + } + if(!this.destroying){ + this.delegateUpdates(); + } + }, + + + onBeforeShowItem : function(item){ + if(item != this.activeTab){ + this.setActiveTab(item); + return false; + } + }, + + + onItemDisabled : function(item){ + var el = this.getTabEl(item); + if(el){ + Ext.fly(el).addClass('x-item-disabled'); + } + this.stack.remove(item); + }, + + + onItemEnabled : function(item){ + var el = this.getTabEl(item); + if(el){ + Ext.fly(el).removeClass('x-item-disabled'); + } + }, + + + onItemTitleChanged : function(item){ + var el = this.getTabEl(item); + if(el){ + Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title; + this.delegateUpdates(); + } + }, + + + onItemIconChanged : function(item, iconCls, oldCls){ + var el = this.getTabEl(item); + if(el){ + el = Ext.get(el); + el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls); + el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon'); + this.delegateUpdates(); + } + }, + + + getTabEl : function(item){ + var c = this.getComponent(item); + return c ? c.tabEl : null; + }, + + + onResize : function(){ + Ext.TabPanel.superclass.onResize.apply(this, arguments); + this.delegateUpdates(); + }, + + + beginUpdate : function(){ + this.suspendUpdates = true; + }, + + + endUpdate : function(){ + this.suspendUpdates = false; + this.delegateUpdates(); + }, + + + hideTabStripItem : function(item){ + item = this.getComponent(item); + var el = this.getTabEl(item); + if(el){ + el.style.display = 'none'; + this.delegateUpdates(); + } + this.stack.remove(item); + }, + + + unhideTabStripItem : function(item){ + item = this.getComponent(item); + var el = this.getTabEl(item); + if(el){ + el.style.display = ''; + this.delegateUpdates(); + } + }, + + + delegateUpdates : function(){ + var rendered = this.rendered; + if(this.suspendUpdates){ + return; + } + if(this.resizeTabs && rendered){ + this.autoSizeTabs(); + } + if(this.enableTabScroll && rendered){ + this.autoScrollTabs(); + } + }, + + + autoSizeTabs : function(){ + var count = this.items.length, + ce = this.tabPosition != 'bottom' ? 'header' : 'footer', + ow = this[ce].dom.offsetWidth, + aw = this[ce].dom.clientWidth; + + if(!this.resizeTabs || count < 1 || !aw){ + return; + } + + var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); + this.lastTabWidth = each; + var lis = this.strip.query('li:not(.x-tab-edge)'); + for(var i = 0, len = lis.length; i < len; i++) { + var li = lis[i], + inner = Ext.fly(li).child('.x-tab-strip-inner', true), + tw = li.offsetWidth, + iw = inner.offsetWidth; + inner.style.width = (each - (tw-iw)) + 'px'; + } + }, + + + adjustBodyWidth : function(w){ + if(this.header){ + this.header.setWidth(w); + } + if(this.footer){ + this.footer.setWidth(w); + } + return w; + }, + + + setActiveTab : function(item){ + item = this.getComponent(item); + if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){ + return; + } + if(!this.rendered){ + this.activeTab = item; + return; + } + if(this.activeTab != item){ + if(this.activeTab){ + var oldEl = this.getTabEl(this.activeTab); + if(oldEl){ + Ext.fly(oldEl).removeClass('x-tab-strip-active'); + } + } + this.activeTab = item; + if(item){ + var el = this.getTabEl(item); + Ext.fly(el).addClass('x-tab-strip-active'); + this.stack.add(item); + + this.layout.setActiveItem(item); + + this.delegateUpdates(); + if(this.scrolling){ + this.scrollToTab(item, this.animScroll); + } + } + this.fireEvent('tabchange', this, item); + } + }, + + + getActiveTab : function(){ + return this.activeTab || null; + }, + + + getItem : function(item){ + return this.getComponent(item); + }, + + + autoScrollTabs : function(){ + this.pos = this.tabPosition=='bottom' ? this.footer : this.header; + var count = this.items.length, + ow = this.pos.dom.offsetWidth, + tw = this.pos.dom.clientWidth, + wrap = this.stripWrap, + wd = wrap.dom, + cw = wd.offsetWidth, + pos = this.getScrollPos(), + l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos; + + if(!this.enableTabScroll || cw < 20){ + return; + } + if(count == 0 || l <= tw){ + + wd.scrollLeft = 0; + wrap.setWidth(tw); + if(this.scrolling){ + this.scrolling = false; + this.pos.removeClass('x-tab-scrolling'); + this.scrollLeft.hide(); + this.scrollRight.hide(); + + if(Ext.isAir || Ext.isWebKit){ + wd.style.marginLeft = ''; + wd.style.marginRight = ''; + } + } + }else{ + if(!this.scrolling){ + this.pos.addClass('x-tab-scrolling'); + + if(Ext.isAir || Ext.isWebKit){ + wd.style.marginLeft = '18px'; + wd.style.marginRight = '18px'; + } + } + tw -= wrap.getMargins('lr'); + wrap.setWidth(tw > 20 ? tw : 20); + if(!this.scrolling){ + if(!this.scrollLeft){ + this.createScrollers(); + }else{ + this.scrollLeft.show(); + this.scrollRight.show(); + } + } + this.scrolling = true; + if(pos > (l-tw)){ + wd.scrollLeft = l-tw; + }else{ + this.scrollToTab(this.activeTab, false); + } + this.updateScrollButtons(); + } + }, + + + createScrollers : function(){ + this.pos.addClass('x-tab-scrolling-' + this.tabPosition); + var h = this.stripWrap.dom.offsetHeight; + + + var sl = this.pos.insertFirst({ + cls:'x-tab-scroller-left' + }); + sl.setHeight(h); + sl.addClassOnOver('x-tab-scroller-left-over'); + this.leftRepeater = new Ext.util.ClickRepeater(sl, { + interval : this.scrollRepeatInterval, + handler: this.onScrollLeft, + scope: this + }); + this.scrollLeft = sl; + + + var sr = this.pos.insertFirst({ + cls:'x-tab-scroller-right' + }); + sr.setHeight(h); + sr.addClassOnOver('x-tab-scroller-right-over'); + this.rightRepeater = new Ext.util.ClickRepeater(sr, { + interval : this.scrollRepeatInterval, + handler: this.onScrollRight, + scope: this + }); + this.scrollRight = sr; + }, + + + getScrollWidth : function(){ + return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos(); + }, + + + getScrollPos : function(){ + return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0; + }, + + + getScrollArea : function(){ + return parseInt(this.stripWrap.dom.clientWidth, 10) || 0; + }, + + + getScrollAnim : function(){ + return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this}; + }, + + + getScrollIncrement : function(){ + return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100); + }, + + + + scrollToTab : function(item, animate){ + if(!item){ + return; + } + var el = this.getTabEl(item), + pos = this.getScrollPos(), + area = this.getScrollArea(), + left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos, + right = left + el.offsetWidth; + if(left < pos){ + this.scrollTo(left, animate); + }else if(right > (pos + area)){ + this.scrollTo(right - area, animate); + } + }, + + + scrollTo : function(pos, animate){ + this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false); + if(!animate){ + this.updateScrollButtons(); + } + }, + + onWheel : function(e){ + var d = e.getWheelDelta()*this.wheelIncrement*-1; + e.stopEvent(); + + var pos = this.getScrollPos(), + newpos = pos + d, + sw = this.getScrollWidth()-this.getScrollArea(); + + var s = Math.max(0, Math.min(sw, newpos)); + if(s != pos){ + this.scrollTo(s, false); + } + }, + + + onScrollRight : function(){ + var sw = this.getScrollWidth()-this.getScrollArea(), + pos = this.getScrollPos(), + s = Math.min(sw, pos + this.getScrollIncrement()); + if(s != pos){ + this.scrollTo(s, this.animScroll); + } + }, + + + onScrollLeft : function(){ + var pos = this.getScrollPos(), + s = Math.max(0, pos - this.getScrollIncrement()); + if(s != pos){ + this.scrollTo(s, this.animScroll); + } + }, + + + updateScrollButtons : function(){ + var pos = this.getScrollPos(); + this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled'); + this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled'); + }, + + + beforeDestroy : function() { + Ext.destroy(this.leftRepeater, this.rightRepeater); + this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap'); + this.activeTab = null; + Ext.TabPanel.superclass.beforeDestroy.apply(this); + } + + + + + + + + + + + + + +}); +Ext.reg('tabpanel', Ext.TabPanel); + + +Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab; + + +Ext.TabPanel.AccessStack = function(){ + var items = []; + return { + add : function(item){ + items.push(item); + if(items.length > 10){ + items.shift(); + } + }, + + remove : function(item){ + var s = []; + for(var i = 0, len = items.length; i < len; i++) { + if(items[i] != item){ + s.push(items[i]); + } + } + items = s; + }, + + next : function(){ + return items.pop(); + } + }; +}; + +Ext.Button = Ext.extend(Ext.BoxComponent, { + + hidden : false, + + disabled : false, + + pressed : false, + + + + + + + enableToggle : false, + + + + menuAlign : 'tl-bl?', + + + + + type : 'button', + + + menuClassTarget : 'tr:nth(2)', + + + clickEvent : 'click', + + + handleMouseEvents : true, + + + tooltipType : 'qtip', + + + buttonSelector : 'button:first-child', + + + scale : 'small', + + + + + iconAlign : 'left', + + + arrowAlign : 'right', + + + + + + + initComponent : function(){ + if(this.menu){ + + + if (Ext.isArray(this.menu)){ + this.menu = { items: this.menu }; + } + + + + if (Ext.isObject(this.menu)){ + this.menu.ownerCt = this; + } + + this.menu = Ext.menu.MenuMgr.get(this.menu); + this.menu.ownerCt = undefined; + } + + Ext.Button.superclass.initComponent.call(this); + + this.addEvents( + + 'click', + + 'toggle', + + 'mouseover', + + 'mouseout', + + 'menushow', + + 'menuhide', + + 'menutriggerover', + + 'menutriggerout' + ); + + if(Ext.isString(this.toggleGroup)){ + this.enableToggle = true; + } + }, + + + getTemplateArgs : function(){ + return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id]; + }, + + + setButtonClass : function(){ + if(this.useSetClass){ + if(!Ext.isEmpty(this.oldCls)){ + this.el.removeClass([this.oldCls, 'x-btn-pressed']); + } + this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon'; + this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]); + } + }, + + + getMenuClass : function(){ + return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : ''; + }, + + + onRender : function(ct, position){ + if(!this.template){ + if(!Ext.Button.buttonTemplate){ + + Ext.Button.buttonTemplate = new Ext.Template( + '', + '', + '', + '', + '
      
      
      
    '); + Ext.Button.buttonTemplate.compile(); + } + this.template = Ext.Button.buttonTemplate; + } + + var btn, targs = this.getTemplateArgs(); + + if(position){ + btn = this.template.insertBefore(position, targs, true); + }else{ + btn = this.template.append(ct, targs, true); + } + + this.btnEl = btn.child(this.buttonSelector); + this.mon(this.btnEl, { + scope: this, + focus: this.onFocus, + blur: this.onBlur + }); + + this.initButtonEl(btn, this.btnEl); + + Ext.ButtonToggleMgr.register(this); + }, + + + initButtonEl : function(btn, btnEl){ + this.el = btn; + this.setIcon(this.icon); + this.setText(this.text); + this.setIconClass(this.iconCls); + if(Ext.isDefined(this.tabIndex)){ + btnEl.dom.tabIndex = this.tabIndex; + } + if(this.tooltip){ + this.setTooltip(this.tooltip, true); + } + + if(this.handleMouseEvents){ + this.mon(btn, { + scope: this, + mouseover: this.onMouseOver, + mousedown: this.onMouseDown + }); + + + + } + + if(this.menu){ + this.mon(this.menu, { + scope: this, + show: this.onMenuShow, + hide: this.onMenuHide + }); + } + + if(this.repeat){ + var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {}); + this.mon(repeater, 'click', this.onRepeatClick, this); + }else{ + this.mon(btn, this.clickEvent, this.onClick, this); + } + }, + + + afterRender : function(){ + Ext.Button.superclass.afterRender.call(this); + this.useSetClass = true; + this.setButtonClass(); + this.doc = Ext.getDoc(); + this.doAutoWidth(); + }, + + + setIconClass : function(cls){ + this.iconCls = cls; + if(this.el){ + this.btnEl.dom.className = ''; + this.btnEl.addClass(['x-btn-text', cls || '']); + this.setButtonClass(); + } + return this; + }, + + + setTooltip : function(tooltip, initial){ + if(this.rendered){ + if(!initial){ + this.clearTip(); + } + if(Ext.isObject(tooltip)){ + Ext.QuickTips.register(Ext.apply({ + target: this.btnEl.id + }, tooltip)); + this.tooltip = tooltip; + }else{ + this.btnEl.dom[this.tooltipType] = tooltip; + } + }else{ + this.tooltip = tooltip; + } + return this; + }, + + + clearTip : function(){ + if(Ext.isObject(this.tooltip)){ + Ext.QuickTips.unregister(this.btnEl); + } + }, + + + beforeDestroy : function(){ + if(this.rendered){ + this.clearTip(); + } + if(this.menu && this.destroyMenu !== false) { + Ext.destroy(this.btnEl, this.menu); + } + Ext.destroy(this.repeater); + }, + + + onDestroy : function(){ + if(this.rendered){ + this.doc.un('mouseover', this.monitorMouseOver, this); + this.doc.un('mouseup', this.onMouseUp, this); + delete this.doc; + delete this.btnEl; + Ext.ButtonToggleMgr.unregister(this); + } + Ext.Button.superclass.onDestroy.call(this); + }, + + + doAutoWidth : function(){ + if(this.autoWidth !== false && this.el && this.text && this.width === undefined){ + this.el.setWidth('auto'); + if(Ext.isIE7 && Ext.isStrict){ + var ib = this.btnEl; + if(ib && ib.getWidth() > 20){ + ib.clip(); + ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr')); + } + } + if(this.minWidth){ + if(this.el.getWidth() < this.minWidth){ + this.el.setWidth(this.minWidth); + } + } + } + }, + + + setHandler : function(handler, scope){ + this.handler = handler; + this.scope = scope; + return this; + }, + + + setText : function(text){ + this.text = text; + if(this.el){ + this.btnEl.update(text || ' '); + this.setButtonClass(); + } + this.doAutoWidth(); + return this; + }, + + + setIcon : function(icon){ + this.icon = icon; + if(this.el){ + this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : ''); + this.setButtonClass(); + } + return this; + }, + + + getText : function(){ + return this.text; + }, + + + toggle : function(state, suppressEvent){ + state = state === undefined ? !this.pressed : !!state; + if(state != this.pressed){ + if(this.rendered){ + this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed'); + } + this.pressed = state; + if(!suppressEvent){ + this.fireEvent('toggle', this, state); + if(this.toggleHandler){ + this.toggleHandler.call(this.scope || this, this, state); + } + } + } + return this; + }, + + + onDisable : function(){ + this.onDisableChange(true); + }, + + + onEnable : function(){ + this.onDisableChange(false); + }, + + onDisableChange : function(disabled){ + if(this.el){ + if(!Ext.isIE6 || !this.text){ + this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass); + } + this.el.dom.disabled = disabled; + } + this.disabled = disabled; + }, + + + showMenu : function(){ + if(this.rendered && this.menu){ + if(this.tooltip){ + Ext.QuickTips.getQuickTip().cancelShow(this.btnEl); + } + if(this.menu.isVisible()){ + this.menu.hide(); + } + this.menu.ownerCt = this; + this.menu.show(this.el, this.menuAlign); + } + return this; + }, + + + hideMenu : function(){ + if(this.hasVisibleMenu()){ + this.menu.hide(); + } + return this; + }, + + + hasVisibleMenu : function(){ + return this.menu && this.menu.ownerCt == this && this.menu.isVisible(); + }, + + + onRepeatClick : function(repeat, e){ + this.onClick(e); + }, + + + onClick : function(e){ + if(e){ + e.preventDefault(); + } + if(e.button !== 0){ + return; + } + if(!this.disabled){ + this.doToggle(); + if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){ + this.showMenu(); + } + this.fireEvent('click', this, e); + if(this.handler){ + + this.handler.call(this.scope || this, this, e); + } + } + }, + + + doToggle: function(){ + if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) { + this.toggle(); + } + }, + + + isMenuTriggerOver : function(e, internal){ + return this.menu && !internal; + }, + + + isMenuTriggerOut : function(e, internal){ + return this.menu && !internal; + }, + + + onMouseOver : function(e){ + if(!this.disabled){ + var internal = e.within(this.el, true); + if(!internal){ + this.el.addClass('x-btn-over'); + if(!this.monitoringMouseOver){ + this.doc.on('mouseover', this.monitorMouseOver, this); + this.monitoringMouseOver = true; + } + this.fireEvent('mouseover', this, e); + } + if(this.isMenuTriggerOver(e, internal)){ + this.fireEvent('menutriggerover', this, this.menu, e); + } + } + }, + + + monitorMouseOver : function(e){ + if(e.target != this.el.dom && !e.within(this.el)){ + if(this.monitoringMouseOver){ + this.doc.un('mouseover', this.monitorMouseOver, this); + this.monitoringMouseOver = false; + } + this.onMouseOut(e); + } + }, + + + onMouseOut : function(e){ + var internal = e.within(this.el) && e.target != this.el.dom; + this.el.removeClass('x-btn-over'); + this.fireEvent('mouseout', this, e); + if(this.isMenuTriggerOut(e, internal)){ + this.fireEvent('menutriggerout', this, this.menu, e); + } + }, + + focus : function() { + this.btnEl.focus(); + }, + + blur : function() { + this.btnEl.blur(); + }, + + + onFocus : function(e){ + if(!this.disabled){ + this.el.addClass('x-btn-focus'); + } + }, + + onBlur : function(e){ + this.el.removeClass('x-btn-focus'); + }, + + + getClickEl : function(e, isUp){ + return this.el; + }, + + + onMouseDown : function(e){ + if(!this.disabled && e.button === 0){ + this.getClickEl(e).addClass('x-btn-click'); + this.doc.on('mouseup', this.onMouseUp, this); + } + }, + + onMouseUp : function(e){ + if(e.button === 0){ + this.getClickEl(e, true).removeClass('x-btn-click'); + this.doc.un('mouseup', this.onMouseUp, this); + } + }, + + onMenuShow : function(e){ + if(this.menu.ownerCt == this){ + this.menu.ownerCt = this; + this.ignoreNextClick = 0; + this.el.addClass('x-btn-menu-active'); + this.fireEvent('menushow', this, this.menu); + } + }, + + onMenuHide : function(e){ + if(this.menu.ownerCt == this){ + this.el.removeClass('x-btn-menu-active'); + this.ignoreNextClick = this.restoreClick.defer(250, this); + this.fireEvent('menuhide', this, this.menu); + delete this.menu.ownerCt; + } + }, + + + restoreClick : function(){ + this.ignoreNextClick = 0; + } + + + + + + + +}); +Ext.reg('button', Ext.Button); + + +Ext.ButtonToggleMgr = function(){ + var groups = {}; + + function toggleGroup(btn, state){ + if(state){ + var g = groups[btn.toggleGroup]; + for(var i = 0, l = g.length; i < l; i++){ + if(g[i] != btn){ + g[i].toggle(false); + } + } + } + } + + return { + register : function(btn){ + if(!btn.toggleGroup){ + return; + } + var g = groups[btn.toggleGroup]; + if(!g){ + g = groups[btn.toggleGroup] = []; + } + g.push(btn); + btn.on('toggle', toggleGroup); + }, + + unregister : function(btn){ + if(!btn.toggleGroup){ + return; + } + var g = groups[btn.toggleGroup]; + if(g){ + g.remove(btn); + btn.un('toggle', toggleGroup); + } + }, + + + getPressed : function(group){ + var g = groups[group]; + if(g){ + for(var i = 0, len = g.length; i < len; i++){ + if(g[i].pressed === true){ + return g[i]; + } + } + } + return null; + } + }; +}(); + +Ext.SplitButton = Ext.extend(Ext.Button, { + + arrowSelector : 'em', + split: true, + + + initComponent : function(){ + Ext.SplitButton.superclass.initComponent.call(this); + + this.addEvents("arrowclick"); + }, + + + onRender : function(){ + Ext.SplitButton.superclass.onRender.apply(this, arguments); + if(this.arrowTooltip){ + this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip; + } + }, + + + setArrowHandler : function(handler, scope){ + this.arrowHandler = handler; + this.scope = scope; + }, + + getMenuClass : function(){ + return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : ''); + }, + + isClickOnArrow : function(e){ + if (this.arrowAlign != 'bottom') { + var visBtn = this.el.child('em.x-btn-split'); + var right = visBtn.getRegion().right - visBtn.getPadding('r'); + return e.getPageX() > right; + } else { + return e.getPageY() > this.btnEl.getRegion().bottom; + } + }, + + + onClick : function(e, t){ + e.preventDefault(); + if(!this.disabled){ + if(this.isClickOnArrow(e)){ + if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){ + this.showMenu(); + } + this.fireEvent("arrowclick", this, e); + if(this.arrowHandler){ + this.arrowHandler.call(this.scope || this, this, e); + } + }else{ + this.doToggle(); + this.fireEvent("click", this, e); + if(this.handler){ + this.handler.call(this.scope || this, this, e); + } + } + } + }, + + + isMenuTriggerOver : function(e){ + return this.menu && e.target.tagName == this.arrowSelector; + }, + + + isMenuTriggerOut : function(e, internal){ + return this.menu && e.target.tagName != this.arrowSelector; + } +}); + +Ext.reg('splitbutton', Ext.SplitButton); +Ext.CycleButton = Ext.extend(Ext.SplitButton, { + + + + + + + + + getItemText : function(item){ + if(item && this.showText === true){ + var text = ''; + if(this.prependText){ + text += this.prependText; + } + text += item.text; + return text; + } + return undefined; + }, + + + setActiveItem : function(item, suppressEvent){ + if(!Ext.isObject(item)){ + item = this.menu.getComponent(item); + } + if(item){ + if(!this.rendered){ + this.text = this.getItemText(item); + this.iconCls = item.iconCls; + }else{ + var t = this.getItemText(item); + if(t){ + this.setText(t); + } + this.setIconClass(item.iconCls); + } + this.activeItem = item; + if(!item.checked){ + item.setChecked(true, suppressEvent); + } + if(this.forceIcon){ + this.setIconClass(this.forceIcon); + } + if(!suppressEvent){ + this.fireEvent('change', this, item); + } + } + }, + + + getActiveItem : function(){ + return this.activeItem; + }, + + + initComponent : function(){ + this.addEvents( + + "change" + ); + + if(this.changeHandler){ + this.on('change', this.changeHandler, this.scope||this); + delete this.changeHandler; + } + + this.itemCount = this.items.length; + + this.menu = {cls:'x-cycle-menu', items:[]}; + var checked = 0; + Ext.each(this.items, function(item, i){ + Ext.apply(item, { + group: item.group || this.id, + itemIndex: i, + checkHandler: this.checkHandler, + scope: this, + checked: item.checked || false + }); + this.menu.items.push(item); + if(item.checked){ + checked = i; + } + }, this); + Ext.CycleButton.superclass.initComponent.call(this); + this.on('click', this.toggleSelected, this); + this.setActiveItem(checked, true); + }, + + + checkHandler : function(item, pressed){ + if(pressed){ + this.setActiveItem(item); + } + }, + + + toggleSelected : function(){ + var m = this.menu; + m.render(); + + if(!m.hasLayout){ + m.doLayout(); + } + + var nextIdx, checkItem; + for (var i = 1; i < this.itemCount; i++) { + nextIdx = (this.activeItem.itemIndex + i) % this.itemCount; + + checkItem = m.items.itemAt(nextIdx); + + if (!checkItem.disabled) { + checkItem.setChecked(true); + break; + } + } + } +}); +Ext.reg('cycle', Ext.CycleButton); +Ext.Toolbar = function(config){ + if(Ext.isArray(config)){ + config = {items: config, layout: 'toolbar'}; + } else { + config = Ext.apply({ + layout: 'toolbar' + }, config); + if(config.buttons) { + config.items = config.buttons; + } + } + Ext.Toolbar.superclass.constructor.call(this, config); +}; + +(function(){ + +var T = Ext.Toolbar; + +Ext.extend(T, Ext.Container, { + + defaultType: 'button', + + + + enableOverflow : false, + + + + + trackMenus : true, + internalDefaults: {removeMode: 'container', hideParent: true}, + toolbarCls: 'x-toolbar', + + initComponent : function(){ + T.superclass.initComponent.call(this); + + + this.addEvents('overflowchange'); + }, + + + onRender : function(ct, position){ + if(!this.el){ + if(!this.autoCreate){ + this.autoCreate = { + cls: this.toolbarCls + ' x-small-editor' + }; + } + this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position); + Ext.Toolbar.superclass.onRender.apply(this, arguments); + } + }, + + + + + lookupComponent : function(c){ + if(Ext.isString(c)){ + if(c == '-'){ + c = new T.Separator(); + }else if(c == ' '){ + c = new T.Spacer(); + }else if(c == '->'){ + c = new T.Fill(); + }else{ + c = new T.TextItem(c); + } + this.applyDefaults(c); + }else{ + if(c.isFormField || c.render){ + c = this.createComponent(c); + }else if(c.tag){ + c = new T.Item({autoEl: c}); + }else if(c.tagName){ + c = new T.Item({el:c}); + }else if(Ext.isObject(c)){ + c = c.xtype ? this.createComponent(c) : this.constructButton(c); + } + } + return c; + }, + + + applyDefaults : function(c){ + if(!Ext.isString(c)){ + c = Ext.Toolbar.superclass.applyDefaults.call(this, c); + var d = this.internalDefaults; + if(c.events){ + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + }else{ + Ext.applyIf(c, d); + } + } + return c; + }, + + + addSeparator : function(){ + return this.add(new T.Separator()); + }, + + + addSpacer : function(){ + return this.add(new T.Spacer()); + }, + + + addFill : function(){ + this.add(new T.Fill()); + }, + + + addElement : function(el){ + return this.addItem(new T.Item({el:el})); + }, + + + addItem : function(item){ + return this.add.apply(this, arguments); + }, + + + addButton : function(config){ + if(Ext.isArray(config)){ + var buttons = []; + for(var i = 0, len = config.length; i < len; i++) { + buttons.push(this.addButton(config[i])); + } + return buttons; + } + return this.add(this.constructButton(config)); + }, + + + addText : function(text){ + return this.addItem(new T.TextItem(text)); + }, + + + addDom : function(config){ + return this.add(new T.Item({autoEl: config})); + }, + + + addField : function(field){ + return this.add(field); + }, + + + insertButton : function(index, item){ + if(Ext.isArray(item)){ + var buttons = []; + for(var i = 0, len = item.length; i < len; i++) { + buttons.push(this.insertButton(index + i, item[i])); + } + return buttons; + } + return Ext.Toolbar.superclass.insert.call(this, index, item); + }, + + + trackMenu : function(item, remove){ + if(this.trackMenus && item.menu){ + var method = remove ? 'mun' : 'mon'; + this[method](item, 'menutriggerover', this.onButtonTriggerOver, this); + this[method](item, 'menushow', this.onButtonMenuShow, this); + this[method](item, 'menuhide', this.onButtonMenuHide, this); + } + }, + + + constructButton : function(item){ + var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType); + return b; + }, + + + onAdd : function(c){ + Ext.Toolbar.superclass.onAdd.call(this); + this.trackMenu(c); + if(this.disabled){ + c.disable(); + } + }, + + + onRemove : function(c){ + Ext.Toolbar.superclass.onRemove.call(this); + if (c == this.activeMenuBtn) { + delete this.activeMenuBtn; + } + this.trackMenu(c, true); + }, + + + onDisable : function(){ + this.items.each(function(item){ + if(item.disable){ + item.disable(); + } + }); + }, + + + onEnable : function(){ + this.items.each(function(item){ + if(item.enable){ + item.enable(); + } + }); + }, + + + onButtonTriggerOver : function(btn){ + if(this.activeMenuBtn && this.activeMenuBtn != btn){ + this.activeMenuBtn.hideMenu(); + btn.showMenu(); + this.activeMenuBtn = btn; + } + }, + + + onButtonMenuShow : function(btn){ + this.activeMenuBtn = btn; + }, + + + onButtonMenuHide : function(btn){ + delete this.activeMenuBtn; + } +}); +Ext.reg('toolbar', Ext.Toolbar); + + +T.Item = Ext.extend(Ext.BoxComponent, { + hideParent: true, + enable:Ext.emptyFn, + disable:Ext.emptyFn, + focus:Ext.emptyFn + +}); +Ext.reg('tbitem', T.Item); + + +T.Separator = Ext.extend(T.Item, { + onRender : function(ct, position){ + this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position); + } +}); +Ext.reg('tbseparator', T.Separator); + + +T.Spacer = Ext.extend(T.Item, { + + + onRender : function(ct, position){ + this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position); + } +}); +Ext.reg('tbspacer', T.Spacer); + + +T.Fill = Ext.extend(T.Item, { + + render : Ext.emptyFn, + isFill : true +}); +Ext.reg('tbfill', T.Fill); + + +T.TextItem = Ext.extend(T.Item, { + + + constructor: function(config){ + T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config); + }, + + + onRender : function(ct, position) { + this.autoEl = {cls: 'xtb-text', html: this.text || ''}; + T.TextItem.superclass.onRender.call(this, ct, position); + }, + + + setText : function(t) { + if(this.rendered){ + this.el.update(t); + }else{ + this.text = t; + } + } +}); +Ext.reg('tbtext', T.TextItem); + + +T.Button = Ext.extend(Ext.Button, {}); +T.SplitButton = Ext.extend(Ext.SplitButton, {}); +Ext.reg('tbbutton', T.Button); +Ext.reg('tbsplit', T.SplitButton); + +})(); + +Ext.ButtonGroup = Ext.extend(Ext.Panel, { + + + baseCls: 'x-btn-group', + + layout:'table', + defaultType: 'button', + + frame: true, + internalDefaults: {removeMode: 'container', hideParent: true}, + + initComponent : function(){ + this.layoutConfig = this.layoutConfig || {}; + Ext.applyIf(this.layoutConfig, { + columns : this.columns + }); + if(!this.title){ + this.addClass('x-btn-group-notitle'); + } + this.on('afterlayout', this.onAfterLayout, this); + Ext.ButtonGroup.superclass.initComponent.call(this); + }, + + applyDefaults : function(c){ + c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c); + var d = this.internalDefaults; + if(c.events){ + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + }else{ + Ext.applyIf(c, d); + } + return c; + }, + + onAfterLayout : function(){ + var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth; + this.body.setWidth(bodyWidth); + this.el.setWidth(bodyWidth + this.getFrameWidth()); + } + +}); + +Ext.reg('buttongroup', Ext.ButtonGroup); + +(function() { + +var T = Ext.Toolbar; + +Ext.PagingToolbar = Ext.extend(Ext.Toolbar, { + + + + pageSize : 20, + + + displayMsg : 'Displaying {0} - {1} of {2}', + + emptyMsg : 'No data to display', + + beforePageText : 'Page', + + afterPageText : 'of {0}', + + firstText : 'First Page', + + prevText : 'Previous Page', + + nextText : 'Next Page', + + lastText : 'Last Page', + + refreshText : 'Refresh', + + + + + + + + initComponent : function(){ + var pagingItems = [this.first = new T.Button({ + tooltip: this.firstText, + overflowText: this.firstText, + iconCls: 'x-tbar-page-first', + disabled: true, + handler: this.moveFirst, + scope: this + }), this.prev = new T.Button({ + tooltip: this.prevText, + overflowText: this.prevText, + iconCls: 'x-tbar-page-prev', + disabled: true, + handler: this.movePrevious, + scope: this + }), '-', this.beforePageText, + this.inputItem = new Ext.form.NumberField({ + cls: 'x-tbar-page-number', + allowDecimals: false, + allowNegative: false, + enableKeyEvents: true, + selectOnFocus: true, + submitValue: false, + listeners: { + scope: this, + keydown: this.onPagingKeyDown, + blur: this.onPagingBlur + } + }), this.afterTextItem = new T.TextItem({ + text: String.format(this.afterPageText, 1) + }), '-', this.next = new T.Button({ + tooltip: this.nextText, + overflowText: this.nextText, + iconCls: 'x-tbar-page-next', + disabled: true, + handler: this.moveNext, + scope: this + }), this.last = new T.Button({ + tooltip: this.lastText, + overflowText: this.lastText, + iconCls: 'x-tbar-page-last', + disabled: true, + handler: this.moveLast, + scope: this + }), '-', this.refresh = new T.Button({ + tooltip: this.refreshText, + overflowText: this.refreshText, + iconCls: 'x-tbar-loading', + handler: this.doRefresh, + scope: this + })]; + + + var userItems = this.items || this.buttons || []; + if (this.prependButtons) { + this.items = userItems.concat(pagingItems); + }else{ + this.items = pagingItems.concat(userItems); + } + delete this.buttons; + if(this.displayInfo){ + this.items.push('->'); + this.items.push(this.displayItem = new T.TextItem({})); + } + Ext.PagingToolbar.superclass.initComponent.call(this); + this.addEvents( + + 'change', + + 'beforechange' + ); + this.on('afterlayout', this.onFirstLayout, this, {single: true}); + this.cursor = 0; + this.bindStore(this.store, true); + }, + + + onFirstLayout : function(){ + if(this.dsLoaded){ + this.onLoad.apply(this, this.dsLoaded); + } + }, + + + updateInfo : function(){ + if(this.displayItem){ + var count = this.store.getCount(); + var msg = count == 0 ? + this.emptyMsg : + String.format( + this.displayMsg, + this.cursor+1, this.cursor+count, this.store.getTotalCount() + ); + this.displayItem.setText(msg); + } + }, + + + onLoad : function(store, r, o){ + if(!this.rendered){ + this.dsLoaded = [store, r, o]; + return; + } + var p = this.getParams(); + this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0; + var d = this.getPageData(), ap = d.activePage, ps = d.pages; + + this.afterTextItem.setText(String.format(this.afterPageText, d.pages)); + this.inputItem.setValue(ap); + this.first.setDisabled(ap == 1); + this.prev.setDisabled(ap == 1); + this.next.setDisabled(ap == ps); + this.last.setDisabled(ap == ps); + this.refresh.enable(); + this.updateInfo(); + this.fireEvent('change', this, d); + }, + + + getPageData : function(){ + var total = this.store.getTotalCount(); + return { + total : total, + activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize), + pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize) + }; + }, + + + changePage : function(page){ + this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount())); + }, + + + onLoadError : function(){ + if(!this.rendered){ + return; + } + this.refresh.enable(); + }, + + + readPage : function(d){ + var v = this.inputItem.getValue(), pageNum; + if (!v || isNaN(pageNum = parseInt(v, 10))) { + this.inputItem.setValue(d.activePage); + return false; + } + return pageNum; + }, + + onPagingFocus : function(){ + this.inputItem.select(); + }, + + + onPagingBlur : function(e){ + this.inputItem.setValue(this.getPageData().activePage); + }, + + + onPagingKeyDown : function(field, e){ + var k = e.getKey(), d = this.getPageData(), pageNum; + if (k == e.RETURN) { + e.stopEvent(); + pageNum = this.readPage(d); + if(pageNum !== false){ + pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1; + this.doLoad(pageNum * this.pageSize); + } + }else if (k == e.HOME || k == e.END){ + e.stopEvent(); + pageNum = k == e.HOME ? 1 : d.pages; + field.setValue(pageNum); + }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){ + e.stopEvent(); + if((pageNum = this.readPage(d))){ + var increment = e.shiftKey ? 10 : 1; + if(k == e.DOWN || k == e.PAGEDOWN){ + increment *= -1; + } + pageNum += increment; + if(pageNum >= 1 & pageNum <= d.pages){ + field.setValue(pageNum); + } + } + } + }, + + + getParams : function(){ + + return this.paramNames || this.store.paramNames; + }, + + + beforeLoad : function(){ + if(this.rendered && this.refresh){ + this.refresh.disable(); + } + }, + + + doLoad : function(start){ + var o = {}, pn = this.getParams(); + o[pn.start] = start; + o[pn.limit] = this.pageSize; + if(this.fireEvent('beforechange', this, o) !== false){ + this.store.load({params:o}); + } + }, + + + moveFirst : function(){ + this.doLoad(0); + }, + + + movePrevious : function(){ + this.doLoad(Math.max(0, this.cursor-this.pageSize)); + }, + + + moveNext : function(){ + this.doLoad(this.cursor+this.pageSize); + }, + + + moveLast : function(){ + var total = this.store.getTotalCount(), + extra = total % this.pageSize; + + this.doLoad(extra ? (total - extra) : total - this.pageSize); + }, + + + doRefresh : function(){ + this.doLoad(this.cursor); + }, + + + bindStore : function(store, initial){ + var doLoad; + if(!initial && this.store){ + if(store !== this.store && this.store.autoDestroy){ + this.store.destroy(); + }else{ + this.store.un('beforeload', this.beforeLoad, this); + this.store.un('load', this.onLoad, this); + this.store.un('exception', this.onLoadError, this); + } + if(!store){ + this.store = null; + } + } + if(store){ + store = Ext.StoreMgr.lookup(store); + store.on({ + scope: this, + beforeload: this.beforeLoad, + load: this.onLoad, + exception: this.onLoadError + }); + doLoad = true; + } + this.store = store; + if(doLoad){ + this.onLoad(store, null, {}); + } + }, + + + unbind : function(store){ + this.bindStore(null); + }, + + + bind : function(store){ + this.bindStore(store); + }, + + + onDestroy : function(){ + this.bindStore(null); + Ext.PagingToolbar.superclass.onDestroy.call(this); + } +}); + +})(); +Ext.reg('paging', Ext.PagingToolbar); +Ext.History = (function () { + var iframe, hiddenField; + var ready = false; + var currentToken; + + function getHash() { + var href = location.href, i = href.indexOf("#"), + hash = i >= 0 ? href.substr(i + 1) : null; + + if (Ext.isGecko) { + hash = decodeURIComponent(hash); + } + return hash; + } + + function doSave() { + hiddenField.value = currentToken; + } + + function handleStateChange(token) { + currentToken = token; + Ext.History.fireEvent('change', token); + } + + function updateIFrame (token) { + var html = ['
    ',Ext.util.Format.htmlEncode(token),'
    '].join(''); + try { + var doc = iframe.contentWindow.document; + doc.open(); + doc.write(html); + doc.close(); + return true; + } catch (e) { + return false; + } + } + + function checkIFrame() { + if (!iframe.contentWindow || !iframe.contentWindow.document) { + setTimeout(checkIFrame, 10); + return; + } + + var doc = iframe.contentWindow.document; + var elem = doc.getElementById("state"); + var token = elem ? elem.innerText : null; + + var hash = getHash(); + + setInterval(function () { + + doc = iframe.contentWindow.document; + elem = doc.getElementById("state"); + + var newtoken = elem ? elem.innerText : null; + + var newHash = getHash(); + + if (newtoken !== token) { + token = newtoken; + handleStateChange(token); + location.hash = token; + hash = token; + doSave(); + } else if (newHash !== hash) { + hash = newHash; + updateIFrame(newHash); + } + + }, 50); + + ready = true; + + Ext.History.fireEvent('ready', Ext.History); + } + + function startUp() { + currentToken = hiddenField.value ? hiddenField.value : getHash(); + + if (Ext.isIE) { + checkIFrame(); + } else { + var hash = getHash(); + setInterval(function () { + var newHash = getHash(); + if (newHash !== hash) { + hash = newHash; + handleStateChange(hash); + doSave(); + } + }, 50); + ready = true; + Ext.History.fireEvent('ready', Ext.History); + } + } + + return { + + fieldId: 'x-history-field', + + iframeId: 'x-history-frame', + + events:{}, + + + init: function (onReady, scope) { + if(ready) { + Ext.callback(onReady, scope, [this]); + return; + } + if(!Ext.isReady){ + Ext.onReady(function(){ + Ext.History.init(onReady, scope); + }); + return; + } + hiddenField = Ext.getDom(Ext.History.fieldId); + if (Ext.isIE) { + iframe = Ext.getDom(Ext.History.iframeId); + } + this.addEvents( + + 'ready', + + 'change' + ); + if(onReady){ + this.on('ready', onReady, scope, {single:true}); + } + startUp(); + }, + + + add: function (token, preventDup) { + if(preventDup !== false){ + if(this.getToken() == token){ + return true; + } + } + if (Ext.isIE) { + return updateIFrame(token); + } else { + location.hash = token; + return true; + } + }, + + + back: function(){ + history.go(-1); + }, + + + forward: function(){ + history.go(1); + }, + + + getToken: function() { + return ready ? currentToken : getHash(); + } + }; +})(); +Ext.apply(Ext.History, new Ext.util.Observable()); +Ext.Tip = Ext.extend(Ext.Panel, { + + + + minWidth : 40, + + maxWidth : 300, + + shadow : "sides", + + defaultAlign : "tl-bl?", + autoRender: true, + quickShowInterval : 250, + + + frame:true, + hidden:true, + baseCls: 'x-tip', + floating:{shadow:true,shim:true,useDisplay:true,constrain:false}, + autoHeight:true, + + closeAction: 'hide', + + + initComponent : function(){ + Ext.Tip.superclass.initComponent.call(this); + if(this.closable && !this.title){ + this.elements += ',header'; + } + }, + + + afterRender : function(){ + Ext.Tip.superclass.afterRender.call(this); + if(this.closable){ + this.addTool({ + id: 'close', + handler: this[this.closeAction], + scope: this + }); + } + }, + + + showAt : function(xy){ + Ext.Tip.superclass.show.call(this); + if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){ + this.doAutoWidth(); + } + if(this.constrainPosition){ + xy = this.el.adjustForConstraints(xy); + } + this.setPagePosition(xy[0], xy[1]); + }, + + + doAutoWidth : function(adjust){ + adjust = adjust || 0; + var bw = this.body.getTextWidth(); + if(this.title){ + bw = Math.max(bw, this.header.child('span').getTextWidth(this.title)); + } + bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust; + this.setWidth(bw.constrain(this.minWidth, this.maxWidth)); + + + if(Ext.isIE7 && !this.repainted){ + this.el.repaint(); + this.repainted = true; + } + }, + + + showBy : function(el, pos){ + if(!this.rendered){ + this.render(Ext.getBody()); + } + this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign)); + }, + + initDraggable : function(){ + this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable); + this.header.addClass('x-tip-draggable'); + } +}); + +Ext.reg('tip', Ext.Tip); + + +Ext.Tip.DD = function(tip, config){ + Ext.apply(this, config); + this.tip = tip; + Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id); + this.setHandleElId(tip.header.id); + this.scroll = false; +}; + +Ext.extend(Ext.Tip.DD, Ext.dd.DD, { + moveOnly:true, + scroll:false, + headerOffsets:[100, 25], + startDrag : function(){ + this.tip.el.disableShadow(); + }, + endDrag : function(e){ + this.tip.el.enableShadow(true); + } +}); +Ext.ToolTip = Ext.extend(Ext.Tip, { + + + + + showDelay : 500, + + hideDelay : 200, + + dismissDelay : 5000, + + + trackMouse : false, + + anchorToTarget : true, + + anchorOffset : 0, + + + + targetCounter : 0, + + constrainPosition : false, + + + initComponent : function(){ + Ext.ToolTip.superclass.initComponent.call(this); + this.lastActive = new Date(); + this.initTarget(this.target); + this.origAnchor = this.anchor; + }, + + + onRender : function(ct, position){ + Ext.ToolTip.superclass.onRender.call(this, ct, position); + this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition(); + this.anchorEl = this.el.createChild({ + cls: 'x-tip-anchor ' + this.anchorCls + }); + }, + + + afterRender : function(){ + Ext.ToolTip.superclass.afterRender.call(this); + this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY); + }, + + + initTarget : function(target){ + var t; + if((t = Ext.get(target))){ + if(this.target){ + var tg = Ext.get(this.target); + this.mun(tg, 'mouseover', this.onTargetOver, this); + this.mun(tg, 'mouseout', this.onTargetOut, this); + this.mun(tg, 'mousemove', this.onMouseMove, this); + } + this.mon(t, { + mouseover: this.onTargetOver, + mouseout: this.onTargetOut, + mousemove: this.onMouseMove, + scope: this + }); + this.target = t; + } + if(this.anchor){ + this.anchorTarget = this.target; + } + }, + + + onMouseMove : function(e){ + var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true; + if (t) { + this.targetXY = e.getXY(); + if (t === this.triggerElement) { + if(!this.hidden && this.trackMouse){ + this.setPagePosition(this.getTargetXY()); + } + } else { + this.hide(); + this.lastActive = new Date(0); + this.onTargetOver(e); + } + } else if (!this.closable && this.isVisible()) { + this.hide(); + } + }, + + + getTargetXY : function(){ + if(this.delegate){ + this.anchorTarget = this.triggerElement; + } + if(this.anchor){ + this.targetCounter++; + var offsets = this.getOffsets(), + xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY, + dw = Ext.lib.Dom.getViewWidth() - 5, + dh = Ext.lib.Dom.getViewHeight() - 5, + de = document.documentElement, + bd = document.body, + scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5, + scrollY = (de.scrollTop || bd.scrollTop || 0) + 5, + axy = [xy[0] + offsets[0], xy[1] + offsets[1]], + sz = this.getSize(); + + this.anchorEl.removeClass(this.anchorCls); + + if(this.targetCounter < 2){ + if(axy[0] < scrollX){ + if(this.anchorToTarget){ + this.defaultAlign = 'l-r'; + if(this.mouseOffset){this.mouseOffset[0] *= -1;} + } + this.anchor = 'left'; + return this.getTargetXY(); + } + if(axy[0]+sz.width > dw){ + if(this.anchorToTarget){ + this.defaultAlign = 'r-l'; + if(this.mouseOffset){this.mouseOffset[0] *= -1;} + } + this.anchor = 'right'; + return this.getTargetXY(); + } + if(axy[1] < scrollY){ + if(this.anchorToTarget){ + this.defaultAlign = 't-b'; + if(this.mouseOffset){this.mouseOffset[1] *= -1;} + } + this.anchor = 'top'; + return this.getTargetXY(); + } + if(axy[1]+sz.height > dh){ + if(this.anchorToTarget){ + this.defaultAlign = 'b-t'; + if(this.mouseOffset){this.mouseOffset[1] *= -1;} + } + this.anchor = 'bottom'; + return this.getTargetXY(); + } + } + + this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition(); + this.anchorEl.addClass(this.anchorCls); + this.targetCounter = 0; + return axy; + }else{ + var mouseOffset = this.getMouseOffset(); + return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]]; + } + }, + + getMouseOffset : function(){ + var offset = this.anchor ? [0,0] : [15,18]; + if(this.mouseOffset){ + offset[0] += this.mouseOffset[0]; + offset[1] += this.mouseOffset[1]; + } + return offset; + }, + + + getAnchorPosition : function(){ + if(this.anchor){ + this.tipAnchor = this.anchor.charAt(0); + }else{ + var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/); + if(!m){ + throw 'AnchorTip.defaultAlign is invalid'; + } + this.tipAnchor = m[1].charAt(0); + } + + switch(this.tipAnchor){ + case 't': return 'top'; + case 'b': return 'bottom'; + case 'r': return 'right'; + } + return 'left'; + }, + + + getAnchorAlign : function(){ + switch(this.anchor){ + case 'top' : return 'tl-bl'; + case 'left' : return 'tl-tr'; + case 'right': return 'tr-tl'; + default : return 'bl-tl'; + } + }, + + + getOffsets : function(){ + var offsets, + ap = this.getAnchorPosition().charAt(0); + if(this.anchorToTarget && !this.trackMouse){ + switch(ap){ + case 't': + offsets = [0, 9]; + break; + case 'b': + offsets = [0, -13]; + break; + case 'r': + offsets = [-13, 0]; + break; + default: + offsets = [9, 0]; + break; + } + }else{ + switch(ap){ + case 't': + offsets = [-15-this.anchorOffset, 30]; + break; + case 'b': + offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight]; + break; + case 'r': + offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset]; + break; + default: + offsets = [25, -13-this.anchorOffset]; + break; + } + } + var mouseOffset = this.getMouseOffset(); + offsets[0] += mouseOffset[0]; + offsets[1] += mouseOffset[1]; + + return offsets; + }, + + + onTargetOver : function(e){ + if(this.disabled || e.within(this.target.dom, true)){ + return; + } + var t = e.getTarget(this.delegate); + if (t) { + this.triggerElement = t; + this.clearTimer('hide'); + this.targetXY = e.getXY(); + this.delayShow(); + } + }, + + + delayShow : function(){ + if(this.hidden && !this.showTimer){ + if(this.lastActive.getElapsed() < this.quickShowInterval){ + this.show(); + }else{ + this.showTimer = this.show.defer(this.showDelay, this); + } + }else if(!this.hidden && this.autoHide !== false){ + this.show(); + } + }, + + + onTargetOut : function(e){ + if(this.disabled || e.within(this.target.dom, true)){ + return; + } + this.clearTimer('show'); + if(this.autoHide !== false){ + this.delayHide(); + } + }, + + + delayHide : function(){ + if(!this.hidden && !this.hideTimer){ + this.hideTimer = this.hide.defer(this.hideDelay, this); + } + }, + + + hide: function(){ + this.clearTimer('dismiss'); + this.lastActive = new Date(); + if(this.anchorEl){ + this.anchorEl.hide(); + } + Ext.ToolTip.superclass.hide.call(this); + delete this.triggerElement; + }, + + + show : function(){ + if(this.anchor){ + + + this.showAt([-1000,-1000]); + this.origConstrainPosition = this.constrainPosition; + this.constrainPosition = false; + this.anchor = this.origAnchor; + } + this.showAt(this.getTargetXY()); + + if(this.anchor){ + this.anchorEl.show(); + this.syncAnchor(); + this.constrainPosition = this.origConstrainPosition; + }else{ + this.anchorEl.hide(); + } + }, + + + showAt : function(xy){ + this.lastActive = new Date(); + this.clearTimers(); + Ext.ToolTip.superclass.showAt.call(this, xy); + if(this.dismissDelay && this.autoHide !== false){ + this.dismissTimer = this.hide.defer(this.dismissDelay, this); + } + if(this.anchor && !this.anchorEl.isVisible()){ + this.syncAnchor(); + this.anchorEl.show(); + }else{ + this.anchorEl.hide(); + } + }, + + + syncAnchor : function(){ + var anchorPos, targetPos, offset; + switch(this.tipAnchor.charAt(0)){ + case 't': + anchorPos = 'b'; + targetPos = 'tl'; + offset = [20+this.anchorOffset, 2]; + break; + case 'r': + anchorPos = 'l'; + targetPos = 'tr'; + offset = [-2, 11+this.anchorOffset]; + break; + case 'b': + anchorPos = 't'; + targetPos = 'bl'; + offset = [20+this.anchorOffset, -2]; + break; + default: + anchorPos = 'r'; + targetPos = 'tl'; + offset = [2, 11+this.anchorOffset]; + break; + } + this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset); + }, + + + setPagePosition : function(x, y){ + Ext.ToolTip.superclass.setPagePosition.call(this, x, y); + if(this.anchor){ + this.syncAnchor(); + } + }, + + + clearTimer : function(name){ + name = name + 'Timer'; + clearTimeout(this[name]); + delete this[name]; + }, + + + clearTimers : function(){ + this.clearTimer('show'); + this.clearTimer('dismiss'); + this.clearTimer('hide'); + }, + + + onShow : function(){ + Ext.ToolTip.superclass.onShow.call(this); + Ext.getDoc().on('mousedown', this.onDocMouseDown, this); + }, + + + onHide : function(){ + Ext.ToolTip.superclass.onHide.call(this); + Ext.getDoc().un('mousedown', this.onDocMouseDown, this); + }, + + + onDocMouseDown : function(e){ + if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){ + this.disable(); + this.doEnable.defer(100, this); + } + }, + + + doEnable : function(){ + if(!this.isDestroyed){ + this.enable(); + } + }, + + + onDisable : function(){ + this.clearTimers(); + this.hide(); + }, + + + adjustPosition : function(x, y){ + if(this.constrainPosition){ + var ay = this.targetXY[1], h = this.getSize().height; + if(y <= ay && (y+h) >= ay){ + y = ay-h-5; + } + } + return {x : x, y: y}; + }, + + beforeDestroy : function(){ + this.clearTimers(); + Ext.destroy(this.anchorEl); + delete this.anchorEl; + delete this.target; + delete this.anchorTarget; + delete this.triggerElement; + Ext.ToolTip.superclass.beforeDestroy.call(this); + }, + + + onDestroy : function(){ + Ext.getDoc().un('mousedown', this.onDocMouseDown, this); + Ext.ToolTip.superclass.onDestroy.call(this); + } +}); + +Ext.reg('tooltip', Ext.ToolTip); +Ext.QuickTip = Ext.extend(Ext.ToolTip, { + + + interceptTitles : false, + + + tagConfig : { + namespace : "ext", + attribute : "qtip", + width : "qwidth", + target : "target", + title : "qtitle", + hide : "hide", + cls : "qclass", + align : "qalign", + anchor : "anchor" + }, + + + initComponent : function(){ + this.target = this.target || Ext.getDoc(); + this.targets = this.targets || {}; + Ext.QuickTip.superclass.initComponent.call(this); + }, + + + register : function(config){ + var cs = Ext.isArray(config) ? config : arguments; + for(var i = 0, len = cs.length; i < len; i++){ + var c = cs[i]; + var target = c.target; + if(target){ + if(Ext.isArray(target)){ + for(var j = 0, jlen = target.length; j < jlen; j++){ + this.targets[Ext.id(target[j])] = c; + } + } else{ + this.targets[Ext.id(target)] = c; + } + } + } + }, + + + unregister : function(el){ + delete this.targets[Ext.id(el)]; + }, + + + cancelShow: function(el){ + var at = this.activeTarget; + el = Ext.get(el).dom; + if(this.isVisible()){ + if(at && at.el == el){ + this.hide(); + } + }else if(at && at.el == el){ + this.clearTimer('show'); + } + }, + + getTipCfg: function(e) { + var t = e.getTarget(), + ttp, + cfg; + if(this.interceptTitles && t.title && Ext.isString(t.title)){ + ttp = t.title; + t.qtip = ttp; + t.removeAttribute("title"); + e.preventDefault(); + }else{ + cfg = this.tagConfig; + ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace); + } + return ttp; + }, + + + onTargetOver : function(e){ + if(this.disabled){ + return; + } + this.targetXY = e.getXY(); + var t = e.getTarget(); + if(!t || t.nodeType !== 1 || t == document || t == document.body){ + return; + } + if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){ + this.clearTimer('hide'); + this.show(); + return; + } + if(t && this.targets[t.id]){ + this.activeTarget = this.targets[t.id]; + this.activeTarget.el = t; + this.anchor = this.activeTarget.anchor; + if(this.anchor){ + this.anchorTarget = t; + } + this.delayShow(); + return; + } + var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace; + if(ttp = this.getTipCfg(e)){ + var autoHide = et.getAttribute(cfg.hide, ns); + this.activeTarget = { + el: t, + text: ttp, + width: et.getAttribute(cfg.width, ns), + autoHide: autoHide != "user" && autoHide !== 'false', + title: et.getAttribute(cfg.title, ns), + cls: et.getAttribute(cfg.cls, ns), + align: et.getAttribute(cfg.align, ns) + + }; + this.anchor = et.getAttribute(cfg.anchor, ns); + if(this.anchor){ + this.anchorTarget = t; + } + this.delayShow(); + } + }, + + + onTargetOut : function(e){ + + + if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) { + return; + } + + this.clearTimer('show'); + if(this.autoHide !== false){ + this.delayHide(); + } + }, + + + showAt : function(xy){ + var t = this.activeTarget; + if(t){ + if(!this.rendered){ + this.render(Ext.getBody()); + this.activeTarget = t; + } + if(t.width){ + this.setWidth(t.width); + this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth())); + this.measureWidth = false; + } else{ + this.measureWidth = true; + } + this.setTitle(t.title || ''); + this.body.update(t.text); + this.autoHide = t.autoHide; + this.dismissDelay = t.dismissDelay || this.dismissDelay; + if(this.lastCls){ + this.el.removeClass(this.lastCls); + delete this.lastCls; + } + if(t.cls){ + this.el.addClass(t.cls); + this.lastCls = t.cls; + } + if(this.anchor){ + this.constrainPosition = false; + }else if(t.align){ + xy = this.el.getAlignToXY(t.el, t.align); + this.constrainPosition = false; + }else{ + this.constrainPosition = true; + } + } + Ext.QuickTip.superclass.showAt.call(this, xy); + }, + + + hide: function(){ + delete this.activeTarget; + Ext.QuickTip.superclass.hide.call(this); + } +}); +Ext.reg('quicktip', Ext.QuickTip); +Ext.QuickTips = function(){ + var tip, + disabled = false; + + return { + + init : function(autoRender){ + if(!tip){ + if(!Ext.isReady){ + Ext.onReady(function(){ + Ext.QuickTips.init(autoRender); + }); + return; + } + tip = new Ext.QuickTip({ + elements:'header,body', + disabled: disabled + }); + if(autoRender !== false){ + tip.render(Ext.getBody()); + } + } + }, + + + ddDisable : function(){ + + if(tip && !disabled){ + tip.disable(); + } + }, + + + ddEnable : function(){ + + if(tip && !disabled){ + tip.enable(); + } + }, + + + enable : function(){ + if(tip){ + tip.enable(); + } + disabled = false; + }, + + + disable : function(){ + if(tip){ + tip.disable(); + } + disabled = true; + }, + + + isEnabled : function(){ + return tip !== undefined && !tip.disabled; + }, + + + getQuickTip : function(){ + return tip; + }, + + + register : function(){ + tip.register.apply(tip, arguments); + }, + + + unregister : function(){ + tip.unregister.apply(tip, arguments); + }, + + + tips : function(){ + tip.register.apply(tip, arguments); + } + }; +}(); +Ext.slider.Tip = Ext.extend(Ext.Tip, { + minWidth: 10, + offsets : [0, -10], + + init: function(slider) { + slider.on({ + scope : this, + dragstart: this.onSlide, + drag : this.onSlide, + dragend : this.hide, + destroy : this.destroy + }); + }, + + + onSlide : function(slider, e, thumb) { + this.show(); + this.body.update(this.getText(thumb)); + this.doAutoWidth(); + this.el.alignTo(thumb.el, 'b-t?', this.offsets); + }, + + + getText : function(thumb) { + return String(thumb.value); + } +}); + + +Ext.ux.SliderTip = Ext.slider.Tip; +Ext.tree.TreePanel = Ext.extend(Ext.Panel, { + rootVisible : true, + animate : Ext.enableFx, + lines : true, + enableDD : false, + hlDrop : Ext.enableFx, + pathSeparator : '/', + + + bubbleEvents : [], + + initComponent : function(){ + Ext.tree.TreePanel.superclass.initComponent.call(this); + + if(!this.eventModel){ + this.eventModel = new Ext.tree.TreeEventModel(this); + } + + + var l = this.loader; + if(!l){ + l = new Ext.tree.TreeLoader({ + dataUrl: this.dataUrl, + requestMethod: this.requestMethod + }); + }else if(Ext.isObject(l) && !l.load){ + l = new Ext.tree.TreeLoader(l); + } + this.loader = l; + + this.nodeHash = {}; + + + if(this.root){ + var r = this.root; + delete this.root; + this.setRootNode(r); + } + + + this.addEvents( + + + 'append', + + 'remove', + + 'movenode', + + 'insert', + + 'beforeappend', + + 'beforeremove', + + 'beforemovenode', + + 'beforeinsert', + + + 'beforeload', + + 'load', + + 'textchange', + + 'beforeexpandnode', + + 'beforecollapsenode', + + 'expandnode', + + 'disabledchange', + + 'collapsenode', + + 'beforeclick', + + 'click', + + 'containerclick', + + 'checkchange', + + 'beforedblclick', + + 'dblclick', + + 'containerdblclick', + + 'contextmenu', + + 'containercontextmenu', + + 'beforechildrenrendered', + + 'startdrag', + + 'enddrag', + + 'dragdrop', + + 'beforenodedrop', + + 'nodedrop', + + 'nodedragover' + ); + if(this.singleExpand){ + this.on('beforeexpandnode', this.restrictExpand, this); + } + }, + + + proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){ + if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){ + ename = ename+'node'; + } + + return this.fireEvent(ename, a1, a2, a3, a4, a5, a6); + }, + + + + getRootNode : function(){ + return this.root; + }, + + + setRootNode : function(node){ + this.destroyRoot(); + if(!node.render){ + node = this.loader.createNode(node); + } + this.root = node; + node.ownerTree = this; + node.isRoot = true; + this.registerNode(node); + if(!this.rootVisible){ + var uiP = node.attributes.uiProvider; + node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node); + } + if(this.innerCt){ + this.clearInnerCt(); + this.renderRoot(); + } + return node; + }, + + clearInnerCt : function(){ + this.innerCt.update(''); + }, + + + renderRoot : function(){ + this.root.render(); + if(!this.rootVisible){ + this.root.renderChildren(); + } + }, + + + getNodeById : function(id){ + return this.nodeHash[id]; + }, + + + registerNode : function(node){ + this.nodeHash[node.id] = node; + }, + + + unregisterNode : function(node){ + delete this.nodeHash[node.id]; + }, + + + toString : function(){ + return '[Tree'+(this.id?' '+this.id:'')+']'; + }, + + + restrictExpand : function(node){ + var p = node.parentNode; + if(p){ + if(p.expandedChild && p.expandedChild.parentNode == p){ + p.expandedChild.collapse(); + } + p.expandedChild = node; + } + }, + + + getChecked : function(a, startNode){ + startNode = startNode || this.root; + var r = []; + var f = function(){ + if(this.attributes.checked){ + r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a])); + } + }; + startNode.cascade(f); + return r; + }, + + + getLoader : function(){ + return this.loader; + }, + + + expandAll : function(){ + this.root.expand(true); + }, + + + collapseAll : function(){ + this.root.collapse(true); + }, + + + getSelectionModel : function(){ + if(!this.selModel){ + this.selModel = new Ext.tree.DefaultSelectionModel(); + } + return this.selModel; + }, + + + expandPath : function(path, attr, callback){ + if(Ext.isEmpty(path)){ + if(callback){ + callback(false, undefined); + } + return; + } + attr = attr || 'id'; + var keys = path.split(this.pathSeparator); + var curNode = this.root; + if(curNode.attributes[attr] != keys[1]){ + if(callback){ + callback(false, null); + } + return; + } + var index = 1; + var f = function(){ + if(++index == keys.length){ + if(callback){ + callback(true, curNode); + } + return; + } + var c = curNode.findChild(attr, keys[index]); + if(!c){ + if(callback){ + callback(false, curNode); + } + return; + } + curNode = c; + c.expand(false, false, f); + }; + curNode.expand(false, false, f); + }, + + + selectPath : function(path, attr, callback){ + if(Ext.isEmpty(path)){ + if(callback){ + callback(false, undefined); + } + return; + } + attr = attr || 'id'; + var keys = path.split(this.pathSeparator), + v = keys.pop(); + if(keys.length > 1){ + var f = function(success, node){ + if(success && node){ + var n = node.findChild(attr, v); + if(n){ + n.select(); + if(callback){ + callback(true, n); + } + }else if(callback){ + callback(false, n); + } + }else{ + if(callback){ + callback(false, n); + } + } + }; + this.expandPath(keys.join(this.pathSeparator), attr, f); + }else{ + this.root.select(); + if(callback){ + callback(true, this.root); + } + } + }, + + + getTreeEl : function(){ + return this.body; + }, + + + onRender : function(ct, position){ + Ext.tree.TreePanel.superclass.onRender.call(this, ct, position); + this.el.addClass('x-tree'); + this.innerCt = this.body.createChild({tag:'ul', + cls:'x-tree-root-ct ' + + (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')}); + }, + + + initEvents : function(){ + Ext.tree.TreePanel.superclass.initEvents.call(this); + + if(this.containerScroll){ + Ext.dd.ScrollManager.register(this.body); + } + if((this.enableDD || this.enableDrop) && !this.dropZone){ + + this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || { + ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true + }); + } + if((this.enableDD || this.enableDrag) && !this.dragZone){ + + this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || { + ddGroup: this.ddGroup || 'TreeDD', + scroll: this.ddScroll + }); + } + this.getSelectionModel().init(this); + }, + + + afterRender : function(){ + Ext.tree.TreePanel.superclass.afterRender.call(this); + this.renderRoot(); + }, + + beforeDestroy : function(){ + if(this.rendered){ + Ext.dd.ScrollManager.unregister(this.body); + Ext.destroy(this.dropZone, this.dragZone); + } + this.destroyRoot(); + Ext.destroy(this.loader); + this.nodeHash = this.root = this.loader = null; + Ext.tree.TreePanel.superclass.beforeDestroy.call(this); + }, + + + destroyRoot : function(){ + if(this.root && this.root.destroy){ + this.root.destroy(true); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +}); + +Ext.tree.TreePanel.nodeTypes = {}; + +Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){ + this.tree = tree; + this.tree.on('render', this.initEvents, this); +}; + +Ext.tree.TreeEventModel.prototype = { + initEvents : function(){ + var t = this.tree; + + if(t.trackMouseOver !== false){ + t.mon(t.innerCt, { + scope: this, + mouseover: this.delegateOver, + mouseout: this.delegateOut + }); + } + t.mon(t.getTreeEl(), { + scope: this, + click: this.delegateClick, + dblclick: this.delegateDblClick, + contextmenu: this.delegateContextMenu + }); + }, + + getNode : function(e){ + var t; + if(t = e.getTarget('.x-tree-node-el', 10)){ + var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext'); + if(id){ + return this.tree.getNodeById(id); + } + } + return null; + }, + + getNodeTarget : function(e){ + var t = e.getTarget('.x-tree-node-icon', 1); + if(!t){ + t = e.getTarget('.x-tree-node-el', 6); + } + return t; + }, + + delegateOut : function(e, t){ + if(!this.beforeEvent(e)){ + return; + } + if(e.getTarget('.x-tree-ec-icon', 1)){ + var n = this.getNode(e); + this.onIconOut(e, n); + if(n == this.lastEcOver){ + delete this.lastEcOver; + } + } + if((t = this.getNodeTarget(e)) && !e.within(t, true)){ + this.onNodeOut(e, this.getNode(e)); + } + }, + + delegateOver : function(e, t){ + if(!this.beforeEvent(e)){ + return; + } + if(Ext.isGecko && !this.trackingDoc){ + Ext.getBody().on('mouseover', this.trackExit, this); + this.trackingDoc = true; + } + if(this.lastEcOver){ + this.onIconOut(e, this.lastEcOver); + delete this.lastEcOver; + } + if(e.getTarget('.x-tree-ec-icon', 1)){ + this.lastEcOver = this.getNode(e); + this.onIconOver(e, this.lastEcOver); + } + if(t = this.getNodeTarget(e)){ + this.onNodeOver(e, this.getNode(e)); + } + }, + + trackExit : function(e){ + if(this.lastOverNode){ + if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){ + this.onNodeOut(e, this.lastOverNode); + } + delete this.lastOverNode; + Ext.getBody().un('mouseover', this.trackExit, this); + this.trackingDoc = false; + } + + }, + + delegateClick : function(e, t){ + if(this.beforeEvent(e)){ + if(e.getTarget('input[type=checkbox]', 1)){ + this.onCheckboxClick(e, this.getNode(e)); + }else if(e.getTarget('.x-tree-ec-icon', 1)){ + this.onIconClick(e, this.getNode(e)); + }else if(this.getNodeTarget(e)){ + this.onNodeClick(e, this.getNode(e)); + } + }else{ + this.checkContainerEvent(e, 'click'); + } + }, + + delegateDblClick : function(e, t){ + if(this.beforeEvent(e)){ + if(this.getNodeTarget(e)){ + this.onNodeDblClick(e, this.getNode(e)); + } + }else{ + this.checkContainerEvent(e, 'dblclick'); + } + }, + + delegateContextMenu : function(e, t){ + if(this.beforeEvent(e)){ + if(this.getNodeTarget(e)){ + this.onNodeContextMenu(e, this.getNode(e)); + } + }else{ + this.checkContainerEvent(e, 'contextmenu'); + } + }, + + checkContainerEvent: function(e, type){ + if(this.disabled){ + e.stopEvent(); + return false; + } + this.onContainerEvent(e, type); + }, + + onContainerEvent: function(e, type){ + this.tree.fireEvent('container' + type, this.tree, e); + }, + + onNodeClick : function(e, node){ + node.ui.onClick(e); + }, + + onNodeOver : function(e, node){ + this.lastOverNode = node; + node.ui.onOver(e); + }, + + onNodeOut : function(e, node){ + node.ui.onOut(e); + }, + + onIconOver : function(e, node){ + node.ui.addClass('x-tree-ec-over'); + }, + + onIconOut : function(e, node){ + node.ui.removeClass('x-tree-ec-over'); + }, + + onIconClick : function(e, node){ + node.ui.ecClick(e); + }, + + onCheckboxClick : function(e, node){ + node.ui.onCheckChange(e); + }, + + onNodeDblClick : function(e, node){ + node.ui.onDblClick(e); + }, + + onNodeContextMenu : function(e, node){ + node.ui.onContextMenu(e); + }, + + beforeEvent : function(e){ + var node = this.getNode(e); + if(this.disabled || !node || !node.ui){ + e.stopEvent(); + return false; + } + return true; + }, + + disable: function(){ + this.disabled = true; + }, + + enable: function(){ + this.disabled = false; + } +}; +Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, { + + constructor : function(config){ + this.selNode = null; + + this.addEvents( + + 'selectionchange', + + + 'beforeselect' + ); + + Ext.apply(this, config); + Ext.tree.DefaultSelectionModel.superclass.constructor.call(this); + }, + + init : function(tree){ + this.tree = tree; + tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this); + tree.on('click', this.onNodeClick, this); + }, + + onNodeClick : function(node, e){ + this.select(node); + }, + + + select : function(node, selectNextNode){ + + if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) { + return selectNextNode.call(this, node); + } + var last = this.selNode; + if(node == last){ + node.ui.onSelectedChange(true); + }else if(this.fireEvent('beforeselect', this, node, last) !== false){ + if(last && last.ui){ + last.ui.onSelectedChange(false); + } + this.selNode = node; + node.ui.onSelectedChange(true); + this.fireEvent('selectionchange', this, node, last); + } + return node; + }, + + + unselect : function(node, silent){ + if(this.selNode == node){ + this.clearSelections(silent); + } + }, + + + clearSelections : function(silent){ + var n = this.selNode; + if(n){ + n.ui.onSelectedChange(false); + this.selNode = null; + if(silent !== true){ + this.fireEvent('selectionchange', this, null); + } + } + return n; + }, + + + getSelectedNode : function(){ + return this.selNode; + }, + + + isSelected : function(node){ + return this.selNode == node; + }, + + + selectPrevious : function( s){ + if(!(s = s || this.selNode || this.lastSelNode)){ + return null; + } + + var ps = s.previousSibling; + if(ps){ + if(!ps.isExpanded() || ps.childNodes.length < 1){ + return this.select(ps, this.selectPrevious); + } else{ + var lc = ps.lastChild; + while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){ + lc = lc.lastChild; + } + return this.select(lc, this.selectPrevious); + } + } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){ + return this.select(s.parentNode, this.selectPrevious); + } + return null; + }, + + + selectNext : function( s){ + if(!(s = s || this.selNode || this.lastSelNode)){ + return null; + } + + if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){ + return this.select(s.firstChild, this.selectNext); + }else if(s.nextSibling){ + return this.select(s.nextSibling, this.selectNext); + }else if(s.parentNode){ + var newS = null; + s.parentNode.bubble(function(){ + if(this.nextSibling){ + newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext); + return false; + } + }); + return newS; + } + return null; + }, + + onKeyDown : function(e){ + var s = this.selNode || this.lastSelNode; + + var sm = this; + if(!s){ + return; + } + var k = e.getKey(); + switch(k){ + case e.DOWN: + e.stopEvent(); + this.selectNext(); + break; + case e.UP: + e.stopEvent(); + this.selectPrevious(); + break; + case e.RIGHT: + e.preventDefault(); + if(s.hasChildNodes()){ + if(!s.isExpanded()){ + s.expand(); + }else if(s.firstChild){ + this.select(s.firstChild, e); + } + } + break; + case e.LEFT: + e.preventDefault(); + if(s.hasChildNodes() && s.isExpanded()){ + s.collapse(); + }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){ + this.select(s.parentNode, e); + } + break; + }; + } +}); + + +Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, { + + constructor : function(config){ + this.selNodes = []; + this.selMap = {}; + this.addEvents( + + 'selectionchange' + ); + Ext.apply(this, config); + Ext.tree.MultiSelectionModel.superclass.constructor.call(this); + }, + + init : function(tree){ + this.tree = tree; + tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this); + tree.on('click', this.onNodeClick, this); + }, + + onNodeClick : function(node, e){ + if(e.ctrlKey && this.isSelected(node)){ + this.unselect(node); + }else{ + this.select(node, e, e.ctrlKey); + } + }, + + + select : function(node, e, keepExisting){ + if(keepExisting !== true){ + this.clearSelections(true); + } + if(this.isSelected(node)){ + this.lastSelNode = node; + return node; + } + this.selNodes.push(node); + this.selMap[node.id] = node; + this.lastSelNode = node; + node.ui.onSelectedChange(true); + this.fireEvent('selectionchange', this, this.selNodes); + return node; + }, + + + unselect : function(node){ + if(this.selMap[node.id]){ + node.ui.onSelectedChange(false); + var sn = this.selNodes; + var index = sn.indexOf(node); + if(index != -1){ + this.selNodes.splice(index, 1); + } + delete this.selMap[node.id]; + this.fireEvent('selectionchange', this, this.selNodes); + } + }, + + + clearSelections : function(suppressEvent){ + var sn = this.selNodes; + if(sn.length > 0){ + for(var i = 0, len = sn.length; i < len; i++){ + sn[i].ui.onSelectedChange(false); + } + this.selNodes = []; + this.selMap = {}; + if(suppressEvent !== true){ + this.fireEvent('selectionchange', this, this.selNodes); + } + } + }, + + + isSelected : function(node){ + return this.selMap[node.id] ? true : false; + }, + + + getSelectedNodes : function(){ + return this.selNodes.concat([]); + }, + + onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown, + + selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext, + + selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious +}); +Ext.data.Tree = Ext.extend(Ext.util.Observable, { + + constructor: function(root){ + this.nodeHash = {}; + + this.root = null; + if(root){ + this.setRootNode(root); + } + this.addEvents( + + "append", + + "remove", + + "move", + + "insert", + + "beforeappend", + + "beforeremove", + + "beforemove", + + "beforeinsert" + ); + Ext.data.Tree.superclass.constructor.call(this); + }, + + + pathSeparator: "/", + + + proxyNodeEvent : function(){ + return this.fireEvent.apply(this, arguments); + }, + + + getRootNode : function(){ + return this.root; + }, + + + setRootNode : function(node){ + this.root = node; + node.ownerTree = this; + node.isRoot = true; + this.registerNode(node); + return node; + }, + + + getNodeById : function(id){ + return this.nodeHash[id]; + }, + + + registerNode : function(node){ + this.nodeHash[node.id] = node; + }, + + + unregisterNode : function(node){ + delete this.nodeHash[node.id]; + }, + + toString : function(){ + return "[Tree"+(this.id?" "+this.id:"")+"]"; + } +}); + + +Ext.data.Node = Ext.extend(Ext.util.Observable, { + + constructor: function(attributes){ + + this.attributes = attributes || {}; + this.leaf = this.attributes.leaf; + + this.id = this.attributes.id; + if(!this.id){ + this.id = Ext.id(null, "xnode-"); + this.attributes.id = this.id; + } + + this.childNodes = []; + + this.parentNode = null; + + this.firstChild = null; + + this.lastChild = null; + + this.previousSibling = null; + + this.nextSibling = null; + + this.addEvents({ + + "append" : true, + + "remove" : true, + + "move" : true, + + "insert" : true, + + "beforeappend" : true, + + "beforeremove" : true, + + "beforemove" : true, + + "beforeinsert" : true + }); + this.listeners = this.attributes.listeners; + Ext.data.Node.superclass.constructor.call(this); + }, + + + fireEvent : function(evtName){ + + if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){ + return false; + } + + var ot = this.getOwnerTree(); + if(ot){ + if(ot.proxyNodeEvent.apply(ot, arguments) === false){ + return false; + } + } + return true; + }, + + + isLeaf : function(){ + return this.leaf === true; + }, + + + setFirstChild : function(node){ + this.firstChild = node; + }, + + + setLastChild : function(node){ + this.lastChild = node; + }, + + + + isLast : function(){ + return (!this.parentNode ? true : this.parentNode.lastChild == this); + }, + + + isFirst : function(){ + return (!this.parentNode ? true : this.parentNode.firstChild == this); + }, + + + hasChildNodes : function(){ + return !this.isLeaf() && this.childNodes.length > 0; + }, + + + isExpandable : function(){ + return this.attributes.expandable || this.hasChildNodes(); + }, + + + appendChild : function(node){ + var multi = false; + if(Ext.isArray(node)){ + multi = node; + }else if(arguments.length > 1){ + multi = arguments; + } + + if(multi){ + for(var i = 0, len = multi.length; i < len; i++) { + this.appendChild(multi[i]); + } + }else{ + if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){ + return false; + } + var index = this.childNodes.length; + var oldParent = node.parentNode; + + if(oldParent){ + if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){ + return false; + } + oldParent.removeChild(node); + } + index = this.childNodes.length; + if(index === 0){ + this.setFirstChild(node); + } + this.childNodes.push(node); + node.parentNode = this; + var ps = this.childNodes[index-1]; + if(ps){ + node.previousSibling = ps; + ps.nextSibling = node; + }else{ + node.previousSibling = null; + } + node.nextSibling = null; + this.setLastChild(node); + node.setOwnerTree(this.getOwnerTree()); + this.fireEvent("append", this.ownerTree, this, node, index); + if(oldParent){ + node.fireEvent("move", this.ownerTree, node, oldParent, this, index); + } + return node; + } + }, + + + removeChild : function(node, destroy){ + var index = this.childNodes.indexOf(node); + if(index == -1){ + return false; + } + if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){ + return false; + } + + + this.childNodes.splice(index, 1); + + + if(node.previousSibling){ + node.previousSibling.nextSibling = node.nextSibling; + } + if(node.nextSibling){ + node.nextSibling.previousSibling = node.previousSibling; + } + + + if(this.firstChild == node){ + this.setFirstChild(node.nextSibling); + } + if(this.lastChild == node){ + this.setLastChild(node.previousSibling); + } + + this.fireEvent("remove", this.ownerTree, this, node); + if(destroy){ + node.destroy(true); + }else{ + node.clear(); + } + return node; + }, + + + clear : function(destroy){ + + this.setOwnerTree(null, destroy); + this.parentNode = this.previousSibling = this.nextSibling = null; + if(destroy){ + this.firstChild = this.lastChild = null; + } + }, + + + destroy : function( silent){ + + if(silent === true){ + this.purgeListeners(); + this.clear(true); + Ext.each(this.childNodes, function(n){ + n.destroy(true); + }); + this.childNodes = null; + }else{ + this.remove(true); + } + }, + + + insertBefore : function(node, refNode){ + if(!refNode){ + return this.appendChild(node); + } + + if(node == refNode){ + return false; + } + + if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){ + return false; + } + var index = this.childNodes.indexOf(refNode); + var oldParent = node.parentNode; + var refIndex = index; + + + if(oldParent == this && this.childNodes.indexOf(node) < index){ + refIndex--; + } + + + if(oldParent){ + if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){ + return false; + } + oldParent.removeChild(node); + } + if(refIndex === 0){ + this.setFirstChild(node); + } + this.childNodes.splice(refIndex, 0, node); + node.parentNode = this; + var ps = this.childNodes[refIndex-1]; + if(ps){ + node.previousSibling = ps; + ps.nextSibling = node; + }else{ + node.previousSibling = null; + } + node.nextSibling = refNode; + refNode.previousSibling = node; + node.setOwnerTree(this.getOwnerTree()); + this.fireEvent("insert", this.ownerTree, this, node, refNode); + if(oldParent){ + node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode); + } + return node; + }, + + + remove : function(destroy){ + if (this.parentNode) { + this.parentNode.removeChild(this, destroy); + } + return this; + }, + + + removeAll : function(destroy){ + var cn = this.childNodes, + n; + while((n = cn[0])){ + this.removeChild(n, destroy); + } + return this; + }, + + + item : function(index){ + return this.childNodes[index]; + }, + + + replaceChild : function(newChild, oldChild){ + var s = oldChild ? oldChild.nextSibling : null; + this.removeChild(oldChild); + this.insertBefore(newChild, s); + return oldChild; + }, + + + indexOf : function(child){ + return this.childNodes.indexOf(child); + }, + + + getOwnerTree : function(){ + + if(!this.ownerTree){ + var p = this; + while(p){ + if(p.ownerTree){ + this.ownerTree = p.ownerTree; + break; + } + p = p.parentNode; + } + } + return this.ownerTree; + }, + + + getDepth : function(){ + var depth = 0; + var p = this; + while(p.parentNode){ + ++depth; + p = p.parentNode; + } + return depth; + }, + + + setOwnerTree : function(tree, destroy){ + + if(tree != this.ownerTree){ + if(this.ownerTree){ + this.ownerTree.unregisterNode(this); + } + this.ownerTree = tree; + + if(destroy !== true){ + Ext.each(this.childNodes, function(n){ + n.setOwnerTree(tree); + }); + } + if(tree){ + tree.registerNode(this); + } + } + }, + + + setId: function(id){ + if(id !== this.id){ + var t = this.ownerTree; + if(t){ + t.unregisterNode(this); + } + this.id = this.attributes.id = id; + if(t){ + t.registerNode(this); + } + this.onIdChange(id); + } + }, + + + onIdChange: Ext.emptyFn, + + + getPath : function(attr){ + attr = attr || "id"; + var p = this.parentNode; + var b = [this.attributes[attr]]; + while(p){ + b.unshift(p.attributes[attr]); + p = p.parentNode; + } + var sep = this.getOwnerTree().pathSeparator; + return sep + b.join(sep); + }, + + + bubble : function(fn, scope, args){ + var p = this; + while(p){ + if(fn.apply(scope || p, args || [p]) === false){ + break; + } + p = p.parentNode; + } + }, + + + cascade : function(fn, scope, args){ + if(fn.apply(scope || this, args || [this]) !== false){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++) { + cs[i].cascade(fn, scope, args); + } + } + }, + + + eachChild : function(fn, scope, args){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++) { + if(fn.apply(scope || cs[i], args || [cs[i]]) === false){ + break; + } + } + }, + + + findChild : function(attribute, value, deep){ + return this.findChildBy(function(){ + return this.attributes[attribute] == value; + }, null, deep); + }, + + + findChildBy : function(fn, scope, deep){ + var cs = this.childNodes, + len = cs.length, + i = 0, + n, + res; + for(; i < len; i++){ + n = cs[i]; + if(fn.call(scope || n, n) === true){ + return n; + }else if (deep){ + res = n.findChildBy(fn, scope, deep); + if(res != null){ + return res; + } + } + + } + return null; + }, + + + sort : function(fn, scope){ + var cs = this.childNodes; + var len = cs.length; + if(len > 0){ + var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn; + cs.sort(sortFn); + for(var i = 0; i < len; i++){ + var n = cs[i]; + n.previousSibling = cs[i-1]; + n.nextSibling = cs[i+1]; + if(i === 0){ + this.setFirstChild(n); + } + if(i == len-1){ + this.setLastChild(n); + } + } + } + }, + + + contains : function(node){ + return node.isAncestor(this); + }, + + + isAncestor : function(node){ + var p = this.parentNode; + while(p){ + if(p == node){ + return true; + } + p = p.parentNode; + } + return false; + }, + + toString : function(){ + return "[Node"+(this.id?" "+this.id:"")+"]"; + } +}); +Ext.tree.TreeNode = Ext.extend(Ext.data.Node, { + + constructor : function(attributes){ + attributes = attributes || {}; + if(Ext.isString(attributes)){ + attributes = {text: attributes}; + } + this.childrenRendered = false; + this.rendered = false; + Ext.tree.TreeNode.superclass.constructor.call(this, attributes); + this.expanded = attributes.expanded === true; + this.isTarget = attributes.isTarget !== false; + this.draggable = attributes.draggable !== false && attributes.allowDrag !== false; + this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false; + + + this.text = attributes.text; + + this.disabled = attributes.disabled === true; + + this.hidden = attributes.hidden === true; + + this.addEvents( + + 'textchange', + + 'beforeexpand', + + 'beforecollapse', + + 'expand', + + 'disabledchange', + + 'collapse', + + 'beforeclick', + + 'click', + + 'checkchange', + + 'beforedblclick', + + 'dblclick', + + 'contextmenu', + + 'beforechildrenrendered' + ); + + var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI; + + + this.ui = new uiClass(this); + }, + + preventHScroll : true, + + isExpanded : function(){ + return this.expanded; + }, + + + getUI : function(){ + return this.ui; + }, + + getLoader : function(){ + var owner; + return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader())); + }, + + + setFirstChild : function(node){ + var of = this.firstChild; + Ext.tree.TreeNode.superclass.setFirstChild.call(this, node); + if(this.childrenRendered && of && node != of){ + of.renderIndent(true, true); + } + if(this.rendered){ + this.renderIndent(true, true); + } + }, + + + setLastChild : function(node){ + var ol = this.lastChild; + Ext.tree.TreeNode.superclass.setLastChild.call(this, node); + if(this.childrenRendered && ol && node != ol){ + ol.renderIndent(true, true); + } + if(this.rendered){ + this.renderIndent(true, true); + } + }, + + + + appendChild : function(n){ + if(!n.render && !Ext.isArray(n)){ + n = this.getLoader().createNode(n); + } + var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n); + if(node && this.childrenRendered){ + node.render(); + } + this.ui.updateExpandIcon(); + return node; + }, + + + removeChild : function(node, destroy){ + this.ownerTree.getSelectionModel().unselect(node); + Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments); + + if(!destroy){ + var rendered = node.ui.rendered; + + if(rendered){ + node.ui.remove(); + } + if(rendered && this.childNodes.length < 1){ + this.collapse(false, false); + }else{ + this.ui.updateExpandIcon(); + } + if(!this.firstChild && !this.isHiddenRoot()){ + this.childrenRendered = false; + } + } + return node; + }, + + + insertBefore : function(node, refNode){ + if(!node.render){ + node = this.getLoader().createNode(node); + } + var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode); + if(newNode && refNode && this.childrenRendered){ + node.render(); + } + this.ui.updateExpandIcon(); + return newNode; + }, + + + setText : function(text){ + var oldText = this.text; + this.text = this.attributes.text = text; + if(this.rendered){ + this.ui.onTextChange(this, text, oldText); + } + this.fireEvent('textchange', this, text, oldText); + }, + + + setIconCls : function(cls){ + var old = this.attributes.iconCls; + this.attributes.iconCls = cls; + if(this.rendered){ + this.ui.onIconClsChange(this, cls, old); + } + }, + + + setTooltip : function(tip, title){ + this.attributes.qtip = tip; + this.attributes.qtipTitle = title; + if(this.rendered){ + this.ui.onTipChange(this, tip, title); + } + }, + + + setIcon : function(icon){ + this.attributes.icon = icon; + if(this.rendered){ + this.ui.onIconChange(this, icon); + } + }, + + + setHref : function(href, target){ + this.attributes.href = href; + this.attributes.hrefTarget = target; + if(this.rendered){ + this.ui.onHrefChange(this, href, target); + } + }, + + + setCls : function(cls){ + var old = this.attributes.cls; + this.attributes.cls = cls; + if(this.rendered){ + this.ui.onClsChange(this, cls, old); + } + }, + + + select : function(){ + var t = this.getOwnerTree(); + if(t){ + t.getSelectionModel().select(this); + } + }, + + + unselect : function(silent){ + var t = this.getOwnerTree(); + if(t){ + t.getSelectionModel().unselect(this, silent); + } + }, + + + isSelected : function(){ + var t = this.getOwnerTree(); + return t ? t.getSelectionModel().isSelected(this) : false; + }, + + + expand : function(deep, anim, callback, scope){ + if(!this.expanded){ + if(this.fireEvent('beforeexpand', this, deep, anim) === false){ + return; + } + if(!this.childrenRendered){ + this.renderChildren(); + } + this.expanded = true; + if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){ + this.ui.animExpand(function(){ + this.fireEvent('expand', this); + this.runCallback(callback, scope || this, [this]); + if(deep === true){ + this.expandChildNodes(true, true); + } + }.createDelegate(this)); + return; + }else{ + this.ui.expand(); + this.fireEvent('expand', this); + this.runCallback(callback, scope || this, [this]); + } + }else{ + this.runCallback(callback, scope || this, [this]); + } + if(deep === true){ + this.expandChildNodes(true); + } + }, + + runCallback : function(cb, scope, args){ + if(Ext.isFunction(cb)){ + cb.apply(scope, args); + } + }, + + isHiddenRoot : function(){ + return this.isRoot && !this.getOwnerTree().rootVisible; + }, + + + collapse : function(deep, anim, callback, scope){ + if(this.expanded && !this.isHiddenRoot()){ + if(this.fireEvent('beforecollapse', this, deep, anim) === false){ + return; + } + this.expanded = false; + if((this.getOwnerTree().animate && anim !== false) || anim){ + this.ui.animCollapse(function(){ + this.fireEvent('collapse', this); + this.runCallback(callback, scope || this, [this]); + if(deep === true){ + this.collapseChildNodes(true); + } + }.createDelegate(this)); + return; + }else{ + this.ui.collapse(); + this.fireEvent('collapse', this); + this.runCallback(callback, scope || this, [this]); + } + }else if(!this.expanded){ + this.runCallback(callback, scope || this, [this]); + } + if(deep === true){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++) { + cs[i].collapse(true, false); + } + } + }, + + + delayedExpand : function(delay){ + if(!this.expandProcId){ + this.expandProcId = this.expand.defer(delay, this); + } + }, + + + cancelExpand : function(){ + if(this.expandProcId){ + clearTimeout(this.expandProcId); + } + this.expandProcId = false; + }, + + + toggle : function(){ + if(this.expanded){ + this.collapse(); + }else{ + this.expand(); + } + }, + + + ensureVisible : function(callback, scope){ + var tree = this.getOwnerTree(); + tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){ + var node = tree.getNodeById(this.id); + tree.getTreeEl().scrollChildIntoView(node.ui.anchor); + this.runCallback(callback, scope || this, [this]); + }.createDelegate(this)); + }, + + + expandChildNodes : function(deep, anim) { + var cs = this.childNodes, + i, + len = cs.length; + for (i = 0; i < len; i++) { + cs[i].expand(deep, anim); + } + }, + + + collapseChildNodes : function(deep){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++) { + cs[i].collapse(deep); + } + }, + + + disable : function(){ + this.disabled = true; + this.unselect(); + if(this.rendered && this.ui.onDisableChange){ + this.ui.onDisableChange(this, true); + } + this.fireEvent('disabledchange', this, true); + }, + + + enable : function(){ + this.disabled = false; + if(this.rendered && this.ui.onDisableChange){ + this.ui.onDisableChange(this, false); + } + this.fireEvent('disabledchange', this, false); + }, + + + renderChildren : function(suppressEvent){ + if(suppressEvent !== false){ + this.fireEvent('beforechildrenrendered', this); + } + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++){ + cs[i].render(true); + } + this.childrenRendered = true; + }, + + + sort : function(fn, scope){ + Ext.tree.TreeNode.superclass.sort.apply(this, arguments); + if(this.childrenRendered){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++){ + cs[i].render(true); + } + } + }, + + + render : function(bulkRender){ + this.ui.render(bulkRender); + if(!this.rendered){ + + this.getOwnerTree().registerNode(this); + this.rendered = true; + if(this.expanded){ + this.expanded = false; + this.expand(false, false); + } + } + }, + + + renderIndent : function(deep, refresh){ + if(refresh){ + this.ui.childIndent = null; + } + this.ui.renderIndent(); + if(deep === true && this.childrenRendered){ + var cs = this.childNodes; + for(var i = 0, len = cs.length; i < len; i++){ + cs[i].renderIndent(true, refresh); + } + } + }, + + beginUpdate : function(){ + this.childrenRendered = false; + }, + + endUpdate : function(){ + if(this.expanded && this.rendered){ + this.renderChildren(); + } + }, + + + destroy : function(silent){ + if(silent === true){ + this.unselect(true); + } + Ext.tree.TreeNode.superclass.destroy.call(this, silent); + Ext.destroy(this.ui, this.loader); + this.ui = this.loader = null; + }, + + + onIdChange : function(id){ + this.ui.onIdChange(id); + } +}); + +Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode; + Ext.tree.AsyncTreeNode = function(config){ + this.loaded = config && config.loaded === true; + this.loading = false; + Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments); + + this.addEvents('beforeload', 'load'); + + +}; +Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, { + expand : function(deep, anim, callback, scope){ + if(this.loading){ + var timer; + var f = function(){ + if(!this.loading){ + clearInterval(timer); + this.expand(deep, anim, callback, scope); + } + }.createDelegate(this); + timer = setInterval(f, 200); + return; + } + if(!this.loaded){ + if(this.fireEvent("beforeload", this) === false){ + return; + } + this.loading = true; + this.ui.beforeLoad(this); + var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader(); + if(loader){ + loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this); + return; + } + } + Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope); + }, + + + isLoading : function(){ + return this.loading; + }, + + loadComplete : function(deep, anim, callback, scope){ + this.loading = false; + this.loaded = true; + this.ui.afterLoad(this); + this.fireEvent("load", this); + this.expand(deep, anim, callback, scope); + }, + + + isLoaded : function(){ + return this.loaded; + }, + + hasChildNodes : function(){ + if(!this.isLeaf() && !this.loaded){ + return true; + }else{ + return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this); + } + }, + + + reload : function(callback, scope){ + this.collapse(false, false); + while(this.firstChild){ + this.removeChild(this.firstChild).destroy(); + } + this.childrenRendered = false; + this.loaded = false; + if(this.isHiddenRoot()){ + this.expanded = false; + } + this.expand(false, false, callback, scope); + } +}); + +Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode; +Ext.tree.TreeNodeUI = Ext.extend(Object, { + + constructor : function(node){ + Ext.apply(this, { + node: node, + rendered: false, + animating: false, + wasLeaf: true, + ecc: 'x-tree-ec-icon x-tree-elbow', + emptyIcon: Ext.BLANK_IMAGE_URL + }); + }, + + + removeChild : function(node){ + if(this.rendered){ + this.ctNode.removeChild(node.ui.getEl()); + } + }, + + + beforeLoad : function(){ + this.addClass("x-tree-node-loading"); + }, + + + afterLoad : function(){ + this.removeClass("x-tree-node-loading"); + }, + + + onTextChange : function(node, text, oldText){ + if(this.rendered){ + this.textNode.innerHTML = text; + } + }, + + + onIconClsChange : function(node, cls, oldCls){ + if(this.rendered){ + Ext.fly(this.iconNode).replaceClass(oldCls, cls); + } + }, + + + onIconChange : function(node, icon){ + if(this.rendered){ + + var empty = Ext.isEmpty(icon); + this.iconNode.src = empty ? this.emptyIcon : icon; + Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon'); + } + }, + + + onTipChange : function(node, tip, title){ + if(this.rendered){ + var hasTitle = Ext.isDefined(title); + if(this.textNode.setAttributeNS){ + this.textNode.setAttributeNS("ext", "qtip", tip); + if(hasTitle){ + this.textNode.setAttributeNS("ext", "qtitle", title); + } + }else{ + this.textNode.setAttribute("ext:qtip", tip); + if(hasTitle){ + this.textNode.setAttribute("ext:qtitle", title); + } + } + } + }, + + + onHrefChange : function(node, href, target){ + if(this.rendered){ + this.anchor.href = this.getHref(href); + if(Ext.isDefined(target)){ + this.anchor.target = target; + } + } + }, + + + onClsChange : function(node, cls, oldCls){ + if(this.rendered){ + Ext.fly(this.elNode).replaceClass(oldCls, cls); + } + }, + + + onDisableChange : function(node, state){ + this.disabled = state; + if (this.checkbox) { + this.checkbox.disabled = state; + } + this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled'); + }, + + + onSelectedChange : function(state){ + if(state){ + this.focus(); + this.addClass("x-tree-selected"); + }else{ + + this.removeClass("x-tree-selected"); + } + }, + + + onMove : function(tree, node, oldParent, newParent, index, refNode){ + this.childIndent = null; + if(this.rendered){ + var targetNode = newParent.ui.getContainer(); + if(!targetNode){ + this.holder = document.createElement("div"); + this.holder.appendChild(this.wrap); + return; + } + var insertBefore = refNode ? refNode.ui.getEl() : null; + if(insertBefore){ + targetNode.insertBefore(this.wrap, insertBefore); + }else{ + targetNode.appendChild(this.wrap); + } + this.node.renderIndent(true, oldParent != newParent); + } + }, + + + addClass : function(cls){ + if(this.elNode){ + Ext.fly(this.elNode).addClass(cls); + } + }, + + + removeClass : function(cls){ + if(this.elNode){ + Ext.fly(this.elNode).removeClass(cls); + } + }, + + + remove : function(){ + if(this.rendered){ + this.holder = document.createElement("div"); + this.holder.appendChild(this.wrap); + } + }, + + + fireEvent : function(){ + return this.node.fireEvent.apply(this.node, arguments); + }, + + + initEvents : function(){ + this.node.on("move", this.onMove, this); + + if(this.node.disabled){ + this.onDisableChange(this.node, true); + } + if(this.node.hidden){ + this.hide(); + } + var ot = this.node.getOwnerTree(); + var dd = ot.enableDD || ot.enableDrag || ot.enableDrop; + if(dd && (!this.node.isRoot || ot.rootVisible)){ + Ext.dd.Registry.register(this.elNode, { + node: this.node, + handles: this.getDDHandles(), + isHandle: false + }); + } + }, + + + getDDHandles : function(){ + return [this.iconNode, this.textNode, this.elNode]; + }, + + + hide : function(){ + this.node.hidden = true; + if(this.wrap){ + this.wrap.style.display = "none"; + } + }, + + + show : function(){ + this.node.hidden = false; + if(this.wrap){ + this.wrap.style.display = ""; + } + }, + + + onContextMenu : function(e){ + if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) { + e.preventDefault(); + this.focus(); + this.fireEvent("contextmenu", this.node, e); + } + }, + + + onClick : function(e){ + if(this.dropping){ + e.stopEvent(); + return; + } + if(this.fireEvent("beforeclick", this.node, e) !== false){ + var a = e.getTarget('a'); + if(!this.disabled && this.node.attributes.href && a){ + this.fireEvent("click", this.node, e); + return; + }else if(a && e.ctrlKey){ + e.stopEvent(); + } + e.preventDefault(); + if(this.disabled){ + return; + } + + if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){ + this.node.toggle(); + } + + this.fireEvent("click", this.node, e); + }else{ + e.stopEvent(); + } + }, + + + onDblClick : function(e){ + e.preventDefault(); + if(this.disabled){ + return; + } + if(this.fireEvent("beforedblclick", this.node, e) !== false){ + if(this.checkbox){ + this.toggleCheck(); + } + if(!this.animating && this.node.isExpandable()){ + this.node.toggle(); + } + this.fireEvent("dblclick", this.node, e); + } + }, + + onOver : function(e){ + this.addClass('x-tree-node-over'); + }, + + onOut : function(e){ + this.removeClass('x-tree-node-over'); + }, + + + onCheckChange : function(){ + var checked = this.checkbox.checked; + + this.checkbox.defaultChecked = checked; + this.node.attributes.checked = checked; + this.fireEvent('checkchange', this.node, checked); + }, + + + ecClick : function(e){ + if(!this.animating && this.node.isExpandable()){ + this.node.toggle(); + } + }, + + + startDrop : function(){ + this.dropping = true; + }, + + + endDrop : function(){ + setTimeout(function(){ + this.dropping = false; + }.createDelegate(this), 50); + }, + + + expand : function(){ + this.updateExpandIcon(); + this.ctNode.style.display = ""; + }, + + + focus : function(){ + if(!this.node.preventHScroll){ + try{this.anchor.focus(); + }catch(e){} + }else{ + try{ + var noscroll = this.node.getOwnerTree().getTreeEl().dom; + var l = noscroll.scrollLeft; + this.anchor.focus(); + noscroll.scrollLeft = l; + }catch(e){} + } + }, + + + toggleCheck : function(value){ + var cb = this.checkbox; + if(cb){ + cb.checked = (value === undefined ? !cb.checked : value); + this.onCheckChange(); + } + }, + + + blur : function(){ + try{ + this.anchor.blur(); + }catch(e){} + }, + + + animExpand : function(callback){ + var ct = Ext.get(this.ctNode); + ct.stopFx(); + if(!this.node.isExpandable()){ + this.updateExpandIcon(); + this.ctNode.style.display = ""; + Ext.callback(callback); + return; + } + this.animating = true; + this.updateExpandIcon(); + + ct.slideIn('t', { + callback : function(){ + this.animating = false; + Ext.callback(callback); + }, + scope: this, + duration: this.node.ownerTree.duration || .25 + }); + }, + + + highlight : function(){ + var tree = this.node.getOwnerTree(); + Ext.fly(this.wrap).highlight( + tree.hlColor || "C3DAF9", + {endColor: tree.hlBaseColor} + ); + }, + + + collapse : function(){ + this.updateExpandIcon(); + this.ctNode.style.display = "none"; + }, + + + animCollapse : function(callback){ + var ct = Ext.get(this.ctNode); + ct.enableDisplayMode('block'); + ct.stopFx(); + + this.animating = true; + this.updateExpandIcon(); + + ct.slideOut('t', { + callback : function(){ + this.animating = false; + Ext.callback(callback); + }, + scope: this, + duration: this.node.ownerTree.duration || .25 + }); + }, + + + getContainer : function(){ + return this.ctNode; + }, + + + getEl : function(){ + return this.wrap; + }, + + + appendDDGhost : function(ghostNode){ + ghostNode.appendChild(this.elNode.cloneNode(true)); + }, + + + getDDRepairXY : function(){ + return Ext.lib.Dom.getXY(this.iconNode); + }, + + + onRender : function(){ + this.render(); + }, + + + render : function(bulkRender){ + var n = this.node, a = n.attributes; + var targetNode = n.parentNode ? + n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom; + + if(!this.rendered){ + this.rendered = true; + + this.renderElements(n, a, targetNode, bulkRender); + + if(a.qtip){ + this.onTipChange(n, a.qtip, a.qtipTitle); + }else if(a.qtipCfg){ + a.qtipCfg.target = Ext.id(this.textNode); + Ext.QuickTips.register(a.qtipCfg); + } + this.initEvents(); + if(!this.node.expanded){ + this.updateExpandIcon(true); + } + }else{ + if(bulkRender === true) { + targetNode.appendChild(this.wrap); + } + } + }, + + + renderElements : function(n, a, targetNode, bulkRender){ + + this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; + + var cb = Ext.isBoolean(a.checked), + nel, + href = this.getHref(a.href), + buf = ['
  • ', + '',this.indentMarkup,"", + '', + '', + cb ? ('' : '/>')) : '', + '',n.text,"
    ", + '', + "
  • "].join(''); + + if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){ + this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf); + }else{ + this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf); + } + + this.elNode = this.wrap.childNodes[0]; + this.ctNode = this.wrap.childNodes[1]; + var cs = this.elNode.childNodes; + this.indentNode = cs[0]; + this.ecNode = cs[1]; + this.iconNode = cs[2]; + var index = 3; + if(cb){ + this.checkbox = cs[3]; + + this.checkbox.defaultChecked = this.checkbox.checked; + index++; + } + this.anchor = cs[index]; + this.textNode = cs[index].firstChild; + }, + + + getHref : function(href){ + return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href; + }, + + + getAnchor : function(){ + return this.anchor; + }, + + + getTextEl : function(){ + return this.textNode; + }, + + + getIconEl : function(){ + return this.iconNode; + }, + + + isChecked : function(){ + return this.checkbox ? this.checkbox.checked : false; + }, + + + updateExpandIcon : function(){ + if(this.rendered){ + var n = this.node, + c1, + c2, + cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow", + hasChild = n.hasChildNodes(); + if(hasChild || n.attributes.expandable){ + if(n.expanded){ + cls += "-minus"; + c1 = "x-tree-node-collapsed"; + c2 = "x-tree-node-expanded"; + }else{ + cls += "-plus"; + c1 = "x-tree-node-expanded"; + c2 = "x-tree-node-collapsed"; + } + if(this.wasLeaf){ + this.removeClass("x-tree-node-leaf"); + this.wasLeaf = false; + } + if(this.c1 != c1 || this.c2 != c2){ + Ext.fly(this.elNode).replaceClass(c1, c2); + this.c1 = c1; this.c2 = c2; + } + }else{ + if(!this.wasLeaf){ + Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed"); + delete this.c1; + delete this.c2; + this.wasLeaf = true; + } + } + var ecc = "x-tree-ec-icon "+cls; + if(this.ecc != ecc){ + this.ecNode.className = ecc; + this.ecc = ecc; + } + } + }, + + + onIdChange: function(id){ + if(this.rendered){ + this.elNode.setAttribute('ext:tree-node-id', id); + } + }, + + + getChildIndent : function(){ + if(!this.childIndent){ + var buf = [], + p = this.node; + while(p){ + if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){ + if(!p.isLast()) { + buf.unshift(''); + } else { + buf.unshift(''); + } + } + p = p.parentNode; + } + this.childIndent = buf.join(""); + } + return this.childIndent; + }, + + + renderIndent : function(){ + if(this.rendered){ + var indent = "", + p = this.node.parentNode; + if(p){ + indent = p.ui.getChildIndent(); + } + if(this.indentMarkup != indent){ + this.indentNode.innerHTML = indent; + this.indentMarkup = indent; + } + this.updateExpandIcon(); + } + }, + + destroy : function(){ + if(this.elNode){ + Ext.dd.Registry.unregister(this.elNode.id); + } + + Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){ + if(this[el]){ + Ext.fly(this[el]).remove(); + delete this[el]; + } + }, this); + delete this.node; + } +}); + + +Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { + + render : function(){ + if(!this.rendered){ + var targetNode = this.node.ownerTree.innerCt.dom; + this.node.expanded = true; + targetNode.innerHTML = '
    '; + this.wrap = this.ctNode = targetNode.firstChild; + } + }, + collapse : Ext.emptyFn, + expand : Ext.emptyFn +}); +Ext.tree.TreeLoader = function(config){ + this.baseParams = {}; + Ext.apply(this, config); + + this.addEvents( + + "beforeload", + + "load", + + "loadexception" + ); + Ext.tree.TreeLoader.superclass.constructor.call(this); + if(Ext.isString(this.paramOrder)){ + this.paramOrder = this.paramOrder.split(/[\s,|]/); + } +}; + +Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, { + + + + + + + + uiProviders : {}, + + + clearOnLoad : true, + + + paramOrder: undefined, + + + paramsAsHash: false, + + + nodeParameter: 'node', + + + directFn : undefined, + + + load : function(node, callback, scope){ + if(this.clearOnLoad){ + while(node.firstChild){ + node.removeChild(node.firstChild); + } + } + if(this.doPreload(node)){ + this.runCallback(callback, scope || node, [node]); + }else if(this.directFn || this.dataUrl || this.url){ + this.requestData(node, callback, scope || node); + } + }, + + doPreload : function(node){ + if(node.attributes.children){ + if(node.childNodes.length < 1){ + var cs = node.attributes.children; + node.beginUpdate(); + for(var i = 0, len = cs.length; i < len; i++){ + var cn = node.appendChild(this.createNode(cs[i])); + if(this.preloadChildren){ + this.doPreload(cn); + } + } + node.endUpdate(); + } + return true; + } + return false; + }, + + getParams: function(node){ + var bp = Ext.apply({}, this.baseParams), + np = this.nodeParameter, + po = this.paramOrder; + + np && (bp[ np ] = node.id); + + if(this.directFn){ + var buf = [node.id]; + if(po){ + + if(np && po.indexOf(np) > -1){ + buf = []; + } + + for(var i = 0, len = po.length; i < len; i++){ + buf.push(bp[ po[i] ]); + } + }else if(this.paramsAsHash){ + buf = [bp]; + } + return buf; + }else{ + return bp; + } + }, + + requestData : function(node, callback, scope){ + if(this.fireEvent("beforeload", this, node, callback) !== false){ + if(this.directFn){ + var args = this.getParams(node); + args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true)); + this.directFn.apply(window, args); + }else{ + this.transId = Ext.Ajax.request({ + method:this.requestMethod, + url: this.dataUrl||this.url, + success: this.handleResponse, + failure: this.handleFailure, + scope: this, + argument: {callback: callback, node: node, scope: scope}, + params: this.getParams(node) + }); + } + }else{ + + + this.runCallback(callback, scope || node, []); + } + }, + + processDirectResponse: function(result, response, args){ + if(response.status){ + this.handleResponse({ + responseData: Ext.isArray(result) ? result : null, + responseText: result, + argument: args + }); + }else{ + this.handleFailure({ + argument: args + }); + } + }, + + + runCallback: function(cb, scope, args){ + if(Ext.isFunction(cb)){ + cb.apply(scope, args); + } + }, + + isLoading : function(){ + return !!this.transId; + }, + + abort : function(){ + if(this.isLoading()){ + Ext.Ajax.abort(this.transId); + } + }, + + + createNode : function(attr){ + + if(this.baseAttrs){ + Ext.applyIf(attr, this.baseAttrs); + } + if(this.applyLoader !== false && !attr.loader){ + attr.loader = this; + } + if(Ext.isString(attr.uiProvider)){ + attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider); + } + if(attr.nodeType){ + return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr); + }else{ + return attr.leaf ? + new Ext.tree.TreeNode(attr) : + new Ext.tree.AsyncTreeNode(attr); + } + }, + + processResponse : function(response, node, callback, scope){ + var json = response.responseText; + try { + var o = response.responseData || Ext.decode(json); + node.beginUpdate(); + for(var i = 0, len = o.length; i < len; i++){ + var n = this.createNode(o[i]); + if(n){ + node.appendChild(n); + } + } + node.endUpdate(); + this.runCallback(callback, scope || node, [node]); + }catch(e){ + this.handleFailure(response); + } + }, + + handleResponse : function(response){ + this.transId = false; + var a = response.argument; + this.processResponse(response, a.node, a.callback, a.scope); + this.fireEvent("load", this, a.node, response); + }, + + handleFailure : function(response){ + this.transId = false; + var a = response.argument; + this.fireEvent("loadexception", this, a.node, response); + this.runCallback(a.callback, a.scope || a.node, [a.node]); + }, + + destroy : function(){ + this.abort(); + this.purgeListeners(); + } +}); +Ext.tree.TreeFilter = function(tree, config){ + this.tree = tree; + this.filtered = {}; + Ext.apply(this, config); +}; + +Ext.tree.TreeFilter.prototype = { + clearBlank:false, + reverse:false, + autoClear:false, + remove:false, + + + filter : function(value, attr, startNode){ + attr = attr || "text"; + var f; + if(typeof value == "string"){ + var vlen = value.length; + + if(vlen == 0 && this.clearBlank){ + this.clear(); + return; + } + value = value.toLowerCase(); + f = function(n){ + return n.attributes[attr].substr(0, vlen).toLowerCase() == value; + }; + }else if(value.exec){ + f = function(n){ + return value.test(n.attributes[attr]); + }; + }else{ + throw 'Illegal filter type, must be string or regex'; + } + this.filterBy(f, null, startNode); + }, + + + filterBy : function(fn, scope, startNode){ + startNode = startNode || this.tree.root; + if(this.autoClear){ + this.clear(); + } + var af = this.filtered, rv = this.reverse; + var f = function(n){ + if(n == startNode){ + return true; + } + if(af[n.id]){ + return false; + } + var m = fn.call(scope || n, n); + if(!m || rv){ + af[n.id] = n; + n.ui.hide(); + return false; + } + return true; + }; + startNode.cascade(f); + if(this.remove){ + for(var id in af){ + if(typeof id != "function"){ + var n = af[id]; + if(n && n.parentNode){ + n.parentNode.removeChild(n); + } + } + } + } + }, + + + clear : function(){ + var t = this.tree; + var af = this.filtered; + for(var id in af){ + if(typeof id != "function"){ + var n = af[id]; + if(n){ + n.ui.show(); + } + } + } + this.filtered = {}; + } +}; + +Ext.tree.TreeSorter = Ext.extend(Object, { + + constructor: function(tree, config){ + + + + + + + + Ext.apply(this, config); + tree.on({ + scope: this, + beforechildrenrendered: this.doSort, + append: this.updateSort, + insert: this.updateSort, + textchange: this.updateSortParent + }); + + var desc = this.dir && this.dir.toLowerCase() == 'desc', + prop = this.property || 'text', + sortType = this.sortType, + folderSort = this.folderSort, + caseSensitive = this.caseSensitive === true, + leafAttr = this.leafAttr || 'leaf'; + + if(Ext.isString(sortType)){ + sortType = Ext.data.SortTypes[sortType]; + } + this.sortFn = function(n1, n2){ + var attr1 = n1.attributes, + attr2 = n2.attributes; + + if(folderSort){ + if(attr1[leafAttr] && !attr2[leafAttr]){ + return 1; + } + if(!attr1[leafAttr] && attr2[leafAttr]){ + return -1; + } + } + var prop1 = attr1[prop], + prop2 = attr2[prop], + v1 = sortType ? sortType(prop1, n1) : (caseSensitive ? prop1 : prop1.toUpperCase()), + v2 = sortType ? sortType(prop2, n2) : (caseSensitive ? prop2 : prop2.toUpperCase()); + + if(v1 < v2){ + return desc ? 1 : -1; + }else if(v1 > v2){ + return desc ? -1 : 1; + } + return 0; + }; + }, + + doSort : function(node){ + node.sort(this.sortFn); + }, + + updateSort : function(tree, node){ + if(node.childrenRendered){ + this.doSort.defer(1, this, [node]); + } + }, + + updateSortParent : function(node){ + var p = node.parentNode; + if(p && p.childrenRendered){ + this.doSort.defer(1, this, [p]); + } + } +}); + +if(Ext.dd.DropZone){ + +Ext.tree.TreeDropZone = function(tree, config){ + + this.allowParentInsert = config.allowParentInsert || false; + + this.allowContainerDrop = config.allowContainerDrop || false; + + this.appendOnly = config.appendOnly || false; + + Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config); + + this.tree = tree; + + this.dragOverData = {}; + + this.lastInsertClass = "x-tree-no-status"; +}; + +Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, { + + ddGroup : "TreeDD", + + + expandDelay : 1000, + + + expandNode : function(node){ + if(node.hasChildNodes() && !node.isExpanded()){ + node.expand(false, null, this.triggerCacheRefresh.createDelegate(this)); + } + }, + + + queueExpand : function(node){ + this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]); + }, + + + cancelExpand : function(){ + if(this.expandProcId){ + clearTimeout(this.expandProcId); + this.expandProcId = false; + } + }, + + + isValidDropPoint : function(n, pt, dd, e, data){ + if(!n || !data){ return false; } + var targetNode = n.node; + var dropNode = data.node; + + if(!(targetNode && targetNode.isTarget && pt)){ + return false; + } + if(pt == "append" && targetNode.allowChildren === false){ + return false; + } + if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){ + return false; + } + if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){ + return false; + } + + var overEvent = this.dragOverData; + overEvent.tree = this.tree; + overEvent.target = targetNode; + overEvent.data = data; + overEvent.point = pt; + overEvent.source = dd; + overEvent.rawEvent = e; + overEvent.dropNode = dropNode; + overEvent.cancel = false; + var result = this.tree.fireEvent("nodedragover", overEvent); + return overEvent.cancel === false && result !== false; + }, + + + getDropPoint : function(e, n, dd){ + var tn = n.node; + if(tn.isRoot){ + return tn.allowChildren !== false ? "append" : false; + } + var dragEl = n.ddel; + var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight; + var y = Ext.lib.Event.getPageY(e); + var noAppend = tn.allowChildren === false || tn.isLeaf(); + if(this.appendOnly || tn.parentNode.allowChildren === false){ + return noAppend ? false : "append"; + } + var noBelow = false; + if(!this.allowParentInsert){ + noBelow = tn.hasChildNodes() && tn.isExpanded(); + } + var q = (b - t) / (noAppend ? 2 : 3); + if(y >= t && y < (t + q)){ + return "above"; + }else if(!noBelow && (noAppend || y >= b-q && y <= b)){ + return "below"; + }else{ + return "append"; + } + }, + + + onNodeEnter : function(n, dd, e, data){ + this.cancelExpand(); + }, + + onContainerOver : function(dd, e, data) { + if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) { + return this.dropAllowed; + } + return this.dropNotAllowed; + }, + + + onNodeOver : function(n, dd, e, data){ + var pt = this.getDropPoint(e, n, dd); + var node = n.node; + + + if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){ + this.queueExpand(node); + }else if(pt != "append"){ + this.cancelExpand(); + } + + + var returnCls = this.dropNotAllowed; + if(this.isValidDropPoint(n, pt, dd, e, data)){ + if(pt){ + var el = n.ddel; + var cls; + if(pt == "above"){ + returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between"; + cls = "x-tree-drag-insert-above"; + }else if(pt == "below"){ + returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between"; + cls = "x-tree-drag-insert-below"; + }else{ + returnCls = "x-tree-drop-ok-append"; + cls = "x-tree-drag-append"; + } + if(this.lastInsertClass != cls){ + Ext.fly(el).replaceClass(this.lastInsertClass, cls); + this.lastInsertClass = cls; + } + } + } + return returnCls; + }, + + + onNodeOut : function(n, dd, e, data){ + this.cancelExpand(); + this.removeDropIndicators(n); + }, + + + onNodeDrop : function(n, dd, e, data){ + var point = this.getDropPoint(e, n, dd); + var targetNode = n.node; + targetNode.ui.startDrop(); + if(!this.isValidDropPoint(n, point, dd, e, data)){ + targetNode.ui.endDrop(); + return false; + } + + var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null); + return this.processDrop(targetNode, data, point, dd, e, dropNode); + }, + + onContainerDrop : function(dd, e, data){ + if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) { + var targetNode = this.tree.getRootNode(); + targetNode.ui.startDrop(); + var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null); + return this.processDrop(targetNode, data, 'append', dd, e, dropNode); + } + return false; + }, + + + processDrop: function(target, data, point, dd, e, dropNode){ + var dropEvent = { + tree : this.tree, + target: target, + data: data, + point: point, + source: dd, + rawEvent: e, + dropNode: dropNode, + cancel: !dropNode, + dropStatus: false + }; + var retval = this.tree.fireEvent("beforenodedrop", dropEvent); + if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){ + target.ui.endDrop(); + return dropEvent.dropStatus; + } + + target = dropEvent.target; + if(point == 'append' && !target.isExpanded()){ + target.expand(false, null, function(){ + this.completeDrop(dropEvent); + }.createDelegate(this)); + }else{ + this.completeDrop(dropEvent); + } + return true; + }, + + + completeDrop : function(de){ + var ns = de.dropNode, p = de.point, t = de.target; + if(!Ext.isArray(ns)){ + ns = [ns]; + } + var n; + for(var i = 0, len = ns.length; i < len; i++){ + n = ns[i]; + if(p == "above"){ + t.parentNode.insertBefore(n, t); + }else if(p == "below"){ + t.parentNode.insertBefore(n, t.nextSibling); + }else{ + t.appendChild(n); + } + } + n.ui.focus(); + if(Ext.enableFx && this.tree.hlDrop){ + n.ui.highlight(); + } + t.ui.endDrop(); + this.tree.fireEvent("nodedrop", de); + }, + + + afterNodeMoved : function(dd, data, e, targetNode, dropNode){ + if(Ext.enableFx && this.tree.hlDrop){ + dropNode.ui.focus(); + dropNode.ui.highlight(); + } + this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e); + }, + + + getTree : function(){ + return this.tree; + }, + + + removeDropIndicators : function(n){ + if(n && n.ddel){ + var el = n.ddel; + Ext.fly(el).removeClass([ + "x-tree-drag-insert-above", + "x-tree-drag-insert-below", + "x-tree-drag-append"]); + this.lastInsertClass = "_noclass"; + } + }, + + + beforeDragDrop : function(target, e, id){ + this.cancelExpand(); + return true; + }, + + + afterRepair : function(data){ + if(data && Ext.enableFx){ + data.node.ui.highlight(); + } + this.hideProxy(); + } +}); + +} +if(Ext.dd.DragZone){ +Ext.tree.TreeDragZone = function(tree, config){ + Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config); + + this.tree = tree; +}; + +Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, { + + ddGroup : "TreeDD", + + + onBeforeDrag : function(data, e){ + var n = data.node; + return n && n.draggable && !n.disabled; + }, + + + onInitDrag : function(e){ + var data = this.dragData; + this.tree.getSelectionModel().select(data.node); + this.tree.eventModel.disable(); + this.proxy.update(""); + data.node.ui.appendDDGhost(this.proxy.ghost.dom); + this.tree.fireEvent("startdrag", this.tree, data.node, e); + }, + + + getRepairXY : function(e, data){ + return data.node.ui.getDDRepairXY(); + }, + + + onEndDrag : function(data, e){ + this.tree.eventModel.enable.defer(100, this.tree.eventModel); + this.tree.fireEvent("enddrag", this.tree, data.node, e); + }, + + + onValidDrop : function(dd, e, id){ + this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e); + this.hideProxy(); + }, + + + beforeInvalidDrop : function(e, id){ + + var sm = this.tree.getSelectionModel(); + sm.clearSelections(); + sm.select(this.dragData.node); + }, + + + afterRepair : function(){ + if (Ext.enableFx && this.tree.hlDrop) { + Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9"); + } + this.dragging = false; + } +}); +} +Ext.tree.TreeEditor = function(tree, fc, config){ + fc = fc || {}; + var field = fc.events ? fc : new Ext.form.TextField(fc); + + Ext.tree.TreeEditor.superclass.constructor.call(this, field, config); + + this.tree = tree; + + if(!tree.rendered){ + tree.on('render', this.initEditor, this); + }else{ + this.initEditor(tree); + } +}; + +Ext.extend(Ext.tree.TreeEditor, Ext.Editor, { + + alignment: "l-l", + + autoSize: false, + + hideEl : false, + + cls: "x-small-editor x-tree-editor", + + shim:false, + + shadow:"frame", + + maxWidth: 250, + + editDelay : 350, + + initEditor : function(tree){ + tree.on({ + scope : this, + beforeclick: this.beforeNodeClick, + dblclick : this.onNodeDblClick + }); + + this.on({ + scope : this, + complete : this.updateNode, + beforestartedit: this.fitToTree, + specialkey : this.onSpecialKey + }); + + this.on('startedit', this.bindScroll, this, {delay:10}); + }, + + + fitToTree : function(ed, el){ + var td = this.tree.getTreeEl().dom, nd = el.dom; + if(td.scrollLeft > nd.offsetLeft){ + td.scrollLeft = nd.offsetLeft; + } + var w = Math.min( + this.maxWidth, + (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5); + this.setSize(w, ''); + }, + + + triggerEdit : function(node, defer){ + this.completeEdit(); + if(node.attributes.editable !== false){ + + this.editNode = node; + if(this.tree.autoScroll){ + Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body); + } + var value = node.text || ''; + if (!Ext.isGecko && Ext.isEmpty(node.text)){ + node.setText(' '); + } + this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]); + return false; + } + }, + + + bindScroll : function(){ + this.tree.getTreeEl().on('scroll', this.cancelEdit, this); + }, + + + beforeNodeClick : function(node, e){ + clearTimeout(this.autoEditTimer); + if(this.tree.getSelectionModel().isSelected(node)){ + e.stopEvent(); + return this.triggerEdit(node); + } + }, + + onNodeDblClick : function(node, e){ + clearTimeout(this.autoEditTimer); + }, + + + updateNode : function(ed, value){ + this.tree.getTreeEl().un('scroll', this.cancelEdit, this); + this.editNode.setText(value); + }, + + + onHide : function(){ + Ext.tree.TreeEditor.superclass.onHide.call(this); + if(this.editNode){ + this.editNode.ui.focus.defer(50, this.editNode.ui); + } + }, + + + onSpecialKey : function(field, e){ + var k = e.getKey(); + if(k == e.ESC){ + e.stopEvent(); + this.cancelEdit(); + }else if(k == e.ENTER && !e.hasModifier()){ + e.stopEvent(); + this.completeEdit(); + } + }, + + onDestroy : function(){ + clearTimeout(this.autoEditTimer); + Ext.tree.TreeEditor.superclass.onDestroy.call(this); + var tree = this.tree; + tree.un('beforeclick', this.beforeNodeClick, this); + tree.un('dblclick', this.onNodeDblClick, this); + } +}); + +var swfobject = function() { + + var UNDEF = "undefined", + OBJECT = "object", + SHOCKWAVE_FLASH = "Shockwave Flash", + SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", + FLASH_MIME_TYPE = "application/x-shockwave-flash", + EXPRESS_INSTALL_ID = "SWFObjectExprInst", + ON_READY_STATE_CHANGE = "onreadystatechange", + + win = window, + doc = document, + nav = navigator, + + plugin = false, + domLoadFnArr = [main], + regObjArr = [], + objIdArr = [], + listenersArr = [], + storedAltContent, + storedAltContentId, + storedCallbackFn, + storedCallbackObj, + isDomLoaded = false, + isExpressInstallActive = false, + dynamicStylesheet, + dynamicStylesheetMedia, + autoHideShow = true, + + + ua = function() { + var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF, + u = nav.userAgent.toLowerCase(), + p = nav.platform.toLowerCase(), + windows = p ? (/win/).test(p) : /win/.test(u), + mac = p ? (/mac/).test(p) : /mac/.test(u), + webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, + ie = !+"\v1", + playerVersion = [0,0,0], + d = null; + if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) { + d = nav.plugins[SHOCKWAVE_FLASH].description; + if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { + plugin = true; + ie = false; + d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); + playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10); + playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10); + playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0; + } + } + else if (typeof win.ActiveXObject != UNDEF) { + try { + var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); + if (a) { + d = a.GetVariable("$version"); + if (d) { + ie = true; + d = d.split(" ")[1].split(","); + playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + } + catch(e) {} + } + return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; + }(), + + + onDomLoad = function() { + if (!ua.w3) { return; } + if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { + callDomLoadFunctions(); + } + if (!isDomLoaded) { + if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); + } + if (ua.ie && ua.win) { + doc.attachEvent(ON_READY_STATE_CHANGE, function() { + if (doc.readyState == "complete") { + doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee); + callDomLoadFunctions(); + } + }); + if (win == top) { + (function(){ + if (isDomLoaded) { return; } + try { + doc.documentElement.doScroll("left"); + } + catch(e) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + } + if (ua.wk) { + (function(){ + if (isDomLoaded) { return; } + if (!(/loaded|complete/).test(doc.readyState)) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + addLoadEvent(callDomLoadFunctions); + } + }(); + + function callDomLoadFunctions() { + if (isDomLoaded) { return; } + try { + var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span")); + t.parentNode.removeChild(t); + } + catch (e) { return; } + isDomLoaded = true; + var dl = domLoadFnArr.length; + for (var i = 0; i < dl; i++) { + domLoadFnArr[i](); + } + } + + function addDomLoadEvent(fn) { + if (isDomLoaded) { + fn(); + } + else { + domLoadFnArr[domLoadFnArr.length] = fn; + } + } + + + function addLoadEvent(fn) { + if (typeof win.addEventListener != UNDEF) { + win.addEventListener("load", fn, false); + } + else if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("load", fn, false); + } + else if (typeof win.attachEvent != UNDEF) { + addListener(win, "onload", fn); + } + else if (typeof win.onload == "function") { + var fnOld = win.onload; + win.onload = function() { + fnOld(); + fn(); + }; + } + else { + win.onload = fn; + } + } + + + function main() { + //~ if (plugin) { + //~ testPlayerVersion(); + //~ } + //~ else { + matchVersions(); + //~ } + } + + + function testPlayerVersion() { + var b = doc.getElementsByTagName("body")[0]; + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + var t = b.appendChild(o); + if (t) { + var counter = 0; + (function(){ + if (typeof t.GetVariable != UNDEF) { + var d = t.GetVariable("$version"); + if (d) { + d = d.split(" ")[1].split(","); + ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + else if (counter < 10) { + counter++; + setTimeout(arguments.callee, 10); + return; + } + b.removeChild(o); + t = null; + matchVersions(); + })(); + } + else { + matchVersions(); + } + } + + + function matchVersions() { + var rl = regObjArr.length; + if (rl > 0) { + for (var i = 0; i < rl; i++) { + var id = regObjArr[i].id; + var cb = regObjArr[i].callbackFn; + var cbObj = {success:false, id:id}; + if (ua.pv[0] > 0) { + var obj = getElementById(id); + if (obj) { + if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { + setVisibility(id, true); + if (cb) { + cbObj.success = true; + cbObj.ref = getObjectById(id); + cb(cbObj); + } + } + else if (regObjArr[i].expressInstall && canExpressInstall()) { + var att = {}; + att.data = regObjArr[i].expressInstall; + att.width = obj.getAttribute("width") || "0"; + att.height = obj.getAttribute("height") || "0"; + if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } + if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } + + var par = {}; + var p = obj.getElementsByTagName("param"); + var pl = p.length; + for (var j = 0; j < pl; j++) { + if (p[j].getAttribute("name").toLowerCase() != "movie") { + par[p[j].getAttribute("name")] = p[j].getAttribute("value"); + } + } + showExpressInstall(att, par, id, cb); + } + else { + displayAltContent(obj); + if (cb) { cb(cbObj); } + } + } + } + else { + setVisibility(id, true); + if (cb) { + var o = getObjectById(id); + if (o && typeof o.SetVariable != UNDEF) { + cbObj.success = true; + cbObj.ref = o; + } + cb(cbObj); + } + } + } + } + } + + function getObjectById(objectIdStr) { + var r = null; + var o = getElementById(objectIdStr); + if (o && o.nodeName == "OBJECT") { + if (typeof o.SetVariable != UNDEF) { + r = o; + } + else { + var n = o.getElementsByTagName(OBJECT)[0]; + if (n) { + r = n; + } + } + } + return r; + } + + + function canExpressInstall() { + return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); + } + + + function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { + isExpressInstallActive = true; + storedCallbackFn = callbackFn || null; + storedCallbackObj = {success:false, id:replaceElemIdStr}; + var obj = getElementById(replaceElemIdStr); + if (obj) { + if (obj.nodeName == "OBJECT") { + storedAltContent = abstractAltContent(obj); + storedAltContentId = null; + } + else { + storedAltContent = obj; + storedAltContentId = replaceElemIdStr; + } + att.id = EXPRESS_INSTALL_ID; + if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) { + att.width = "310"; + } + + if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) { + att.height = "137"; + } + doc.title = doc.title.slice(0, 47) + " - Flash Player Installation"; + var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn", + fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + fv; + } + else { + par.flashvars = fv; + } + + + if (ua.ie && ua.win && obj.readyState != 4) { + var newObj = createElement("div"); + replaceElemIdStr += "SWFObjectNew"; + newObj.setAttribute("id", replaceElemIdStr); + obj.parentNode.insertBefore(newObj, obj); + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + createSWF(att, par, replaceElemIdStr); + } + } + + + function displayAltContent(obj) { + if (ua.ie && ua.win && obj.readyState != 4) { + + + var el = createElement("div"); + obj.parentNode.insertBefore(el, obj); + el.parentNode.replaceChild(abstractAltContent(obj), el); + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.replaceChild(abstractAltContent(obj), obj); + } + } + + function abstractAltContent(obj) { + var ac = createElement("div"); + if (ua.win && ua.ie) { + ac.innerHTML = obj.innerHTML; + } + else { + var nestedObj = obj.getElementsByTagName(OBJECT)[0]; + if (nestedObj) { + var c = nestedObj.childNodes; + if (c) { + var cl = c.length; + for (var i = 0; i < cl; i++) { + if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) { + ac.appendChild(c[i].cloneNode(true)); + } + } + } + } + } + return ac; + } + + + function createSWF(attObj, parObj, id) { + var r, el = getElementById(id); + if (ua.wk && ua.wk < 312) { return r; } + if (el) { + if (typeof attObj.id == UNDEF) { + attObj.id = id; + } + if (ua.ie && ua.win) { + var att = ""; + for (var i in attObj) { + if (attObj[i] != Object.prototype[i]) { + if (i.toLowerCase() == "data") { + parObj.movie = attObj[i]; + } + else if (i.toLowerCase() == "styleclass") { + att += ' class="' + attObj[i] + '"'; + } + else if (i.toLowerCase() != "classid") { + att += ' ' + i + '="' + attObj[i] + '"'; + } + } + } + var par = ""; + for (var j in parObj) { + if (parObj[j] != Object.prototype[j]) { + par += ''; + } + } + el.outerHTML = '' + par + ''; + objIdArr[objIdArr.length] = attObj.id; + r = getElementById(attObj.id); + } + else { + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + for (var m in attObj) { + if (attObj[m] != Object.prototype[m]) { + if (m.toLowerCase() == "styleclass") { + o.setAttribute("class", attObj[m]); + } + else if (m.toLowerCase() != "classid") { + o.setAttribute(m, attObj[m]); + } + } + } + for (var n in parObj) { + if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { + createObjParam(o, n, parObj[n]); + } + } + el.parentNode.replaceChild(o, el); + r = o; + } + } + return r; + } + + function createObjParam(el, pName, pValue) { + var p = createElement("param"); + p.setAttribute("name", pName); + p.setAttribute("value", pValue); + el.appendChild(p); + } + + + function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (ua.ie && ua.win) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + + function getElementById(id) { + var el = null; + try { + el = doc.getElementById(id); + } + catch (e) {} + return el; + } + + function createElement(el) { + return doc.createElement(el); + } + + + function addListener(target, eventType, fn) { + target.attachEvent(eventType, fn); + listenersArr[listenersArr.length] = [target, eventType, fn]; + } + + + function hasPlayerVersion(rv) { + var pv = ua.pv, v = rv.split("."); + v[0] = parseInt(v[0], 10); + v[1] = parseInt(v[1], 10) || 0; + v[2] = parseInt(v[2], 10) || 0; + return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; + } + + + function createCSS(sel, decl, media, newStyle) { + if (ua.ie && ua.mac) { return; } + var h = doc.getElementsByTagName("head")[0]; + if (!h) { return; } + var m = (media && typeof media == "string") ? media : "screen"; + if (newStyle) { + dynamicStylesheet = null; + dynamicStylesheetMedia = null; + } + if (!dynamicStylesheet || dynamicStylesheetMedia != m) { + + var s = createElement("style"); + s.setAttribute("type", "text/css"); + s.setAttribute("media", m); + dynamicStylesheet = h.appendChild(s); + if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) { + dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; + } + dynamicStylesheetMedia = m; + } + + if (ua.ie && ua.win) { + if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { + dynamicStylesheet.addRule(sel, decl); + } + } + else { + if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { + dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); + } + } + } + + function setVisibility(id, isVisible) { + if (!autoHideShow) { return; } + var v = isVisible ? "visible" : "hidden"; + if (isDomLoaded && getElementById(id)) { + getElementById(id).style.visibility = v; + } + else { + createCSS("#" + id, "visibility:" + v); + } + } + + + function urlEncodeIfNecessary(s) { + var regex = /[\\\"<>\.;]/; + var hasBadChars = regex.exec(s) != null; + return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; + } + + + var cleanup = function() { + if (ua.ie && ua.win) { + window.attachEvent("onunload", function() { + + var ll = listenersArr.length; + for (var i = 0; i < ll; i++) { + listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); + } + + var il = objIdArr.length; + for (var j = 0; j < il; j++) { + removeSWF(objIdArr[j]); + } + + for (var k in ua) { + ua[k] = null; + } + ua = null; + for (var l in swfobject) { + swfobject[l] = null; + } + swfobject = null; + window.detachEvent('onunload', arguments.callee); + }); + } + }(); + + return { + + registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { + if (ua.w3 && objectIdStr && swfVersionStr) { + var regObj = {}; + regObj.id = objectIdStr; + regObj.swfVersion = swfVersionStr; + regObj.expressInstall = xiSwfUrlStr; + regObj.callbackFn = callbackFn; + regObjArr[regObjArr.length] = regObj; + setVisibility(objectIdStr, false); + } + else if (callbackFn) { + callbackFn({success:false, id:objectIdStr}); + } + }, + + getObjectById: function(objectIdStr) { + if (ua.w3) { + return getObjectById(objectIdStr); + } + }, + + embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { + var callbackObj = {success:false, id:replaceElemIdStr}; + if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { + setVisibility(replaceElemIdStr, false); + addDomLoadEvent(function() { + widthStr += ""; + heightStr += ""; + var att = {}; + if (attObj && typeof attObj === OBJECT) { + for (var i in attObj) { + att[i] = attObj[i]; + } + } + att.data = swfUrlStr; + att.width = widthStr; + att.height = heightStr; + var par = {}; + if (parObj && typeof parObj === OBJECT) { + for (var j in parObj) { + par[j] = parObj[j]; + } + } + if (flashvarsObj && typeof flashvarsObj === OBJECT) { + for (var k in flashvarsObj) { + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + k + "=" + flashvarsObj[k]; + } + else { + par.flashvars = k + "=" + flashvarsObj[k]; + } + } + } + if (hasPlayerVersion(swfVersionStr)) { + var obj = createSWF(att, par, replaceElemIdStr); + if (att.id == replaceElemIdStr) { + setVisibility(replaceElemIdStr, true); + } + callbackObj.success = true; + callbackObj.ref = obj; + } + else if (xiSwfUrlStr && canExpressInstall()) { + att.data = xiSwfUrlStr; + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + return; + } + else { + setVisibility(replaceElemIdStr, true); + } + if (callbackFn) { callbackFn(callbackObj); } + }); + } + else if (callbackFn) { callbackFn(callbackObj); } + }, + + switchOffAutoHideShow: function() { + autoHideShow = false; + }, + + ua: ua, + + getFlashPlayerVersion: function() { + return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; + }, + + hasFlashPlayerVersion: hasPlayerVersion, + + createSWF: function(attObj, parObj, replaceElemIdStr) { + if (ua.w3) { + return createSWF(attObj, parObj, replaceElemIdStr); + } + else { + return undefined; + } + }, + + showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { + if (ua.w3 && canExpressInstall()) { + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + } + }, + + removeSWF: function(objElemIdStr) { + if (ua.w3) { + removeSWF(objElemIdStr); + } + }, + + createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { + if (ua.w3) { + createCSS(selStr, declStr, mediaStr, newStyleBoolean); + } + }, + + addDomLoadEvent: addDomLoadEvent, + + addLoadEvent: addLoadEvent, + + getQueryParamValue: function(param) { + var q = doc.location.search || doc.location.hash; + if (q) { + if (/\?/.test(q)) { q = q.split("?")[1]; } + if (param == null) { + return urlEncodeIfNecessary(q); + } + var pairs = q.split("&"); + for (var i = 0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); + } + } + } + return ""; + }, + + + expressInstallCallback: function() { + if (isExpressInstallActive) { + var obj = getElementById(EXPRESS_INSTALL_ID); + if (obj && storedAltContent) { + obj.parentNode.replaceChild(storedAltContent, obj); + if (storedAltContentId) { + setVisibility(storedAltContentId, true); + if (ua.ie && ua.win) { storedAltContent.style.display = "block"; } + } + if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } + } + isExpressInstallActive = false; + } + } + }; +}(); + +Ext.FlashComponent = Ext.extend(Ext.BoxComponent, { + + flashVersion : '9.0.115', + + + backgroundColor: '#ffffff', + + + wmode: 'opaque', + + + flashVars: undefined, + + + flashParams: undefined, + + + url: undefined, + swfId : undefined, + swfWidth: '100%', + swfHeight: '100%', + + + expressInstall: false, + + initComponent : function(){ + Ext.FlashComponent.superclass.initComponent.call(this); + + this.addEvents( + + 'initialize' + ); + }, + + onRender : function(){ + Ext.FlashComponent.superclass.onRender.apply(this, arguments); + + var params = Ext.apply({ + allowScriptAccess: 'always', + bgcolor: this.backgroundColor, + wmode: this.wmode + }, this.flashParams), vars = Ext.apply({ + allowedDomain: document.location.hostname, + YUISwfId: this.getId(), + YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent' + }, this.flashVars); + + new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion, + this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params); + + this.swf = Ext.getDom(this.id); + this.el = Ext.get(this.swf); + }, + + getSwfId : function(){ + return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID)); + }, + + getId : function(){ + return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID)); + }, + + onFlashEvent : function(e){ + switch(e.type){ + case "swfReady": + this.initSwf(); + return; + case "log": + return; + } + e.component = this; + this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e); + }, + + initSwf : function(){ + this.onSwfReady(!!this.isInitialized); + this.isInitialized = true; + this.fireEvent('initialize', this); + }, + + beforeDestroy: function(){ + if(this.rendered){ + swfobject.removeSWF(this.swf.id); + } + Ext.FlashComponent.superclass.beforeDestroy.call(this); + }, + + onSwfReady : Ext.emptyFn +}); + + +Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf'; + +Ext.reg('flash', Ext.FlashComponent); +Ext.FlashEventProxy = { + onEvent : function(id, e){ + var fp = Ext.getCmp(id); + if(fp){ + fp.onFlashEvent(e); + }else{ + arguments.callee.defer(10, this, [id, e]); + } + } +}; + + Ext.chart.Chart = Ext.extend(Ext.FlashComponent, { + refreshBuffer: 100, + + + + + chartStyle: { + padding: 10, + animationEnabled: true, + font: { + name: 'Tahoma', + color: 0x444444, + size: 11 + }, + dataTip: { + padding: 5, + border: { + color: 0x99bbe8, + size:1 + }, + background: { + color: 0xDAE7F6, + alpha: .9 + }, + font: { + name: 'Tahoma', + color: 0x15428B, + size: 10, + bold: true + } + } + }, + + + + + extraStyle: null, + + + seriesStyles: null, + + + disableCaching: Ext.isIE || Ext.isOpera, + disableCacheParam: '_dc', + + initComponent : function(){ + Ext.chart.Chart.superclass.initComponent.call(this); + if(!this.url){ + this.url = Ext.chart.Chart.CHART_URL; + } + if(this.disableCaching){ + this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime())); + } + this.addEvents( + 'itemmouseover', + 'itemmouseout', + 'itemclick', + 'itemdoubleclick', + 'itemdragstart', + 'itemdrag', + 'itemdragend', + + 'beforerefresh', + + 'refresh' + ); + this.store = Ext.StoreMgr.lookup(this.store); + }, + + + setStyle: function(name, value){ + this.swf.setStyle(name, Ext.encode(value)); + }, + + + setStyles: function(styles){ + this.swf.setStyles(Ext.encode(styles)); + }, + + + setSeriesStyles: function(styles){ + this.seriesStyles = styles; + var s = []; + Ext.each(styles, function(style){ + s.push(Ext.encode(style)); + }); + this.swf.setSeriesStyles(s); + }, + + setCategoryNames : function(names){ + this.swf.setCategoryNames(names); + }, + + setLegendRenderer : function(fn, scope){ + var chart = this; + scope = scope || chart; + chart.removeFnProxy(chart.legendFnName); + chart.legendFnName = chart.createFnProxy(function(name){ + return fn.call(scope, name); + }); + chart.swf.setLegendLabelFunction(chart.legendFnName); + }, + + setTipRenderer : function(fn, scope){ + var chart = this; + scope = scope || chart; + chart.removeFnProxy(chart.tipFnName); + chart.tipFnName = chart.createFnProxy(function(item, index, series){ + var record = chart.store.getAt(index); + return fn.call(scope, chart, record, index, series); + }); + chart.swf.setDataTipFunction(chart.tipFnName); + }, + + setSeries : function(series){ + this.series = series; + this.refresh(); + }, + + + bindStore : function(store, initial){ + if(!initial && this.store){ + if(store !== this.store && this.store.autoDestroy){ + this.store.destroy(); + }else{ + this.store.un("datachanged", this.refresh, this); + this.store.un("add", this.delayRefresh, this); + this.store.un("remove", this.delayRefresh, this); + this.store.un("update", this.delayRefresh, this); + this.store.un("clear", this.refresh, this); + } + } + if(store){ + store = Ext.StoreMgr.lookup(store); + store.on({ + scope: this, + datachanged: this.refresh, + add: this.delayRefresh, + remove: this.delayRefresh, + update: this.delayRefresh, + clear: this.refresh + }); + } + this.store = store; + if(store && !initial){ + this.refresh(); + } + }, + + onSwfReady : function(isReset){ + Ext.chart.Chart.superclass.onSwfReady.call(this, isReset); + var ref; + this.swf.setType(this.type); + + if(this.chartStyle){ + this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle)); + } + + if(this.categoryNames){ + this.setCategoryNames(this.categoryNames); + } + + if(this.tipRenderer){ + ref = this.getFunctionRef(this.tipRenderer); + this.setTipRenderer(ref.fn, ref.scope); + } + if(this.legendRenderer){ + ref = this.getFunctionRef(this.legendRenderer); + this.setLegendRenderer(ref.fn, ref.scope); + } + if(!isReset){ + this.bindStore(this.store, true); + } + this.refresh.defer(10, this); + }, + + delayRefresh : function(){ + if(!this.refreshTask){ + this.refreshTask = new Ext.util.DelayedTask(this.refresh, this); + } + this.refreshTask.delay(this.refreshBuffer); + }, + + refresh : function(){ + if(this.fireEvent('beforerefresh', this) !== false){ + var styleChanged = false; + + var data = [], rs = this.store.data.items; + for(var j = 0, len = rs.length; j < len; j++){ + data[j] = rs[j].data; + } + + + var dataProvider = []; + var seriesCount = 0; + var currentSeries = null; + var i = 0; + if(this.series){ + seriesCount = this.series.length; + for(i = 0; i < seriesCount; i++){ + currentSeries = this.series[i]; + var clonedSeries = {}; + for(var prop in currentSeries){ + if(prop == "style" && currentSeries.style !== null){ + clonedSeries.style = Ext.encode(currentSeries.style); + styleChanged = true; + + + + + } else{ + clonedSeries[prop] = currentSeries[prop]; + } + } + dataProvider.push(clonedSeries); + } + } + + if(seriesCount > 0){ + for(i = 0; i < seriesCount; i++){ + currentSeries = dataProvider[i]; + if(!currentSeries.type){ + currentSeries.type = this.type; + } + currentSeries.dataProvider = data; + } + } else{ + dataProvider.push({type: this.type, dataProvider: data}); + } + this.swf.setDataProvider(dataProvider); + if(this.seriesStyles){ + this.setSeriesStyles(this.seriesStyles); + } + this.fireEvent('refresh', this); + } + }, + + + createFnProxy : function(fn){ + var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID); + Ext.chart.Chart.proxyFunction[fnName] = fn; + return 'Ext.chart.Chart.proxyFunction.' + fnName; + }, + + + removeFnProxy : function(fn){ + if(!Ext.isEmpty(fn)){ + fn = fn.replace('Ext.chart.Chart.proxyFunction.', ''); + delete Ext.chart.Chart.proxyFunction[fn]; + } + }, + + + getFunctionRef : function(val){ + if(Ext.isFunction(val)){ + return { + fn: val, + scope: this + }; + }else{ + return { + fn: val.fn, + scope: val.scope || this + }; + } + }, + + + onDestroy: function(){ + if (this.refreshTask && this.refreshTask.cancel){ + this.refreshTask.cancel(); + } + Ext.chart.Chart.superclass.onDestroy.call(this); + this.bindStore(null); + this.removeFnProxy(this.tipFnName); + this.removeFnProxy(this.legendFnName); + } +}); +Ext.reg('chart', Ext.chart.Chart); +Ext.chart.Chart.PROXY_FN_ID = 0; +Ext.chart.Chart.proxyFunction = {}; + + +Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf'; + + +Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, { + type: 'pie', + + onSwfReady : function(isReset){ + Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset); + + this.setDataField(this.dataField); + this.setCategoryField(this.categoryField); + }, + + setDataField : function(field){ + this.dataField = field; + this.swf.setDataField(field); + }, + + setCategoryField : function(field){ + this.categoryField = field; + this.swf.setCategoryField(field); + } +}); +Ext.reg('piechart', Ext.chart.PieChart); + + +Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, { + onSwfReady : function(isReset){ + Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset); + this.labelFn = []; + if(this.xField){ + this.setXField(this.xField); + } + if(this.yField){ + this.setYField(this.yField); + } + if(this.xAxis){ + this.setXAxis(this.xAxis); + } + if(this.xAxes){ + this.setXAxes(this.xAxes); + } + if(this.yAxis){ + this.setYAxis(this.yAxis); + } + if(this.yAxes){ + this.setYAxes(this.yAxes); + } + if(Ext.isDefined(this.constrainViewport)){ + this.swf.setConstrainViewport(this.constrainViewport); + } + }, + + setXField : function(value){ + this.xField = value; + this.swf.setHorizontalField(value); + }, + + setYField : function(value){ + this.yField = value; + this.swf.setVerticalField(value); + }, + + setXAxis : function(value){ + this.xAxis = this.createAxis('xAxis', value); + this.swf.setHorizontalAxis(this.xAxis); + }, + + setXAxes : function(value){ + var axis; + for(var i = 0; i < value.length; i++) { + axis = this.createAxis('xAxis' + i, value[i]); + this.swf.setHorizontalAxis(axis); + } + }, + + setYAxis : function(value){ + this.yAxis = this.createAxis('yAxis', value); + this.swf.setVerticalAxis(this.yAxis); + }, + + setYAxes : function(value){ + var axis; + for(var i = 0; i < value.length; i++) { + axis = this.createAxis('yAxis' + i, value[i]); + this.swf.setVerticalAxis(axis); + } + }, + + createAxis : function(axis, value){ + var o = Ext.apply({}, value), + ref, + old; + + if(this[axis]){ + old = this[axis].labelFunction; + this.removeFnProxy(old); + this.labelFn.remove(old); + } + if(o.labelRenderer){ + ref = this.getFunctionRef(o.labelRenderer); + o.labelFunction = this.createFnProxy(function(v){ + return ref.fn.call(ref.scope, v); + }); + delete o.labelRenderer; + this.labelFn.push(o.labelFunction); + } + if(axis.indexOf('xAxis') > -1 && o.position == 'left'){ + o.position = 'bottom'; + } + return o; + }, + + onDestroy : function(){ + Ext.chart.CartesianChart.superclass.onDestroy.call(this); + Ext.each(this.labelFn, function(fn){ + this.removeFnProxy(fn); + }, this); + } +}); +Ext.reg('cartesianchart', Ext.chart.CartesianChart); + + +Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, { + type: 'line' +}); +Ext.reg('linechart', Ext.chart.LineChart); + + +Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, { + type: 'column' +}); +Ext.reg('columnchart', Ext.chart.ColumnChart); + + +Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, { + type: 'stackcolumn' +}); +Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart); + + +Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, { + type: 'bar' +}); +Ext.reg('barchart', Ext.chart.BarChart); + + +Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, { + type: 'stackbar' +}); +Ext.reg('stackedbarchart', Ext.chart.StackedBarChart); + + + + +Ext.chart.Axis = function(config){ + Ext.apply(this, config); +}; + +Ext.chart.Axis.prototype = +{ + + type: null, + + + orientation: "horizontal", + + + reverse: false, + + + labelFunction: null, + + + hideOverlappingLabels: true, + + + labelSpacing: 2 +}; + + +Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, { + type: "numeric", + + + minimum: NaN, + + + maximum: NaN, + + + majorUnit: NaN, + + + minorUnit: NaN, + + + snapToUnits: true, + + + alwaysShowZero: true, + + + scale: "linear", + + + roundMajorUnit: true, + + + calculateByLabelSize: true, + + + position: 'left', + + + adjustMaximumByMajorUnit: true, + + + adjustMinimumByMajorUnit: true + +}); + + +Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, { + type: "time", + + + minimum: null, + + + maximum: null, + + + majorUnit: NaN, + + + majorTimeUnit: null, + + + minorUnit: NaN, + + + minorTimeUnit: null, + + + snapToUnits: true, + + + stackingEnabled: false, + + + calculateByLabelSize: true + +}); + + +Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, { + type: "category", + + + categoryNames: null, + + + calculateCategoryCount: false + +}); + + +Ext.chart.Series = function(config) { Ext.apply(this, config); }; + +Ext.chart.Series.prototype = +{ + + type: null, + + + displayName: null +}; + + +Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, { + + xField: null, + + + yField: null, + + + showInLegend: true, + + + axis: 'primary' +}); + + +Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, { + type: "column" +}); + + +Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, { + type: "line" +}); + + +Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, { + type: "bar" +}); + + + +Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, { + type: "pie", + dataField: null, + categoryField: null +}); +Ext.menu.Menu = Ext.extend(Ext.Container, { + + + + minWidth : 120, + + shadow : 'sides', + + subMenuAlign : 'tl-tr?', + + defaultAlign : 'tl-bl?', + + allowOtherMenus : false, + + ignoreParentClicks : false, + + enableScrolling : true, + + maxHeight : null, + + scrollIncrement : 24, + + showSeparator : true, + + defaultOffsets : [0, 0], + + + plain : false, + + + floating : true, + + + + zIndex: 15000, + + + hidden : true, + + + layout : 'menu', + hideMode : 'offsets', + scrollerHeight : 8, + autoLayout : true, + defaultType : 'menuitem', + bufferResize : false, + + initComponent : function(){ + if(Ext.isArray(this.initialConfig)){ + Ext.apply(this, {items:this.initialConfig}); + } + this.addEvents( + + 'click', + + 'mouseover', + + 'mouseout', + + 'itemclick' + ); + Ext.menu.MenuMgr.register(this); + if(this.floating){ + Ext.EventManager.onWindowResize(this.hide, this); + }else{ + if(this.initialConfig.hidden !== false){ + this.hidden = false; + } + this.internalDefaults = {hideOnClick: false}; + } + Ext.menu.Menu.superclass.initComponent.call(this); + if(this.autoLayout){ + var fn = this.doLayout.createDelegate(this, []); + this.on({ + add: fn, + remove: fn + }); + } + }, + + + getLayoutTarget : function() { + return this.ul; + }, + + + onRender : function(ct, position){ + if(!ct){ + ct = Ext.getBody(); + } + + var dh = { + id: this.getId(), + cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'), + style: this.style, + cn: [ + {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'}, + {tag: 'ul', cls: 'x-menu-list'} + ] + }; + if(this.floating){ + this.el = new Ext.Layer({ + shadow: this.shadow, + dh: dh, + constrain: false, + parentEl: ct, + zindex: this.zIndex + }); + }else{ + this.el = ct.createChild(dh); + } + Ext.menu.Menu.superclass.onRender.call(this, ct, position); + + if(!this.keyNav){ + this.keyNav = new Ext.menu.MenuNav(this); + } + + this.focusEl = this.el.child('a.x-menu-focus'); + this.ul = this.el.child('ul.x-menu-list'); + this.mon(this.ul, { + scope: this, + click: this.onClick, + mouseover: this.onMouseOver, + mouseout: this.onMouseOut + }); + if(this.enableScrolling){ + this.mon(this.el, { + scope: this, + delegate: '.x-menu-scroller', + click: this.onScroll, + mouseover: this.deactivateActive + }); + } + }, + + + findTargetItem : function(e){ + var t = e.getTarget('.x-menu-list-item', this.ul, true); + if(t && t.menuItemId){ + return this.items.get(t.menuItemId); + } + }, + + + onClick : function(e){ + var t = this.findTargetItem(e); + if(t){ + if(t.isFormField){ + this.setActiveItem(t); + }else if(t instanceof Ext.menu.BaseItem){ + if(t.menu && this.ignoreParentClicks){ + t.expandMenu(); + e.preventDefault(); + }else if(t.onClick){ + t.onClick(e); + this.fireEvent('click', this, t, e); + } + } + } + }, + + + setActiveItem : function(item, autoExpand){ + if(item != this.activeItem){ + this.deactivateActive(); + if((this.activeItem = item).isFormField){ + item.focus(); + }else{ + item.activate(autoExpand); + } + }else if(autoExpand){ + item.expandMenu(); + } + }, + + deactivateActive : function(){ + var a = this.activeItem; + if(a){ + if(a.isFormField){ + + if(a.collapse){ + a.collapse(); + } + }else{ + a.deactivate(); + } + delete this.activeItem; + } + }, + + + tryActivate : function(start, step){ + var items = this.items; + for(var i = start, len = items.length; i >= 0 && i < len; i+= step){ + var item = items.get(i); + if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){ + this.setActiveItem(item, false); + return item; + } + } + return false; + }, + + + onMouseOver : function(e){ + var t = this.findTargetItem(e); + if(t){ + if(t.canActivate && !t.disabled){ + this.setActiveItem(t, true); + } + } + this.over = true; + this.fireEvent('mouseover', this, e, t); + }, + + + onMouseOut : function(e){ + var t = this.findTargetItem(e); + if(t){ + if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){ + this.activeItem.deactivate(); + delete this.activeItem; + } + } + this.over = false; + this.fireEvent('mouseout', this, e, t); + }, + + + onScroll : function(e, t){ + if(e){ + e.stopEvent(); + } + var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top'); + ul.scrollTop += this.scrollIncrement * (top ? -1 : 1); + if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){ + this.onScrollerOut(null, t); + } + }, + + + onScrollerIn : function(e, t){ + var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top'); + if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){ + Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']); + } + }, + + + onScrollerOut : function(e, t){ + Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']); + }, + + + show : function(el, pos, parentMenu){ + if(this.floating){ + this.parentMenu = parentMenu; + if(!this.el){ + this.render(); + this.doLayout(false, true); + } + this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu); + }else{ + Ext.menu.Menu.superclass.show.call(this); + } + }, + + + showAt : function(xy, parentMenu){ + if(this.fireEvent('beforeshow', this) !== false){ + this.parentMenu = parentMenu; + if(!this.el){ + this.render(); + } + if(this.enableScrolling){ + + this.el.setXY(xy); + + xy[1] = this.constrainScroll(xy[1]); + xy = [this.el.adjustForConstraints(xy)[0], xy[1]]; + }else{ + + xy = this.el.adjustForConstraints(xy); + } + this.el.setXY(xy); + this.el.show(); + Ext.menu.Menu.superclass.onShow.call(this); + if(Ext.isIE9m){ + + this.fireEvent('autosize', this); + if(!Ext.isIE8){ + this.el.repaint(); + } + } + this.hidden = false; + this.focus(); + this.fireEvent('show', this); + } + }, + + constrainScroll : function(y){ + var max, full = this.ul.setHeight('auto').getHeight(), + returnY = y, normalY, parentEl, scrollTop, viewHeight; + if(this.floating){ + parentEl = Ext.fly(this.el.dom.parentNode); + scrollTop = parentEl.getScroll().top; + viewHeight = parentEl.getViewSize().height; + + + normalY = y - scrollTop; + max = this.maxHeight ? this.maxHeight : viewHeight - normalY; + if(full > viewHeight) { + max = viewHeight; + + returnY = y - normalY; + } else if(max < full) { + returnY = y - (full - max); + max = full; + } + }else{ + max = this.getHeight(); + } + + if (this.maxHeight){ + max = Math.min(this.maxHeight, max); + } + if(full > max && max > 0){ + this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0); + this.ul.setHeight(this.activeMax); + this.createScrollers(); + this.el.select('.x-menu-scroller').setDisplayed(''); + }else{ + this.ul.setHeight(full); + this.el.select('.x-menu-scroller').setDisplayed('none'); + } + this.ul.dom.scrollTop = 0; + return returnY; + }, + + createScrollers : function(){ + if(!this.scroller){ + this.scroller = { + pos: 0, + top: this.el.insertFirst({ + tag: 'div', + cls: 'x-menu-scroller x-menu-scroller-top', + html: ' ' + }), + bottom: this.el.createChild({ + tag: 'div', + cls: 'x-menu-scroller x-menu-scroller-bottom', + html: ' ' + }) + }; + this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this); + this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, { + listeners: { + click: this.onScroll.createDelegate(this, [null, this.scroller.top], false) + } + }); + this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this); + this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, { + listeners: { + click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false) + } + }); + } + }, + + onLayout : function(){ + if(this.isVisible()){ + if(this.enableScrolling){ + this.constrainScroll(this.el.getTop()); + } + if(this.floating){ + this.el.sync(); + } + } + }, + + focus : function(){ + if(!this.hidden){ + this.doFocus.defer(50, this); + } + }, + + doFocus : function(){ + if(!this.hidden){ + this.focusEl.focus(); + } + }, + + + hide : function(deep){ + if (!this.isDestroyed) { + this.deepHide = deep; + Ext.menu.Menu.superclass.hide.call(this); + delete this.deepHide; + } + }, + + + onHide : function(){ + Ext.menu.Menu.superclass.onHide.call(this); + this.deactivateActive(); + if(this.el && this.floating){ + this.el.hide(); + } + var pm = this.parentMenu; + if(this.deepHide === true && pm){ + if(pm.floating){ + pm.hide(true); + }else{ + pm.deactivateActive(); + } + } + }, + + + lookupComponent : function(c){ + if(Ext.isString(c)){ + c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c); + this.applyDefaults(c); + }else{ + if(Ext.isObject(c)){ + c = this.getMenuItem(c); + }else if(c.tagName || c.el){ + c = new Ext.BoxComponent({ + el: c + }); + } + } + return c; + }, + + applyDefaults : function(c) { + if (!Ext.isString(c)) { + c = Ext.menu.Menu.superclass.applyDefaults.call(this, c); + var d = this.internalDefaults; + if(d){ + if(c.events){ + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + }else{ + Ext.applyIf(c, d); + } + } + } + return c; + }, + + + getMenuItem : function(config) { + config.ownerCt = this; + + if (!config.isXType) { + if (!config.xtype && Ext.isBoolean(config.checked)) { + return new Ext.menu.CheckItem(config); + } + return Ext.create(config, this.defaultType); + } + return config; + }, + + + addSeparator : function() { + return this.add(new Ext.menu.Separator()); + }, + + + addElement : function(el) { + return this.add(new Ext.menu.BaseItem({ + el: el + })); + }, + + + addItem : function(item) { + return this.add(item); + }, + + + addMenuItem : function(config) { + return this.add(this.getMenuItem(config)); + }, + + + addText : function(text){ + return this.add(new Ext.menu.TextItem(text)); + }, + + + onDestroy : function(){ + Ext.EventManager.removeResizeListener(this.hide, this); + var pm = this.parentMenu; + if(pm && pm.activeChild == this){ + delete pm.activeChild; + } + delete this.parentMenu; + Ext.menu.Menu.superclass.onDestroy.call(this); + Ext.menu.MenuMgr.unregister(this); + if(this.keyNav) { + this.keyNav.disable(); + } + var s = this.scroller; + if(s){ + Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom); + } + Ext.destroy( + this.el, + this.focusEl, + this.ul + ); + } +}); + +Ext.reg('menu', Ext.menu.Menu); + + +Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){ + function up(e, m){ + if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){ + m.tryActivate(m.items.length-1, -1); + } + } + function down(e, m){ + if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){ + m.tryActivate(0, 1); + } + } + return { + constructor : function(menu){ + Ext.menu.MenuNav.superclass.constructor.call(this, menu.el); + this.scope = this.menu = menu; + }, + + doRelay : function(e, h){ + var k = e.getKey(); + + if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) { + return false; + } + if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){ + this.menu.tryActivate(0, 1); + return false; + } + return h.call(this.scope || this, e, this.menu); + }, + + tab: function(e, m) { + e.stopEvent(); + if (e.shiftKey) { + up(e, m); + } else { + down(e, m); + } + }, + + up : up, + + down : down, + + right : function(e, m){ + if(m.activeItem){ + m.activeItem.expandMenu(true); + } + }, + + left : function(e, m){ + m.hide(); + if(m.parentMenu && m.parentMenu.activeItem){ + m.parentMenu.activeItem.activate(); + } + }, + + enter : function(e, m){ + if(m.activeItem){ + e.stopPropagation(); + m.activeItem.onClick(e); + m.fireEvent('click', this, m.activeItem); + return true; + } + } + }; +}()); + +Ext.menu.MenuMgr = function(){ + var menus, + active, + map, + groups = {}, + attached = false, + lastShow = new Date(); + + + + function init(){ + menus = {}; + active = new Ext.util.MixedCollection(); + map = Ext.getDoc().addKeyListener(27, hideAll); + map.disable(); + } + + + function hideAll(){ + if(active && active.length > 0){ + var c = active.clone(); + c.each(function(m){ + m.hide(); + }); + return true; + } + return false; + } + + + function onHide(m){ + active.remove(m); + if(active.length < 1){ + map.disable(); + Ext.getDoc().un("mousedown", onMouseDown); + attached = false; + } + } + + + function onShow(m){ + var last = active.last(); + lastShow = new Date(); + active.add(m); + if(!attached){ + map.enable(); + Ext.getDoc().on("mousedown", onMouseDown); + attached = true; + } + if(m.parentMenu){ + m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3); + m.parentMenu.activeChild = m; + }else if(last && !last.isDestroyed && last.isVisible()){ + m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3); + } + } + + + function onBeforeHide(m){ + if(m.activeChild){ + m.activeChild.hide(); + } + if(m.autoHideTimer){ + clearTimeout(m.autoHideTimer); + delete m.autoHideTimer; + } + } + + + function onBeforeShow(m){ + var pm = m.parentMenu; + if(!pm && !m.allowOtherMenus){ + hideAll(); + }else if(pm && pm.activeChild){ + pm.activeChild.hide(); + } + } + + + function onMouseDown(e){ + if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){ + hideAll(); + } + } + + return { + + + hideAll : function(){ + return hideAll(); + }, + + + register : function(menu){ + if(!menus){ + init(); + } + menus[menu.id] = menu; + menu.on({ + beforehide: onBeforeHide, + hide: onHide, + beforeshow: onBeforeShow, + show: onShow + }); + }, + + + get : function(menu){ + if(typeof menu == "string"){ + if(!menus){ + return null; + } + return menus[menu]; + }else if(menu.events){ + return menu; + }else if(typeof menu.length == 'number'){ + return new Ext.menu.Menu({items:menu}); + }else{ + return Ext.create(menu, 'menu'); + } + }, + + + unregister : function(menu){ + delete menus[menu.id]; + menu.un("beforehide", onBeforeHide); + menu.un("hide", onHide); + menu.un("beforeshow", onBeforeShow); + menu.un("show", onShow); + }, + + + registerCheckable : function(menuItem){ + var g = menuItem.group; + if(g){ + if(!groups[g]){ + groups[g] = []; + } + groups[g].push(menuItem); + } + }, + + + unregisterCheckable : function(menuItem){ + var g = menuItem.group; + if(g){ + groups[g].remove(menuItem); + } + }, + + + onCheckChange: function(item, state){ + if(item.group && state){ + var group = groups[item.group], + i = 0, + len = group.length, + current; + + for(; i < len; i++){ + current = group[i]; + if(current != item){ + current.setChecked(false); + } + } + } + }, + + getCheckedItem : function(groupId){ + var g = groups[groupId]; + if(g){ + for(var i = 0, l = g.length; i < l; i++){ + if(g[i].checked){ + return g[i]; + } + } + } + return null; + }, + + setCheckedItem : function(groupId, itemId){ + var g = groups[groupId]; + if(g){ + for(var i = 0, l = g.length; i < l; i++){ + if(g[i].id == itemId){ + g[i].setChecked(true); + } + } + } + return null; + } + }; +}(); + +Ext.menu.BaseItem = Ext.extend(Ext.Component, { + + + + + canActivate : false, + + activeClass : "x-menu-item-active", + + hideOnClick : true, + + clickHideDelay : 1, + + + ctype : "Ext.menu.BaseItem", + + + actionMode : "container", + + initComponent : function(){ + Ext.menu.BaseItem.superclass.initComponent.call(this); + this.addEvents( + + 'click', + + 'activate', + + 'deactivate' + ); + if(this.handler){ + this.on("click", this.handler, this.scope); + } + }, + + + onRender : function(container, position){ + Ext.menu.BaseItem.superclass.onRender.apply(this, arguments); + if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){ + this.parentMenu = this.ownerCt; + }else{ + this.container.addClass('x-menu-list-item'); + this.mon(this.el, { + scope: this, + click: this.onClick, + mouseenter: this.activate, + mouseleave: this.deactivate + }); + } + }, + + + setHandler : function(handler, scope){ + if(this.handler){ + this.un("click", this.handler, this.scope); + } + this.on("click", this.handler = handler, this.scope = scope); + }, + + + onClick : function(e){ + if(!this.disabled && this.fireEvent("click", this, e) !== false + && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){ + this.handleClick(e); + }else{ + e.stopEvent(); + } + }, + + + activate : function(){ + if(this.disabled){ + return false; + } + var li = this.container; + li.addClass(this.activeClass); + this.region = li.getRegion().adjust(2, 2, -2, -2); + this.fireEvent("activate", this); + return true; + }, + + + deactivate : function(){ + this.container.removeClass(this.activeClass); + this.fireEvent("deactivate", this); + }, + + + shouldDeactivate : function(e){ + return !this.region || !this.region.contains(e.getPoint()); + }, + + + handleClick : function(e){ + var pm = this.parentMenu; + if(this.hideOnClick){ + if(pm.floating){ + this.clickHideDelayTimer = pm.hide.defer(this.clickHideDelay, pm, [true]); + }else{ + pm.deactivateActive(); + } + } + }, + + beforeDestroy: function(){ + clearTimeout(this.clickHideDelayTimer); + Ext.menu.BaseItem.superclass.beforeDestroy.call(this); + }, + + + expandMenu : Ext.emptyFn, + + + hideMenu : Ext.emptyFn +}); +Ext.reg('menubaseitem', Ext.menu.BaseItem); +Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, { + + + hideOnClick : false, + + itemCls : "x-menu-text", + + constructor : function(config) { + if (typeof config == 'string') { + config = { + text: config + }; + } + Ext.menu.TextItem.superclass.constructor.call(this, config); + }, + + + onRender : function() { + var s = document.createElement("span"); + s.className = this.itemCls; + s.innerHTML = this.text; + this.el = s; + Ext.menu.TextItem.superclass.onRender.apply(this, arguments); + } +}); +Ext.reg('menutextitem', Ext.menu.TextItem); +Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, { + + itemCls : "x-menu-sep", + + hideOnClick : false, + + + activeClass: '', + + + onRender : function(li){ + var s = document.createElement("span"); + s.className = this.itemCls; + s.innerHTML = " "; + this.el = s; + li.addClass("x-menu-sep-li"); + Ext.menu.Separator.superclass.onRender.apply(this, arguments); + } +}); +Ext.reg('menuseparator', Ext.menu.Separator); +Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, { + + + + + + + + + itemCls : 'x-menu-item', + + canActivate : true, + + showDelay: 200, + + + altText: '', + + + hideDelay: 200, + + + ctype: 'Ext.menu.Item', + + initComponent : function(){ + Ext.menu.Item.superclass.initComponent.call(this); + if(this.menu){ + + + if (Ext.isArray(this.menu)){ + this.menu = { items: this.menu }; + } + + + + if (Ext.isObject(this.menu)){ + this.menu.ownerCt = this; + } + + this.menu = Ext.menu.MenuMgr.get(this.menu); + this.menu.ownerCt = undefined; + } + }, + + + onRender : function(container, position){ + if (!this.itemTpl) { + this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate( + '', + ' target="{hrefTarget}"', + '', + '>', + '{altText}', + '{text}', + '' + ); + } + var a = this.getTemplateArgs(); + this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true); + this.iconEl = this.el.child('img.x-menu-item-icon'); + this.textEl = this.el.child('.x-menu-item-text'); + if(!this.href) { + this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true }); + } + Ext.menu.Item.superclass.onRender.call(this, container, position); + }, + + getTemplateArgs: function() { + return { + id: this.id, + cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''), + href: this.href || '#', + hrefTarget: this.hrefTarget, + icon: this.icon || Ext.BLANK_IMAGE_URL, + iconCls: this.iconCls || '', + text: this.itemText||this.text||' ', + altText: this.altText || '' + }; + }, + + + setText : function(text){ + this.text = text||' '; + if(this.rendered){ + this.textEl.update(this.text); + this.parentMenu.layout.doAutoSize(); + } + }, + + + setIconClass : function(cls){ + var oldCls = this.iconCls; + this.iconCls = cls; + if(this.rendered){ + this.iconEl.replaceClass(oldCls, this.iconCls); + } + }, + + + beforeDestroy: function(){ + clearTimeout(this.showTimer); + clearTimeout(this.hideTimer); + if (this.menu){ + delete this.menu.ownerCt; + this.menu.destroy(); + } + Ext.menu.Item.superclass.beforeDestroy.call(this); + }, + + + handleClick : function(e){ + if(!this.href){ + e.stopEvent(); + } + Ext.menu.Item.superclass.handleClick.apply(this, arguments); + }, + + + activate : function(autoExpand){ + if(Ext.menu.Item.superclass.activate.apply(this, arguments)){ + this.focus(); + if(autoExpand){ + this.expandMenu(); + } + } + return true; + }, + + + shouldDeactivate : function(e){ + if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){ + if(this.menu && this.menu.isVisible()){ + return !this.menu.getEl().getRegion().contains(e.getPoint()); + } + return true; + } + return false; + }, + + + deactivate : function(){ + Ext.menu.Item.superclass.deactivate.apply(this, arguments); + this.hideMenu(); + }, + + + expandMenu : function(autoActivate){ + if(!this.disabled && this.menu){ + clearTimeout(this.hideTimer); + delete this.hideTimer; + if(!this.menu.isVisible() && !this.showTimer){ + this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]); + }else if (this.menu.isVisible() && autoActivate){ + this.menu.tryActivate(0, 1); + } + } + }, + + + deferExpand : function(autoActivate){ + delete this.showTimer; + this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu); + if(autoActivate){ + this.menu.tryActivate(0, 1); + } + }, + + + hideMenu : function(){ + clearTimeout(this.showTimer); + delete this.showTimer; + if(!this.hideTimer && this.menu && this.menu.isVisible()){ + this.hideTimer = this.deferHide.defer(this.hideDelay, this); + } + }, + + + deferHide : function(){ + delete this.hideTimer; + if(this.menu.over){ + this.parentMenu.setActiveItem(this, false); + }else{ + this.menu.hide(); + } + } +}); +Ext.reg('menuitem', Ext.menu.Item); +Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, { + + + itemCls : "x-menu-item x-menu-check-item", + + groupClass : "x-menu-group-item", + + + checked: false, + + + ctype: "Ext.menu.CheckItem", + + initComponent : function(){ + Ext.menu.CheckItem.superclass.initComponent.call(this); + this.addEvents( + + "beforecheckchange" , + + "checkchange" + ); + + if(this.checkHandler){ + this.on('checkchange', this.checkHandler, this.scope); + } + Ext.menu.MenuMgr.registerCheckable(this); + }, + + + onRender : function(c){ + Ext.menu.CheckItem.superclass.onRender.apply(this, arguments); + if(this.group){ + this.el.addClass(this.groupClass); + } + if(this.checked){ + this.checked = false; + this.setChecked(true, true); + } + }, + + + destroy : function(){ + Ext.menu.MenuMgr.unregisterCheckable(this); + Ext.menu.CheckItem.superclass.destroy.apply(this, arguments); + }, + + + setChecked : function(state, suppressEvent){ + var suppress = suppressEvent === true; + if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){ + Ext.menu.MenuMgr.onCheckChange(this, state); + if(this.container){ + this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked"); + } + this.checked = state; + if(!suppress){ + this.fireEvent("checkchange", this, state); + } + } + }, + + + handleClick : function(e){ + if(!this.disabled && !(this.checked && this.group)){ + this.setChecked(!this.checked); + } + Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments); + } +}); +Ext.reg('menucheckitem', Ext.menu.CheckItem); + Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, { + + enableScrolling : false, + + + + hideOnClick : true, + + + pickerId : null, + + + + + cls : 'x-date-menu', + + + + + + initComponent : function(){ + this.on('beforeshow', this.onBeforeShow, this); + if(this.strict = (Ext.isIE7 && Ext.isStrict)){ + this.on('show', this.onShow, this, {single: true, delay: 20}); + } + Ext.apply(this, { + plain: true, + showSeparator: false, + items: this.picker = new Ext.DatePicker(Ext.applyIf({ + internalRender: this.strict || !Ext.isIE9m, + ctCls: 'x-menu-date-item', + id: this.pickerId + }, this.initialConfig)) + }); + this.picker.purgeListeners(); + Ext.menu.DateMenu.superclass.initComponent.call(this); + + this.relayEvents(this.picker, ['select']); + this.on('show', this.picker.focus, this.picker); + this.on('select', this.menuHide, this); + if(this.handler){ + this.on('select', this.handler, this.scope || this); + } + }, + + menuHide : function() { + if(this.hideOnClick){ + this.hide(true); + } + }, + + onBeforeShow : function(){ + if(this.picker){ + this.picker.hideMonthPicker(true); + } + }, + + onShow : function(){ + var el = this.picker.getEl(); + el.setWidth(el.getWidth()); + } + }); + Ext.reg('datemenu', Ext.menu.DateMenu); + + Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, { + + enableScrolling : false, + + + + + hideOnClick : true, + + cls : 'x-color-menu', + + + paletteId : null, + + + + + + + + + + + initComponent : function(){ + Ext.apply(this, { + plain: true, + showSeparator: false, + items: this.palette = new Ext.ColorPalette(Ext.applyIf({ + id: this.paletteId + }, this.initialConfig)) + }); + this.palette.purgeListeners(); + Ext.menu.ColorMenu.superclass.initComponent.call(this); + + this.relayEvents(this.palette, ['select']); + this.on('select', this.menuHide, this); + if(this.handler){ + this.on('select', this.handler, this.scope || this); + } + }, + + menuHide : function(){ + if(this.hideOnClick){ + this.hide(true); + } + } +}); +Ext.reg('colormenu', Ext.menu.ColorMenu); + +Ext.form.Field = Ext.extend(Ext.BoxComponent, { + + + + + + + + + invalidClass : 'x-form-invalid', + + invalidText : 'The value in this field is invalid', + + focusClass : 'x-form-focus', + + + validationEvent : 'keyup', + + validateOnBlur : true, + + validationDelay : 250, + + defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'}, + + fieldClass : 'x-form-field', + + msgTarget : 'qtip', + + msgFx : 'normal', + + readOnly : false, + + disabled : false, + + submitValue: true, + + + isFormField : true, + + + msgDisplay: '', + + + hasFocus : false, + + + initComponent : function(){ + Ext.form.Field.superclass.initComponent.call(this); + this.addEvents( + + 'focus', + + 'blur', + + 'specialkey', + + 'change', + + 'invalid', + + 'valid' + ); + }, + + + getName : function(){ + return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || ''; + }, + + + onRender : function(ct, position){ + if(!this.el){ + var cfg = this.getAutoCreate(); + + if(!cfg.name){ + cfg.name = this.name || this.id; + } + if(this.inputType){ + cfg.type = this.inputType; + } + this.autoEl = cfg; + } + Ext.form.Field.superclass.onRender.call(this, ct, position); + if(this.submitValue === false){ + this.el.dom.removeAttribute('name'); + } + var type = this.el.dom.type; + if(type){ + if(type == 'password'){ + type = 'text'; + } + this.el.addClass('x-form-'+type); + } + if(this.readOnly){ + this.setReadOnly(true); + } + if(this.tabIndex !== undefined){ + this.el.dom.setAttribute('tabIndex', this.tabIndex); + } + + this.el.addClass([this.fieldClass, this.cls]); + }, + + + getItemCt : function(){ + return this.itemCt; + }, + + + initValue : function(){ + if(this.value !== undefined){ + this.setValue(this.value); + }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){ + this.setValue(this.el.dom.value); + } + + this.originalValue = this.getValue(); + }, + + + isDirty : function() { + if(this.disabled || !this.rendered) { + return false; + } + return String(this.getValue()) !== String(this.originalValue); + }, + + + setReadOnly : function(readOnly){ + if(this.rendered){ + this.el.dom.readOnly = readOnly; + } + this.readOnly = readOnly; + }, + + + afterRender : function(){ + Ext.form.Field.superclass.afterRender.call(this); + this.initEvents(); + this.initValue(); + }, + + + fireKey : function(e){ + if(e.isSpecialKey()){ + this.fireEvent('specialkey', this, e); + } + }, + + + reset : function(){ + this.setValue(this.originalValue); + this.clearInvalid(); + }, + + + initEvents : function(){ + this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey, this); + this.mon(this.el, 'focus', this.onFocus, this); + + + + this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null); + }, + + + preFocus: Ext.emptyFn, + + + onFocus : function(){ + this.preFocus(); + if(this.focusClass){ + this.el.addClass(this.focusClass); + } + if(!this.hasFocus){ + this.hasFocus = true; + + this.startValue = this.getValue(); + this.fireEvent('focus', this); + } + }, + + + beforeBlur : Ext.emptyFn, + + + onBlur : function(){ + this.beforeBlur(); + if(this.focusClass){ + this.el.removeClass(this.focusClass); + } + this.hasFocus = false; + if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){ + this.validate(); + } + var v = this.getValue(); + if(String(v) !== String(this.startValue)){ + this.fireEvent('change', this, v, this.startValue); + } + this.fireEvent('blur', this); + this.postBlur(); + }, + + + postBlur : Ext.emptyFn, + + + isValid : function(preventMark){ + if(this.disabled){ + return true; + } + var restore = this.preventMark; + this.preventMark = preventMark === true; + var v = this.validateValue(this.processValue(this.getRawValue()), preventMark); + this.preventMark = restore; + return v; + }, + + + validate : function(){ + if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){ + this.clearInvalid(); + return true; + } + return false; + }, + + + processValue : function(value){ + return value; + }, + + + validateValue : function(value) { + + var error = this.getErrors(value)[0]; + + if (error == undefined) { + return true; + } else { + this.markInvalid(error); + return false; + } + }, + + + getErrors: function() { + return []; + }, + + + getActiveError : function(){ + return this.activeError || ''; + }, + + + markInvalid : function(msg){ + + if (this.rendered && !this.preventMark) { + msg = msg || this.invalidText; + + var mt = this.getMessageHandler(); + if(mt){ + mt.mark(this, msg); + }else if(this.msgTarget){ + this.el.addClass(this.invalidClass); + var t = Ext.getDom(this.msgTarget); + if(t){ + t.innerHTML = msg; + t.style.display = this.msgDisplay; + } + } + } + + this.setActiveError(msg); + }, + + + clearInvalid : function(){ + + if (this.rendered && !this.preventMark) { + this.el.removeClass(this.invalidClass); + var mt = this.getMessageHandler(); + if(mt){ + mt.clear(this); + }else if(this.msgTarget){ + this.el.removeClass(this.invalidClass); + var t = Ext.getDom(this.msgTarget); + if(t){ + t.innerHTML = ''; + t.style.display = 'none'; + } + } + } + + this.unsetActiveError(); + }, + + + setActiveError: function(msg, suppressEvent) { + this.activeError = msg; + if (suppressEvent !== true) this.fireEvent('invalid', this, msg); + }, + + + unsetActiveError: function(suppressEvent) { + delete this.activeError; + if (suppressEvent !== true) this.fireEvent('valid', this); + }, + + + getMessageHandler : function(){ + return Ext.form.MessageTargets[this.msgTarget]; + }, + + + getErrorCt : function(){ + return this.el.findParent('.x-form-element', 5, true) || + this.el.findParent('.x-form-field-wrap', 5, true); + }, + + + alignErrorEl : function(){ + this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20); + }, + + + alignErrorIcon : function(){ + this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]); + }, + + + getRawValue : function(){ + var v = this.rendered ? this.el.getValue() : Ext.value(this.value, ''); + if(v === this.emptyText){ + v = ''; + } + return v; + }, + + + getValue : function(){ + if(!this.rendered) { + return this.value; + } + var v = this.el.getValue(); + if(v === this.emptyText || v === undefined){ + v = ''; + } + return v; + }, + + + setRawValue : function(v){ + return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : ''; + }, + + + setValue : function(v){ + this.value = v; + if(this.rendered){ + this.el.dom.value = (Ext.isEmpty(v) ? '' : v); + this.validate(); + } + return this; + }, + + + append : function(v){ + this.setValue([this.getValue(), v].join('')); + } + + + + + +}); + + +Ext.form.MessageTargets = { + 'qtip' : { + mark: function(field, msg){ + field.el.addClass(field.invalidClass); + field.el.dom.qtip = msg; + field.el.dom.qclass = 'x-form-invalid-tip'; + if(Ext.QuickTips){ + Ext.QuickTips.enable(); + } + }, + clear: function(field){ + field.el.removeClass(field.invalidClass); + field.el.dom.qtip = ''; + } + }, + 'title' : { + mark: function(field, msg){ + field.el.addClass(field.invalidClass); + field.el.dom.title = msg; + }, + clear: function(field){ + field.el.dom.title = ''; + } + }, + 'under' : { + mark: function(field, msg){ + field.el.addClass(field.invalidClass); + if(!field.errorEl){ + var elp = field.getErrorCt(); + if(!elp){ + field.el.dom.title = msg; + return; + } + field.errorEl = elp.createChild({cls:'x-form-invalid-msg'}); + field.on('resize', field.alignErrorEl, field); + field.on('destroy', function(){ + Ext.destroy(this.errorEl); + }, field); + } + field.alignErrorEl(); + field.errorEl.update(msg); + Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field); + }, + clear: function(field){ + field.el.removeClass(field.invalidClass); + if(field.errorEl){ + Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field); + }else{ + field.el.dom.title = ''; + } + } + }, + 'side' : { + mark: function(field, msg){ + field.el.addClass(field.invalidClass); + if(!field.errorIcon){ + var elp = field.getErrorCt(); + + if(!elp){ + field.el.dom.title = msg; + return; + } + field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'}); + if (field.ownerCt) { + field.ownerCt.on('afterlayout', field.alignErrorIcon, field); + field.ownerCt.on('expand', field.alignErrorIcon, field); + } + field.on('resize', field.alignErrorIcon, field); + field.on('destroy', function(){ + Ext.destroy(this.errorIcon); + }, field); + } + field.alignErrorIcon(); + field.errorIcon.dom.qtip = msg; + field.errorIcon.dom.qclass = 'x-form-invalid-tip'; + field.errorIcon.show(); + }, + clear: function(field){ + field.el.removeClass(field.invalidClass); + if(field.errorIcon){ + field.errorIcon.dom.qtip = ''; + field.errorIcon.hide(); + }else{ + field.el.dom.title = ''; + } + } + } +}; + + +Ext.form.Field.msgFx = { + normal : { + show: function(msgEl, f){ + msgEl.setDisplayed('block'); + }, + + hide : function(msgEl, f){ + msgEl.setDisplayed(false).update(''); + } + }, + + slide : { + show: function(msgEl, f){ + msgEl.slideIn('t', {stopFx:true}); + }, + + hide : function(msgEl, f){ + msgEl.slideOut('t', {stopFx:true,useDisplay:true}); + } + }, + + slideRight : { + show: function(msgEl, f){ + msgEl.fixDisplay(); + msgEl.alignTo(f.el, 'tl-tr'); + msgEl.slideIn('l', {stopFx:true}); + }, + + hide : function(msgEl, f){ + msgEl.slideOut('l', {stopFx:true,useDisplay:true}); + } + } +}; +Ext.reg('field', Ext.form.Field); + +Ext.form.TextField = Ext.extend(Ext.form.Field, { + + + + grow : false, + + growMin : 30, + + growMax : 800, + + vtype : null, + + maskRe : null, + + disableKeyFilter : false, + + allowBlank : true, + + minLength : 0, + + maxLength : Number.MAX_VALUE, + + minLengthText : 'The minimum length for this field is {0}', + + maxLengthText : 'The maximum length for this field is {0}', + + selectOnFocus : false, + + blankText : 'This field is required', + + validator : null, + + regex : null, + + regexText : '', + + emptyText : null, + + emptyClass : 'x-form-empty-field', + + + + initComponent : function(){ + Ext.form.TextField.superclass.initComponent.call(this); + this.addEvents( + + 'autosize', + + + 'keydown', + + 'keyup', + + 'keypress' + ); + }, + + + initEvents : function(){ + Ext.form.TextField.superclass.initEvents.call(this); + if(this.validationEvent == 'keyup'){ + this.validationTask = new Ext.util.DelayedTask(this.validate, this); + this.mon(this.el, 'keyup', this.filterValidation, this); + } + else if(this.validationEvent !== false && this.validationEvent != 'blur'){ + this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay}); + } + if(this.selectOnFocus || this.emptyText){ + this.mon(this.el, 'mousedown', this.onMouseDown, this); + + if(this.emptyText){ + this.applyEmptyText(); + } + } + if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){ + this.mon(this.el, 'keypress', this.filterKeys, this); + } + if(this.grow){ + this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50}); + this.mon(this.el, 'click', this.autoSize, this); + } + if(this.enableKeyEvents){ + this.mon(this.el, { + scope: this, + keyup: this.onKeyUp, + keydown: this.onKeyDown, + keypress: this.onKeyPress + }); + } + }, + + onMouseDown: function(e){ + if(!this.hasFocus){ + this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true }); + } + }, + + processValue : function(value){ + if(this.stripCharsRe){ + var newValue = value.replace(this.stripCharsRe, ''); + if(newValue !== value){ + this.setRawValue(newValue); + return newValue; + } + } + return value; + }, + + filterValidation : function(e){ + if(!e.isNavKeyPress()){ + this.validationTask.delay(this.validationDelay); + } + }, + + + onDisable: function(){ + Ext.form.TextField.superclass.onDisable.call(this); + if(Ext.isIE){ + this.el.dom.unselectable = 'on'; + } + }, + + + onEnable: function(){ + Ext.form.TextField.superclass.onEnable.call(this); + if(Ext.isIE){ + this.el.dom.unselectable = ''; + } + }, + + + onKeyUpBuffered : function(e){ + if(this.doAutoSize(e)){ + this.autoSize(); + } + }, + + + doAutoSize : function(e){ + return !e.isNavKeyPress(); + }, + + + onKeyUp : function(e){ + this.fireEvent('keyup', this, e); + }, + + + onKeyDown : function(e){ + this.fireEvent('keydown', this, e); + }, + + + onKeyPress : function(e){ + this.fireEvent('keypress', this, e); + }, + + + reset : function(){ + Ext.form.TextField.superclass.reset.call(this); + this.applyEmptyText(); + }, + + applyEmptyText : function(){ + if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){ + this.setRawValue(this.emptyText); + this.el.addClass(this.emptyClass); + } + }, + + + preFocus : function(){ + var el = this.el, + isEmpty; + if(this.emptyText){ + if(el.dom.value == this.emptyText){ + this.setRawValue(''); + isEmpty = true; + } + el.removeClass(this.emptyClass); + } + if(this.selectOnFocus || isEmpty){ + el.dom.select(); + } + }, + + + postBlur : function(){ + this.applyEmptyText(); + }, + + + filterKeys : function(e){ + if(e.ctrlKey){ + return; + } + var k = e.getKey(); + if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){ + return; + } + var cc = String.fromCharCode(e.getCharCode()); + if(!Ext.isGecko && e.isSpecialKey() && !cc){ + return; + } + if(!this.maskRe.test(cc)){ + e.stopEvent(); + } + }, + + setValue : function(v){ + if(this.emptyText && this.el && !Ext.isEmpty(v)){ + this.el.removeClass(this.emptyClass); + } + Ext.form.TextField.superclass.setValue.apply(this, arguments); + this.applyEmptyText(); + this.autoSize(); + return this; + }, + + + getErrors: function(value) { + var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments); + + value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue()); + + if (Ext.isFunction(this.validator)) { + var msg = this.validator(value); + if (msg !== true) { + errors.push(msg); + } + } + + if (value.length < 1 || value === this.emptyText) { + if (this.allowBlank) { + + return errors; + } else { + errors.push(this.blankText); + } + } + + if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { + errors.push(this.blankText); + } + + if (value.length < this.minLength) { + errors.push(String.format(this.minLengthText, this.minLength)); + } + + if (value.length > this.maxLength) { + errors.push(String.format(this.maxLengthText, this.maxLength)); + } + + if (this.vtype) { + var vt = Ext.form.VTypes; + if(!vt[this.vtype](value, this)){ + errors.push(this.vtypeText || vt[this.vtype +'Text']); + } + } + + if (this.regex && !this.regex.test(value)) { + errors.push(this.regexText); + } + + return errors; + }, + + + selectText : function(start, end){ + var v = this.getRawValue(); + var doFocus = false; + if(v.length > 0){ + start = start === undefined ? 0 : start; + end = end === undefined ? v.length : end; + var d = this.el.dom; + if(d.setSelectionRange){ + d.setSelectionRange(start, end); + }else if(d.createTextRange){ + var range = d.createTextRange(); + range.moveStart('character', start); + range.moveEnd('character', end-v.length); + range.select(); + } + doFocus = Ext.isGecko || Ext.isOpera; + }else{ + doFocus = true; + } + if(doFocus){ + this.focus(); + } + }, + + + autoSize : function(){ + if(!this.grow || !this.rendered){ + return; + } + if(!this.metrics){ + this.metrics = Ext.util.TextMetrics.createInstance(this.el); + } + var el = this.el; + var v = el.dom.value; + var d = document.createElement('div'); + d.appendChild(document.createTextNode(v)); + v = d.innerHTML; + Ext.removeNode(d); + d = null; + v += ' '; + var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin)); + this.el.setWidth(w); + this.fireEvent('autosize', this, w); + }, + + onDestroy: function(){ + if(this.validationTask){ + this.validationTask.cancel(); + this.validationTask = null; + } + Ext.form.TextField.superclass.onDestroy.call(this); + } +}); +Ext.reg('textfield', Ext.form.TextField); + +Ext.form.TriggerField = Ext.extend(Ext.form.TextField, { + + + + defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"}, + + hideTrigger:false, + + editable: true, + + readOnly: false, + + wrapFocusClass: 'x-trigger-wrap-focus', + + autoSize: Ext.emptyFn, + + monitorTab : true, + + deferHeight : true, + + mimicing : false, + + actionMode: 'wrap', + + defaultTriggerWidth: 17, + + + onResize : function(w, h){ + Ext.form.TriggerField.superclass.onResize.call(this, w, h); + var tw = this.getTriggerWidth(); + if(Ext.isNumber(w)){ + this.el.setWidth(w - tw); + } + this.wrap.setWidth(this.el.getWidth() + tw); + }, + + getTriggerWidth: function(){ + var tw = this.trigger.getWidth(); + if(!this.hideTrigger && !this.readOnly && tw === 0){ + tw = this.defaultTriggerWidth; + } + return tw; + }, + + + alignErrorIcon : function(){ + if(this.wrap){ + this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); + } + }, + + + onRender : function(ct, position){ + this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc(); + Ext.form.TriggerField.superclass.onRender.call(this, ct, position); + + this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'}); + this.trigger = this.wrap.createChild(this.triggerConfig || + {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass}); + this.initTrigger(); + if(!this.width){ + this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth()); + } + this.resizeEl = this.positionEl = this.wrap; + }, + + getWidth: function() { + return(this.el.getWidth() + this.trigger.getWidth()); + }, + + updateEditState: function(){ + if(this.rendered){ + if (this.readOnly) { + this.el.dom.readOnly = true; + this.el.addClass('x-trigger-noedit'); + this.mun(this.el, 'click', this.onTriggerClick, this); + this.trigger.setDisplayed(false); + } else { + if (!this.editable) { + this.el.dom.readOnly = true; + this.el.addClass('x-trigger-noedit'); + this.mon(this.el, 'click', this.onTriggerClick, this); + } else { + this.el.dom.readOnly = false; + this.el.removeClass('x-trigger-noedit'); + this.mun(this.el, 'click', this.onTriggerClick, this); + } + this.trigger.setDisplayed(!this.hideTrigger); + } + this.onResize(this.width || this.wrap.getWidth()); + } + }, + + + setHideTrigger: function(hideTrigger){ + if(hideTrigger != this.hideTrigger){ + this.hideTrigger = hideTrigger; + this.updateEditState(); + } + }, + + + setEditable: function(editable){ + if(editable != this.editable){ + this.editable = editable; + this.updateEditState(); + } + }, + + + setReadOnly: function(readOnly){ + if(readOnly != this.readOnly){ + this.readOnly = readOnly; + this.updateEditState(); + } + }, + + afterRender : function(){ + Ext.form.TriggerField.superclass.afterRender.call(this); + this.updateEditState(); + }, + + + initTrigger : function(){ + this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true}); + this.trigger.addClassOnOver('x-form-trigger-over'); + this.trigger.addClassOnClick('x-form-trigger-click'); + }, + + + onDestroy : function(){ + Ext.destroy(this.trigger, this.wrap); + if (this.mimicing){ + this.doc.un('mousedown', this.mimicBlur, this); + } + delete this.doc; + Ext.form.TriggerField.superclass.onDestroy.call(this); + }, + + + onFocus : function(){ + Ext.form.TriggerField.superclass.onFocus.call(this); + if(!this.mimicing){ + this.wrap.addClass(this.wrapFocusClass); + this.mimicing = true; + this.doc.on('mousedown', this.mimicBlur, this, {delay: 10}); + if(this.monitorTab){ + this.on('specialkey', this.checkTab, this); + } + } + }, + + + checkTab : function(me, e){ + if(e.getKey() == e.TAB){ + this.triggerBlur(); + } + }, + + + onBlur : Ext.emptyFn, + + + mimicBlur : function(e){ + if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){ + this.triggerBlur(); + } + }, + + + triggerBlur : function(){ + this.mimicing = false; + this.doc.un('mousedown', this.mimicBlur, this); + if(this.monitorTab && this.el){ + this.un('specialkey', this.checkTab, this); + } + Ext.form.TriggerField.superclass.onBlur.call(this); + if(this.wrap){ + this.wrap.removeClass(this.wrapFocusClass); + } + }, + + beforeBlur : Ext.emptyFn, + + + + validateBlur : function(e){ + return true; + }, + + + onTriggerClick : Ext.emptyFn + + + + +}); + + +Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, { + + + + + initComponent : function(){ + Ext.form.TwinTriggerField.superclass.initComponent.call(this); + + this.triggerConfig = { + tag:'span', cls:'x-form-twin-triggers', cn:[ + {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class}, + {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class} + ]}; + }, + + getTrigger : function(index){ + return this.triggers[index]; + }, + + afterRender: function(){ + Ext.form.TwinTriggerField.superclass.afterRender.call(this); + var triggers = this.triggers, + i = 0, + len = triggers.length; + + for(; i < len; ++i){ + if(this['hideTrigger' + (i + 1)]){ + triggers[i].hide(); + } + + } + }, + + initTrigger : function(){ + var ts = this.trigger.select('.x-form-trigger', true), + triggerField = this; + + ts.each(function(t, all, index){ + var triggerIndex = 'Trigger'+(index+1); + t.hide = function(){ + var w = triggerField.wrap.getWidth(); + this.dom.style.display = 'none'; + triggerField.el.setWidth(w-triggerField.trigger.getWidth()); + triggerField['hidden' + triggerIndex] = true; + }; + t.show = function(){ + var w = triggerField.wrap.getWidth(); + this.dom.style.display = ''; + triggerField.el.setWidth(w-triggerField.trigger.getWidth()); + triggerField['hidden' + triggerIndex] = false; + }; + this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true}); + t.addClassOnOver('x-form-trigger-over'); + t.addClassOnClick('x-form-trigger-click'); + }, this); + this.triggers = ts.elements; + }, + + getTriggerWidth: function(){ + var tw = 0; + Ext.each(this.triggers, function(t, index){ + var triggerIndex = 'Trigger' + (index + 1), + w = t.getWidth(); + if(w === 0 && !this['hidden' + triggerIndex]){ + tw += this.defaultTriggerWidth; + }else{ + tw += w; + } + }, this); + return tw; + }, + + + onDestroy : function() { + Ext.destroy(this.triggers); + Ext.form.TwinTriggerField.superclass.onDestroy.call(this); + }, + + + onTrigger1Click : Ext.emptyFn, + + onTrigger2Click : Ext.emptyFn +}); +Ext.reg('trigger', Ext.form.TriggerField); +Ext.reg('twintrigger', Ext.form.TwinTriggerField); +Ext.form.TextArea = Ext.extend(Ext.form.TextField, { + + growMin : 60, + + growMax: 1000, + growAppend : ' \n ', + + enterIsSpecial : false, + + + preventScrollbars: false, + + + + onRender : function(ct, position){ + if(!this.el){ + this.defaultAutoCreate = { + tag: "textarea", + style:"width:100px;height:60px;", + autocomplete: "off" + }; + } + Ext.form.TextArea.superclass.onRender.call(this, ct, position); + if(this.grow){ + this.textSizeEl = Ext.DomHelper.append(document.body, { + tag: "pre", cls: "x-form-grow-sizer" + }); + if(this.preventScrollbars){ + this.el.setStyle("overflow", "hidden"); + } + this.el.setHeight(this.growMin); + } + }, + + onDestroy : function(){ + Ext.removeNode(this.textSizeEl); + Ext.form.TextArea.superclass.onDestroy.call(this); + }, + + fireKey : function(e){ + if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){ + this.fireEvent("specialkey", this, e); + } + }, + + + doAutoSize : function(e){ + return !e.isNavKeyPress() || e.getKey() == e.ENTER; + }, + + + filterValidation: function(e) { + if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){ + this.validationTask.delay(this.validationDelay); + } + }, + + + autoSize: function(){ + if(!this.grow || !this.textSizeEl){ + return; + } + var el = this.el, + v = Ext.util.Format.htmlEncode(el.dom.value), + ts = this.textSizeEl, + h; + + Ext.fly(ts).setWidth(this.el.getWidth()); + if(v.length < 1){ + v = "  "; + }else{ + v += this.growAppend; + if(Ext.isIE){ + v = v.replace(/\n/g, ' 
    '); + } + } + ts.innerHTML = v; + h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)); + if(h != this.lastHeight){ + this.lastHeight = h; + this.el.setHeight(h); + this.fireEvent("autosize", this, h); + } + } +}); +Ext.reg('textarea', Ext.form.TextArea); +Ext.form.NumberField = Ext.extend(Ext.form.TextField, { + + + + fieldClass: "x-form-field x-form-num-field", + + + allowDecimals : true, + + + decimalSeparator : ".", + + + decimalPrecision : 2, + + + allowNegative : true, + + + minValue : Number.NEGATIVE_INFINITY, + + + maxValue : Number.MAX_VALUE, + + + minText : "The minimum value for this field is {0}", + + + maxText : "The maximum value for this field is {0}", + + + nanText : "{0} is not a valid number", + + + baseChars : "0123456789", + + + autoStripChars: false, + + + initEvents : function() { + var allowed = this.baseChars + ''; + if (this.allowDecimals) { + allowed += this.decimalSeparator; + } + if (this.allowNegative) { + allowed += '-'; + } + allowed = Ext.escapeRe(allowed); + this.maskRe = new RegExp('[' + allowed + ']'); + if (this.autoStripChars) { + this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); + } + + Ext.form.NumberField.superclass.initEvents.call(this); + }, + + + getErrors: function(value) { + var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments); + + value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue()); + + if (value.length < 1) { + return errors; + } + + value = String(value).replace(this.decimalSeparator, "."); + + if(isNaN(value)){ + errors.push(String.format(this.nanText, value)); + } + + var num = this.parseValue(value); + + if (num < this.minValue) { + errors.push(String.format(this.minText, this.minValue)); + } + + if (num > this.maxValue) { + errors.push(String.format(this.maxText, this.maxValue)); + } + + return errors; + }, + + getValue : function() { + return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this))); + }, + + setValue : function(v) { + v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, ".")); + v = this.fixPrecision(v); + v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator); + return Ext.form.NumberField.superclass.setValue.call(this, v); + }, + + + setMinValue : function(value) { + this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY); + }, + + + setMaxValue : function(value) { + this.maxValue = Ext.num(value, Number.MAX_VALUE); + }, + + + parseValue : function(value) { + value = parseFloat(String(value).replace(this.decimalSeparator, ".")); + return isNaN(value) ? '' : value; + }, + + + fixPrecision : function(value) { + var nan = isNaN(value); + + if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) { + return nan ? '' : value; + } + + return parseFloat(parseFloat(value).toFixed(this.decimalPrecision)); + }, + + beforeBlur : function() { + var v = this.parseValue(this.getRawValue()); + + if (!Ext.isEmpty(v)) { + this.setValue(v); + } + } +}); + +Ext.reg('numberfield', Ext.form.NumberField); + +Ext.form.DateField = Ext.extend(Ext.form.TriggerField, { + + format : "m/d/Y", + + altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j", + + disabledDaysText : "Disabled", + + disabledDatesText : "Disabled", + + minText : "The date in this field must be equal to or after {0}", + + maxText : "The date in this field must be equal to or before {0}", + + invalidText : "{0} is not a valid date - it must be in the format {1}", + + triggerClass : 'x-form-date-trigger', + + showToday : true, + + + startDay : 0, + + + + + + + + + defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"}, + + + + initTime: '12', + + initTimeFormat: 'H', + + + safeParse : function(value, format) { + if (Date.formatContainsHourInfo(format)) { + + return Date.parseDate(value, format); + } else { + + var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat); + + if (parsedDate) { + return parsedDate.clearTime(); + } + } + }, + + initComponent : function(){ + Ext.form.DateField.superclass.initComponent.call(this); + + this.addEvents( + + 'select' + ); + + if(Ext.isString(this.minValue)){ + this.minValue = this.parseDate(this.minValue); + } + if(Ext.isString(this.maxValue)){ + this.maxValue = this.parseDate(this.maxValue); + } + this.disabledDatesRE = null; + this.initDisabledDays(); + }, + + initEvents: function() { + Ext.form.DateField.superclass.initEvents.call(this); + this.keyNav = new Ext.KeyNav(this.el, { + "down": function(e) { + this.onTriggerClick(); + }, + scope: this, + forceKeyDown: true + }); + }, + + + + initDisabledDays : function(){ + if(this.disabledDates){ + var dd = this.disabledDates, + len = dd.length - 1, + re = "(?:"; + + Ext.each(dd, function(d, i){ + re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i]; + if(i != len){ + re += '|'; + } + }, this); + this.disabledDatesRE = new RegExp(re + ')'); + } + }, + + + setDisabledDates : function(dd){ + this.disabledDates = dd; + this.initDisabledDays(); + if(this.menu){ + this.menu.picker.setDisabledDates(this.disabledDatesRE); + } + }, + + + setDisabledDays : function(dd){ + this.disabledDays = dd; + if(this.menu){ + this.menu.picker.setDisabledDays(dd); + } + }, + + + setMinValue : function(dt){ + this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt); + if(this.menu){ + this.menu.picker.setMinDate(this.minValue); + } + }, + + + setMaxValue : function(dt){ + this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt); + if(this.menu){ + this.menu.picker.setMaxDate(this.maxValue); + } + }, + + + getErrors: function(value) { + var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments); + + value = this.formatDate(value || this.processValue(this.getRawValue())); + + if (value.length < 1) { + return errors; + } + + var svalue = value; + value = this.parseDate(value); + if (!value) { + errors.push(String.format(this.invalidText, svalue, this.format)); + return errors; + } + + var time = value.getTime(); + if (this.minValue && time < this.minValue.clearTime().getTime()) { + errors.push(String.format(this.minText, this.formatDate(this.minValue))); + } + + if (this.maxValue && time > this.maxValue.clearTime().getTime()) { + errors.push(String.format(this.maxText, this.formatDate(this.maxValue))); + } + + if (this.disabledDays) { + var day = value.getDay(); + + for(var i = 0; i < this.disabledDays.length; i++) { + if (day === this.disabledDays[i]) { + errors.push(this.disabledDaysText); + break; + } + } + } + + var fvalue = this.formatDate(value); + if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) { + errors.push(String.format(this.disabledDatesText, fvalue)); + } + + return errors; + }, + + + + validateBlur : function(){ + return !this.menu || !this.menu.isVisible(); + }, + + + getValue : function(){ + return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || ""; + }, + + + setValue : function(date){ + return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date))); + }, + + + parseDate : function(value) { + if(!value || Ext.isDate(value)){ + return value; + } + + var v = this.safeParse(value, this.format), + af = this.altFormats, + afa = this.altFormatsArray; + + if (!v && af) { + afa = afa || af.split("|"); + + for (var i = 0, len = afa.length; i < len && !v; i++) { + v = this.safeParse(value, afa[i]); + } + } + return v; + }, + + + onDestroy : function(){ + Ext.destroy(this.menu, this.keyNav); + Ext.form.DateField.superclass.onDestroy.call(this); + }, + + + formatDate : function(date){ + return Ext.isDate(date) ? date.dateFormat(this.format) : date; + }, + + + + + onTriggerClick : function(){ + if(this.disabled){ + return; + } + if(this.menu == null){ + this.menu = new Ext.menu.DateMenu({ + hideOnClick: false, + focusOnSelect: false + }); + } + this.onFocus(); + Ext.apply(this.menu.picker, { + minDate : this.minValue, + maxDate : this.maxValue, + disabledDatesRE : this.disabledDatesRE, + disabledDatesText : this.disabledDatesText, + disabledDays : this.disabledDays, + disabledDaysText : this.disabledDaysText, + format : this.format, + showToday : this.showToday, + startDay: this.startDay, + minText : String.format(this.minText, this.formatDate(this.minValue)), + maxText : String.format(this.maxText, this.formatDate(this.maxValue)) + }); + this.menu.picker.setValue(this.getValue() || new Date()); + this.menu.show(this.el, "tl-bl?"); + this.menuEvents('on'); + }, + + + menuEvents: function(method){ + this.menu[method]('select', this.onSelect, this); + this.menu[method]('hide', this.onMenuHide, this); + this.menu[method]('show', this.onFocus, this); + }, + + onSelect: function(m, d){ + this.setValue(d); + this.fireEvent('select', this, d); + this.menu.hide(); + }, + + onMenuHide: function(){ + this.focus(false, 60); + this.menuEvents('un'); + }, + + + beforeBlur : function(){ + var v = this.parseDate(this.getRawValue()); + if(v){ + this.setValue(v); + } + } + + + + + +}); +Ext.reg('datefield', Ext.form.DateField); + +Ext.form.DisplayField = Ext.extend(Ext.form.Field, { + validationEvent : false, + validateOnBlur : false, + defaultAutoCreate : {tag: "div"}, + + fieldClass : "x-form-display-field", + + htmlEncode: false, + + + initEvents : Ext.emptyFn, + + isValid : function(){ + return true; + }, + + validate : function(){ + return true; + }, + + getRawValue : function(){ + var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, ''); + if(v === this.emptyText){ + v = ''; + } + if(this.htmlEncode){ + v = Ext.util.Format.htmlDecode(v); + } + return v; + }, + + getValue : function(){ + return this.getRawValue(); + }, + + getName: function() { + return this.name; + }, + + setRawValue : function(v){ + if(this.htmlEncode){ + v = Ext.util.Format.htmlEncode(v); + } + return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v); + }, + + setValue : function(v){ + this.setRawValue(v); + return this; + } + + + + + + +}); + +Ext.reg('displayfield', Ext.form.DisplayField); + +Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, { + + + + + + + + defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"}, + + + + + + + + listClass : '', + + selectedClass : 'x-combo-selected', + + listEmptyText: '', + + triggerClass : 'x-form-arrow-trigger', + + shadow : 'sides', + + listAlign : 'tl-bl?', + + maxHeight : 300, + + minHeight : 90, + + triggerAction : 'query', + + minChars : 4, + + autoSelect : true, + + typeAhead : false, + + queryDelay : 500, + + pageSize : 0, + + selectOnFocus : false, + + queryParam : 'query', + + loadingText : 'Loading...', + + resizable : false, + + handleHeight : 8, + + allQuery: '', + + mode: 'remote', + + minListWidth : 70, + + forceSelection : false, + + typeAheadDelay : 250, + + + + lazyInit : true, + + + clearFilterOnReset : true, + + + submitValue: undefined, + + + + + initComponent : function(){ + Ext.form.ComboBox.superclass.initComponent.call(this); + this.addEvents( + + 'expand', + + 'collapse', + + + 'beforeselect', + + 'select', + + 'beforequery' + ); + if(this.transform){ + var s = Ext.getDom(this.transform); + if(!this.hiddenName){ + this.hiddenName = s.name; + } + if(!this.store){ + this.mode = 'local'; + var d = [], opts = s.options; + for(var i = 0, len = opts.length;i < len; i++){ + var o = opts[i], + value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text; + if(o.selected && Ext.isEmpty(this.value, true)) { + this.value = value; + } + d.push([value, o.text]); + } + this.store = new Ext.data.ArrayStore({ + idIndex: 0, + fields: ['value', 'text'], + data : d, + autoDestroy: true + }); + this.valueField = 'value'; + this.displayField = 'text'; + } + s.name = Ext.id(); + if(!this.lazyRender){ + this.target = true; + this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate); + this.render(this.el.parentNode, s); + } + Ext.removeNode(s); + } + + else if(this.store){ + this.store = Ext.StoreMgr.lookup(this.store); + if(this.store.autoCreated){ + this.displayField = this.valueField = 'field1'; + if(!this.store.expandData){ + this.displayField = 'field2'; + } + this.mode = 'local'; + } + } + + this.selectedIndex = -1; + if(this.mode == 'local'){ + if(!Ext.isDefined(this.initialConfig.queryDelay)){ + this.queryDelay = 10; + } + if(!Ext.isDefined(this.initialConfig.minChars)){ + this.minChars = 0; + } + } + }, + + + onRender : function(ct, position){ + if(this.hiddenName && !Ext.isDefined(this.submitValue)){ + this.submitValue = false; + } + Ext.form.ComboBox.superclass.onRender.call(this, ct, position); + if(this.hiddenName){ + this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, + id: (this.hiddenId || Ext.id())}, 'before', true); + + } + if(Ext.isGecko){ + this.el.dom.setAttribute('autocomplete', 'off'); + } + + if(!this.lazyInit){ + this.initList(); + }else{ + this.on('focus', this.initList, this, {single: true}); + } + }, + + + initValue : function(){ + Ext.form.ComboBox.superclass.initValue.call(this); + if(this.hiddenField){ + this.hiddenField.value = + Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, ''); + } + }, + + getParentZIndex : function(){ + var zindex; + if (this.ownerCt){ + this.findParentBy(function(ct){ + zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10); + return !!zindex; + }); + } + return zindex; + }, + + getZIndex : function(listParent){ + listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody()); + var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10); + if(!zindex){ + zindex = this.getParentZIndex(); + } + return (zindex || 12000) + 5; + }, + + + initList : function(){ + if(!this.list){ + var cls = 'x-combo-list', + listParent = Ext.getDom(this.getListParent() || Ext.getBody()); + + this.list = new Ext.Layer({ + parentEl: listParent, + shadow: this.shadow, + cls: [cls, this.listClass].join(' '), + constrain:false, + zindex: this.getZIndex(listParent) + }); + + var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth); + this.list.setSize(lw, 0); + this.list.swallowEvent('mousewheel'); + this.assetHeight = 0; + if(this.syncFont !== false){ + this.list.setStyle('font-size', this.el.getStyle('font-size')); + } + if(this.title){ + this.header = this.list.createChild({cls:cls+'-hd', html: this.title}); + this.assetHeight += this.header.getHeight(); + } + + this.innerList = this.list.createChild({cls:cls+'-inner'}); + this.mon(this.innerList, 'mouseover', this.onViewOver, this); + this.mon(this.innerList, 'mousemove', this.onViewMove, this); + this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); + + if(this.pageSize){ + this.footer = this.list.createChild({cls:cls+'-ft'}); + this.pageTb = new Ext.PagingToolbar({ + store: this.store, + pageSize: this.pageSize, + renderTo:this.footer + }); + this.assetHeight += this.footer.getHeight(); + } + + if(!this.tpl){ + + this.tpl = '
    {' + this.displayField + '}
    '; + + } + + + this.view = new Ext.DataView({ + applyTo: this.innerList, + tpl: this.tpl, + singleSelect: true, + selectedClass: this.selectedClass, + itemSelector: this.itemSelector || '.' + cls + '-item', + emptyText: this.listEmptyText, + deferEmptyText: false + }); + + this.mon(this.view, { + containerclick : this.onViewClick, + click : this.onViewClick, + scope :this + }); + + this.bindStore(this.store, true); + + if(this.resizable){ + this.resizer = new Ext.Resizable(this.list, { + pinned:true, handles:'se' + }); + this.mon(this.resizer, 'resize', function(r, w, h){ + this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight; + this.listWidth = w; + this.innerList.setWidth(w - this.list.getFrameWidth('lr')); + this.restrictHeight(); + }, this); + + this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px'); + } + } + }, + + + getListParent : function() { + return document.body; + }, + + + getStore : function(){ + return this.store; + }, + + + bindStore : function(store, initial){ + if(this.store && !initial){ + if(this.store !== store && this.store.autoDestroy){ + this.store.destroy(); + }else{ + this.store.un('beforeload', this.onBeforeLoad, this); + this.store.un('load', this.onLoad, this); + this.store.un('exception', this.collapse, this); + } + if(!store){ + this.store = null; + if(this.view){ + this.view.bindStore(null); + } + if(this.pageTb){ + this.pageTb.bindStore(null); + } + } + } + if(store){ + if(!initial) { + this.lastQuery = null; + if(this.pageTb) { + this.pageTb.bindStore(store); + } + } + + this.store = Ext.StoreMgr.lookup(store); + this.store.on({ + scope: this, + beforeload: this.onBeforeLoad, + load: this.onLoad, + exception: this.collapse + }); + + if(this.view){ + this.view.bindStore(store); + } + } + }, + + reset : function(){ + if(this.clearFilterOnReset && this.mode == 'local'){ + this.store.clearFilter(); + } + Ext.form.ComboBox.superclass.reset.call(this); + }, + + + initEvents : function(){ + Ext.form.ComboBox.superclass.initEvents.call(this); + + + this.keyNav = new Ext.KeyNav(this.el, { + "up" : function(e){ + this.inKeyMode = true; + this.selectPrev(); + }, + + "down" : function(e){ + if(!this.isExpanded()){ + this.onTriggerClick(); + }else{ + this.inKeyMode = true; + this.selectNext(); + } + }, + + "enter" : function(e){ + this.onViewClick(); + }, + + "esc" : function(e){ + this.collapse(); + }, + + "tab" : function(e){ + if (this.forceSelection === true) { + this.collapse(); + } else { + this.onViewClick(false); + } + return true; + }, + + scope : this, + + doRelay : function(e, h, hname){ + if(hname == 'down' || this.scope.isExpanded()){ + + var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments); + if((((Ext.isIE9 && Ext.isStrict) || Ext.isIE10p) || !Ext.isIE) && Ext.EventManager.useKeydown){ + + this.scope.fireKey(e); + } + return relay; + } + return true; + }, + + forceKeyDown : true, + defaultEventAction: 'stopEvent' + }); + this.queryDelay = Math.max(this.queryDelay || 10, + this.mode == 'local' ? 10 : 250); + this.dqTask = new Ext.util.DelayedTask(this.initQuery, this); + if(this.typeAhead){ + this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this); + } + if(!this.enableKeyEvents){ + this.mon(this.el, 'keyup', this.onKeyUp, this); + } + }, + + + + onDestroy : function(){ + if (this.dqTask){ + this.dqTask.cancel(); + this.dqTask = null; + } + this.bindStore(null); + Ext.destroy( + this.resizer, + this.view, + this.pageTb, + this.list + ); + Ext.destroyMembers(this, 'hiddenField'); + Ext.form.ComboBox.superclass.onDestroy.call(this); + }, + + + fireKey : function(e){ + if (!this.isExpanded()) { + Ext.form.ComboBox.superclass.fireKey.call(this, e); + } + }, + + + onResize : function(w, h){ + Ext.form.ComboBox.superclass.onResize.apply(this, arguments); + if(!isNaN(w) && this.isVisible() && this.list){ + this.doResize(w); + }else{ + this.bufferSize = w; + } + }, + + doResize: function(w){ + if(!Ext.isDefined(this.listWidth)){ + var lw = Math.max(w, this.minListWidth); + this.list.setWidth(lw); + this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); + } + }, + + + onEnable : function(){ + Ext.form.ComboBox.superclass.onEnable.apply(this, arguments); + if(this.hiddenField){ + this.hiddenField.disabled = false; + } + }, + + + onDisable : function(){ + Ext.form.ComboBox.superclass.onDisable.apply(this, arguments); + if(this.hiddenField){ + this.hiddenField.disabled = true; + } + }, + + + onBeforeLoad : function(){ + if(!this.hasFocus){ + return; + } + this.innerList.update(this.loadingText ? + '
    '+this.loadingText+'
    ' : ''); + this.restrictHeight(); + this.selectedIndex = -1; + }, + + + onLoad : function(){ + if(!this.hasFocus){ + return; + } + if(this.store.getCount() > 0 || this.listEmptyText){ + this.expand(); + this.restrictHeight(); + if(this.lastQuery == this.allQuery){ + if(this.editable){ + this.el.dom.select(); + } + + if(this.autoSelect !== false && !this.selectByValue(this.value, true)){ + this.select(0, true); + } + }else{ + if(this.autoSelect !== false){ + this.selectNext(); + } + if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){ + this.taTask.delay(this.typeAheadDelay); + } + } + }else{ + this.collapse(); + } + + }, + + + onTypeAhead : function(){ + if(this.store.getCount() > 0){ + var r = this.store.getAt(0); + var newValue = r.data[this.displayField]; + var len = newValue.length; + var selStart = this.getRawValue().length; + if(selStart != len){ + this.setRawValue(newValue); + this.selectText(selStart, newValue.length); + } + } + }, + + + assertValue : function(){ + var val = this.getRawValue(), + rec; + + if(this.valueField && Ext.isDefined(this.value)){ + rec = this.findRecord(this.valueField, this.value); + } + if(!rec || rec.get(this.displayField) != val){ + rec = this.findRecord(this.displayField, val); + } + if(!rec && this.forceSelection){ + if(val.length > 0 && val != this.emptyText){ + this.el.dom.value = Ext.value(this.lastSelectionText, ''); + this.applyEmptyText(); + }else{ + this.clearValue(); + } + }else{ + if(rec && this.valueField){ + + + + if (this.value == val){ + return; + } + val = rec.get(this.valueField || this.displayField); + } + this.setValue(val); + } + }, + + + onSelect : function(record, index){ + if(this.fireEvent('beforeselect', this, record, index) !== false){ + this.setValue(record.data[this.valueField || this.displayField]); + this.collapse(); + this.fireEvent('select', this, record, index); + } + }, + + + getName: function(){ + var hf = this.hiddenField; + return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this); + }, + + + getValue : function(){ + if(this.valueField){ + return Ext.isDefined(this.value) ? this.value : ''; + }else{ + return Ext.form.ComboBox.superclass.getValue.call(this); + } + }, + + + clearValue : function(){ + if(this.hiddenField){ + this.hiddenField.value = ''; + } + this.setRawValue(''); + this.lastSelectionText = ''; + this.applyEmptyText(); + this.value = ''; + }, + + + setValue : function(v){ + var text = v; + if(this.valueField){ + var r = this.findRecord(this.valueField, v); + if(r){ + text = r.data[this.displayField]; + }else if(Ext.isDefined(this.valueNotFoundText)){ + text = this.valueNotFoundText; + } + } + this.lastSelectionText = text; + if(this.hiddenField){ + this.hiddenField.value = Ext.value(v, ''); + } + Ext.form.ComboBox.superclass.setValue.call(this, text); + this.value = v; + return this; + }, + + + findRecord : function(prop, value){ + var record; + if(this.store.getCount() > 0){ + this.store.each(function(r){ + if(r.data[prop] == value){ + record = r; + return false; + } + }); + } + return record; + }, + + + onViewMove : function(e, t){ + this.inKeyMode = false; + }, + + + onViewOver : function(e, t){ + if(this.inKeyMode){ + return; + } + var item = this.view.findItemFromChild(t); + if(item){ + var index = this.view.indexOf(item); + this.select(index, false); + } + }, + + + onViewClick : function(doFocus){ + var index = this.view.getSelectedIndexes()[0], + s = this.store, + r = s.getAt(index); + if(r){ + this.onSelect(r, index); + }else { + this.collapse(); + } + if(doFocus !== false){ + this.el.focus(); + } + }, + + + + restrictHeight : function(){ + this.innerList.dom.style.height = ''; + var inner = this.innerList.dom, + pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight, + h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight), + ha = this.getPosition()[1]-Ext.getBody().getScroll().top, + hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height, + space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5; + + h = Math.min(h, space, this.maxHeight); + + this.innerList.setHeight(h); + this.list.beginUpdate(); + this.list.setHeight(h+pad); + this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign)); + this.list.endUpdate(); + }, + + + isExpanded : function(){ + return this.list && this.list.isVisible(); + }, + + + selectByValue : function(v, scrollIntoView){ + if(!Ext.isEmpty(v, true)){ + var r = this.findRecord(this.valueField || this.displayField, v); + if(r){ + this.select(this.store.indexOf(r), scrollIntoView); + return true; + } + } + return false; + }, + + + select : function(index, scrollIntoView){ + this.selectedIndex = index; + this.view.select(index); + if(scrollIntoView !== false){ + var el = this.view.getNode(index); + if(el){ + this.innerList.scrollChildIntoView(el, false); + } + } + + }, + + + selectNext : function(){ + var ct = this.store.getCount(); + if(ct > 0){ + if(this.selectedIndex == -1){ + this.select(0); + }else if(this.selectedIndex < ct-1){ + this.select(this.selectedIndex+1); + } + } + }, + + + selectPrev : function(){ + var ct = this.store.getCount(); + if(ct > 0){ + if(this.selectedIndex == -1){ + this.select(0); + }else if(this.selectedIndex !== 0){ + this.select(this.selectedIndex-1); + } + } + }, + + + onKeyUp : function(e){ + var k = e.getKey(); + if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){ + + this.lastKey = k; + this.dqTask.delay(this.queryDelay); + } + Ext.form.ComboBox.superclass.onKeyUp.call(this, e); + }, + + + validateBlur : function(){ + return !this.list || !this.list.isVisible(); + }, + + + initQuery : function(){ + this.doQuery(this.getRawValue()); + }, + + + beforeBlur : function(){ + this.assertValue(); + }, + + + postBlur : function(){ + Ext.form.ComboBox.superclass.postBlur.call(this); + this.collapse(); + this.inKeyMode = false; + }, + + + doQuery : function(q, forceAll){ + q = Ext.isEmpty(q) ? '' : q; + var qe = { + query: q, + forceAll: forceAll, + combo: this, + cancel:false + }; + if(this.fireEvent('beforequery', qe)===false || qe.cancel){ + return false; + } + q = qe.query; + forceAll = qe.forceAll; + if(forceAll === true || (q.length >= this.minChars)){ + if(this.lastQuery !== q){ + this.lastQuery = q; + if(this.mode == 'local'){ + this.selectedIndex = -1; + if(forceAll){ + this.store.clearFilter(); + }else{ + this.store.filter(this.displayField, q); + } + this.onLoad(); + }else{ + this.store.baseParams[this.queryParam] = q; + this.store.load({ + params: this.getParams(q) + }); + this.expand(); + } + }else{ + this.selectedIndex = -1; + this.onLoad(); + } + } + }, + + + getParams : function(q){ + var params = {}, + paramNames = this.store.paramNames; + if(this.pageSize){ + params[paramNames.start] = 0; + params[paramNames.limit] = this.pageSize; + } + return params; + }, + + + collapse : function(){ + if(!this.isExpanded()){ + return; + } + this.list.hide(); + Ext.getDoc().un('mousewheel', this.collapseIf, this); + Ext.getDoc().un('mousedown', this.collapseIf, this); + this.fireEvent('collapse', this); + }, + + + collapseIf : function(e){ + if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){ + this.collapse(); + } + }, + + + expand : function(){ + if(this.isExpanded() || !this.hasFocus){ + return; + } + + if(this.title || this.pageSize){ + this.assetHeight = 0; + if(this.title){ + this.assetHeight += this.header.getHeight(); + } + if(this.pageSize){ + this.assetHeight += this.footer.getHeight(); + } + } + + if(this.bufferSize){ + this.doResize(this.bufferSize); + delete this.bufferSize; + } + this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign)); + + + this.list.setZIndex(this.getZIndex()); + this.list.show(); + if(Ext.isGecko2){ + this.innerList.setOverflow('auto'); + } + this.mon(Ext.getDoc(), { + scope: this, + mousewheel: this.collapseIf, + mousedown: this.collapseIf + }); + this.fireEvent('expand', this); + }, + + + + + onTriggerClick : function(){ + if(this.readOnly || this.disabled){ + return; + } + if(this.isExpanded()){ + this.collapse(); + this.el.focus(); + }else { + this.onFocus({}); + if(this.triggerAction == 'all') { + this.doQuery(this.allQuery, true); + } else { + this.doQuery(this.getRawValue()); + } + this.el.focus(); + } + } + + + + + + +}); +Ext.reg('combo', Ext.form.ComboBox); + +Ext.form.Checkbox = Ext.extend(Ext.form.Field, { + + focusClass : undefined, + + fieldClass : 'x-form-field', + + checked : false, + + boxLabel: ' ', + + defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'}, + + + + + + actionMode : 'wrap', + + + initComponent : function(){ + Ext.form.Checkbox.superclass.initComponent.call(this); + this.addEvents( + + 'check' + ); + }, + + + onResize : function(){ + Ext.form.Checkbox.superclass.onResize.apply(this, arguments); + if(!this.boxLabel && !this.fieldLabel){ + this.el.alignTo(this.wrap, 'c-c'); + } + }, + + + initEvents : function(){ + Ext.form.Checkbox.superclass.initEvents.call(this); + this.mon(this.el, { + scope: this, + click: this.onClick, + change: this.onClick + }); + }, + + + markInvalid : Ext.emptyFn, + + clearInvalid : Ext.emptyFn, + + + onRender : function(ct, position){ + Ext.form.Checkbox.superclass.onRender.call(this, ct, position); + if(this.inputValue !== undefined){ + this.el.dom.value = this.inputValue; + } + this.wrap = this.el.wrap({cls: 'x-form-check-wrap'}); + if(this.boxLabel){ + this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel}); + } + if(this.checked){ + this.setValue(true); + }else{ + this.checked = this.el.dom.checked; + } + + if (Ext.isIEQuirks) { + this.wrap.repaint(); + } + this.resizeEl = this.positionEl = this.wrap; + }, + + + onDestroy : function(){ + Ext.destroy(this.wrap); + Ext.form.Checkbox.superclass.onDestroy.call(this); + }, + + + initValue : function() { + this.originalValue = this.getValue(); + }, + + + getValue : function(){ + if(this.rendered){ + return this.el.dom.checked; + } + return this.checked; + }, + + + onClick : function(){ + if(this.el.dom.checked != this.checked){ + this.setValue(this.el.dom.checked); + } + }, + + + setValue : function(v){ + var checked = this.checked, + inputVal = this.inputValue; + + if (v === false) { + this.checked = false; + } else { + this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on')); + } + + if(this.rendered){ + this.el.dom.checked = this.checked; + this.el.dom.defaultChecked = this.checked; + } + if(checked != this.checked){ + this.fireEvent('check', this, this.checked); + if(this.handler){ + this.handler.call(this.scope || this, this, this.checked); + } + } + return this; + } +}); +Ext.reg('checkbox', Ext.form.Checkbox); + +Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, { + + + columns : 'auto', + + vertical : false, + + allowBlank : true, + + blankText : "You must select at least one item in this group", + + + defaultType : 'checkbox', + + + groupCls : 'x-form-check-group', + + + initComponent: function(){ + this.addEvents( + + 'change' + ); + this.on('change', this.validate, this); + Ext.form.CheckboxGroup.superclass.initComponent.call(this); + }, + + + onRender : function(ct, position){ + if(!this.el){ + var panelCfg = { + autoEl: { + id: this.id + }, + cls: this.groupCls, + layout: 'column', + renderTo: ct, + bufferResize: false + }; + var colCfg = { + xtype: 'container', + defaultType: this.defaultType, + layout: 'form', + defaults: { + hideLabel: true, + anchor: '100%' + } + }; + + if(this.items[0].items){ + + + + Ext.apply(panelCfg, { + layoutConfig: {columns: this.items.length}, + defaults: this.defaults, + items: this.items + }); + for(var i=0, len=this.items.length; i0 && i%rows==0){ + ri++; + } + if(this.items[i].fieldLabel){ + this.items[i].hideLabel = false; + } + cols[ri].items.push(this.items[i]); + }; + }else{ + for(var i=0, len=this.items.length; i -1){ + item.setValue(true); + } + }); + }, + + + getBox : function(id){ + var box = null; + this.eachItem(function(f){ + if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){ + box = f; + return false; + } + }); + return box; + }, + + + getValue : function(){ + var out = []; + this.eachItem(function(item){ + if(item.checked){ + out.push(item); + } + }); + return out; + }, + + + eachItem: function(fn, scope) { + if(this.items && this.items.each){ + this.items.each(fn, scope || this); + } + }, + + + + + getRawValue : Ext.emptyFn, + + + setRawValue : Ext.emptyFn + +}); + +Ext.reg('checkboxgroup', Ext.form.CheckboxGroup); + +Ext.form.CompositeField = Ext.extend(Ext.form.Field, { + + + defaultMargins: '0 5 0 0', + + + skipLastItemMargin: true, + + + isComposite: true, + + + combineErrors: true, + + + labelConnector: ', ', + + + + + + initComponent: function() { + var labels = [], + items = this.items, + item; + + for (var i=0, j = items.length; i < j; i++) { + item = items[i]; + + if (!Ext.isEmpty(item.ref)){ + item.ref = '../' + item.ref; + } + + labels.push(item.fieldLabel); + + + Ext.applyIf(item, this.defaults); + + + if (!(i == j - 1 && this.skipLastItemMargin)) { + Ext.applyIf(item, {margins: this.defaultMargins}); + } + } + + this.fieldLabel = this.fieldLabel || this.buildLabel(labels); + + + this.fieldErrors = new Ext.util.MixedCollection(true, function(item) { + return item.field; + }); + + this.fieldErrors.on({ + scope : this, + add : this.updateInvalidMark, + remove : this.updateInvalidMark, + replace: this.updateInvalidMark + }); + + Ext.form.CompositeField.superclass.initComponent.apply(this, arguments); + + this.innerCt = new Ext.Container({ + layout : 'hbox', + items : this.items, + cls : 'x-form-composite', + defaultMargins: '0 3 0 0', + ownerCt: this + }); + delete this.innerCt.ownerCt; + + var fields = this.innerCt.findBy(function(c) { + return c.isFormField; + }, this); + + + this.items = new Ext.util.MixedCollection(); + this.items.addAll(fields); + + }, + + + onRender: function(ct, position) { + if (!this.el) { + + var innerCt = this.innerCt; + innerCt.render(ct); + this.innerCt.ownerCt = this; + + this.el = innerCt.getEl(); + + + + if (this.combineErrors) { + this.eachItem(function(field) { + Ext.apply(field, { + markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0), + clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0) + }); + }); + } + + + var l = this.el.parent().parent().child('label', true); + if (l) { + l.setAttribute('for', this.items.items[0].id); + } + } + + Ext.form.CompositeField.superclass.onRender.apply(this, arguments); + }, + + + onFieldMarkInvalid: function(field, message) { + var name = field.getName(), + error = { + field: name, + errorName: field.fieldLabel || name, + error: message + }; + + this.fieldErrors.replace(name, error); + + if (!field.preventMark) { + field.el.addClass(field.invalidClass); + } + }, + + + onFieldClearInvalid: function(field) { + this.fieldErrors.removeKey(field.getName()); + + field.el.removeClass(field.invalidClass); + }, + + + updateInvalidMark: function() { + var ieStrict = Ext.isIE6 && Ext.isStrict; + + if (this.fieldErrors.length == 0) { + this.clearInvalid(); + + + if (ieStrict) { + this.clearInvalid.defer(50, this); + } + } else { + var message = this.buildCombinedErrorMessage(this.fieldErrors.items); + + this.sortErrors(); + this.markInvalid(message); + + + if (ieStrict) { + this.markInvalid(message); + } + } + }, + + + validateValue: function(value, preventMark) { + var valid = true; + + this.eachItem(function(field) { + if (!field.isValid(preventMark)) { + valid = false; + } + }); + + return valid; + }, + + + buildCombinedErrorMessage: function(errors) { + var combined = [], + error; + + for (var i = 0, j = errors.length; i < j; i++) { + error = errors[i]; + + combined.push(String.format("{0}: {1}", error.errorName, error.error)); + } + + return combined.join("
    "); + }, + + + sortErrors: function() { + var fields = this.items; + + this.fieldErrors.sort("ASC", function(a, b) { + var findByName = function(key) { + return function(field) { + return field.getName() == key; + }; + }; + + var aIndex = fields.findIndexBy(findByName(a.field)), + bIndex = fields.findIndexBy(findByName(b.field)); + + return aIndex < bIndex ? -1 : 1; + }); + }, + + + reset: function() { + this.eachItem(function(item) { + item.reset(); + }); + + + + (function() { + this.clearInvalid(); + }).defer(50, this); + }, + + + clearInvalidChildren: function() { + this.eachItem(function(item) { + item.clearInvalid(); + }); + }, + + + buildLabel: function(segments) { + return Ext.clean(segments).join(this.labelConnector); + }, + + + isDirty: function(){ + + if (this.disabled || !this.rendered) { + return false; + } + + var dirty = false; + this.eachItem(function(item){ + if(item.isDirty()){ + dirty = true; + return false; + } + }); + return dirty; + }, + + + eachItem: function(fn, scope) { + if(this.items && this.items.each){ + this.items.each(fn, scope || this); + } + }, + + + onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) { + var innerCt = this.innerCt; + + if (this.rendered && innerCt.rendered) { + innerCt.setSize(adjWidth, adjHeight); + } + + Ext.form.CompositeField.superclass.onResize.apply(this, arguments); + }, + + + doLayout: function(shallow, force) { + if (this.rendered) { + var innerCt = this.innerCt; + + innerCt.forceLayout = this.ownerCt.forceLayout; + innerCt.doLayout(shallow, force); + } + }, + + + beforeDestroy: function(){ + Ext.destroy(this.innerCt); + + Ext.form.CompositeField.superclass.beforeDestroy.call(this); + }, + + + setReadOnly : function(readOnly) { + if (readOnly == undefined) { + readOnly = true; + } + readOnly = !!readOnly; + + if(this.rendered){ + this.eachItem(function(item){ + item.setReadOnly(readOnly); + }); + } + this.readOnly = readOnly; + }, + + onShow : function() { + Ext.form.CompositeField.superclass.onShow.call(this); + this.doLayout(); + }, + + + onDisable : function(){ + this.eachItem(function(item){ + item.disable(); + }); + }, + + + onEnable : function(){ + this.eachItem(function(item){ + item.enable(); + }); + } +}); + +Ext.reg('compositefield', Ext.form.CompositeField); +Ext.form.Radio = Ext.extend(Ext.form.Checkbox, { + inputType: 'radio', + + + markInvalid : Ext.emptyFn, + + clearInvalid : Ext.emptyFn, + + + getGroupValue : function(){ + var p = this.el.up('form') || Ext.getBody(); + var c = p.child('input[name="'+this.el.dom.name+'"]:checked', true); + return c ? c.value : null; + }, + + + setValue : function(v){ + var checkEl, + els, + radio; + if (typeof v == 'boolean') { + Ext.form.Radio.superclass.setValue.call(this, v); + } else if (this.rendered) { + checkEl = this.getCheckEl(); + radio = checkEl.child('input[name="' + this.el.dom.name + '"][value="' + v + '"]', true); + if(radio){ + Ext.getCmp(radio.id).setValue(true); + } + } + if(this.rendered && this.checked){ + checkEl = checkEl || this.getCheckEl(); + els = this.getCheckEl().select('input[name="' + this.el.dom.name + '"]'); + els.each(function(el){ + if(el.dom.id != this.id){ + Ext.getCmp(el.dom.id).setValue(false); + } + }, this); + } + return this; + }, + + + getCheckEl: function(){ + if(this.inGroup){ + return this.el.up('.x-form-radio-group'); + } + return this.el.up('form') || Ext.getBody(); + } +}); +Ext.reg('radio', Ext.form.Radio); + +Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, { + + + allowBlank : true, + + blankText : 'You must select one item in this group', + + + defaultType : 'radio', + + + groupCls : 'x-form-radio-group', + + + + + getValue : function(){ + var out = null; + this.eachItem(function(item){ + if(item.checked){ + out = item; + return false; + } + }); + return out; + }, + + + onSetValue : function(id, value){ + if(arguments.length > 1){ + var f = this.getBox(id); + if(f){ + f.setValue(value); + if(f.checked){ + this.eachItem(function(item){ + if (item !== f){ + item.setValue(false); + } + }); + } + } + }else{ + this.setValueForItem(id); + } + }, + + setValueForItem : function(val){ + val = String(val).split(',')[0]; + this.eachItem(function(item){ + item.setValue(val == item.inputValue); + }); + }, + + + fireChecked : function(){ + if(!this.checkTask){ + this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this); + } + this.checkTask.delay(10); + }, + + + bufferChecked : function(){ + var out = null; + this.eachItem(function(item){ + if(item.checked){ + out = item; + return false; + } + }); + this.fireEvent('change', this, out); + }, + + onDestroy : function(){ + if(this.checkTask){ + this.checkTask.cancel(); + this.checkTask = null; + } + Ext.form.RadioGroup.superclass.onDestroy.call(this); + } + +}); + +Ext.reg('radiogroup', Ext.form.RadioGroup); + +Ext.form.Hidden = Ext.extend(Ext.form.Field, { + + inputType : 'hidden', + + shouldLayout: false, + + + onRender : function(){ + Ext.form.Hidden.superclass.onRender.apply(this, arguments); + }, + + + initEvents : function(){ + this.originalValue = this.getValue(); + }, + + + setSize : Ext.emptyFn, + setWidth : Ext.emptyFn, + setHeight : Ext.emptyFn, + setPosition : Ext.emptyFn, + setPagePosition : Ext.emptyFn, + markInvalid : Ext.emptyFn, + clearInvalid : Ext.emptyFn +}); +Ext.reg('hidden', Ext.form.Hidden); +Ext.form.BasicForm = Ext.extend(Ext.util.Observable, { + + constructor: function(el, config){ + Ext.apply(this, config); + if(Ext.isString(this.paramOrder)){ + this.paramOrder = this.paramOrder.split(/[\s,|]/); + } + + this.items = new Ext.util.MixedCollection(false, function(o){ + return o.getItemId(); + }); + this.addEvents( + + 'beforeaction', + + 'actionfailed', + + 'actioncomplete' + ); + + if(el){ + this.initEl(el); + } + Ext.form.BasicForm.superclass.constructor.call(this); + }, + + + + + + + + + timeout: 30, + + + + + paramOrder: undefined, + + + paramsAsHash: false, + + + waitTitle: 'Please Wait...', + + + activeAction : null, + + + trackResetOnLoad : false, + + + + + + initEl : function(el){ + this.el = Ext.get(el); + this.id = this.el.id || Ext.id(); + if(!this.standardSubmit){ + this.el.on('submit', this.onSubmit, this); + } + this.el.addClass('x-form'); + }, + + + getEl: function(){ + return this.el; + }, + + + onSubmit : function(e){ + e.stopEvent(); + }, + + + destroy: function(bound){ + if(bound !== true){ + this.items.each(function(f){ + Ext.destroy(f); + }); + Ext.destroy(this.el); + } + this.items.clear(); + this.purgeListeners(); + }, + + + isValid : function(){ + var valid = true; + this.items.each(function(f){ + if(!f.validate()){ + valid = false; + } + }); + return valid; + }, + + + isDirty : function(){ + var dirty = false; + this.items.each(function(f){ + if(f.isDirty()){ + dirty = true; + return false; + } + }); + return dirty; + }, + + + doAction : function(action, options){ + if(Ext.isString(action)){ + action = new Ext.form.Action.ACTION_TYPES[action](this, options); + } + if(this.fireEvent('beforeaction', this, action) !== false){ + this.beforeAction(action); + action.run.defer(100, action); + } + return this; + }, + + + submit : function(options){ + options = options || {}; + if(this.standardSubmit){ + var v = options.clientValidation === false || this.isValid(); + if(v){ + var el = this.el.dom; + if(this.url && Ext.isEmpty(el.action)){ + el.action = this.url; + } + el.submit(); + } + return v; + } + var submitAction = String.format('{0}submit', this.api ? 'direct' : ''); + this.doAction(submitAction, options); + return this; + }, + + + load : function(options){ + var loadAction = String.format('{0}load', this.api ? 'direct' : ''); + this.doAction(loadAction, options); + return this; + }, + + + updateRecord : function(record){ + record.beginEdit(); + var fs = record.fields, + field, + value; + fs.each(function(f){ + field = this.findField(f.name); + if(field){ + value = field.getValue(); + if (Ext.type(value) !== false && value.getGroupValue) { + value = value.getGroupValue(); + } else if ( field.eachItem ) { + value = []; + field.eachItem(function(item){ + value.push(item.getValue()); + }); + } + record.set(f.name, value); + } + }, this); + record.endEdit(); + return this; + }, + + + loadRecord : function(record){ + this.setValues(record.data); + return this; + }, + + + beforeAction : function(action){ + + this.items.each(function(f){ + if(f.isFormField && f.syncValue){ + f.syncValue(); + } + }); + var o = action.options; + if(o.waitMsg){ + if(this.waitMsgTarget === true){ + this.el.mask(o.waitMsg, 'x-mask-loading'); + }else if(this.waitMsgTarget){ + this.waitMsgTarget = Ext.get(this.waitMsgTarget); + this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading'); + }else{ + Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle); + } + } + }, + + + afterAction : function(action, success){ + this.activeAction = null; + var o = action.options; + if(o.waitMsg){ + if(this.waitMsgTarget === true){ + this.el.unmask(); + }else if(this.waitMsgTarget){ + this.waitMsgTarget.unmask(); + }else{ + Ext.MessageBox.updateProgress(1); + Ext.MessageBox.hide(); + } + } + if(success){ + if(o.reset){ + this.reset(); + } + Ext.callback(o.success, o.scope, [this, action]); + this.fireEvent('actioncomplete', this, action); + }else{ + Ext.callback(o.failure, o.scope, [this, action]); + this.fireEvent('actionfailed', this, action); + } + }, + + + findField : function(id) { + var field = this.items.get(id); + + if (!Ext.isObject(field)) { + + var findMatchingField = function(f) { + if (f.isFormField) { + if (f.dataIndex == id || f.id == id || f.getName() == id) { + field = f; + return false; + } else if (f.isComposite) { + return f.items.each(findMatchingField); + } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) { + return f.eachItem(findMatchingField); + } + } + }; + + this.items.each(findMatchingField); + } + return field || null; + }, + + + + markInvalid : function(errors){ + if (Ext.isArray(errors)) { + for(var i = 0, len = errors.length; i < len; i++){ + var fieldError = errors[i]; + var f = this.findField(fieldError.id); + if(f){ + f.markInvalid(fieldError.msg); + } + } + } else { + var field, id; + for(id in errors){ + if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){ + field.markInvalid(errors[id]); + } + } + } + + return this; + }, + + + setValues : function(values){ + if(Ext.isArray(values)){ + for(var i = 0, len = values.length; i < len; i++){ + var v = values[i]; + var f = this.findField(v.id); + if(f){ + f.setValue(v.value); + if(this.trackResetOnLoad){ + f.originalValue = f.getValue(); + } + } + } + }else{ + var field, id; + for(id in values){ + if(!Ext.isFunction(values[id]) && (field = this.findField(id))){ + field.setValue(values[id]); + if(this.trackResetOnLoad){ + field.originalValue = field.getValue(); + } + } + } + } + return this; + }, + + + getValues : function(asString){ + var fs = Ext.lib.Ajax.serializeForm(this.el.dom); + if(asString === true){ + return fs; + } + return Ext.urlDecode(fs); + }, + + + getFieldValues : function(dirtyOnly){ + var o = {}, + n, + key, + val; + this.items.each(function(f) { + if (!f.disabled && (dirtyOnly !== true || f.isDirty())) { + n = f.getName(); + key = o[n]; + val = f.getValue(); + + if(Ext.isDefined(key)){ + if(Ext.isArray(key)){ + o[n].push(val); + }else{ + o[n] = [key, val]; + } + }else{ + o[n] = val; + } + } + }); + return o; + }, + + + clearInvalid : function(){ + this.items.each(function(f){ + f.clearInvalid(); + }); + return this; + }, + + + reset : function(){ + this.items.each(function(f){ + f.reset(); + }); + return this; + }, + + + add : function(){ + this.items.addAll(Array.prototype.slice.call(arguments, 0)); + return this; + }, + + + remove : function(field){ + this.items.remove(field); + return this; + }, + + + cleanDestroyed : function() { + this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this); + }, + + + render : function(){ + this.items.each(function(f){ + if(f.isFormField && !f.rendered && document.getElementById(f.id)){ + f.applyToMarkup(f.id); + } + }); + return this; + }, + + + applyToFields : function(o){ + this.items.each(function(f){ + Ext.apply(f, o); + }); + return this; + }, + + + applyIfToFields : function(o){ + this.items.each(function(f){ + Ext.applyIf(f, o); + }); + return this; + }, + + callFieldMethod : function(fnName, args){ + args = args || []; + this.items.each(function(f){ + if(Ext.isFunction(f[fnName])){ + f[fnName].apply(f, args); + } + }); + return this; + } +}); + + +Ext.BasicForm = Ext.form.BasicForm; + +Ext.FormPanel = Ext.extend(Ext.Panel, { + + + + + + + + + + + minButtonWidth : 75, + + + labelAlign : 'left', + + + monitorValid : false, + + + monitorPoll : 200, + + + layout : 'form', + + + initComponent : function(){ + this.form = this.createForm(); + Ext.FormPanel.superclass.initComponent.call(this); + + this.bodyCfg = { + tag: 'form', + cls: this.baseCls + '-body', + method : this.method || 'POST', + id : this.formId || Ext.id() + }; + if(this.fileUpload) { + this.bodyCfg.enctype = 'multipart/form-data'; + } + this.initItems(); + + this.addEvents( + + 'clientvalidation' + ); + + this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']); + }, + + + createForm : function(){ + var config = Ext.applyIf({listeners: {}}, this.initialConfig); + return new Ext.form.BasicForm(null, config); + }, + + + initFields : function(){ + var f = this.form; + var formPanel = this; + var fn = function(c){ + if(formPanel.isField(c)){ + f.add(c); + }else if(c.findBy && c != formPanel){ + formPanel.applySettings(c); + + if(c.items && c.items.each){ + c.items.each(fn, this); + } + } + }; + this.items.each(fn, this); + }, + + + applySettings: function(c){ + var ct = c.ownerCt; + Ext.applyIf(c, { + labelAlign: ct.labelAlign, + labelWidth: ct.labelWidth, + itemCls: ct.itemCls + }); + }, + + + getLayoutTarget : function(){ + return this.form.el; + }, + + + getForm : function(){ + return this.form; + }, + + + onRender : function(ct, position){ + this.initFields(); + Ext.FormPanel.superclass.onRender.call(this, ct, position); + this.form.initEl(this.body); + }, + + + beforeDestroy : function(){ + this.stopMonitoring(); + this.form.destroy(true); + Ext.FormPanel.superclass.beforeDestroy.call(this); + }, + + + isField : function(c) { + return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid; + }, + + + initEvents : function(){ + Ext.FormPanel.superclass.initEvents.call(this); + + this.on({ + scope: this, + add: this.onAddEvent, + remove: this.onRemoveEvent + }); + if(this.monitorValid){ + this.startMonitoring(); + } + }, + + + onAdd: function(c){ + Ext.FormPanel.superclass.onAdd.call(this, c); + this.processAdd(c); + }, + + + onAddEvent: function(ct, c){ + if(ct !== this){ + this.processAdd(c); + } + }, + + + processAdd : function(c){ + + if(this.isField(c)){ + this.form.add(c); + + }else if(c.findBy){ + this.applySettings(c); + this.form.add.apply(this.form, c.findBy(this.isField)); + } + }, + + + onRemove: function(c){ + Ext.FormPanel.superclass.onRemove.call(this, c); + this.processRemove(c); + }, + + onRemoveEvent: function(ct, c){ + if(ct !== this){ + this.processRemove(c); + } + }, + + + processRemove: function(c){ + if(!this.destroying){ + + if(this.isField(c)){ + this.form.remove(c); + + }else if (c.findBy){ + Ext.each(c.findBy(this.isField), this.form.remove, this.form); + + this.form.cleanDestroyed(); + } + } + }, + + + startMonitoring : function(){ + if(!this.validTask){ + this.validTask = new Ext.util.TaskRunner(); + this.validTask.start({ + run : this.bindHandler, + interval : this.monitorPoll || 200, + scope: this + }); + } + }, + + + stopMonitoring : function(){ + if(this.validTask){ + this.validTask.stopAll(); + this.validTask = null; + } + }, + + + load : function(){ + this.form.load.apply(this.form, arguments); + }, + + + onDisable : function(){ + Ext.FormPanel.superclass.onDisable.call(this); + if(this.form){ + this.form.items.each(function(){ + this.disable(); + }); + } + }, + + + onEnable : function(){ + Ext.FormPanel.superclass.onEnable.call(this); + if(this.form){ + this.form.items.each(function(){ + this.enable(); + }); + } + }, + + + bindHandler : function(){ + var valid = true; + this.form.items.each(function(f){ + if(!f.isValid(true)){ + valid = false; + return false; + } + }); + if(this.fbar){ + var fitems = this.fbar.items.items; + for(var i = 0, len = fitems.length; i < len; i++){ + var btn = fitems[i]; + if(btn.formBind === true && btn.disabled === valid){ + btn.setDisabled(!valid); + } + } + } + this.fireEvent('clientvalidation', this, valid); + } +}); +Ext.reg('form', Ext.FormPanel); + +Ext.form.FormPanel = Ext.FormPanel; + +Ext.form.FieldSet = Ext.extend(Ext.Panel, { + + + + + + + baseCls : 'x-fieldset', + + layout : 'form', + + animCollapse : false, + + + onRender : function(ct, position){ + if(!this.el){ + this.el = document.createElement('fieldset'); + this.el.id = this.id; + if (this.title || this.header || this.checkboxToggle) { + this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header'; + } + } + + Ext.form.FieldSet.superclass.onRender.call(this, ct, position); + + if(this.checkboxToggle){ + var o = typeof this.checkboxToggle == 'object' ? + this.checkboxToggle : + {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'}; + this.checkbox = this.header.insertFirst(o); + this.checkbox.dom.checked = !this.collapsed; + this.mon(this.checkbox, 'click', this.onCheckClick, this); + } + }, + + + onCollapse : function(doAnim, animArg){ + if(this.checkbox){ + this.checkbox.dom.checked = false; + } + Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg); + + }, + + + onExpand : function(doAnim, animArg){ + if(this.checkbox){ + this.checkbox.dom.checked = true; + } + Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg); + }, + + + onCheckClick : function(){ + this[this.checkbox.dom.checked ? 'expand' : 'collapse'](); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +}); +Ext.reg('fieldset', Ext.form.FieldSet); + +Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, { + + enableFormat : true, + + enableFontSize : true, + + enableColors : true, + + enableAlignments : true, + + enableLists : true, + + enableSourceEdit : true, + + enableLinks : true, + + enableFont : true, + + createLinkText : 'Please enter the URL for the link:', + + defaultLinkValue : 'http:/'+'/', + + fontFamilies : [ + 'Arial', + 'Courier New', + 'Tahoma', + 'Times New Roman', + 'Verdana' + ], + defaultFont: 'tahoma', + + defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​', + + + actionMode: 'wrap', + validationEvent : false, + deferHeight: true, + initialized : false, + activated : false, + sourceEditMode : false, + onFocus : Ext.emptyFn, + iframePad:3, + hideMode:'offsets', + defaultAutoCreate : { + tag: "textarea", + style:"width:500px;height:300px;", + autocomplete: "off" + }, + + + initComponent : function(){ + this.addEvents( + + 'initialize', + + 'activate', + + 'beforesync', + + 'beforepush', + + 'sync', + + 'push', + + 'editmodechange' + ); + Ext.form.HtmlEditor.superclass.initComponent.call(this); + }, + + + createFontOptions : function(){ + var buf = [], fs = this.fontFamilies, ff, lc; + for(var i = 0, len = fs.length; i< len; i++){ + ff = fs[i]; + lc = ff.toLowerCase(); + buf.push( + '' + ); + } + return buf.join(''); + }, + + + createToolbar : function(editor){ + var items = []; + var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled(); + + + function btn(id, toggle, handler){ + return { + itemId : id, + cls : 'x-btn-icon', + iconCls: 'x-edit-'+id, + enableToggle:toggle !== false, + scope: editor, + handler:handler||editor.relayBtnCmd, + clickEvent:'mousedown', + tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined, + overflowText: editor.buttonTips[id].title || undefined, + tabIndex:-1 + }; + } + + + if(this.enableFont && !Ext.isSafari2){ + var fontSelectItem = new Ext.Toolbar.Item({ + autoEl: { + tag:'select', + cls:'x-font-select', + html: this.createFontOptions() + } + }); + + items.push( + fontSelectItem, + '-' + ); + } + + if(this.enableFormat){ + items.push( + btn('bold'), + btn('italic'), + btn('underline') + ); + } + + if(this.enableFontSize){ + items.push( + '-', + btn('increasefontsize', false, this.adjustFont), + btn('decreasefontsize', false, this.adjustFont) + ); + } + + if(this.enableColors){ + items.push( + '-', { + itemId:'forecolor', + cls:'x-btn-icon', + iconCls: 'x-edit-forecolor', + clickEvent:'mousedown', + tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined, + tabIndex:-1, + menu : new Ext.menu.ColorMenu({ + allowReselect: true, + focus: Ext.emptyFn, + value:'000000', + plain:true, + listeners: { + scope: this, + select: function(cp, color){ + this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); + this.deferFocus(); + } + }, + clickEvent:'mousedown' + }) + }, { + itemId:'backcolor', + cls:'x-btn-icon', + iconCls: 'x-edit-backcolor', + clickEvent:'mousedown', + tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined, + tabIndex:-1, + menu : new Ext.menu.ColorMenu({ + focus: Ext.emptyFn, + value:'FFFFFF', + plain:true, + allowReselect: true, + listeners: { + scope: this, + select: function(cp, color){ + if(Ext.isGecko){ + this.execCmd('useCSS', false); + this.execCmd('hilitecolor', color); + this.execCmd('useCSS', true); + this.deferFocus(); + }else{ + this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); + this.deferFocus(); + } + } + }, + clickEvent:'mousedown' + }) + } + ); + } + + if(this.enableAlignments){ + items.push( + '-', + btn('justifyleft'), + btn('justifycenter'), + btn('justifyright') + ); + } + + if(!Ext.isSafari2){ + if(this.enableLinks){ + items.push( + '-', + btn('createlink', false, this.createLink) + ); + } + + if(this.enableLists){ + items.push( + '-', + btn('insertorderedlist'), + btn('insertunorderedlist') + ); + } + if(this.enableSourceEdit){ + items.push( + '-', + btn('sourceedit', true, function(btn){ + this.toggleSourceEdit(!this.sourceEditMode); + }) + ); + } + } + + + var tb = new Ext.Toolbar({ + renderTo: this.wrap.dom.firstChild, + items: items + }); + + if (fontSelectItem) { + this.fontSelect = fontSelectItem.el; + + this.mon(this.fontSelect, 'change', function(){ + var font = this.fontSelect.dom.value; + this.relayCmd('fontname', font); + this.deferFocus(); + }, this); + } + + + this.mon(tb.el, 'click', function(e){ + e.preventDefault(); + }); + + this.tb = tb; + this.tb.doLayout(); + }, + + onDisable: function(){ + this.wrap.mask(); + Ext.form.HtmlEditor.superclass.onDisable.call(this); + }, + + onEnable: function(){ + this.wrap.unmask(); + Ext.form.HtmlEditor.superclass.onEnable.call(this); + }, + + setReadOnly: function(readOnly){ + + Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly); + if(this.initialized){ + if(Ext.isIE){ + this.getEditorBody().contentEditable = !readOnly; + }else{ + this.setDesignMode(!readOnly); + } + var bd = this.getEditorBody(); + if(bd){ + bd.style.cursor = this.readOnly ? 'default' : 'text'; + } + this.disableItems(readOnly); + } + }, + + + getDocMarkup : function(){ + var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2; + return String.format('', this.iframePad, h); + }, + + + getEditorBody : function(){ + var doc = this.getDoc(); + return doc.body || doc.documentElement; + }, + + + getDoc : function(){ + return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document); + }, + + + getWin : function(){ + return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name]; + }, + + + onRender : function(ct, position){ + Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position); + this.el.dom.style.border = '0 none'; + this.el.dom.setAttribute('tabIndex', -1); + this.el.addClass('x-hidden'); + if(Ext.isIE){ + this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;'); + } + this.wrap = this.el.wrap({ + cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'} + }); + + this.createToolbar(this); + + this.disableItems(true); + + this.tb.doLayout(); + + this.createIFrame(); + + if(!this.width){ + var sz = this.el.getSize(); + this.setSize(sz.width, this.height || sz.height); + } + this.resizeEl = this.positionEl = this.wrap; + }, + + createIFrame: function(){ + var iframe = document.createElement('iframe'); + iframe.name = Ext.id(); + iframe.frameBorder = '0'; + iframe.style.overflow = 'auto'; + iframe.src = Ext.SSL_SECURE_URL; + + this.wrap.dom.appendChild(iframe); + this.iframe = iframe; + + this.monitorTask = Ext.TaskMgr.start({ + run: this.checkDesignMode, + scope: this, + interval:100 + }); + }, + + initFrame : function(){ + Ext.TaskMgr.stop(this.monitorTask); + var doc = this.getDoc(); + this.win = this.getWin(); + + doc.open(); + doc.write(this.getDocMarkup()); + doc.close(); + + this.readyTask = { + run : function(){ + var doc = this.getDoc(); + if(doc.body || doc.readyState == 'complete'){ + Ext.TaskMgr.stop(this.readyTask); + this.setDesignMode(true); + this.initEditor.defer(10, this); + } + }, + interval : 10, + duration:10000, + scope: this + }; + Ext.TaskMgr.start(this.readyTask); + }, + + + checkDesignMode : function(){ + if(this.wrap && this.wrap.dom.offsetWidth){ + var doc = this.getDoc(); + if(!doc){ + return; + } + if(!doc.editorInitialized || this.getDesignMode() != 'on'){ + this.initFrame(); + } + } + }, + + + setDesignMode : function(mode){ + var doc = this.getDoc(); + if (doc) { + if(this.readOnly){ + mode = false; + } + doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off'; + } + + }, + + + getDesignMode : function(){ + var doc = this.getDoc(); + if(!doc){ return ''; } + return String(doc.designMode).toLowerCase(); + + }, + + disableItems: function(disabled){ + if(this.fontSelect){ + this.fontSelect.dom.disabled = disabled; + } + this.tb.items.each(function(item){ + if(item.getItemId() != 'sourceedit'){ + item.setDisabled(disabled); + } + }); + }, + + + onResize : function(w, h){ + Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments); + if(this.el && this.iframe){ + if(Ext.isNumber(w)){ + var aw = w - this.wrap.getFrameWidth('lr'); + this.el.setWidth(aw); + this.tb.setWidth(aw); + this.iframe.style.width = Math.max(aw, 0) + 'px'; + } + if(Ext.isNumber(h)){ + var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight(); + this.el.setHeight(ah); + this.iframe.style.height = Math.max(ah, 0) + 'px'; + var bd = this.getEditorBody(); + if(bd){ + bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px'; + } + } + } + }, + + + toggleSourceEdit : function(sourceEditMode){ + var iframeHeight, + elHeight; + + if (sourceEditMode === undefined) { + sourceEditMode = !this.sourceEditMode; + } + this.sourceEditMode = sourceEditMode === true; + var btn = this.tb.getComponent('sourceedit'); + + if (btn.pressed !== this.sourceEditMode) { + btn.toggle(this.sourceEditMode); + if (!btn.xtbHidden) { + return; + } + } + if (this.sourceEditMode) { + + this.previousSize = this.getSize(); + + iframeHeight = Ext.get(this.iframe).getHeight(); + + this.disableItems(true); + this.syncValue(); + this.iframe.className = 'x-hidden'; + this.el.removeClass('x-hidden'); + this.el.dom.removeAttribute('tabIndex'); + this.el.focus(); + this.el.dom.style.height = iframeHeight + 'px'; + } + else { + elHeight = parseInt(this.el.dom.style.height, 10); + if (this.initialized) { + this.disableItems(this.readOnly); + } + this.pushValue(); + this.iframe.className = ''; + this.el.addClass('x-hidden'); + this.el.dom.setAttribute('tabIndex', -1); + this.deferFocus(); + + this.setSize(this.previousSize); + delete this.previousSize; + this.iframe.style.height = elHeight + 'px'; + } + this.fireEvent('editmodechange', this, this.sourceEditMode); + }, + + + createLink : function() { + var url = prompt(this.createLinkText, this.defaultLinkValue); + if(url && url != 'http:/'+'/'){ + this.relayCmd('createlink', url); + } + }, + + + initEvents : function(){ + this.originalValue = this.getValue(); + }, + + + markInvalid : Ext.emptyFn, + + + clearInvalid : Ext.emptyFn, + + + setValue : function(v){ + Ext.form.HtmlEditor.superclass.setValue.call(this, v); + this.pushValue(); + return this; + }, + + + cleanHtml: function(html) { + html = String(html); + if(Ext.isWebKit){ + html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, ''); + } + + + if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){ + html = html.substring(1); + } + return html; + }, + + + syncValue : function(){ + if(this.initialized){ + var bd = this.getEditorBody(); + var html = bd.innerHTML; + if(Ext.isWebKit){ + var bs = bd.getAttribute('style'); + var m = bs.match(/text-align:(.*?);/i); + if(m && m[1]){ + html = '
    ' + html + '
    '; + } + } + html = this.cleanHtml(html); + if(this.fireEvent('beforesync', this, html) !== false){ + this.el.dom.value = html; + this.fireEvent('sync', this, html); + } + } + }, + + + getValue : function() { + this[this.sourceEditMode ? 'pushValue' : 'syncValue'](); + return Ext.form.HtmlEditor.superclass.getValue.call(this); + }, + + + pushValue : function(){ + if(this.initialized){ + var v = this.el.dom.value; + if(!this.activated && v.length < 1){ + v = this.defaultValue; + } + if(this.fireEvent('beforepush', this, v) !== false){ + this.getEditorBody().innerHTML = v; + if(Ext.isGecko){ + + this.setDesignMode(false); + this.setDesignMode(true); + } + this.fireEvent('push', this, v); + } + + } + }, + + + deferFocus : function(){ + this.focus.defer(10, this); + }, + + + focus : function(){ + if(this.win && !this.sourceEditMode){ + this.win.focus(); + }else{ + this.el.focus(); + } + }, + + + initEditor : function(){ + + try{ + var dbody = this.getEditorBody(), + ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'), + doc, + fn; + + ss['background-attachment'] = 'fixed'; + dbody.bgProperties = 'fixed'; + + Ext.DomHelper.applyStyles(dbody, ss); + + doc = this.getDoc(); + + if(doc){ + try{ + Ext.EventManager.removeAll(doc); + }catch(e){} + } + + + fn = this.onEditorEvent.createDelegate(this); + Ext.EventManager.on(doc, { + mousedown: fn, + dblclick: fn, + click: fn, + keyup: fn, + buffer:100 + }); + + if(Ext.isGecko){ + Ext.EventManager.on(doc, 'keypress', this.applyCommand, this); + } + if(Ext.isIE || Ext.isWebKit || Ext.isOpera){ + Ext.EventManager.on(doc, 'keydown', this.fixKeys, this); + } + doc.editorInitialized = true; + this.initialized = true; + this.pushValue(); + this.setReadOnly(this.readOnly); + this.fireEvent('initialize', this); + }catch(e){} + }, + + + beforeDestroy : function(){ + if(this.monitorTask){ + Ext.TaskMgr.stop(this.monitorTask); + } + if(this.readyTask){ + Ext.TaskMgr.stop(this.readyTask); + } + if(this.rendered){ + Ext.destroy(this.tb); + var doc = this.getDoc(); + Ext.EventManager.removeFromSpecialCache(doc); + if(doc){ + try{ + Ext.EventManager.removeAll(doc); + for (var prop in doc){ + delete doc[prop]; + } + }catch(e){} + } + if(this.wrap){ + this.wrap.dom.innerHTML = ''; + this.wrap.remove(); + } + } + Ext.form.HtmlEditor.superclass.beforeDestroy.call(this); + }, + + + onFirstFocus : function(){ + this.activated = true; + this.disableItems(this.readOnly); + if(Ext.isGecko){ + this.win.focus(); + var s = this.win.getSelection(); + if(!s.focusNode || s.focusNode.nodeType != 3){ + var r = s.getRangeAt(0); + r.selectNodeContents(this.getEditorBody()); + r.collapse(true); + this.deferFocus(); + } + try{ + this.execCmd('useCSS', true); + this.execCmd('styleWithCSS', false); + }catch(e){} + } + this.fireEvent('activate', this); + }, + + + adjustFont: function(btn){ + var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1, + doc = this.getDoc(), + v = parseInt(doc.queryCommandValue('FontSize') || 2, 10); + if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){ + + + if(v <= 10){ + v = 1 + adjust; + }else if(v <= 13){ + v = 2 + adjust; + }else if(v <= 16){ + v = 3 + adjust; + }else if(v <= 18){ + v = 4 + adjust; + }else if(v <= 24){ + v = 5 + adjust; + }else { + v = 6 + adjust; + } + v = v.constrain(1, 6); + }else{ + if(Ext.isSafari){ + adjust *= 2; + } + v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0); + } + this.execCmd('FontSize', v); + }, + + + onEditorEvent : function(e){ + this.updateToolbar(); + }, + + + + updateToolbar: function(){ + + if(this.readOnly){ + return; + } + + if(!this.activated){ + this.onFirstFocus(); + return; + } + + var btns = this.tb.items.map, + doc = this.getDoc(); + + if(this.enableFont && !Ext.isSafari2){ + var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase(); + if(name != this.fontSelect.dom.value){ + this.fontSelect.dom.value = name; + } + } + if(this.enableFormat){ + btns.bold.toggle(doc.queryCommandState('bold')); + btns.italic.toggle(doc.queryCommandState('italic')); + btns.underline.toggle(doc.queryCommandState('underline')); + } + if(this.enableAlignments){ + btns.justifyleft.toggle(doc.queryCommandState('justifyleft')); + btns.justifycenter.toggle(doc.queryCommandState('justifycenter')); + btns.justifyright.toggle(doc.queryCommandState('justifyright')); + } + if(!Ext.isSafari2 && this.enableLists){ + btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist')); + btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist')); + } + + Ext.menu.MenuMgr.hideAll(); + + this.syncValue(); + }, + + + relayBtnCmd : function(btn){ + this.relayCmd(btn.getItemId()); + }, + + + relayCmd : function(cmd, value){ + (function(){ + this.focus(); + this.execCmd(cmd, value); + this.updateToolbar(); + }).defer(10, this); + }, + + + execCmd : function(cmd, value){ + var doc = this.getDoc(); + doc.execCommand(cmd, false, value === undefined ? null : value); + this.syncValue(); + }, + + + applyCommand : function(e){ + if(e.ctrlKey){ + var c = e.getCharCode(), cmd; + if(c > 0){ + c = String.fromCharCode(c); + switch(c){ + case 'b': + cmd = 'bold'; + break; + case 'i': + cmd = 'italic'; + break; + case 'u': + cmd = 'underline'; + break; + } + if(cmd){ + this.win.focus(); + this.execCmd(cmd); + this.deferFocus(); + e.preventDefault(); + } + } + } + }, + + + insertAtCursor : function(text){ + if(!this.activated){ + return; + } + if(Ext.isIE){ + this.win.focus(); + var doc = this.getDoc(), + r = doc.selection.createRange(); + if(r){ + r.pasteHTML(text); + this.syncValue(); + this.deferFocus(); + } + }else{ + this.win.focus(); + this.execCmd('InsertHTML', text); + this.deferFocus(); + } + }, + + + fixKeys : function(){ + if(Ext.isIE){ + return function(e){ + var k = e.getKey(), + doc = this.getDoc(), + r; + if(k == e.TAB){ + e.stopEvent(); + r = doc.selection.createRange(); + if(r){ + r.collapse(true); + r.pasteHTML('    '); + this.deferFocus(); + } + }else if(k == e.ENTER){ + r = doc.selection.createRange(); + if(r){ + var target = r.parentElement(); + if(!target || target.tagName.toLowerCase() != 'li'){ + e.stopEvent(); + r.pasteHTML('
    '); + r.collapse(false); + r.select(); + } + } + } + }; + }else if(Ext.isOpera){ + return function(e){ + var k = e.getKey(); + if(k == e.TAB){ + e.stopEvent(); + this.win.focus(); + this.execCmd('InsertHTML','    '); + this.deferFocus(); + } + }; + }else if(Ext.isWebKit){ + return function(e){ + var k = e.getKey(); + if(k == e.TAB){ + e.stopEvent(); + this.execCmd('InsertText','\t'); + this.deferFocus(); + }else if(k == e.ENTER){ + e.stopEvent(); + this.execCmd('InsertHtml','

    '); + this.deferFocus(); + } + }; + } + }(), + + + getToolbar : function(){ + return this.tb; + }, + + + buttonTips : { + bold : { + title: 'Bold (Ctrl+B)', + text: 'Make the selected text bold.', + cls: 'x-html-editor-tip' + }, + italic : { + title: 'Italic (Ctrl+I)', + text: 'Make the selected text italic.', + cls: 'x-html-editor-tip' + }, + underline : { + title: 'Underline (Ctrl+U)', + text: 'Underline the selected text.', + cls: 'x-html-editor-tip' + }, + increasefontsize : { + title: 'Grow Text', + text: 'Increase the font size.', + cls: 'x-html-editor-tip' + }, + decreasefontsize : { + title: 'Shrink Text', + text: 'Decrease the font size.', + cls: 'x-html-editor-tip' + }, + backcolor : { + title: 'Text Highlight Color', + text: 'Change the background color of the selected text.', + cls: 'x-html-editor-tip' + }, + forecolor : { + title: 'Font Color', + text: 'Change the color of the selected text.', + cls: 'x-html-editor-tip' + }, + justifyleft : { + title: 'Align Text Left', + text: 'Align text to the left.', + cls: 'x-html-editor-tip' + }, + justifycenter : { + title: 'Center Text', + text: 'Center text in the editor.', + cls: 'x-html-editor-tip' + }, + justifyright : { + title: 'Align Text Right', + text: 'Align text to the right.', + cls: 'x-html-editor-tip' + }, + insertunorderedlist : { + title: 'Bullet List', + text: 'Start a bulleted list.', + cls: 'x-html-editor-tip' + }, + insertorderedlist : { + title: 'Numbered List', + text: 'Start a numbered list.', + cls: 'x-html-editor-tip' + }, + createlink : { + title: 'Hyperlink', + text: 'Make the selected text a hyperlink.', + cls: 'x-html-editor-tip' + }, + sourceedit : { + title: 'Source Edit', + text: 'Switch to source editing mode.', + cls: 'x-html-editor-tip' + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +}); +Ext.reg('htmleditor', Ext.form.HtmlEditor); + +Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, { + + minValue : undefined, + + maxValue : undefined, + + minText : "The time in this field must be equal to or after {0}", + + maxText : "The time in this field must be equal to or before {0}", + + invalidText : "{0} is not a valid time", + + format : "g:i A", + + altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A", + + increment: 15, + + + mode: 'local', + + triggerAction: 'all', + + typeAhead: false, + + + + + initDate: '1/1/2008', + + initDateFormat: 'j/n/Y', + + + initComponent : function(){ + if(Ext.isDefined(this.minValue)){ + this.setMinValue(this.minValue, true); + } + if(Ext.isDefined(this.maxValue)){ + this.setMaxValue(this.maxValue, true); + } + if(!this.store){ + this.generateStore(true); + } + Ext.form.TimeField.superclass.initComponent.call(this); + }, + + + setMinValue: function(value, initial){ + this.setLimit(value, true, initial); + return this; + }, + + + setMaxValue: function(value, initial){ + this.setLimit(value, false, initial); + return this; + }, + + + generateStore: function(initial){ + var min = this.minValue || new Date(this.initDate).clearTime(), + max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1), + times = []; + + while(min <= max){ + times.push(min.dateFormat(this.format)); + min = min.add('mi', this.increment); + } + this.bindStore(times, initial); + }, + + + setLimit: function(value, isMin, initial){ + var d; + if(Ext.isString(value)){ + d = this.parseDate(value); + }else if(Ext.isDate(value)){ + d = value; + } + if(d){ + var val = new Date(this.initDate).clearTime(); + val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()); + this[isMin ? 'minValue' : 'maxValue'] = val; + if(!initial){ + this.generateStore(); + } + } + }, + + + getValue : function(){ + var v = Ext.form.TimeField.superclass.getValue.call(this); + return this.formatDate(this.parseDate(v)) || ''; + }, + + + setValue : function(value){ + return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value))); + }, + + + validateValue : Ext.form.DateField.prototype.validateValue, + + formatDate : Ext.form.DateField.prototype.formatDate, + + parseDate: function(value) { + if (!value || Ext.isDate(value)) { + return value; + } + + var id = this.initDate + ' ', + idf = this.initDateFormat + ' ', + v = Date.parseDate(id + value, idf + this.format), + af = this.altFormats; + + if (!v && af) { + if (!this.altFormatsArray) { + this.altFormatsArray = af.split("|"); + } + for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) { + v = Date.parseDate(id + value, idf + afa[i]); + } + } + + return v; + } +}); +Ext.reg('timefield', Ext.form.TimeField); +Ext.form.SliderField = Ext.extend(Ext.form.Field, { + + + useTips : true, + + + tipText : null, + + + actionMode: 'wrap', + + + initComponent : function() { + var cfg = Ext.copyTo({ + id: this.id + '-slider' + }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']); + + + if (this.useTips) { + var plug = this.tipText ? {getText: this.tipText} : {}; + cfg.plugins = [new Ext.slider.Tip(plug)]; + } + this.slider = new Ext.Slider(cfg); + Ext.form.SliderField.superclass.initComponent.call(this); + }, + + + onRender : function(ct, position){ + this.autoCreate = { + id: this.id, + name: this.name, + type: 'hidden', + tag: 'input' + }; + Ext.form.SliderField.superclass.onRender.call(this, ct, position); + this.wrap = this.el.wrap({cls: 'x-form-field-wrap'}); + this.resizeEl = this.positionEl = this.wrap; + this.slider.render(this.wrap); + }, + + + onResize : function(w, h, aw, ah){ + Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah); + this.slider.setSize(w, h); + }, + + + initEvents : function(){ + Ext.form.SliderField.superclass.initEvents.call(this); + this.slider.on('change', this.onChange, this); + }, + + + onChange : function(slider, v){ + this.setValue(v, undefined, true); + }, + + + onEnable : function(){ + Ext.form.SliderField.superclass.onEnable.call(this); + this.slider.enable(); + }, + + + onDisable : function(){ + Ext.form.SliderField.superclass.onDisable.call(this); + this.slider.disable(); + }, + + + beforeDestroy : function(){ + Ext.destroy(this.slider); + Ext.form.SliderField.superclass.beforeDestroy.call(this); + }, + + + alignErrorIcon : function(){ + this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]); + }, + + + setMinValue : function(v){ + this.slider.setMinValue(v); + return this; + }, + + + setMaxValue : function(v){ + this.slider.setMaxValue(v); + return this; + }, + + + setValue : function(v, animate, silent){ + + + if(!silent){ + this.slider.setValue(v, animate); + } + return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue()); + }, + + + getValue : function(){ + return this.slider.getValue(); + } +}); + +Ext.reg('sliderfield', Ext.form.SliderField); +Ext.form.Label = Ext.extend(Ext.BoxComponent, { + + + + + + onRender : function(ct, position){ + if(!this.el){ + this.el = document.createElement('label'); + this.el.id = this.getId(); + this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || ''); + if(this.forId){ + this.el.setAttribute('for', this.forId); + } + } + Ext.form.Label.superclass.onRender.call(this, ct, position); + }, + + + setText : function(t, encode){ + var e = encode === false; + this[!e ? 'text' : 'html'] = t; + delete this[e ? 'text' : 'html']; + if(this.rendered){ + this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t; + } + return this; + } +}); + +Ext.reg('label', Ext.form.Label); +Ext.form.Action = function(form, options){ + this.form = form; + this.options = options || {}; +}; + + +Ext.form.Action.CLIENT_INVALID = 'client'; + +Ext.form.Action.SERVER_INVALID = 'server'; + +Ext.form.Action.CONNECT_FAILURE = 'connect'; + +Ext.form.Action.LOAD_FAILURE = 'load'; + +Ext.form.Action.prototype = { + + + + + + + + + + + + + + + type : 'default', + + + + + + run : function(options){ + + }, + + + success : function(response){ + + }, + + + handleResponse : function(response){ + + }, + + + failure : function(response){ + this.response = response; + this.failureType = Ext.form.Action.CONNECT_FAILURE; + this.form.afterAction(this, false); + }, + + + + + processResponse : function(response){ + this.response = response; + if(!response.responseText && !response.responseXML){ + return true; + } + this.result = this.handleResponse(response); + return this.result; + }, + + decodeResponse: function(response) { + try { + return Ext.decode(response.responseText); + } catch(e) { + return false; + } + }, + + + getUrl : function(appendParams){ + var url = this.options.url || this.form.url || this.form.el.dom.action; + if(appendParams){ + var p = this.getParams(); + if(p){ + url = Ext.urlAppend(url, p); + } + } + return url; + }, + + + getMethod : function(){ + return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase(); + }, + + + getParams : function(){ + var bp = this.form.baseParams; + var p = this.options.params; + if(p){ + if(typeof p == "object"){ + p = Ext.urlEncode(Ext.applyIf(p, bp)); + }else if(typeof p == 'string' && bp){ + p += '&' + Ext.urlEncode(bp); + } + }else if(bp){ + p = Ext.urlEncode(bp); + } + return p; + }, + + + createCallback : function(opts){ + var opts = opts || {}; + return { + success: this.success, + failure: this.failure, + scope: this, + timeout: (opts.timeout*1000) || (this.form.timeout*1000), + upload: this.form.fileUpload ? this.success : undefined + }; + } +}; + + +Ext.form.Action.Submit = function(form, options){ + Ext.form.Action.Submit.superclass.constructor.call(this, form, options); +}; + +Ext.extend(Ext.form.Action.Submit, Ext.form.Action, { + + + type : 'submit', + + + run : function(){ + var o = this.options, + method = this.getMethod(), + isGet = method == 'GET'; + if(o.clientValidation === false || this.form.isValid()){ + if (o.submitEmptyText === false) { + var fields = this.form.items, + emptyFields = [], + setupEmptyFields = function(f){ + if (f.el.getValue() == f.emptyText) { + emptyFields.push(f); + f.el.dom.value = ""; + } + if(f.isComposite && f.rendered){ + f.items.each(setupEmptyFields); + } + }; + + fields.each(setupEmptyFields); + } + Ext.Ajax.request(Ext.apply(this.createCallback(o), { + form:this.form.el.dom, + url:this.getUrl(isGet), + method: method, + headers: o.headers, + params:!isGet ? this.getParams() : null, + isUpload: this.form.fileUpload + })); + if (o.submitEmptyText === false) { + Ext.each(emptyFields, function(f) { + if (f.applyEmptyText) { + f.applyEmptyText(); + } + }); + } + }else if (o.clientValidation !== false){ + this.failureType = Ext.form.Action.CLIENT_INVALID; + this.form.afterAction(this, false); + } + }, + + + success : function(response){ + var result = this.processResponse(response); + if(result === true || result.success){ + this.form.afterAction(this, true); + return; + } + if(result.errors){ + this.form.markInvalid(result.errors); + } + this.failureType = Ext.form.Action.SERVER_INVALID; + this.form.afterAction(this, false); + }, + + + handleResponse : function(response){ + if(this.form.errorReader){ + var rs = this.form.errorReader.read(response); + var errors = []; + if(rs.records){ + for(var i = 0, len = rs.records.length; i < len; i++) { + var r = rs.records[i]; + errors[i] = r.data; + } + } + if(errors.length < 1){ + errors = null; + } + return { + success : rs.success, + errors : errors + }; + } + return this.decodeResponse(response); + } +}); + + + +Ext.form.Action.Load = function(form, options){ + Ext.form.Action.Load.superclass.constructor.call(this, form, options); + this.reader = this.form.reader; +}; + +Ext.extend(Ext.form.Action.Load, Ext.form.Action, { + + type : 'load', + + + run : function(){ + Ext.Ajax.request(Ext.apply( + this.createCallback(this.options), { + method:this.getMethod(), + url:this.getUrl(false), + headers: this.options.headers, + params:this.getParams() + })); + }, + + + success : function(response){ + var result = this.processResponse(response); + if(result === true || !result.success || !result.data){ + this.failureType = Ext.form.Action.LOAD_FAILURE; + this.form.afterAction(this, false); + return; + } + this.form.clearInvalid(); + this.form.setValues(result.data); + this.form.afterAction(this, true); + }, + + + handleResponse : function(response){ + if(this.form.reader){ + var rs = this.form.reader.read(response); + var data = rs.records && rs.records[0] ? rs.records[0].data : null; + return { + success : rs.success, + data : data + }; + } + return this.decodeResponse(response); + } +}); + + + + +Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, { + constructor: function(form, opts) { + Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts); + }, + type : 'directload', + + run : function(){ + var args = this.getParams(); + args.push(this.success, this); + this.form.api.load.apply(window, args); + }, + + getParams : function() { + var buf = [], o = {}; + var bp = this.form.baseParams; + var p = this.options.params; + Ext.apply(o, p, bp); + var paramOrder = this.form.paramOrder; + if(paramOrder){ + for(var i = 0, len = paramOrder.length; i < len; i++){ + buf.push(o[paramOrder[i]]); + } + }else if(this.form.paramsAsHash){ + buf.push(o); + } + return buf; + }, + + + + processResponse : function(result) { + this.result = result; + return result; + }, + + success : function(response, trans){ + if(trans.type == Ext.Direct.exceptions.SERVER){ + response = {}; + } + Ext.form.Action.DirectLoad.superclass.success.call(this, response); + } +}); + + +Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, { + constructor : function(form, opts) { + Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts); + }, + type : 'directsubmit', + + run : function(){ + var o = this.options; + if(o.clientValidation === false || this.form.isValid()){ + + + this.success.params = this.getParams(); + this.form.api.submit(this.form.el.dom, this.success, this); + }else if (o.clientValidation !== false){ + this.failureType = Ext.form.Action.CLIENT_INVALID; + this.form.afterAction(this, false); + } + }, + + getParams : function() { + var o = {}; + var bp = this.form.baseParams; + var p = this.options.params; + Ext.apply(o, p, bp); + return o; + }, + + + + processResponse : function(result) { + this.result = result; + return result; + }, + + success : function(response, trans){ + if(trans.type == Ext.Direct.exceptions.SERVER){ + response = {}; + } + Ext.form.Action.DirectSubmit.superclass.success.call(this, response); + } +}); + +Ext.form.Action.ACTION_TYPES = { + 'load' : Ext.form.Action.Load, + 'submit' : Ext.form.Action.Submit, + 'directload' : Ext.form.Action.DirectLoad, + 'directsubmit' : Ext.form.Action.DirectSubmit +}; + +Ext.form.VTypes = function(){ + + var alpha = /^[a-zA-Z_]+$/, + alphanum = /^[a-zA-Z0-9_]+$/, + email = /^(\w+)([\-+.\'][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/, + url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i; + + + return { + + 'email' : function(v){ + return email.test(v); + }, + + 'emailText' : 'This field should be an e-mail address in the format "user@example.com"', + + 'emailMask' : /[a-z0-9_\.\-\+\'@]/i, + + /** + * The function used to validate URLs + * @param {String} value The URL + * @return {Boolean} true if the RegExp test passed, and false if not. + */ + 'url' : function(v){ + return url.test(v); + }, + /** + * The error text to display when the url validation function returns false. Defaults to: + * 'This field should be a URL in the format "http:/'+'/www.example.com"' + * @type String + */ + 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"', + + /** + * The function used to validate alpha values + * @param {String} value The value + * @return {Boolean} true if the RegExp test passed, and false if not. + */ + 'alpha' : function(v){ + return alpha.test(v); + }, + /** + * The error text to display when the alpha validation function returns false. Defaults to: + * 'This field should only contain letters and _' + * @type String + */ + 'alphaText' : 'This field should only contain letters and _', + /** + * The keystroke filter mask to be applied on alpha input. Defaults to: + * /[a-z_]/i + * @type RegExp + */ + 'alphaMask' : /[a-z_]/i, + + /** + * The function used to validate alphanumeric values + * @param {String} value The value + * @return {Boolean} true if the RegExp test passed, and false if not. + */ + 'alphanum' : function(v){ + return alphanum.test(v); + }, + /** + * The error text to display when the alphanumeric validation function returns false. Defaults to: + * 'This field should only contain letters, numbers and _' + * @type String + */ + 'alphanumText' : 'This field should only contain letters, numbers and _', + /** + * The keystroke filter mask to be applied on alphanumeric input. Defaults to: + * /[a-z0-9_]/i + * @type RegExp + */ + 'alphanumMask' : /[a-z0-9_]/i + }; +}(); +/** + * @class Ext.grid.GridPanel + * @extends Ext.Panel + *

    This class represents the primary interface of a component based grid control to represent data + * in a tabular format of rows and columns. The GridPanel is composed of the following:

    + *
      + *
    • {@link Ext.data.Store Store} : The Model holding the data records (rows) + *
    • + *
    • {@link Ext.grid.ColumnModel Column model} : Column makeup + *
    • + *
    • {@link Ext.grid.GridView View} : Encapsulates the user interface + *
    • + *
    • {@link Ext.grid.AbstractSelectionModel selection model} : Selection behavior + *
    • + *
    + *

    Example usage:

    + *
    
    +var grid = new Ext.grid.GridPanel({
    +    {@link #store}: new {@link Ext.data.Store}({
    +        {@link Ext.data.Store#autoDestroy autoDestroy}: true,
    +        {@link Ext.data.Store#reader reader}: reader,
    +        {@link Ext.data.Store#data data}: xg.dummyData
    +    }),
    +    {@link #colModel}: new {@link Ext.grid.ColumnModel}({
    +        {@link Ext.grid.ColumnModel#defaults defaults}: {
    +            width: 120,
    +            sortable: true
    +        },
    +        {@link Ext.grid.ColumnModel#columns columns}: [
    +            {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
    +            {header: 'Price', renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
    +            {header: 'Change', dataIndex: 'change'},
    +            {header: '% Change', dataIndex: 'pctChange'},
    +            // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
    +            {
    +                header: 'Last Updated', width: 135, dataIndex: 'lastChange',
    +                xtype: 'datecolumn', format: 'M d, Y'
    +            }
    +        ]
    +    }),
    +    {@link #viewConfig}: {
    +        {@link Ext.grid.GridView#forceFit forceFit}: true,
    +
    +//      Return CSS class to apply to rows depending upon data values
    +        {@link Ext.grid.GridView#getRowClass getRowClass}: function(record, index) {
    +            var c = record.{@link Ext.data.Record#get get}('change');
    +            if (c < 0) {
    +                return 'price-fall';
    +            } else if (c > 0) {
    +                return 'price-rise';
    +            }
    +        }
    +    },
    +    {@link #sm}: new Ext.grid.RowSelectionModel({singleSelect:true}),
    +    width: 600,
    +    height: 300,
    +    frame: true,
    +    title: 'Framed with Row Selection and Horizontal Scrolling',
    +    iconCls: 'icon-grid'
    +});
    + * 
    + *

    Notes:

    + *
      + *
    • Although this class inherits many configuration options from base classes, some of them + * (such as autoScroll, autoWidth, layout, items, etc) are not used by this class, and will + * have no effect.
    • + *
    • A grid requires a width in which to scroll its columns, and a height in which to + * scroll its rows. These dimensions can either be set explicitly through the + * {@link Ext.BoxComponent#height height} and {@link Ext.BoxComponent#width width} + * configuration options or implicitly set by using the grid as a child item of a + * {@link Ext.Container Container} which will have a {@link Ext.Container#layout layout manager} + * provide the sizing of its child items (for example the Container of the Grid may specify + * {@link Ext.Container#layout layout}:'fit').
    • + *
    • To access the data in a Grid, it is necessary to use the data model encapsulated + * by the {@link #store Store}. See the {@link #cellclick} event for more details.
    • + *
    + * @constructor + * @param {Object} config The config object + * @xtype grid + */ +Ext.grid.GridPanel = Ext.extend(Ext.Panel, { + /** + * @cfg {String} autoExpandColumn + *

    The {@link Ext.grid.Column#id id} of a {@link Ext.grid.Column column} in + * this grid that should expand to fill unused space. This value specified here can not + * be 0.

    + *

    Note: If the Grid's {@link Ext.grid.GridView view} is configured with + * {@link Ext.grid.GridView#forceFit forceFit}=true the autoExpandColumn + * is ignored. See {@link Ext.grid.Column}.{@link Ext.grid.Column#width width} + * for additional details.

    + *

    See {@link #autoExpandMax} and {@link #autoExpandMin} also.

    + */ + autoExpandColumn : false, + + + autoExpandMax : 1000, + + + autoExpandMin : 50, + + + columnLines : false, + + + + + + + ddText : '{0} selected row{1}', + + + + + deferRowRender : true, + + + + + enableColumnHide : true, + + + enableColumnMove : true, + + + enableDragDrop : false, + + + enableHdMenu : true, + + + + loadMask : false, + + + + minColumnWidth : 25, + + + + + + stripeRows : false, + + + trackMouseOver : true, + + + stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'], + + + view : null, + + + bubbleEvents: [], + + + + + rendered : false, + + + viewReady : false, + + + initComponent : function() { + Ext.grid.GridPanel.superclass.initComponent.call(this); + + if (this.columnLines) { + this.cls = (this.cls || '') + ' x-grid-with-col-lines'; + } + + + this.autoScroll = false; + this.autoWidth = false; + + if(Ext.isArray(this.columns)){ + this.colModel = new Ext.grid.ColumnModel(this.columns); + delete this.columns; + } + + + if(this.ds){ + this.store = this.ds; + delete this.ds; + } + if(this.cm){ + this.colModel = this.cm; + delete this.cm; + } + if(this.sm){ + this.selModel = this.sm; + delete this.sm; + } + this.store = Ext.StoreMgr.lookup(this.store); + + this.addEvents( + + + 'click', + + 'dblclick', + + 'contextmenu', + + 'mousedown', + + 'mouseup', + + 'mouseover', + + 'mouseout', + + 'keypress', + + 'keydown', + + + + 'cellmousedown', + + 'rowmousedown', + + 'headermousedown', + + + 'groupmousedown', + + + 'rowbodymousedown', + + + 'containermousedown', + + + 'cellclick', + + 'celldblclick', + + 'rowclick', + + 'rowdblclick', + + 'headerclick', + + 'headerdblclick', + + 'groupclick', + + 'groupdblclick', + + 'containerclick', + + 'containerdblclick', + + + 'rowbodyclick', + + 'rowbodydblclick', + + + 'rowcontextmenu', + + 'cellcontextmenu', + + 'headercontextmenu', + + 'groupcontextmenu', + + 'containercontextmenu', + + 'rowbodycontextmenu', + + 'bodyscroll', + + 'columnresize', + + 'columnmove', + + 'sortchange', + + 'groupchange', + + 'reconfigure', + + 'viewready' + ); + }, + + + onRender : function(ct, position){ + Ext.grid.GridPanel.superclass.onRender.apply(this, arguments); + + var c = this.getGridEl(); + + this.el.addClass('x-grid-panel'); + + this.mon(c, { + scope: this, + mousedown: this.onMouseDown, + click: this.onClick, + dblclick: this.onDblClick, + contextmenu: this.onContextMenu + }); + + this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']); + + var view = this.getView(); + view.init(this); + view.render(); + this.getSelectionModel().init(this); + }, + + + initEvents : function(){ + Ext.grid.GridPanel.superclass.initEvents.call(this); + + if(this.loadMask){ + this.loadMask = new Ext.LoadMask(this.bwrap, + Ext.apply({store:this.store}, this.loadMask)); + } + }, + + initStateEvents : function(){ + Ext.grid.GridPanel.superclass.initStateEvents.call(this); + this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100}); + }, + + applyState : function(state){ + var cm = this.colModel, + cs = state.columns, + store = this.store, + s, + c, + colIndex; + + if(cs){ + for(var i = 0, len = cs.length; i < len; i++){ + s = cs[i]; + c = cm.getColumnById(s.id); + if(c){ + colIndex = cm.getIndexById(s.id); + cm.setState(colIndex, { + hidden: s.hidden, + width: s.width, + sortable: c.sortable, + editable: c.editable + }); + if(colIndex != i){ + cm.moveColumn(colIndex, i); + } + } + } + } + if(store){ + s = state.sort; + if(s){ + store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction); + } + s = state.group; + if(store.groupBy){ + if(s){ + store.groupBy(s); + }else{ + store.clearGrouping(); + } + } + + } + var o = Ext.apply({}, state); + delete o.columns; + delete o.sort; + Ext.grid.GridPanel.superclass.applyState.call(this, o); + }, + + getState : function(){ + var o = {columns: []}, + store = this.store, + ss, + gs; + + for(var i = 0, c; (c = this.colModel.config[i]); i++){ + o.columns[i] = { + id: c.id, + width: c.width + }; + if(c.hidden){ + o.columns[i].hidden = true; + } + } + if(store){ + ss = store.getSortState(); + if(ss){ + o.sort = ss; + } + if(store.getGroupState){ + gs = store.getGroupState(); + if(gs){ + o.group = gs; + } + } + } + return o; + }, + + + afterRender : function(){ + Ext.grid.GridPanel.superclass.afterRender.call(this); + var v = this.view; + this.on('bodyresize', v.layout, v); + v.layout(true); + if(this.deferRowRender){ + if (!this.deferRowRenderTask){ + this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view); + } + this.deferRowRenderTask.delay(10); + }else{ + v.afterRender(); + } + this.viewReady = true; + }, + + + reconfigure : function(store, colModel){ + var rendered = this.rendered; + if(rendered){ + if(this.loadMask){ + this.loadMask.destroy(); + this.loadMask = new Ext.LoadMask(this.bwrap, + Ext.apply({}, {store:store}, this.initialConfig.loadMask)); + } + } + if(this.view){ + this.view.initData(store, colModel); + } + this.store = store; + this.colModel = colModel; + if(rendered){ + this.view.refresh(true); + } + this.fireEvent('reconfigure', this, store, colModel); + }, + + + onDestroy : function(){ + if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){ + this.deferRowRenderTask.cancel(); + } + if(this.rendered){ + Ext.destroy(this.view, this.loadMask); + }else if(this.store && this.store.autoDestroy){ + this.store.destroy(); + } + Ext.destroy(this.colModel, this.selModel); + this.store = this.selModel = this.colModel = this.view = this.loadMask = null; + Ext.grid.GridPanel.superclass.onDestroy.call(this); + }, + + + processEvent : function(name, e){ + this.view.processEvent(name, e); + }, + + + onClick : function(e){ + this.processEvent('click', e); + }, + + + onMouseDown : function(e){ + this.processEvent('mousedown', e); + }, + + + onContextMenu : function(e, t){ + this.processEvent('contextmenu', e); + }, + + + onDblClick : function(e){ + this.processEvent('dblclick', e); + }, + + + walkCells : function(row, col, step, fn, scope){ + var cm = this.colModel, + clen = cm.getColumnCount(), + ds = this.store, + rlen = ds.getCount(), + first = true; + + if(step < 0){ + if(col < 0){ + row--; + first = false; + } + while(row >= 0){ + if(!first){ + col = clen-1; + } + first = false; + while(col >= 0){ + if(fn.call(scope || this, row, col, cm) === true){ + return [row, col]; + } + col--; + } + row--; + } + } else { + if(col >= clen){ + row++; + first = false; + } + while(row < rlen){ + if(!first){ + col = 0; + } + first = false; + while(col < clen){ + if(fn.call(scope || this, row, col, cm) === true){ + return [row, col]; + } + col++; + } + row++; + } + } + return null; + }, + + + getGridEl : function(){ + return this.body; + }, + + + stopEditing : Ext.emptyFn, + + + getSelectionModel : function(){ + if(!this.selModel){ + this.selModel = new Ext.grid.RowSelectionModel( + this.disableSelection ? {selectRow: Ext.emptyFn} : null); + } + return this.selModel; + }, + + + getStore : function(){ + return this.store; + }, + + + getColumnModel : function(){ + return this.colModel; + }, + + + getView : function() { + if (!this.view) { + this.view = new Ext.grid.GridView(this.viewConfig); + } + + return this.view; + }, + + getDragDropText : function(){ + var count = this.selModel.getCount ? this.selModel.getCount() : 1; + return String.format(this.ddText, count, count == 1 ? '' : 's'); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +}); +Ext.reg('grid', Ext.grid.GridPanel); +Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, { + + + aggregator: 'sum', + + + renderer: undefined, + + + + + + + + + initComponent: function() { + Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments); + + this.initAxes(); + + + this.enableColumnResize = false; + + this.viewConfig = Ext.apply(this.viewConfig || {}, { + forceFit: true + }); + + + + this.colModel = new Ext.grid.ColumnModel({}); + }, + + + getAggregator: function() { + if (typeof this.aggregator == 'string') { + return Ext.grid.PivotAggregatorMgr.types[this.aggregator]; + } else { + return this.aggregator; + } + }, + + + setAggregator: function(aggregator) { + this.aggregator = aggregator; + }, + + + setMeasure: function(measure) { + this.measure = measure; + }, + + + setLeftAxis: function(axis, refresh) { + + this.leftAxis = axis; + + if (refresh) { + this.view.refresh(); + } + }, + + + setTopAxis: function(axis, refresh) { + + this.topAxis = axis; + + if (refresh) { + this.view.refresh(); + } + }, + + + initAxes: function() { + var PivotAxis = Ext.grid.PivotAxis; + + if (!(this.leftAxis instanceof PivotAxis)) { + this.setLeftAxis(new PivotAxis({ + orientation: 'vertical', + dimensions : this.leftAxis || [], + store : this.store + })); + }; + + if (!(this.topAxis instanceof PivotAxis)) { + this.setTopAxis(new PivotAxis({ + orientation: 'horizontal', + dimensions : this.topAxis || [], + store : this.store + })); + }; + }, + + + extractData: function() { + var records = this.store.data.items, + recCount = records.length, + cells = [], + record, i, j, k; + + if (recCount == 0) { + return []; + } + + var leftTuples = this.leftAxis.getTuples(), + leftCount = leftTuples.length, + topTuples = this.topAxis.getTuples(), + topCount = topTuples.length, + aggregator = this.getAggregator(); + + for (i = 0; i < recCount; i++) { + record = records[i]; + + for (j = 0; j < leftCount; j++) { + cells[j] = cells[j] || []; + + if (leftTuples[j].matcher(record) === true) { + for (k = 0; k < topCount; k++) { + cells[j][k] = cells[j][k] || []; + + if (topTuples[k].matcher(record)) { + cells[j][k].push(record); + } + } + } + } + } + + var rowCount = cells.length, + colCount, row; + + for (i = 0; i < rowCount; i++) { + row = cells[i]; + colCount = row.length; + + for (j = 0; j < colCount; j++) { + cells[i][j] = aggregator(cells[i][j], this.measure); + } + } + + return cells; + }, + + + getView: function() { + if (!this.view) { + this.view = new Ext.grid.PivotGridView(this.viewConfig); + } + + return this.view; + } +}); + +Ext.reg('pivotgrid', Ext.grid.PivotGrid); + + +Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager(); + +Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) { + var length = records.length, + total = 0, + i; + + for (i = 0; i < length; i++) { + total += records[i].get(measure); + } + + return total; +}); + +Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) { + var length = records.length, + total = 0, + i; + + for (i = 0; i < length; i++) { + total += records[i].get(measure); + } + + return (total / length) || 'n/a'; +}); + +Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) { + var data = [], + length = records.length, + i; + + for (i = 0; i < length; i++) { + data.push(records[i].get(measure)); + } + + return Math.min.apply(this, data) || 'n/a'; +}); + +Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) { + var data = [], + length = records.length, + i; + + for (i = 0; i < length; i++) { + data.push(records[i].get(measure)); + } + + return Math.max.apply(this, data) || 'n/a'; +}); + +Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) { + return records.length; +}); +Ext.grid.GridView = Ext.extend(Ext.util.Observable, { + + + + + + + + + + + + deferEmptyText : true, + + + scrollOffset : undefined, + + + autoFill : false, + + + forceFit : false, + + + sortClasses : ['sort-asc', 'sort-desc'], + + + sortAscText : 'Sort Ascending', + + + sortDescText : 'Sort Descending', + + + hideSortIcons: false, + + + columnsText : 'Columns', + + + selectedRowClass : 'x-grid3-row-selected', + + + borderWidth : 2, + tdClass : 'x-grid3-cell', + hdCls : 'x-grid3-hd', + + + + markDirty : true, + + + cellSelectorDepth : 4, + + + rowSelectorDepth : 10, + + + rowBodySelectorDepth : 10, + + + cellSelector : 'td.x-grid3-cell', + + + rowSelector : 'div.x-grid3-row', + + + rowBodySelector : 'div.x-grid3-row-body', + + + firstRowCls: 'x-grid3-row-first', + lastRowCls: 'x-grid3-row-last', + rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g, + + + headerMenuOpenCls: 'x-grid3-hd-menu-open', + + + rowOverCls: 'x-grid3-row-over', + + constructor : function(config) { + Ext.apply(this, config); + + + this.addEvents( + + 'beforerowremoved', + + + 'beforerowsinserted', + + + 'beforerefresh', + + + 'rowremoved', + + + 'rowsinserted', + + + 'rowupdated', + + + 'refresh' + ); + + Ext.grid.GridView.superclass.constructor.call(this); + }, + + + + + masterTpl: new Ext.Template( + '
    ', + '
    ', + '
    ', + '
    ', + '
    {header}
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    {body}
    ', + '', + '
    ', + '
    ', + '
     
    ', + '
     
    ', + '
    ' + ), + + + headerTpl: new Ext.Template( + '', + '', + '{cells}', + '', + '
    ' + ), + + + bodyTpl: new Ext.Template('{rows}'), + + + cellTpl: new Ext.Template( + '', + '
    {value}
    ', + '' + ), + + + initTemplates : function() { + var templates = this.templates || {}, + template, name, + + headerCellTpl = new Ext.Template( + '', + '
    ', + this.grid.enableHdMenu ? '' : '', + '{value}', + '', + '
    ', + '' + ), + + rowBodyText = [ + '', + '', + '
    {body}
    ', + '', + '' + ].join(""), + + innerText = [ + '', + '', + '{cells}', + this.enableRowBody ? rowBodyText : '', + '', + '
    ' + ].join(""); + + Ext.applyIf(templates, { + hcell : headerCellTpl, + cell : this.cellTpl, + body : this.bodyTpl, + header : this.headerTpl, + master : this.masterTpl, + row : new Ext.Template('
    ' + innerText + '
    '), + rowInner: new Ext.Template(innerText) + }); + + for (name in templates) { + template = templates[name]; + + if (template && Ext.isFunction(template.compile) && !template.compiled) { + template.disableFormats = true; + template.compile(); + } + } + + this.templates = templates; + this.colRe = new RegExp('x-grid3-td-([^\\s]+)', ''); + }, + + + fly : function(el) { + if (!this._flyweight) { + this._flyweight = new Ext.Element.Flyweight(document.body); + } + this._flyweight.dom = el; + return this._flyweight; + }, + + + getEditorParent : function() { + return this.scroller.dom; + }, + + + initElements : function() { + var Element = Ext.Element, + el = Ext.get(this.grid.getGridEl().dom.firstChild), + mainWrap = new Element(el.child('div.x-grid3-viewport')), + mainHd = new Element(mainWrap.child('div.x-grid3-header')), + scroller = new Element(mainWrap.child('div.x-grid3-scroller')); + + if (this.grid.hideHeaders) { + mainHd.setDisplayed(false); + } + + if (this.forceFit) { + scroller.setStyle('overflow-x', 'hidden'); + } + + + + Ext.apply(this, { + el : el, + mainWrap: mainWrap, + scroller: scroller, + mainHd : mainHd, + innerHd : mainHd.child('div.x-grid3-header-inner').dom, + mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')), + focusEl : new Element(Element.fly(scroller).child('a')), + + resizeMarker: new Element(el.child('div.x-grid3-resize-marker')), + resizeProxy : new Element(el.child('div.x-grid3-resize-proxy')) + }); + + this.focusEl.swallowEvent('click', true); + }, + + + getRows : function() { + return this.hasRows() ? this.mainBody.dom.childNodes : []; + }, + + + + + findCell : function(el) { + if (!el) { + return false; + } + return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth); + }, + + + findCellIndex : function(el, requiredCls) { + var cell = this.findCell(el), + hasCls; + + if (cell) { + hasCls = this.fly(cell).hasClass(requiredCls); + if (!requiredCls || hasCls) { + return this.getCellIndex(cell); + } + } + return false; + }, + + + getCellIndex : function(el) { + if (el) { + var match = el.className.match(this.colRe); + + if (match && match[1]) { + return this.cm.getIndexById(match[1]); + } + } + return false; + }, + + + findHeaderCell : function(el) { + var cell = this.findCell(el); + return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null; + }, + + + findHeaderIndex : function(el){ + return this.findCellIndex(el, this.hdCls); + }, + + + findRow : function(el) { + if (!el) { + return false; + } + return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth); + }, + + + findRowIndex : function(el) { + var row = this.findRow(el); + return row ? row.rowIndex : false; + }, + + + findRowBody : function(el) { + if (!el) { + return false; + } + + return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth); + }, + + + + + getRow : function(row) { + return this.getRows()[row]; + }, + + + getCell : function(row, col) { + return Ext.fly(this.getRow(row)).query(this.cellSelector)[col]; + }, + + + getHeaderCell : function(index) { + return this.mainHd.dom.getElementsByTagName('td')[index]; + }, + + + + + addRowClass : function(rowId, cls) { + var row = this.getRow(rowId); + if (row) { + this.fly(row).addClass(cls); + } + }, + + + removeRowClass : function(row, cls) { + var r = this.getRow(row); + if(r){ + this.fly(r).removeClass(cls); + } + }, + + + removeRow : function(row) { + Ext.removeNode(this.getRow(row)); + this.syncFocusEl(row); + }, + + + removeRows : function(firstRow, lastRow) { + var bd = this.mainBody.dom, + rowIndex; + + for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){ + Ext.removeNode(bd.childNodes[firstRow]); + } + + this.syncFocusEl(firstRow); + }, + + + + + getScrollState : function() { + var sb = this.scroller.dom; + + return { + left: sb.scrollLeft, + top : sb.scrollTop + }; + }, + + + restoreScroll : function(state) { + var sb = this.scroller.dom; + sb.scrollLeft = state.left; + sb.scrollTop = state.top; + }, + + + scrollToTop : function() { + var dom = this.scroller.dom; + + dom.scrollTop = 0; + dom.scrollLeft = 0; + }, + + + syncScroll : function() { + this.syncHeaderScroll(); + var mb = this.scroller.dom; + this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop); + }, + + + syncHeaderScroll : function() { + var innerHd = this.innerHd, + scrollLeft = this.scroller.dom.scrollLeft; + + innerHd.scrollLeft = scrollLeft; + innerHd.scrollLeft = scrollLeft; + }, + + + updateSortIcon : function(col, dir) { + var sortClasses = this.sortClasses, + sortClass = sortClasses[dir == "DESC" ? 1 : 0], + headers = this.mainHd.select('td').removeClass(sortClasses); + + headers.item(col).addClass(sortClass); + }, + + + updateAllColumnWidths : function() { + var totalWidth = this.getTotalWidth(), + colCount = this.cm.getColumnCount(), + rows = this.getRows(), + rowCount = rows.length, + widths = [], + row, rowFirstChild, trow, i, j; + + for (i = 0; i < colCount; i++) { + widths[i] = this.getColumnWidth(i); + this.getHeaderCell(i).style.width = widths[i]; + } + + this.updateHeaderWidth(); + + for (i = 0; i < rowCount; i++) { + row = rows[i]; + row.style.width = totalWidth; + rowFirstChild = row.firstChild; + + if (rowFirstChild) { + rowFirstChild.style.width = totalWidth; + trow = rowFirstChild.rows[0]; + + for (j = 0; j < colCount; j++) { + trow.childNodes[j].style.width = widths[j]; + } + } + } + + this.onAllColumnWidthsUpdated(widths, totalWidth); + }, + + + updateColumnWidth : function(column, width) { + var columnWidth = this.getColumnWidth(column), + totalWidth = this.getTotalWidth(), + headerCell = this.getHeaderCell(column), + nodes = this.getRows(), + nodeCount = nodes.length, + row, i, firstChild; + + this.updateHeaderWidth(); + headerCell.style.width = columnWidth; + + for (i = 0; i < nodeCount; i++) { + row = nodes[i]; + firstChild = row.firstChild; + + row.style.width = totalWidth; + if (firstChild) { + firstChild.style.width = totalWidth; + firstChild.rows[0].childNodes[column].style.width = columnWidth; + } + } + + this.onColumnWidthUpdated(column, columnWidth, totalWidth); + }, + + + updateColumnHidden : function(col, hidden) { + var totalWidth = this.getTotalWidth(), + display = hidden ? 'none' : '', + headerCell = this.getHeaderCell(col), + nodes = this.getRows(), + nodeCount = nodes.length, + row, rowFirstChild, i; + + this.updateHeaderWidth(); + headerCell.style.display = display; + + for (i = 0; i < nodeCount; i++) { + row = nodes[i]; + row.style.width = totalWidth; + rowFirstChild = row.firstChild; + + if (rowFirstChild) { + rowFirstChild.style.width = totalWidth; + rowFirstChild.rows[0].childNodes[col].style.display = display; + } + } + + this.onColumnHiddenUpdated(col, hidden, totalWidth); + delete this.lastViewWidth; + this.layout(); + }, + + + doRender : function(columns, records, store, startRow, colCount, stripe) { + var templates = this.templates, + cellTemplate = templates.cell, + rowTemplate = templates.row, + last = colCount - 1, + tstyle = 'width:' + this.getTotalWidth() + ';', + + rowBuffer = [], + colBuffer = [], + rowParams = {tstyle: tstyle}, + meta = {}, + len = records.length, + alt, + column, + record, i, j, rowIndex; + + + for (j = 0; j < len; j++) { + record = records[j]; + colBuffer = []; + + rowIndex = j + startRow; + + + for (i = 0; i < colCount; i++) { + column = columns[i]; + + meta.id = column.id; + meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : ''); + meta.attr = meta.cellAttr = ''; + meta.style = column.style; + meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store); + + if (Ext.isEmpty(meta.value)) { + meta.value = ' '; + } + + if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') { + meta.css += ' x-grid3-dirty-cell'; + } + + colBuffer[colBuffer.length] = cellTemplate.apply(meta); + } + + alt = []; + + if (stripe && ((rowIndex + 1) % 2 === 0)) { + alt[0] = 'x-grid3-row-alt'; + } + + if (record.dirty) { + alt[1] = ' x-grid3-dirty-row'; + } + + rowParams.cols = colCount; + + if (this.getRowClass) { + alt[2] = this.getRowClass(record, rowIndex, rowParams, store); + } + + rowParams.alt = alt.join(' '); + rowParams.cells = colBuffer.join(''); + + rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams); + } + + return rowBuffer.join(''); + }, + + + processRows : function(startRow, skipStripe) { + if (!this.ds || this.ds.getCount() < 1) { + return; + } + + var rows = this.getRows(), + length = rows.length, + row, i; + + skipStripe = skipStripe || !this.grid.stripeRows; + startRow = startRow || 0; + + for (i = 0; i < length; i++) { + row = rows[i]; + if (row) { + row.rowIndex = i; + if (!skipStripe) { + row.className = row.className.replace(this.rowClsRe, ' '); + if ((i + 1) % 2 === 0){ + row.className += ' x-grid3-row-alt'; + } + } + } + } + + + if (startRow === 0) { + Ext.fly(rows[0]).addClass(this.firstRowCls); + } + + Ext.fly(rows[length - 1]).addClass(this.lastRowCls); + }, + + + afterRender : function() { + if (!this.ds || !this.cm) { + return; + } + + this.mainBody.dom.innerHTML = this.renderBody() || ' '; + this.processRows(0, true); + + if (this.deferEmptyText !== true) { + this.applyEmptyText(); + } + + this.grid.fireEvent('viewready', this.grid); + }, + + + afterRenderUI: function() { + var grid = this.grid; + + this.initElements(); + + + Ext.fly(this.innerHd).on('click', this.handleHdDown, this); + + this.mainHd.on({ + scope : this, + mouseover: this.handleHdOver, + mouseout : this.handleHdOut, + mousemove: this.handleHdMove + }); + + this.scroller.on('scroll', this.syncScroll, this); + + if (grid.enableColumnResize !== false) { + this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom); + } + + if (grid.enableColumnMove) { + this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd); + this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom); + } + + if (grid.enableHdMenu !== false) { + this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'}); + this.hmenu.add( + {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, + {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} + ); + + if (grid.enableColumnHide !== false) { + this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'}); + this.colMenu.on({ + scope : this, + beforeshow: this.beforeColMenuShow, + itemclick : this.handleHdMenuClick + }); + this.hmenu.add({ + itemId: 'sortSep', + xtype: 'menuseparator' + }, { + itemId:'columns', + hideOnClick: false, + text: this.columnsText, + menu: this.colMenu, + iconCls: 'x-cols-icon' + }); + } + + this.hmenu.on('itemclick', this.handleHdMenuClick, this); + } + + if (grid.trackMouseOver) { + this.mainBody.on({ + scope : this, + mouseover: this.onRowOver, + mouseout : this.onRowOut + }); + } + + if (grid.enableDragDrop || grid.enableDrag) { + this.dragZone = new Ext.grid.GridDragZone(grid, { + ddGroup : grid.ddGroup || 'GridDD' + }); + } + + this.updateHeaderSortState(); + }, + + + renderUI : function() { + var templates = this.templates; + + return templates.master.apply({ + body : templates.body.apply({rows:' '}), + header: this.renderHeaders(), + ostyle: 'width:' + this.getOffsetWidth() + ';', + bstyle: 'width:' + this.getTotalWidth() + ';' + }); + }, + + + processEvent : function(name, e) { + var target = e.getTarget(), + grid = this.grid, + header = this.findHeaderIndex(target), + row, cell, col, body; + + grid.fireEvent(name, e); + + if (header !== false) { + grid.fireEvent('header' + name, grid, header, e); + } else { + row = this.findRowIndex(target); + + + + + if (row !== false) { + cell = this.findCellIndex(target); + if (cell !== false) { + col = grid.colModel.getColumnAt(cell); + if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) { + if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) { + grid.fireEvent('row' + name, grid, row, e); + } + } + } else { + if (grid.fireEvent('row' + name, grid, row, e) !== false) { + (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e); + } + } + } else { + grid.fireEvent('container' + name, grid, e); + } + } + }, + + + layout : function(initial) { + if (!this.mainBody) { + return; + } + + var grid = this.grid, + gridEl = grid.getGridEl(), + gridSize = gridEl.getSize(true), + gridWidth = gridSize.width, + gridHeight = gridSize.height, + scroller = this.scroller, + scrollStyle, headerHeight, scrollHeight; + + if (gridWidth < 20 || gridHeight < 20) { + return; + } + + if (grid.autoHeight) { + scrollStyle = scroller.dom.style; + scrollStyle.overflow = 'visible'; + + if (Ext.isWebKit) { + scrollStyle.position = 'static'; + } + } else { + this.el.setSize(gridWidth, gridHeight); + + headerHeight = this.mainHd.getHeight(); + scrollHeight = gridHeight - headerHeight; + + scroller.setSize(gridWidth, scrollHeight); + + if (this.innerHd) { + this.innerHd.style.width = (gridWidth) + "px"; + } + } + + if (this.forceFit || (initial === true && this.autoFill)) { + if (this.lastViewWidth != gridWidth) { + this.fitColumns(false, false); + this.lastViewWidth = gridWidth; + } + } else { + this.autoExpand(); + this.syncHeaderScroll(); + } + + this.onLayout(gridWidth, scrollHeight); + }, + + + + onLayout : function(vw, vh) { + + }, + + onColumnWidthUpdated : function(col, w, tw) { + + }, + + onAllColumnWidthsUpdated : function(ws, tw) { + + }, + + onColumnHiddenUpdated : function(col, hidden, tw) { + + }, + + updateColumnText : function(col, text) { + + }, + + afterMove : function(colIndex) { + + }, + + + + init : function(grid) { + this.grid = grid; + + this.initTemplates(); + this.initData(grid.store, grid.colModel); + this.initUI(grid); + }, + + + getColumnId : function(index){ + return this.cm.getColumnId(index); + }, + + + getOffsetWidth : function() { + return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px'; + }, + + + getScrollOffset: function() { + return Ext.num(this.scrollOffset, Ext.getScrollBarWidth()); + }, + + + renderHeaders : function() { + var colModel = this.cm, + templates = this.templates, + headerTpl = templates.hcell, + properties = {}, + colCount = colModel.getColumnCount(), + last = colCount - 1, + cells = [], + i, cssCls; + + for (i = 0; i < colCount; i++) { + if (i == 0) { + cssCls = 'x-grid3-cell-first '; + } else { + cssCls = i == last ? 'x-grid3-cell-last ' : ''; + } + + properties = { + id : colModel.getColumnId(i), + value : colModel.getColumnHeader(i) || '', + style : this.getColumnStyle(i, true), + css : cssCls, + tooltip: this.getColumnTooltip(i) + }; + + if (colModel.config[i].align == 'right') { + properties.istyle = 'padding-right: 16px;'; + } else { + delete properties.istyle; + } + + cells[i] = headerTpl.apply(properties); + } + + return templates.header.apply({ + cells : cells.join(""), + tstyle: String.format("width: {0};", this.getTotalWidth()) + }); + }, + + + getColumnTooltip : function(i) { + var tooltip = this.cm.getColumnTooltip(i); + if (tooltip) { + if (Ext.QuickTips.isEnabled()) { + return 'ext:qtip="' + tooltip + '"'; + } else { + return 'title="' + tooltip + '"'; + } + } + + return ''; + }, + + + beforeUpdate : function() { + this.grid.stopEditing(true); + }, + + + updateHeaders : function() { + this.innerHd.firstChild.innerHTML = this.renderHeaders(); + + this.updateHeaderWidth(false); + }, + + + updateHeaderWidth: function(updateMain) { + var innerHdChild = this.innerHd.firstChild, + totalWidth = this.getTotalWidth(); + + innerHdChild.style.width = this.getOffsetWidth(); + innerHdChild.firstChild.style.width = totalWidth; + + if (updateMain !== false) { + this.mainBody.dom.style.width = totalWidth; + } + }, + + + focusRow : function(row) { + this.focusCell(row, 0, false); + }, + + + focusCell : function(row, col, hscroll) { + this.syncFocusEl(this.ensureVisible(row, col, hscroll)); + + var focusEl = this.focusEl; + + if (Ext.isGecko) { + focusEl.focus(); + } else { + focusEl.focus.defer(1, focusEl); + } + }, + + + resolveCell : function(row, col, hscroll) { + if (!Ext.isNumber(row)) { + row = row.rowIndex; + } + + if (!this.ds) { + return null; + } + + if (row < 0 || row >= this.ds.getCount()) { + return null; + } + col = (col !== undefined ? col : 0); + + var rowEl = this.getRow(row), + colModel = this.cm, + colCount = colModel.getColumnCount(), + cellEl; + + if (!(hscroll === false && col === 0)) { + while (col < colCount && colModel.isHidden(col)) { + col++; + } + + cellEl = this.getCell(row, col); + } + + return {row: rowEl, cell: cellEl}; + }, + + + getResolvedXY : function(resolved) { + if (!resolved) { + return null; + } + + var cell = resolved.cell, + row = resolved.row; + + if (cell) { + return Ext.fly(cell).getXY(); + } else { + return [this.el.getX(), Ext.fly(row).getY()]; + } + }, + + + syncFocusEl : function(row, col, hscroll) { + var xy = row; + + if (!Ext.isArray(xy)) { + row = Math.min(row, Math.max(0, this.getRows().length-1)); + + if (isNaN(row)) { + return; + } + + xy = this.getResolvedXY(this.resolveCell(row, col, hscroll)); + } + + this.focusEl.setXY(xy || this.scroller.getXY()); + }, + + + ensureVisible : function(row, col, hscroll) { + var resolved = this.resolveCell(row, col, hscroll); + + if (!resolved || !resolved.row) { + return null; + } + + var rowEl = resolved.row, + cellEl = resolved.cell, + c = this.scroller.dom, + p = rowEl, + ctop = 0, + stop = this.el.dom; + + while (p && p != stop) { + ctop += p.offsetTop; + p = p.offsetParent; + } + + ctop -= this.mainHd.dom.offsetHeight; + stop = parseInt(c.scrollTop, 10); + + var cbot = ctop + rowEl.offsetHeight, + ch = c.clientHeight, + sbot = stop + ch; + + + if (ctop < stop) { + c.scrollTop = ctop; + } else if(cbot > sbot) { + c.scrollTop = cbot-ch; + } + + if (hscroll !== false) { + var cleft = parseInt(cellEl.offsetLeft, 10), + cright = cleft + cellEl.offsetWidth, + sleft = parseInt(c.scrollLeft, 10), + sright = sleft + c.clientWidth; + + if (cleft < sleft) { + c.scrollLeft = cleft; + } else if(cright > sright) { + c.scrollLeft = cright-c.clientWidth; + } + } + + return this.getResolvedXY(resolved); + }, + + + insertRows : function(dm, firstRow, lastRow, isUpdate) { + var last = dm.getCount() - 1; + if( !isUpdate && firstRow === 0 && lastRow >= last) { + this.fireEvent('beforerowsinserted', this, firstRow, lastRow); + this.refresh(); + this.fireEvent('rowsinserted', this, firstRow, lastRow); + } else { + if (!isUpdate) { + this.fireEvent('beforerowsinserted', this, firstRow, lastRow); + } + var html = this.renderRows(firstRow, lastRow), + before = this.getRow(firstRow); + if (before) { + if(firstRow === 0){ + Ext.fly(this.getRow(0)).removeClass(this.firstRowCls); + } + Ext.DomHelper.insertHtml('beforeBegin', before, html); + } else { + var r = this.getRow(last - 1); + if(r){ + Ext.fly(r).removeClass(this.lastRowCls); + } + Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); + } + if (!isUpdate) { + this.processRows(firstRow); + this.fireEvent('rowsinserted', this, firstRow, lastRow); + } else if (firstRow === 0 || firstRow >= last) { + + Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls); + } + } + this.syncFocusEl(firstRow); + }, + + + deleteRows : function(dm, firstRow, lastRow) { + if (dm.getRowCount() < 1) { + this.refresh(); + } else { + this.fireEvent('beforerowsdeleted', this, firstRow, lastRow); + + this.removeRows(firstRow, lastRow); + + this.processRows(firstRow); + this.fireEvent('rowsdeleted', this, firstRow, lastRow); + } + }, + + + getColumnStyle : function(colIndex, isHeader) { + var colModel = this.cm, + colConfig = colModel.config, + style = isHeader ? '' : colConfig[colIndex].css || '', + align = colConfig[colIndex].align; + + style += String.format("width: {0};", this.getColumnWidth(colIndex)); + + if (colModel.isHidden(colIndex)) { + style += 'display: none; '; + } + + if (align) { + style += String.format("text-align: {0};", align); + } + + return style; + }, + + + getColumnWidth : function(column) { + var columnWidth = this.cm.getColumnWidth(column), + borderWidth = this.borderWidth; + + if (Ext.isNumber(columnWidth)) { + if (Ext.isBorderBox) { + return columnWidth + "px"; + } else { + return Math.max(columnWidth - borderWidth, 0) + "px"; + } + } else { + return columnWidth; + } + }, + + + getTotalWidth : function() { + return this.cm.getTotalWidth() + 'px'; + }, + + + fitColumns : function(preventRefresh, onlyExpand, omitColumn) { + var grid = this.grid, + colModel = this.cm, + totalColWidth = colModel.getTotalWidth(false), + gridWidth = this.getGridInnerWidth(), + extraWidth = gridWidth - totalColWidth, + columns = [], + extraCol = 0, + width = 0, + colWidth, fraction, i; + + + if (gridWidth < 20 || extraWidth === 0) { + return false; + } + + var visibleColCount = colModel.getColumnCount(true), + totalColCount = colModel.getColumnCount(false), + adjCount = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0); + + if (adjCount === 0) { + adjCount = 1; + omitColumn = undefined; + } + + + for (i = 0; i < totalColCount; i++) { + if (!colModel.isFixed(i) && i !== omitColumn) { + colWidth = colModel.getColumnWidth(i); + columns.push(i, colWidth); + + if (!colModel.isHidden(i)) { + extraCol = i; + width += colWidth; + } + } + } + + fraction = (gridWidth - colModel.getTotalWidth()) / width; + + while (columns.length) { + colWidth = columns.pop(); + i = columns.pop(); + + colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true); + } + + + totalColWidth = colModel.getTotalWidth(false); + + if (totalColWidth > gridWidth) { + var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn, + newWidth = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth)); + + colModel.setColumnWidth(adjustCol, newWidth, true); + } + + if (preventRefresh !== true) { + this.updateAllColumnWidths(); + } + + return true; + }, + + + autoExpand : function(preventUpdate) { + var grid = this.grid, + colModel = this.cm, + gridWidth = this.getGridInnerWidth(), + totalColumnWidth = colModel.getTotalWidth(false), + autoExpandColumn = grid.autoExpandColumn; + + if (!this.userResized && autoExpandColumn) { + if (gridWidth != totalColumnWidth) { + + var colIndex = colModel.getIndexById(autoExpandColumn), + currentWidth = colModel.getColumnWidth(colIndex), + desiredWidth = gridWidth - totalColumnWidth + currentWidth, + newWidth = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax); + + if (currentWidth != newWidth) { + colModel.setColumnWidth(colIndex, newWidth, true); + + if (preventUpdate !== true) { + this.updateColumnWidth(colIndex, newWidth); + } + } + } + } + }, + + + getGridInnerWidth: function() { + return this.grid.getGridEl().getWidth(true) - this.getScrollOffset(); + }, + + + getColumnData : function() { + var columns = [], + colModel = this.cm, + colCount = colModel.getColumnCount(), + fields = this.ds.fields, + i, name; + + for (i = 0; i < colCount; i++) { + name = colModel.getDataIndex(i); + + columns[i] = { + name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined), + renderer: colModel.getRenderer(i), + scope : colModel.getRendererScope(i), + id : colModel.getColumnId(i), + style : this.getColumnStyle(i) + }; + } + + return columns; + }, + + + renderRows : function(startRow, endRow) { + var grid = this.grid, + store = grid.store, + stripe = grid.stripeRows, + colModel = grid.colModel, + colCount = colModel.getColumnCount(), + rowCount = store.getCount(), + records; + + if (rowCount < 1) { + return ''; + } + + startRow = startRow || 0; + endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1; + records = store.getRange(startRow, endRow); + + return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe); + }, + + + renderBody : function(){ + var markup = this.renderRows() || ' '; + return this.templates.body.apply({rows: markup}); + }, + + + refreshRow: function(record) { + var store = this.ds, + colCount = this.cm.getColumnCount(), + columns = this.getColumnData(), + last = colCount - 1, + cls = ['x-grid3-row'], + rowParams = { + tstyle: String.format("width: {0};", this.getTotalWidth()) + }, + colBuffer = [], + cellTpl = this.templates.cell, + rowIndex, row, column, meta, css, i; + + if (Ext.isNumber(record)) { + rowIndex = record; + record = store.getAt(rowIndex); + } else { + rowIndex = store.indexOf(record); + } + + + if (!record || rowIndex < 0) { + return; + } + + + for (i = 0; i < colCount; i++) { + column = columns[i]; + + if (i == 0) { + css = 'x-grid3-cell-first'; + } else { + css = (i == last) ? 'x-grid3-cell-last ' : ''; + } + + meta = { + id : column.id, + style : column.style, + css : css, + attr : "", + cellAttr: "" + }; + + meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store); + + if (Ext.isEmpty(meta.value)) { + meta.value = ' '; + } + + if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') { + meta.css += ' x-grid3-dirty-cell'; + } + + colBuffer[i] = cellTpl.apply(meta); + } + + row = this.getRow(rowIndex); + row.className = ''; + + if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) { + cls.push('x-grid3-row-alt'); + } + + if (this.getRowClass) { + rowParams.cols = colCount; + cls.push(this.getRowClass(record, rowIndex, rowParams, store)); + } + + this.fly(row).addClass(cls).setStyle(rowParams.tstyle); + rowParams.cells = colBuffer.join(""); + row.innerHTML = this.templates.rowInner.apply(rowParams); + + this.fireEvent('rowupdated', this, rowIndex, record); + }, + + + refresh : function(headersToo) { + this.fireEvent('beforerefresh', this); + this.grid.stopEditing(true); + + var result = this.renderBody(); + this.mainBody.update(result).setWidth(this.getTotalWidth()); + if (headersToo === true) { + this.updateHeaders(); + this.updateHeaderSortState(); + } + this.processRows(0, true); + this.layout(); + this.applyEmptyText(); + this.fireEvent('refresh', this); + }, + + + applyEmptyText : function() { + if (this.emptyText && !this.hasRows()) { + this.mainBody.update('
    ' + this.emptyText + '
    '); + } + }, + + + updateHeaderSortState : function() { + var state = this.ds.getSortState(); + if (!state) { + return; + } + + if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) { + this.grid.fireEvent('sortchange', this.grid, state); + } + + this.sortState = state; + + var sortColumn = this.cm.findColumnIndex(state.field); + if (sortColumn != -1) { + var sortDir = state.direction; + this.updateSortIcon(sortColumn, sortDir); + } + }, + + + clearHeaderSortState : function() { + if (!this.sortState) { + return; + } + this.grid.fireEvent('sortchange', this.grid, null); + this.mainHd.select('td').removeClass(this.sortClasses); + delete this.sortState; + }, + + + destroy : function() { + var me = this, + grid = me.grid, + gridEl = grid.getGridEl(), + dragZone = me.dragZone, + splitZone = me.splitZone, + columnDrag = me.columnDrag, + columnDrop = me.columnDrop, + scrollToTopTask = me.scrollToTopTask, + columnDragData, + columnDragProxy; + + if (scrollToTopTask && scrollToTopTask.cancel) { + scrollToTopTask.cancel(); + } + + Ext.destroyMembers(me, 'colMenu', 'hmenu'); + + me.initData(null, null); + me.purgeListeners(); + + Ext.fly(me.innerHd).un("click", me.handleHdDown, me); + + if (grid.enableColumnMove) { + columnDragData = columnDrag.dragData; + columnDragProxy = columnDrag.proxy; + Ext.destroy( + columnDrag.el, + columnDragProxy.ghost, + columnDragProxy.el, + columnDrop.el, + columnDrop.proxyTop, + columnDrop.proxyBottom, + columnDragData.ddel, + columnDragData.header + ); + + if (columnDragProxy.anim) { + Ext.destroy(columnDragProxy.anim); + } + + delete columnDragProxy.ghost; + delete columnDragData.ddel; + delete columnDragData.header; + columnDrag.destroy(); + + delete Ext.dd.DDM.locationCache[columnDrag.id]; + delete columnDrag._domRef; + + delete columnDrop.proxyTop; + delete columnDrop.proxyBottom; + columnDrop.destroy(); + delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id]; + delete columnDrop._domRef; + delete Ext.dd.DDM.ids[columnDrop.ddGroup]; + } + + if (splitZone) { + splitZone.destroy(); + delete splitZone._domRef; + delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id]; + } + + Ext.fly(me.innerHd).removeAllListeners(); + Ext.removeNode(me.innerHd); + delete me.innerHd; + + Ext.destroy( + me.el, + me.mainWrap, + me.mainHd, + me.scroller, + me.mainBody, + me.focusEl, + me.resizeMarker, + me.resizeProxy, + me.activeHdBtn, + me._flyweight, + dragZone, + splitZone + ); + + delete grid.container; + + if (dragZone) { + dragZone.destroy(); + } + + Ext.dd.DDM.currentTarget = null; + delete Ext.dd.DDM.locationCache[gridEl.id]; + + Ext.EventManager.removeResizeListener(me.onWindowResize, me); + }, + + + onDenyColumnHide : function() { + + }, + + + render : function() { + if (this.autoFill) { + var ct = this.grid.ownerCt; + + if (ct && ct.getLayout()) { + ct.on('afterlayout', function() { + this.fitColumns(true, true); + this.updateHeaders(); + this.updateHeaderSortState(); + }, this, {single: true}); + } + } else if (this.forceFit) { + this.fitColumns(true, false); + } else if (this.grid.autoExpandColumn) { + this.autoExpand(true); + } + + this.grid.getGridEl().dom.innerHTML = this.renderUI(); + + this.afterRenderUI(); + }, + + + + + initData : function(newStore, newColModel) { + var me = this; + + if (me.ds) { + var oldStore = me.ds; + + oldStore.un('add', me.onAdd, me); + oldStore.un('load', me.onLoad, me); + oldStore.un('clear', me.onClear, me); + oldStore.un('remove', me.onRemove, me); + oldStore.un('update', me.onUpdate, me); + oldStore.un('datachanged', me.onDataChange, me); + + if (oldStore !== newStore && oldStore.autoDestroy) { + oldStore.destroy(); + } + } + + if (newStore) { + newStore.on({ + scope : me, + load : me.onLoad, + add : me.onAdd, + remove : me.onRemove, + update : me.onUpdate, + clear : me.onClear, + datachanged: me.onDataChange + }); + } + + if (me.cm) { + var oldColModel = me.cm; + + oldColModel.un('configchange', me.onColConfigChange, me); + oldColModel.un('widthchange', me.onColWidthChange, me); + oldColModel.un('headerchange', me.onHeaderChange, me); + oldColModel.un('hiddenchange', me.onHiddenChange, me); + oldColModel.un('columnmoved', me.onColumnMove, me); + } + + if (newColModel) { + delete me.lastViewWidth; + + newColModel.on({ + scope : me, + configchange: me.onColConfigChange, + widthchange : me.onColWidthChange, + headerchange: me.onHeaderChange, + hiddenchange: me.onHiddenChange, + columnmoved : me.onColumnMove + }); + } + + me.ds = newStore; + me.cm = newColModel; + }, + + + onDataChange : function(){ + this.refresh(true); + this.updateHeaderSortState(); + this.syncFocusEl(0); + }, + + + onClear : function() { + this.refresh(); + this.syncFocusEl(0); + }, + + + onUpdate : function(store, record) { + this.refreshRow(record); + }, + + + onAdd : function(store, records, index) { + this.insertRows(store, index, index + (records.length-1)); + }, + + + onRemove : function(store, record, index, isUpdate) { + if (isUpdate !== true) { + this.fireEvent('beforerowremoved', this, index, record); + } + + this.removeRow(index); + + if (isUpdate !== true) { + this.processRows(index); + this.applyEmptyText(); + this.fireEvent('rowremoved', this, index, record); + } + }, + + + onLoad : function() { + if (Ext.isGecko) { + if (!this.scrollToTopTask) { + this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this); + } + this.scrollToTopTask.delay(1); + } else { + this.scrollToTop(); + } + }, + + + onColWidthChange : function(cm, col, width) { + this.updateColumnWidth(col, width); + }, + + + onHeaderChange : function(cm, col, text) { + this.updateHeaders(); + }, + + + onHiddenChange : function(cm, col, hidden) { + this.updateColumnHidden(col, hidden); + }, + + + onColumnMove : function(cm, oldIndex, newIndex) { + this.indexMap = null; + this.refresh(true); + this.restoreScroll(this.getScrollState()); + + this.afterMove(newIndex); + this.grid.fireEvent('columnmove', oldIndex, newIndex); + }, + + + onColConfigChange : function() { + delete this.lastViewWidth; + this.indexMap = null; + this.refresh(true); + }, + + + + initUI : function(grid) { + grid.on('headerclick', this.onHeaderClick, this); + }, + + + initEvents : Ext.emptyFn, + + + onHeaderClick : function(g, index) { + if (this.headersDisabled || !this.cm.isSortable(index)) { + return; + } + g.stopEditing(true); + g.store.sort(this.cm.getDataIndex(index)); + }, + + + onRowOver : function(e, target) { + var row = this.findRowIndex(target); + + if (row !== false) { + this.addRowClass(row, this.rowOverCls); + } + }, + + + onRowOut : function(e, target) { + var row = this.findRowIndex(target); + + if (row !== false && !e.within(this.getRow(row), true)) { + this.removeRowClass(row, this.rowOverCls); + } + }, + + + onRowSelect : function(row) { + this.addRowClass(row, this.selectedRowClass); + }, + + + onRowDeselect : function(row) { + this.removeRowClass(row, this.selectedRowClass); + }, + + + onCellSelect : function(row, col) { + var cell = this.getCell(row, col); + if (cell) { + this.fly(cell).addClass('x-grid3-cell-selected'); + } + }, + + + onCellDeselect : function(row, col) { + var cell = this.getCell(row, col); + if (cell) { + this.fly(cell).removeClass('x-grid3-cell-selected'); + } + }, + + + handleWheel : function(e) { + e.stopPropagation(); + }, + + + onColumnSplitterMoved : function(cellIndex, width) { + this.userResized = true; + this.grid.colModel.setColumnWidth(cellIndex, width, true); + + if (this.forceFit) { + this.fitColumns(true, false, cellIndex); + this.updateAllColumnWidths(); + } else { + this.updateColumnWidth(cellIndex, width); + this.syncHeaderScroll(); + } + + this.grid.fireEvent('columnresize', cellIndex, width); + }, + + + beforeColMenuShow : function() { + var colModel = this.cm, + colCount = colModel.getColumnCount(), + colMenu = this.colMenu, + i; + + colMenu.removeAll(); + + for (i = 0; i < colCount; i++) { + if (colModel.config[i].hideable !== false) { + colMenu.add(new Ext.menu.CheckItem({ + text : colModel.getColumnHeader(i), + itemId : 'col-' + colModel.getColumnId(i), + checked : !colModel.isHidden(i), + disabled : colModel.config[i].hideable === false, + hideOnClick: false + })); + } + } + }, + + + handleHdMenuClick : function(item) { + var store = this.ds, + dataIndex = this.cm.getDataIndex(this.hdCtxIndex); + + switch (item.getItemId()) { + case 'asc': + store.sort(dataIndex, 'ASC'); + break; + case 'desc': + store.sort(dataIndex, 'DESC'); + break; + default: + this.handleHdMenuClickDefault(item); + } + return true; + }, + + + handleHdMenuClickDefault: function(item) { + var colModel = this.cm, + itemId = item.getItemId(), + index = colModel.getIndexById(itemId.substr(4)); + + if (index != -1) { + if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) { + this.onDenyColumnHide(); + return; + } + colModel.setHidden(index, item.checked); + } + }, + + + handleHdDown : function(e, target) { + if (Ext.fly(target).hasClass('x-grid3-hd-btn')) { + e.stopEvent(); + + var colModel = this.cm, + header = this.findHeaderCell(target), + index = this.getCellIndex(header), + sortable = colModel.isSortable(index), + menu = this.hmenu, + menuItems = menu.items, + menuCls = this.headerMenuOpenCls, + sep; + + this.hdCtxIndex = index; + + Ext.fly(header).addClass(menuCls); + if (this.hideSortIcons) { + menuItems.get('asc').setVisible(sortable); + menuItems.get('desc').setVisible(sortable); + sep = menuItems.get('sortSep'); + if (sep) { + sep.setVisible(sortable); + } + } else { + menuItems.get('asc').setDisabled(!sortable); + menuItems.get('desc').setDisabled(!sortable); + } + + menu.on('hide', function() { + Ext.fly(header).removeClass(menuCls); + }, this, {single:true}); + + menu.show(target, 'tl-bl?'); + } + }, + + + handleHdMove : function(e) { + var header = this.findHeaderCell(this.activeHdRef); + + if (header && !this.headersDisabled) { + var handleWidth = this.splitHandleWidth || 5, + activeRegion = this.activeHdRegion, + headerStyle = header.style, + colModel = this.cm, + cursor = '', + pageX = e.getPageX(); + + if (this.grid.enableColumnResize !== false) { + var activeHeaderIndex = this.activeHdIndex, + previousVisible = this.getPreviousVisible(activeHeaderIndex), + currentResizable = colModel.isResizable(activeHeaderIndex), + previousResizable = previousVisible && colModel.isResizable(previousVisible), + inLeftResizer = pageX - activeRegion.left <= handleWidth, + inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2); + + if (inLeftResizer && previousResizable) { + cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; + } else if (inRightResizer && currentResizable) { + cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize'; + } + } + + headerStyle.cursor = cursor; + } + }, + + + getPreviousVisible: function(index) { + while (index > 0) { + if (!this.cm.isHidden(index - 1)) { + return index; + } + index--; + } + return undefined; + }, + + + handleHdOver : function(e, target) { + var header = this.findHeaderCell(target); + + if (header && !this.headersDisabled) { + var fly = this.fly(header); + + this.activeHdRef = target; + this.activeHdIndex = this.getCellIndex(header); + this.activeHdRegion = fly.getRegion(); + + if (!this.isMenuDisabled(this.activeHdIndex, fly)) { + fly.addClass('x-grid3-hd-over'); + this.activeHdBtn = fly.child('.x-grid3-hd-btn'); + + if (this.activeHdBtn) { + this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px'; + } + } + } + }, + + + handleHdOut : function(e, target) { + var header = this.findHeaderCell(target); + + if (header && (!Ext.isIE9m || !e.within(header, true))) { + this.activeHdRef = null; + this.fly(header).removeClass('x-grid3-hd-over'); + header.style.cursor = ''; + } + }, + + + isMenuDisabled: function(cellIndex, el) { + return this.cm.isMenuDisabled(cellIndex); + }, + + + hasRows : function() { + var fc = this.mainBody.dom.firstChild; + return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty'; + }, + + + isHideableColumn : function(c) { + return !c.hidden; + }, + + + bind : function(d, c) { + this.initData(d, c); + } +}); + + + + +Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, { + + constructor: function(grid, hd){ + this.grid = grid; + this.view = grid.getView(); + this.marker = this.view.resizeMarker; + this.proxy = this.view.resizeProxy; + Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd, + 'gridSplitters' + this.grid.getGridEl().id, { + dragElId : Ext.id(this.proxy.dom), resizeFrame:false + }); + this.scroll = false; + this.hw = this.view.splitHandleWidth || 5; + }, + + b4StartDrag : function(x, y){ + this.dragHeadersDisabled = this.view.headersDisabled; + this.view.headersDisabled = true; + var h = this.view.mainWrap.getHeight(); + this.marker.setHeight(h); + this.marker.show(); + this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]); + this.proxy.setHeight(h); + var w = this.cm.getColumnWidth(this.cellIndex), + minw = Math.max(w-this.grid.minColumnWidth, 0); + this.resetConstraints(); + this.setXConstraint(minw, 1000); + this.setYConstraint(0, 0); + this.minX = x - minw; + this.maxX = x + 1000; + this.startPos = x; + Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y); + }, + + allowHeaderDrag : function(e){ + return true; + }, + + handleMouseDown : function(e){ + var t = this.view.findHeaderCell(e.getTarget()); + if(t && this.allowHeaderDrag(e)){ + var xy = this.view.fly(t).getXY(), + x = xy[0], + exy = e.getXY(), + ex = exy[0], + w = t.offsetWidth, + adjust = false; + + if((ex - x) <= this.hw){ + adjust = -1; + }else if((x+w) - ex <= this.hw){ + adjust = 0; + } + if(adjust !== false){ + this.cm = this.grid.colModel; + var ci = this.view.getCellIndex(t); + if(adjust == -1){ + if (ci + adjust < 0) { + return; + } + while(this.cm.isHidden(ci+adjust)){ + --adjust; + if(ci+adjust < 0){ + return; + } + } + } + this.cellIndex = ci+adjust; + this.split = t.dom; + if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){ + Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments); + } + }else if(this.view.columnDrag){ + this.view.columnDrag.callHandleMouseDown(e); + } + } + }, + + endDrag : function(e){ + this.marker.hide(); + var v = this.view, + endX = Math.max(this.minX, e.getPageX()), + diff = endX - this.startPos, + disabled = this.dragHeadersDisabled; + + v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff); + setTimeout(function(){ + v.headersDisabled = disabled; + }, 50); + }, + + autoOffset : function(){ + this.setDelta(0,0); + } +}); + +Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, { + + + colHeaderCellCls: 'grid-hd-group-cell', + + + title: '', + + + + + getColumnHeaders: function() { + return this.grid.topAxis.buildHeaders();; + }, + + + getRowHeaders: function() { + return this.grid.leftAxis.buildHeaders(); + }, + + + renderRows : function(startRow, endRow) { + var grid = this.grid, + rows = grid.extractData(), + rowCount = rows.length, + templates = this.templates, + renderer = grid.renderer, + hasRenderer = typeof renderer == 'function', + getCellCls = this.getCellCls, + hasGetCellCls = typeof getCellCls == 'function', + cellTemplate = templates.cell, + rowTemplate = templates.row, + rowBuffer = [], + meta = {}, + tstyle = 'width:' + this.getGridInnerWidth() + 'px;', + colBuffer, colCount, column, i, row; + + startRow = startRow || 0; + endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1; + + for (i = 0; i < rowCount; i++) { + row = rows[i]; + colCount = row.length; + colBuffer = []; + + + for (var j = 0; j < colCount; j++) { + + meta.id = i + '-' + j; + meta.css = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : ''); + meta.attr = meta.cellAttr = ''; + meta.value = row[j]; + + if (Ext.isEmpty(meta.value)) { + meta.value = ' '; + } + + if (hasRenderer) { + meta.value = renderer(meta.value); + } + + if (hasGetCellCls) { + meta.css += getCellCls(meta.value) + ' '; + } + + colBuffer[colBuffer.length] = cellTemplate.apply(meta); + } + + rowBuffer[rowBuffer.length] = rowTemplate.apply({ + tstyle: tstyle, + cols : colCount, + cells : colBuffer.join(""), + alt : '' + }); + } + + return rowBuffer.join(""); + }, + + + masterTpl: new Ext.Template( + '
    ', + '
    ', + '
    ', + '
    {title}
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    {body}
    ', + '', + '
    ', + '
    ', + '
     
    ', + '
     
    ', + '
    ' + ), + + + initTemplates: function() { + Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments); + + var templates = this.templates || {}; + if (!templates.gcell) { + templates.gcell = new Ext.XTemplate( + '', + '
    ', + this.grid.enableHdMenu ? '' : '', '{value}', + '
    ', + '' + ); + } + + this.templates = templates; + this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", ""); + }, + + + initElements: function() { + Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments); + + + this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers')); + + + this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title')); + }, + + + getGridInnerWidth: function() { + var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments); + + return previousWidth - this.getTotalRowHeaderWidth(); + }, + + + getTotalRowHeaderWidth: function() { + var headers = this.getRowHeaders(), + length = headers.length, + total = 0, + i; + + for (i = 0; i< length; i++) { + total += headers[i].width; + } + + return total; + }, + + + getTotalColumnHeaderHeight: function() { + return this.getColumnHeaders().length * 21; + }, + + + getCellIndex : function(el) { + if (el) { + var match = el.className.match(this.colRe), + data; + + if (match && (data = match[1])) { + return parseInt(data.split('-')[1], 10); + } + } + return false; + }, + + + + renderUI : function() { + var templates = this.templates, + innerWidth = this.getGridInnerWidth(); + + return templates.master.apply({ + body : templates.body.apply({rows:' '}), + ostyle: 'width:' + innerWidth + 'px', + bstyle: 'width:' + innerWidth + 'px' + }); + }, + + + onLayout: function(width, height) { + Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments); + + var width = this.getGridInnerWidth(); + + this.resizeColumnHeaders(width); + this.resizeAllRows(width); + }, + + + refresh : function(headersToo) { + this.fireEvent('beforerefresh', this); + this.grid.stopEditing(true); + + var result = this.renderBody(); + this.mainBody.update(result).setWidth(this.getGridInnerWidth()); + if (headersToo === true) { + this.updateHeaders(); + this.updateHeaderSortState(); + } + this.processRows(0, true); + this.layout(); + this.applyEmptyText(); + this.fireEvent('refresh', this); + }, + + + renderHeaders: Ext.emptyFn, + + + fitColumns: Ext.emptyFn, + + + resizeColumnHeaders: function(width) { + var topAxis = this.grid.topAxis; + + if (topAxis.rendered) { + topAxis.el.setWidth(width); + } + }, + + + resizeRowHeaders: function() { + var rowHeaderWidth = this.getTotalRowHeaderWidth(), + marginStyle = String.format("margin-left: {0}px;", rowHeaderWidth); + + this.rowHeadersEl.setWidth(rowHeaderWidth); + this.mainBody.applyStyles(marginStyle); + Ext.fly(this.innerHd).applyStyles(marginStyle); + + this.headerTitleEl.setWidth(rowHeaderWidth); + this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight()); + }, + + + resizeAllRows: function(width) { + var rows = this.getRows(), + length = rows.length, + i; + + for (i = 0; i < length; i++) { + Ext.fly(rows[i]).setWidth(width); + Ext.fly(rows[i]).child('table').setWidth(width); + } + }, + + + updateHeaders: function() { + this.renderGroupRowHeaders(); + this.renderGroupColumnHeaders(); + }, + + + renderGroupRowHeaders: function() { + var leftAxis = this.grid.leftAxis; + + this.resizeRowHeaders(); + leftAxis.rendered = false; + leftAxis.render(this.rowHeadersEl); + + this.setTitle(this.title); + }, + + + setTitle: function(title) { + this.headerTitleEl.child('span').dom.innerHTML = title; + }, + + + renderGroupColumnHeaders: function() { + var topAxis = this.grid.topAxis; + + topAxis.rendered = false; + topAxis.render(this.innerHd.firstChild); + }, + + + isMenuDisabled: function(cellIndex, el) { + return true; + } +}); +Ext.grid.PivotAxis = Ext.extend(Ext.Component, { + + orientation: 'horizontal', + + + defaultHeaderWidth: 80, + + + paddingWidth: 7, + + + setDimensions: function(dimensions) { + this.dimensions = dimensions; + }, + + + onRender: function(ct, position) { + var rows = this.orientation == 'horizontal' + ? this.renderHorizontalRows() + : this.renderVerticalRows(); + + this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true); + }, + + + renderHorizontalRows: function() { + var headers = this.buildHeaders(), + rowCount = headers.length, + rows = [], + cells, cols, colCount, i, j; + + for (i = 0; i < rowCount; i++) { + cells = []; + cols = headers[i].items; + colCount = cols.length; + + for (j = 0; j < colCount; j++) { + cells.push({ + tag: 'td', + html: cols[j].header, + colspan: cols[j].span + }); + } + + rows[i] = { + tag: 'tr', + cn: cells + }; + } + + return rows; + }, + + + renderVerticalRows: function() { + var headers = this.buildHeaders(), + colCount = headers.length, + rowCells = [], + rows = [], + rowCount, col, row, colWidth, i, j; + + for (i = 0; i < colCount; i++) { + col = headers[i]; + colWidth = col.width || 80; + rowCount = col.items.length; + + for (j = 0; j < rowCount; j++) { + row = col.items[j]; + + rowCells[row.start] = rowCells[row.start] || []; + rowCells[row.start].push({ + tag : 'td', + html : row.header, + rowspan: row.span, + width : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth + }); + } + } + + rowCount = rowCells.length; + for (i = 0; i < rowCount; i++) { + rows[i] = { + tag: 'tr', + cn : rowCells[i] + }; + } + + return rows; + }, + + + getTuples: function() { + var newStore = new Ext.data.Store({}); + + newStore.data = this.store.data.clone(); + newStore.fields = this.store.fields; + + var sorters = [], + dimensions = this.dimensions, + length = dimensions.length, + i; + + for (i = 0; i < length; i++) { + sorters.push({ + field : dimensions[i].dataIndex, + direction: dimensions[i].direction || 'ASC' + }); + } + + newStore.sort(sorters); + + var records = newStore.data.items, + hashes = [], + tuples = [], + recData, hash, info, data, key; + + length = records.length; + + for (i = 0; i < length; i++) { + info = this.getRecordInfo(records[i]); + data = info.data; + hash = ""; + + for (key in data) { + hash += data[key] + '---'; + } + + if (hashes.indexOf(hash) == -1) { + hashes.push(hash); + tuples.push(info); + } + } + + newStore.destroy(); + + return tuples; + }, + + + getRecordInfo: function(record) { + var dimensions = this.dimensions, + length = dimensions.length, + data = {}, + dimension, dataIndex, i; + + + for (i = 0; i < length; i++) { + dimension = dimensions[i]; + dataIndex = dimension.dataIndex; + + data[dataIndex] = record.get(dataIndex); + } + + + + var createMatcherFunction = function(data) { + return function(record) { + for (var dataIndex in data) { + if (record.get(dataIndex) != data[dataIndex]) { + return false; + } + } + + return true; + }; + }; + + return { + data: data, + matcher: createMatcherFunction(data) + }; + }, + + + buildHeaders: function() { + var tuples = this.getTuples(), + rowCount = tuples.length, + dimensions = this.dimensions, + dimension, + colCount = dimensions.length, + headers = [], + tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j; + + for (i = 0; i < colCount; i++) { + dimension = dimensions[i]; + rows = []; + span = 0; + start = 0; + + for (j = 0; j < rowCount; j++) { + tuple = tuples[j]; + isLast = j == (rowCount - 1); + currentHeader = tuple.data[dimension.dataIndex]; + + + changed = previousHeader != undefined && previousHeader != currentHeader; + if (i > 0 && j > 0) { + changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex]; + } + + if (changed) { + rows.push({ + header: previousHeader, + span : span, + start : start + }); + + start += span; + span = 0; + } + + if (isLast) { + rows.push({ + header: currentHeader, + span : span + 1, + start : start + }); + + start += span; + span = 0; + } + + previousHeader = currentHeader; + span++; + } + + headers.push({ + items: rows, + width: dimension.width || this.defaultHeaderWidth + }); + + previousHeader = undefined; + } + + return headers; + } +}); + + +Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, { + maxDragWidth: 120, + + constructor : function(grid, hd, hd2){ + this.grid = grid; + this.view = grid.getView(); + this.ddGroup = "gridHeader" + this.grid.getGridEl().id; + Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd); + if(hd2){ + this.setHandleElId(Ext.id(hd)); + this.setOuterHandleElId(Ext.id(hd2)); + } + this.scroll = false; + }, + + getDragData : function(e){ + var t = Ext.lib.Event.getTarget(e), + h = this.view.findHeaderCell(t); + if(h){ + return {ddel: h.firstChild, header:h}; + } + return false; + }, + + onInitDrag : function(e){ + + this.dragHeadersDisabled = this.view.headersDisabled; + this.view.headersDisabled = true; + var clone = this.dragData.ddel.cloneNode(true); + clone.id = Ext.id(); + clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px"; + this.proxy.update(clone); + return true; + }, + + afterValidDrop : function(){ + this.completeDrop(); + }, + + afterInvalidDrop : function(){ + this.completeDrop(); + }, + + completeDrop: function(){ + var v = this.view, + disabled = this.dragHeadersDisabled; + setTimeout(function(){ + v.headersDisabled = disabled; + }, 50); + } +}); + + + +Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, { + proxyOffsets : [-4, -9], + fly: Ext.Element.fly, + + constructor : function(grid, hd, hd2){ + this.grid = grid; + this.view = grid.getView(); + + this.proxyTop = Ext.DomHelper.append(document.body, { + cls:"col-move-top", html:" " + }, true); + this.proxyBottom = Ext.DomHelper.append(document.body, { + cls:"col-move-bottom", html:" " + }, true); + this.proxyTop.hide = this.proxyBottom.hide = function(){ + this.setLeftTop(-100,-100); + this.setStyle("visibility", "hidden"); + }; + this.ddGroup = "gridHeader" + this.grid.getGridEl().id; + + + Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom); + }, + + getTargetFromEvent : function(e){ + var t = Ext.lib.Event.getTarget(e), + cindex = this.view.findCellIndex(t); + if(cindex !== false){ + return this.view.getHeaderCell(cindex); + } + }, + + nextVisible : function(h){ + var v = this.view, cm = this.grid.colModel; + h = h.nextSibling; + while(h){ + if(!cm.isHidden(v.getCellIndex(h))){ + return h; + } + h = h.nextSibling; + } + return null; + }, + + prevVisible : function(h){ + var v = this.view, cm = this.grid.colModel; + h = h.prevSibling; + while(h){ + if(!cm.isHidden(v.getCellIndex(h))){ + return h; + } + h = h.prevSibling; + } + return null; + }, + + positionIndicator : function(h, n, e){ + var x = Ext.lib.Event.getPageX(e), + r = Ext.lib.Dom.getRegion(n.firstChild), + px, + pt, + py = r.top + this.proxyOffsets[1]; + if((r.right - x) <= (r.right-r.left)/2){ + px = r.right+this.view.borderWidth; + pt = "after"; + }else{ + px = r.left; + pt = "before"; + } + + if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){ + return false; + } + + px += this.proxyOffsets[0]; + this.proxyTop.setLeftTop(px, py); + this.proxyTop.show(); + if(!this.bottomOffset){ + this.bottomOffset = this.view.mainHd.getHeight(); + } + this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset); + this.proxyBottom.show(); + return pt; + }, + + onNodeEnter : function(n, dd, e, data){ + if(data.header != n){ + this.positionIndicator(data.header, n, e); + } + }, + + onNodeOver : function(n, dd, e, data){ + var result = false; + if(data.header != n){ + result = this.positionIndicator(data.header, n, e); + } + if(!result){ + this.proxyTop.hide(); + this.proxyBottom.hide(); + } + return result ? this.dropAllowed : this.dropNotAllowed; + }, + + onNodeOut : function(n, dd, e, data){ + this.proxyTop.hide(); + this.proxyBottom.hide(); + }, + + onNodeDrop : function(n, dd, e, data){ + var h = data.header; + if(h != n){ + var cm = this.grid.colModel, + x = Ext.lib.Event.getPageX(e), + r = Ext.lib.Dom.getRegion(n.firstChild), + pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before", + oldIndex = this.view.getCellIndex(h), + newIndex = this.view.getCellIndex(n); + if(pt == "after"){ + newIndex++; + } + if(oldIndex < newIndex){ + newIndex--; + } + cm.moveColumn(oldIndex, newIndex); + return true; + } + return false; + } +}); + +Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, { + + constructor : function(grid, hd){ + Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null); + this.proxy.el.addClass('x-grid3-col-dd'); + }, + + handleMouseDown : function(e){ + }, + + callHandleMouseDown : function(e){ + Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e); + } +}); + +Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, { + fly: Ext.Element.fly, + + constructor : function(grid, hd, hd2){ + this.grid = grid; + this.view = grid.getView(); + this.proxy = this.view.resizeProxy; + Ext.grid.SplitDragZone.superclass.constructor.call(this, hd, + "gridSplitters" + this.grid.getGridEl().id, { + dragElId : Ext.id(this.proxy.dom), resizeFrame:false + }); + this.setHandleElId(Ext.id(hd)); + this.setOuterHandleElId(Ext.id(hd2)); + this.scroll = false; + }, + + b4StartDrag : function(x, y){ + this.view.headersDisabled = true; + this.proxy.setHeight(this.view.mainWrap.getHeight()); + var w = this.cm.getColumnWidth(this.cellIndex); + var minw = Math.max(w-this.grid.minColumnWidth, 0); + this.resetConstraints(); + this.setXConstraint(minw, 1000); + this.setYConstraint(0, 0); + this.minX = x - minw; + this.maxX = x + 1000; + this.startPos = x; + Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y); + }, + + + handleMouseDown : function(e){ + var ev = Ext.EventObject.setEvent(e); + var t = this.fly(ev.getTarget()); + if(t.hasClass("x-grid-split")){ + this.cellIndex = this.view.getCellIndex(t.dom); + this.split = t.dom; + this.cm = this.grid.colModel; + if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){ + Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments); + } + } + }, + + endDrag : function(e){ + this.view.headersDisabled = false; + var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e)); + var diff = endX - this.startPos; + this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff); + }, + + autoOffset : function(){ + this.setDelta(0,0); + } +}); +Ext.grid.GridDragZone = function(grid, config){ + this.view = grid.getView(); + Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config); + this.scroll = false; + this.grid = grid; + this.ddel = document.createElement('div'); + this.ddel.className = 'x-grid-dd-wrap'; + + this.preventDefault = true; +}; + +Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, { + ddGroup : "GridDD", + + + getDragData : function(e){ + var t = Ext.lib.Event.getTarget(e), + sm, + rowIndex = this.view.findRowIndex(t), + cellIndex, + selectedCell, + selection; + + if (rowIndex !== false){ + sm = this.grid.selModel; + + + + if (sm.getSelectedCell) { + cellIndex = this.view.findCellIndex(t); + selectedCell = sm.getSelectedCell(); + if (!selectedCell || selectedCell[0] !== rowIndex || selectedCell[1] !== cellIndex) { + sm.handleMouseDown(this.grid, rowIndex, cellIndex, e); + } + if (this.grid.dragCell) { + + selection = sm.getSelectedCell(); + if (!this.grid.hasOwnProperty('ddText')) { + this.grid.ddText = '{0} selected cell{1}'; + } + } else { + + selection = [this.grid.store.getAt(rowIndex)]; + } + } else { + if(!sm.isSelected(rowIndex) || e.hasModifier()){ + sm.handleMouseDown(this.grid, rowIndex, e); + } + selection = sm.getSelections(); + } + return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections: selection}; + } + return false; + }, + + + onInitDrag : function(e){ + var data = this.dragData; + this.ddel.innerHTML = this.grid.getDragDropText(); + this.proxy.update(this.ddel); + + }, + + + afterRepair : function(){ + this.dragging = false; + }, + + + getRepairXY : function(e, data){ + return false; + }, + + onEndDrag : function(data, e){ + + }, + + onValidDrop : function(dd, e, id){ + + this.hideProxy(); + }, + + beforeInvalidDrop : function(e, id){ + + } +}); + +Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, { + + defaultWidth: 100, + + + defaultSortable: false, + + + + + + constructor : function(config) { + + if (config.columns) { + Ext.apply(this, config); + this.setConfig(config.columns, true); + } else { + this.setConfig(config, true); + } + + this.addEvents( + + "widthchange", + + + "headerchange", + + + "hiddenchange", + + + "columnmoved", + + + "configchange" + ); + + Ext.grid.ColumnModel.superclass.constructor.call(this); + }, + + + getColumnId : function(index) { + return this.config[index].id; + }, + + getColumnAt : function(index) { + return this.config[index]; + }, + + + setConfig : function(config, initial) { + var i, c, len; + + if (!initial) { + delete this.totalWidth; + + for (i = 0, len = this.config.length; i < len; i++) { + c = this.config[i]; + + if (c.setEditor) { + + c.setEditor(null); + } + } + } + + + this.defaults = Ext.apply({ + width: this.defaultWidth, + sortable: this.defaultSortable + }, this.defaults); + + this.config = config; + this.lookup = {}; + + for (i = 0, len = config.length; i < len; i++) { + c = Ext.applyIf(config[i], this.defaults); + + + if (Ext.isEmpty(c.id)) { + c.id = i; + } + + if (!c.isColumn) { + var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn']; + c = new Cls(c); + config[i] = c; + } + + this.lookup[c.id] = c; + } + + if (!initial) { + this.fireEvent('configchange', this); + } + }, + + + getColumnById : function(id) { + return this.lookup[id]; + }, + + + getIndexById : function(id) { + for (var i = 0, len = this.config.length; i < len; i++) { + if (this.config[i].id == id) { + return i; + } + } + return -1; + }, + + + moveColumn : function(oldIndex, newIndex) { + var config = this.config, + c = config[oldIndex]; + + config.splice(oldIndex, 1); + config.splice(newIndex, 0, c); + this.dataMap = null; + this.fireEvent("columnmoved", this, oldIndex, newIndex); + }, + + + getColumnCount : function(visibleOnly) { + var length = this.config.length, + c = 0, + i; + + if (visibleOnly === true) { + for (i = 0; i < length; i++) { + if (!this.isHidden(i)) { + c++; + } + } + + return c; + } + + return length; + }, + + + getColumnsBy : function(fn, scope) { + var config = this.config, + length = config.length, + result = [], + i, c; + + for (i = 0; i < length; i++){ + c = config[i]; + + if (fn.call(scope || this, c, i) === true) { + result[result.length] = c; + } + } + + return result; + }, + + + isSortable : function(col) { + return !!this.config[col].sortable; + }, + + + isMenuDisabled : function(col) { + return !!this.config[col].menuDisabled; + }, + + + getRenderer : function(col) { + return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer; + }, + + getRendererScope : function(col) { + return this.config[col].scope; + }, + + + setRenderer : function(col, fn) { + this.config[col].renderer = fn; + }, + + + getColumnWidth : function(col) { + var width = this.config[col].width; + if(typeof width != 'number'){ + width = this.defaultWidth; + } + return width; + }, + + + setColumnWidth : function(col, width, suppressEvent) { + this.config[col].width = width; + this.totalWidth = null; + + if (!suppressEvent) { + this.fireEvent("widthchange", this, col, width); + } + }, + + + getTotalWidth : function(includeHidden) { + if (!this.totalWidth) { + this.totalWidth = 0; + for (var i = 0, len = this.config.length; i < len; i++) { + if (includeHidden || !this.isHidden(i)) { + this.totalWidth += this.getColumnWidth(i); + } + } + } + return this.totalWidth; + }, + + + getColumnHeader : function(col) { + return this.config[col].header; + }, + + + setColumnHeader : function(col, header) { + this.config[col].header = header; + this.fireEvent("headerchange", this, col, header); + }, + + + getColumnTooltip : function(col) { + return this.config[col].tooltip; + }, + + setColumnTooltip : function(col, tooltip) { + this.config[col].tooltip = tooltip; + }, + + + getDataIndex : function(col) { + return this.config[col].dataIndex; + }, + + + setDataIndex : function(col, dataIndex) { + this.config[col].dataIndex = dataIndex; + }, + + + findColumnIndex : function(dataIndex) { + var c = this.config; + for(var i = 0, len = c.length; i < len; i++){ + if(c[i].dataIndex == dataIndex){ + return i; + } + } + return -1; + }, + + + isCellEditable : function(colIndex, rowIndex) { + var c = this.config[colIndex], + ed = c.editable; + + + return !!(ed || (!Ext.isDefined(ed) && c.editor)); + }, + + + getCellEditor : function(colIndex, rowIndex) { + return this.config[colIndex].getCellEditor(rowIndex); + }, + + + setEditable : function(col, editable) { + this.config[col].editable = editable; + }, + + + isHidden : function(colIndex) { + return !!this.config[colIndex].hidden; + }, + + + isFixed : function(colIndex) { + return !!this.config[colIndex].fixed; + }, + + + isResizable : function(colIndex) { + return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true; + }, + + + setHidden : function(colIndex, hidden) { + var c = this.config[colIndex]; + if(c.hidden !== hidden){ + c.hidden = hidden; + this.totalWidth = null; + this.fireEvent("hiddenchange", this, colIndex, hidden); + } + }, + + + setEditor : function(col, editor) { + this.config[col].setEditor(editor); + }, + + + destroy : function() { + var length = this.config.length, + i = 0; + + for (; i < length; i++){ + this.config[i].destroy(); + } + delete this.config; + delete this.lookup; + this.purgeListeners(); + }, + + + setState : function(col, state) { + state = Ext.applyIf(state, this.defaults); + Ext.apply(this.config[col], state); + } +}); + + +Ext.grid.ColumnModel.defaultRenderer = function(value) { + if (typeof value == "string" && value.length < 1) { + return " "; + } + return value; +}; +Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, { + + + constructor : function(){ + this.locked = false; + Ext.grid.AbstractSelectionModel.superclass.constructor.call(this); + }, + + + init : function(grid){ + this.grid = grid; + if(this.lockOnInit){ + delete this.lockOnInit; + this.locked = false; + this.lock(); + } + this.initEvents(); + }, + + + lock : function(){ + if(!this.locked){ + this.locked = true; + + var g = this.grid; + if(g){ + g.getView().on({ + scope: this, + beforerefresh: this.sortUnLock, + refresh: this.sortLock + }); + }else{ + this.lockOnInit = true; + } + } + }, + + + sortLock : function() { + this.locked = true; + }, + + + sortUnLock : function() { + this.locked = false; + }, + + + unlock : function(){ + if(this.locked){ + this.locked = false; + var g = this.grid, + gv; + + + if(g){ + gv = g.getView(); + gv.un('beforerefresh', this.sortUnLock, this); + gv.un('refresh', this.sortLock, this); + }else{ + delete this.lockOnInit; + } + } + }, + + + isLocked : function(){ + return this.locked; + }, + + destroy: function(){ + this.unlock(); + this.purgeListeners(); + } +}); +Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, { + + singleSelect : false, + + constructor : function(config){ + Ext.apply(this, config); + this.selections = new Ext.util.MixedCollection(false, function(o){ + return o.id; + }); + + this.last = false; + this.lastActive = false; + + this.addEvents( + + 'selectionchange', + + 'beforerowselect', + + 'rowselect', + + 'rowdeselect' + ); + Ext.grid.RowSelectionModel.superclass.constructor.call(this); + }, + + + + initEvents : function(){ + + if(!this.grid.enableDragDrop && !this.grid.enableDrag){ + this.grid.on('rowmousedown', this.handleMouseDown, this); + } + + this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), { + up: this.onKeyPress, + down: this.onKeyPress, + scope: this + }); + + this.grid.getView().on({ + scope: this, + refresh: this.onRefresh, + rowupdated: this.onRowUpdated, + rowremoved: this.onRemove + }); + }, + + onKeyPress : function(e, name){ + var up = name == 'up', + method = up ? 'selectPrevious' : 'selectNext', + add = up ? -1 : 1, + last; + if(!e.shiftKey || this.singleSelect){ + this[method](false); + }else if(this.last !== false && this.lastActive !== false){ + last = this.last; + this.selectRange(this.last, this.lastActive + add); + this.grid.getView().focusRow(this.lastActive); + if(last !== false){ + this.last = last; + } + }else{ + this.selectFirstRow(); + } + }, + + + onRefresh : function(){ + var ds = this.grid.store, + s = this.getSelections(), + i = 0, + len = s.length, + index, r; + + this.silent = true; + this.clearSelections(true); + for(; i < len; i++){ + r = s[i]; + if((index = ds.indexOfId(r.id)) != -1){ + this.selectRow(index, true); + } + } + if(s.length != this.selections.getCount()){ + this.fireEvent('selectionchange', this); + } + this.silent = false; + }, + + + onRemove : function(v, index, r){ + if(this.selections.remove(r) !== false){ + this.fireEvent('selectionchange', this); + } + }, + + + onRowUpdated : function(v, index, r){ + if(this.isSelected(r)){ + v.onRowSelect(index); + } + }, + + + selectRecords : function(records, keepExisting){ + if(!keepExisting){ + this.clearSelections(); + } + var ds = this.grid.store, + i = 0, + len = records.length; + for(; i < len; i++){ + this.selectRow(ds.indexOf(records[i]), true); + } + }, + + + getCount : function(){ + return this.selections.length; + }, + + + selectFirstRow : function(){ + this.selectRow(0); + }, + + + selectLastRow : function(keepExisting){ + this.selectRow(this.grid.store.getCount() - 1, keepExisting); + }, + + + selectNext : function(keepExisting){ + if(this.hasNext()){ + this.selectRow(this.last+1, keepExisting); + this.grid.getView().focusRow(this.last); + return true; + } + return false; + }, + + + selectPrevious : function(keepExisting){ + if(this.hasPrevious()){ + this.selectRow(this.last-1, keepExisting); + this.grid.getView().focusRow(this.last); + return true; + } + return false; + }, + + + hasNext : function(){ + return this.last !== false && (this.last+1) < this.grid.store.getCount(); + }, + + + hasPrevious : function(){ + return !!this.last; + }, + + + + getSelections : function(){ + return [].concat(this.selections.items); + }, + + + getSelected : function(){ + return this.selections.itemAt(0); + }, + + + each : function(fn, scope){ + var s = this.getSelections(), + i = 0, + len = s.length; + + for(; i < len; i++){ + if(fn.call(scope || this, s[i], i) === false){ + return false; + } + } + return true; + }, + + + clearSelections : function(fast){ + if(this.isLocked()){ + return; + } + if(fast !== true){ + var ds = this.grid.store, + s = this.selections; + s.each(function(r){ + this.deselectRow(ds.indexOfId(r.id)); + }, this); + s.clear(); + }else{ + this.selections.clear(); + } + this.last = false; + }, + + + + selectAll : function(){ + if(this.isLocked()){ + return; + } + this.selections.clear(); + for(var i = 0, len = this.grid.store.getCount(); i < len; i++){ + this.selectRow(i, true); + } + }, + + + hasSelection : function(){ + return this.selections.length > 0; + }, + + + isSelected : function(index){ + var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index; + return (r && this.selections.key(r.id) ? true : false); + }, + + + isIdSelected : function(id){ + return (this.selections.key(id) ? true : false); + }, + + + handleMouseDown : function(g, rowIndex, e){ + if(e.button !== 0 || this.isLocked()){ + return; + } + var view = this.grid.getView(); + if(e.shiftKey && !this.singleSelect && this.last !== false){ + var last = this.last; + this.selectRange(last, rowIndex, e.ctrlKey); + this.last = last; + view.focusRow(rowIndex); + }else{ + var isSelected = this.isSelected(rowIndex); + if(e.ctrlKey && isSelected){ + this.deselectRow(rowIndex); + }else if(!isSelected || this.getCount() > 1){ + this.selectRow(rowIndex, e.ctrlKey || e.shiftKey); + view.focusRow(rowIndex); + } + } + }, + + + selectRows : function(rows, keepExisting){ + if(!keepExisting){ + this.clearSelections(); + } + for(var i = 0, len = rows.length; i < len; i++){ + this.selectRow(rows[i], true); + } + }, + + + selectRange : function(startRow, endRow, keepExisting){ + var i; + if(this.isLocked()){ + return; + } + if(!keepExisting){ + this.clearSelections(); + } + if(startRow <= endRow){ + for(i = startRow; i <= endRow; i++){ + this.selectRow(i, true); + } + }else{ + for(i = startRow; i >= endRow; i--){ + this.selectRow(i, true); + } + } + }, + + + deselectRange : function(startRow, endRow, preventViewNotify){ + if(this.isLocked()){ + return; + } + for(var i = startRow; i <= endRow; i++){ + this.deselectRow(i, preventViewNotify); + } + }, + + + selectRow : function(index, keepExisting, preventViewNotify){ + if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){ + return; + } + var r = this.grid.store.getAt(index); + if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){ + if(!keepExisting || this.singleSelect){ + this.clearSelections(); + } + this.selections.add(r); + this.last = this.lastActive = index; + if(!preventViewNotify){ + this.grid.getView().onRowSelect(index); + } + if(!this.silent){ + this.fireEvent('rowselect', this, index, r); + this.fireEvent('selectionchange', this); + } + } + }, + + + deselectRow : function(index, preventViewNotify){ + if(this.isLocked()){ + return; + } + if(this.last == index){ + this.last = false; + } + if(this.lastActive == index){ + this.lastActive = false; + } + var r = this.grid.store.getAt(index); + if(r){ + this.selections.remove(r); + if(!preventViewNotify){ + this.grid.getView().onRowDeselect(index); + } + this.fireEvent('rowdeselect', this, index, r); + this.fireEvent('selectionchange', this); + } + }, + + + acceptsNav : function(row, col, cm){ + return !cm.isHidden(col) && cm.isCellEditable(col, row); + }, + + + onEditorKey : function(field, e){ + var k = e.getKey(), + newCell, + g = this.grid, + last = g.lastEdit, + ed = g.activeEditor, + shift = e.shiftKey, + ae, last, r, c; + + if(k == e.TAB){ + e.stopEvent(); + ed.completeEdit(); + if(shift){ + newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this); + }else{ + newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this); + } + }else if(k == e.ENTER){ + if(this.moveEditorOnEnter !== false){ + if(shift){ + newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this); + }else{ + newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this); + } + } + } + if(newCell){ + r = newCell[0]; + c = newCell[1]; + + this.onEditorSelect(r, last.row); + + if(g.isEditor && g.editing){ + ae = g.activeEditor; + if(ae && ae.field.triggerBlur){ + + ae.field.triggerBlur(); + } + } + g.startEditing(r, c); + } + }, + + onEditorSelect: function(row, lastRow){ + if(lastRow != row){ + this.selectRow(row); + } + }, + + destroy : function(){ + Ext.destroy(this.rowNav); + this.rowNav = null; + Ext.grid.RowSelectionModel.superclass.destroy.call(this); + } +}); + +Ext.grid.Column = Ext.extend(Ext.util.Observable, { + + + + + + + + + + + + + + + + + + + + + + + + + isColumn : true, + + constructor : function(config){ + Ext.apply(this, config); + + if(Ext.isString(this.renderer)){ + this.renderer = Ext.util.Format[this.renderer]; + }else if(Ext.isObject(this.renderer)){ + this.scope = this.renderer.scope; + this.renderer = this.renderer.fn; + } + if(!this.scope){ + this.scope = this; + } + + var ed = this.editor; + delete this.editor; + this.setEditor(ed); + this.addEvents( + + 'click', + + 'contextmenu', + + 'dblclick', + + 'mousedown' + ); + Ext.grid.Column.superclass.constructor.call(this); + }, + + + processEvent : function(name, e, grid, rowIndex, colIndex){ + return this.fireEvent(name, this, grid, rowIndex, e); + }, + + + destroy: function() { + if(this.setEditor){ + this.setEditor(null); + } + this.purgeListeners(); + }, + + + renderer : function(value){ + return value; + }, + + + getEditor: function(rowIndex){ + return this.editable !== false ? this.editor : null; + }, + + + setEditor : function(editor){ + var ed = this.editor; + if(ed){ + if(ed.gridEditor){ + ed.gridEditor.destroy(); + delete ed.gridEditor; + }else{ + ed.destroy(); + } + } + this.editor = null; + if(editor){ + + if(!editor.isXType){ + editor = Ext.create(editor, 'textfield'); + } + this.editor = editor; + } + }, + + + getCellEditor: function(rowIndex){ + var ed = this.getEditor(rowIndex); + if(ed){ + if(!ed.startEdit){ + if(!ed.gridEditor){ + ed.gridEditor = new Ext.grid.GridEditor(ed); + } + ed = ed.gridEditor; + } + } + return ed; + } +}); + + +Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, { + + trueText: 'true', + + falseText: 'false', + + undefinedText: ' ', + + constructor: function(cfg){ + Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg); + var t = this.trueText, f = this.falseText, u = this.undefinedText; + this.renderer = function(v){ + if(v === undefined){ + return u; + } + if(!v || v === 'false'){ + return f; + } + return t; + }; + } +}); + + +Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, { + + format : '0,000.00', + constructor: function(cfg){ + Ext.grid.NumberColumn.superclass.constructor.call(this, cfg); + this.renderer = Ext.util.Format.numberRenderer(this.format); + } +}); + + +Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, { + + format : 'm/d/Y', + constructor: function(cfg){ + Ext.grid.DateColumn.superclass.constructor.call(this, cfg); + this.renderer = Ext.util.Format.dateRenderer(this.format); + } +}); + + +Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, { + + constructor: function(cfg){ + Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg); + var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl); + this.renderer = function(value, p, r){ + return tpl.apply(r.data); + }; + this.tpl = tpl; + } +}); + + +Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, { + + + + + + + + + header: ' ', + + actionIdRe: /x-action-col-(\d+)/, + + + altText: '', + + constructor: function(cfg) { + var me = this, + items = cfg.items || (me.items = [me]), + l = items.length, + i, + item; + + Ext.grid.ActionColumn.superclass.constructor.call(me, cfg); + + + + me.renderer = function(v, meta) { + + v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : ''; + + meta.css += ' x-action-col-cell'; + for (i = 0; i < l; i++) { + item = items[i]; + v += '' + (item.altText || me.altText) + ''; + } + return v; + }; + }, + + destroy: function() { + delete this.items; + delete this.renderer; + return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments); + }, + + + processEvent : function(name, e, grid, rowIndex, colIndex){ + var m = e.getTarget().className.match(this.actionIdRe), + item, fn; + if (m && (item = this.items[parseInt(m[1], 10)])) { + if (name == 'click') { + (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e); + } else if ((name == 'mousedown') && (item.stopSelection !== false)) { + return false; + } + } + return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments); + } +}); + + +Ext.grid.Column.types = { + gridcolumn : Ext.grid.Column, + booleancolumn: Ext.grid.BooleanColumn, + numbercolumn: Ext.grid.NumberColumn, + datecolumn: Ext.grid.DateColumn, + templatecolumn: Ext.grid.TemplateColumn, + actioncolumn: Ext.grid.ActionColumn +}; +Ext.grid.RowNumberer = Ext.extend(Object, { + + header: "", + + width: 23, + + sortable: false, + + constructor : function(config){ + Ext.apply(this, config); + if(this.rowspan){ + this.renderer = this.renderer.createDelegate(this); + } + }, + + + fixed:true, + hideable: false, + menuDisabled:true, + dataIndex: '', + id: 'numberer', + rowspan: undefined, + + + renderer : function(v, p, record, rowIndex){ + if(this.rowspan){ + p.cellAttr = 'rowspan="'+this.rowspan+'"'; + } + return rowIndex+1; + } +}); +Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, { + + + + header : '
     
    ', + + width : 20, + + sortable : false, + + + menuDisabled : true, + fixed : true, + hideable: false, + dataIndex : '', + id : 'checker', + isColumn: true, + + constructor : function(){ + Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments); + if(this.checkOnly){ + this.handleMouseDown = Ext.emptyFn; + } + }, + + + initEvents : function(){ + Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this); + this.grid.on('render', function(){ + Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this); + }, this); + }, + + + processEvent : function(name, e, grid, rowIndex, colIndex){ + if (name == 'mousedown') { + this.onMouseDown(e, e.getTarget()); + return false; + } else { + return Ext.grid.Column.prototype.processEvent.apply(this, arguments); + } + }, + + + onMouseDown : function(e, t){ + if(e.button === 0 && t.className == 'x-grid3-row-checker'){ + e.stopEvent(); + var row = e.getTarget('.x-grid3-row'); + if(row){ + var index = row.rowIndex; + if(this.isSelected(index)){ + this.deselectRow(index); + }else{ + this.selectRow(index, true); + this.grid.getView().focusRow(index); + } + } + } + }, + + + onHdMouseDown : function(e, t) { + if(t.className == 'x-grid3-hd-checker'){ + e.stopEvent(); + var hd = Ext.fly(t.parentNode); + var isChecked = hd.hasClass('x-grid3-hd-checker-on'); + if(isChecked){ + hd.removeClass('x-grid3-hd-checker-on'); + this.clearSelections(); + }else{ + hd.addClass('x-grid3-hd-checker-on'); + this.selectAll(); + } + } + }, + + + renderer : function(v, p, record){ + return '
     
    '; + }, + + onEditorSelect: function(row, lastRow){ + if(lastRow != row && !this.checkOnly){ + this.selectRow(row); + } + } +}); +Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, { + + constructor : function(config){ + Ext.apply(this, config); + + this.selection = null; + + this.addEvents( + + "beforecellselect", + + "cellselect", + + "selectionchange" + ); + + Ext.grid.CellSelectionModel.superclass.constructor.call(this); + }, + + + initEvents : function(){ + this.grid.on('cellmousedown', this.handleMouseDown, this); + this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this); + this.grid.getView().on({ + scope: this, + refresh: this.onViewChange, + rowupdated: this.onRowUpdated, + beforerowremoved: this.clearSelections, + beforerowsinserted: this.clearSelections + }); + if(this.grid.isEditor){ + this.grid.on('beforeedit', this.beforeEdit, this); + } + }, + + + beforeEdit : function(e){ + this.select(e.row, e.column, false, true, e.record); + }, + + + onRowUpdated : function(v, index, r){ + if(this.selection && this.selection.record == r){ + v.onCellSelect(index, this.selection.cell[1]); + } + }, + + + onViewChange : function(){ + this.clearSelections(true); + }, + + + getSelectedCell : function(){ + return this.selection ? this.selection.cell : null; + }, + + + clearSelections : function(preventNotify){ + var s = this.selection; + if(s){ + if(preventNotify !== true){ + this.grid.view.onCellDeselect(s.cell[0], s.cell[1]); + } + this.selection = null; + this.fireEvent("selectionchange", this, null); + } + }, + + + hasSelection : function(){ + return this.selection ? true : false; + }, + + + handleMouseDown : function(g, row, cell, e){ + if(e.button !== 0 || this.isLocked()){ + return; + } + this.select(row, cell); + }, + + + select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){ + if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){ + this.clearSelections(); + r = r || this.grid.store.getAt(rowIndex); + this.selection = { + record : r, + cell : [rowIndex, colIndex] + }; + if(!preventViewNotify){ + var v = this.grid.getView(); + v.onCellSelect(rowIndex, colIndex); + if(preventFocus !== true){ + v.focusCell(rowIndex, colIndex); + } + } + this.fireEvent("cellselect", this, rowIndex, colIndex); + this.fireEvent("selectionchange", this, this.selection); + } + }, + + + isSelectable : function(rowIndex, colIndex, cm){ + return !cm.isHidden(colIndex); + }, + + + onEditorKey: function(field, e){ + if(e.getKey() == e.TAB){ + this.handleKeyDown(e); + } + }, + + + handleKeyDown : function(e){ + if(!e.isNavKeyPress()){ + return; + } + + var k = e.getKey(), + g = this.grid, + s = this.selection, + sm = this, + walk = function(row, col, step){ + return g.walkCells( + row, + col, + step, + g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, + sm + ); + }, + cell, newCell, r, c, ae; + + switch(k){ + case e.ESC: + case e.PAGE_UP: + case e.PAGE_DOWN: + + break; + default: + + e.stopEvent(); + break; + } + + if(!s){ + cell = walk(0, 0, 1); + if(cell){ + this.select(cell[0], cell[1]); + } + return; + } + + cell = s.cell; + r = cell[0]; + c = cell[1]; + + switch(k){ + case e.TAB: + if(e.shiftKey){ + newCell = walk(r, c - 1, -1); + }else{ + newCell = walk(r, c + 1, 1); + } + break; + case e.DOWN: + newCell = walk(r + 1, c, 1); + break; + case e.UP: + newCell = walk(r - 1, c, -1); + break; + case e.RIGHT: + newCell = walk(r, c + 1, 1); + break; + case e.LEFT: + newCell = walk(r, c - 1, -1); + break; + case e.ENTER: + if (g.isEditor && !g.editing) { + g.startEditing(r, c); + return; + } + break; + } + + if(newCell){ + + r = newCell[0]; + c = newCell[1]; + + this.select(r, c); + + if(g.isEditor && g.editing){ + ae = g.activeEditor; + if(ae && ae.field.triggerBlur){ + + ae.field.triggerBlur(); + } + g.startEditing(r, c); + } + } + }, + + acceptsNav : function(row, col, cm){ + return !cm.isHidden(col) && cm.isCellEditable(col, row); + } +}); +Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, { + + clicksToEdit: 2, + + + forceValidation: false, + + + isEditor : true, + + detectEdit: false, + + + autoEncode : false, + + + + trackMouseOver: false, + + + initComponent : function(){ + Ext.grid.EditorGridPanel.superclass.initComponent.call(this); + + if(!this.selModel){ + + this.selModel = new Ext.grid.CellSelectionModel(); + } + + this.activeEditor = null; + + this.addEvents( + + "beforeedit", + + "afteredit", + + "validateedit" + ); + }, + + + initEvents : function(){ + Ext.grid.EditorGridPanel.superclass.initEvents.call(this); + + this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this); + this.on('columnresize', this.stopEditing, this, [true]); + + if(this.clicksToEdit == 1){ + this.on("cellclick", this.onCellDblClick, this); + }else { + var view = this.getView(); + if(this.clicksToEdit == 'auto' && view.mainBody){ + view.mainBody.on('mousedown', this.onAutoEditClick, this); + } + this.on('celldblclick', this.onCellDblClick, this); + } + }, + + onResize : function(){ + Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments); + var ae = this.activeEditor; + if(this.editing && ae){ + ae.realign(true); + } + }, + + + onCellDblClick : function(g, row, col){ + this.startEditing(row, col); + }, + + + onAutoEditClick : function(e, t){ + if(e.button !== 0){ + return; + } + var row = this.view.findRowIndex(t), + col = this.view.findCellIndex(t); + if(row !== false && col !== false){ + this.stopEditing(); + if(this.selModel.getSelectedCell){ + var sc = this.selModel.getSelectedCell(); + if(sc && sc[0] === row && sc[1] === col){ + this.startEditing(row, col); + } + }else{ + if(this.selModel.isSelected(row)){ + this.startEditing(row, col); + } + } + } + }, + + + onEditComplete : function(ed, value, startValue){ + this.editing = false; + this.lastActiveEditor = this.activeEditor; + this.activeEditor = null; + + var r = ed.record, + field = this.colModel.getDataIndex(ed.col); + value = this.postEditValue(value, startValue, r, field); + if(this.forceValidation === true || String(value) !== String(startValue)){ + var e = { + grid: this, + record: r, + field: field, + originalValue: startValue, + value: value, + row: ed.row, + column: ed.col, + cancel:false + }; + if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){ + r.set(field, e.value); + delete e.cancel; + this.fireEvent("afteredit", e); + } + } + this.view.focusCell(ed.row, ed.col); + }, + + + startEditing : function(row, col){ + this.stopEditing(); + if(this.colModel.isCellEditable(col, row)){ + this.view.ensureVisible(row, col, true); + var r = this.store.getAt(row), + field = this.colModel.getDataIndex(col), + e = { + grid: this, + record: r, + field: field, + value: r.data[field], + row: row, + column: col, + cancel:false + }; + if(this.fireEvent("beforeedit", e) !== false && !e.cancel){ + this.editing = true; + var ed = this.colModel.getCellEditor(col, row); + if(!ed){ + return; + } + if(!ed.rendered){ + ed.parentEl = this.view.getEditorParent(ed); + ed.on({ + scope: this, + render: { + fn: function(c){ + c.field.focus(false, true); + }, + single: true, + scope: this + }, + specialkey: function(field, e){ + this.getSelectionModel().onEditorKey(field, e); + }, + complete: this.onEditComplete, + canceledit: this.stopEditing.createDelegate(this, [true]) + }); + } + Ext.apply(ed, { + row : row, + col : col, + record : r + }); + this.lastEdit = { + row: row, + col: col + }; + this.activeEditor = ed; + if (ed.field.isXType('checkbox')) { + ed.allowBlur = false; + this.setupCheckbox(ed.field); + } + + + ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor); + var v = this.preEditValue(r, field); + ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : ''); + + + (function(){ + delete ed.selectSameEditor; + }).defer(50); + } + } + }, + + setupCheckbox: function(field){ + var me = this, + fn = function() { + field.el.on('click', me.onCheckClick, me, {single: true}); + }; + if (field.rendered) { + fn(); + } else { + field.on('render', fn, null, {single: true}); + } + }, + + onCheckClick: function(){ + var ed = this.activeEditor; + ed.allowBlur = true; + ed.field.focus(false, 10); + }, + + + preEditValue : function(r, field){ + var value = r.data[field]; + return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value; + }, + + + postEditValue : function(value, originalValue, r, field){ + return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value; + }, + + + stopEditing : function(cancel){ + if(this.editing){ + + var ae = this.lastActiveEditor = this.activeEditor; + if(ae){ + ae[cancel === true ? 'cancelEdit' : 'completeEdit'](); + this.view.focusCell(ae.row, ae.col); + } + this.activeEditor = null; + } + this.editing = false; + } +}); +Ext.reg('editorgrid', Ext.grid.EditorGridPanel); + +Ext.grid.GridEditor = function(field, config){ + Ext.grid.GridEditor.superclass.constructor.call(this, field, config); + field.monitorTab = false; +}; + +Ext.extend(Ext.grid.GridEditor, Ext.Editor, { + alignment: "tl-tl", + autoSize: "width", + hideEl : false, + cls: "x-small-editor x-grid-editor", + shim:false, + shadow:false +}); +Ext.grid.PropertyRecord = Ext.data.Record.create([ + {name:'name',type:'string'}, 'value' +]); + + +Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, { + + constructor : function(grid, source){ + this.grid = grid; + this.store = new Ext.data.Store({ + recordType : Ext.grid.PropertyRecord + }); + this.store.on('update', this.onUpdate, this); + if(source){ + this.setSource(source); + } + Ext.grid.PropertyStore.superclass.constructor.call(this); + }, + + + setSource : function(o){ + this.source = o; + this.store.removeAll(); + var data = []; + for(var k in o){ + if(this.isEditableValue(o[k])){ + data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k)); + } + } + this.store.loadRecords({records: data}, {}, true); + }, + + + onUpdate : function(ds, record, type){ + if(type == Ext.data.Record.EDIT){ + var v = record.data.value; + var oldValue = record.modified.value; + if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){ + this.source[record.id] = v; + record.commit(); + this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue); + }else{ + record.reject(); + } + } + }, + + + getProperty : function(row){ + return this.store.getAt(row); + }, + + + isEditableValue: function(val){ + return Ext.isPrimitive(val) || Ext.isDate(val); + }, + + + setValue : function(prop, value, create){ + var r = this.getRec(prop); + if(r){ + r.set('value', value); + this.source[prop] = value; + }else if(create){ + + this.source[prop] = value; + r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop); + this.store.add(r); + + } + }, + + + remove : function(prop){ + var r = this.getRec(prop); + if(r){ + this.store.remove(r); + delete this.source[prop]; + } + }, + + + getRec : function(prop){ + return this.store.getById(prop); + }, + + + getSource : function(){ + return this.source; + } +}); + + +Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, { + + nameText : 'Name', + valueText : 'Value', + dateFormat : 'm/j/Y', + trueText: 'true', + falseText: 'false', + + constructor : function(grid, store){ + var g = Ext.grid, + f = Ext.form; + + this.grid = grid; + g.PropertyColumnModel.superclass.constructor.call(this, [ + {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true}, + {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true} + ]); + this.store = store; + + var bfield = new f.Field({ + autoCreate: {tag: 'select', children: [ + {tag: 'option', value: 'true', html: this.trueText}, + {tag: 'option', value: 'false', html: this.falseText} + ]}, + getValue : function(){ + return this.el.dom.value == 'true'; + } + }); + this.editors = { + 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})), + 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})), + 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})), + 'boolean' : new g.GridEditor(bfield, { + autoSize: 'both' + }) + }; + this.renderCellDelegate = this.renderCell.createDelegate(this); + this.renderPropDelegate = this.renderProp.createDelegate(this); + }, + + + renderDate : function(dateVal){ + return dateVal.dateFormat(this.dateFormat); + }, + + + renderBool : function(bVal){ + return this[bVal ? 'trueText' : 'falseText']; + }, + + + isCellEditable : function(colIndex, rowIndex){ + return colIndex == 1; + }, + + + getRenderer : function(col){ + return col == 1 ? + this.renderCellDelegate : this.renderPropDelegate; + }, + + + renderProp : function(v){ + return this.getPropertyName(v); + }, + + + renderCell : function(val, meta, rec){ + var renderer = this.grid.customRenderers[rec.get('name')]; + if(renderer){ + return renderer.apply(this, arguments); + } + var rv = val; + if(Ext.isDate(val)){ + rv = this.renderDate(val); + }else if(typeof val == 'boolean'){ + rv = this.renderBool(val); + } + return Ext.util.Format.htmlEncode(rv); + }, + + + getPropertyName : function(name){ + var pn = this.grid.propertyNames; + return pn && pn[name] ? pn[name] : name; + }, + + + getCellEditor : function(colIndex, rowIndex){ + var p = this.store.getProperty(rowIndex), + n = p.data.name, + val = p.data.value; + if(this.grid.customEditors[n]){ + return this.grid.customEditors[n]; + } + if(Ext.isDate(val)){ + return this.editors.date; + }else if(typeof val == 'number'){ + return this.editors.number; + }else if(typeof val == 'boolean'){ + return this.editors['boolean']; + }else{ + return this.editors.string; + } + }, + + + destroy : function(){ + Ext.grid.PropertyColumnModel.superclass.destroy.call(this); + this.destroyEditors(this.editors); + this.destroyEditors(this.grid.customEditors); + }, + + destroyEditors: function(editors){ + for(var ed in editors){ + Ext.destroy(editors[ed]); + } + } +}); + + +Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, { + + + + + + + enableColumnMove:false, + stripeRows:false, + trackMouseOver: false, + clicksToEdit:1, + enableHdMenu : false, + viewConfig : { + forceFit:true + }, + + + initComponent : function(){ + this.customRenderers = this.customRenderers || {}; + this.customEditors = this.customEditors || {}; + this.lastEditRow = null; + var store = new Ext.grid.PropertyStore(this); + this.propStore = store; + var cm = new Ext.grid.PropertyColumnModel(this, store); + store.store.sort('name', 'ASC'); + this.addEvents( + + 'beforepropertychange', + + 'propertychange' + ); + this.cm = cm; + this.ds = store.store; + Ext.grid.PropertyGrid.superclass.initComponent.call(this); + + this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){ + if(colIndex === 0){ + this.startEditing.defer(200, this, [rowIndex, 1]); + return false; + } + }, this); + }, + + + onRender : function(){ + Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments); + + this.getGridEl().addClass('x-props-grid'); + }, + + + afterRender: function(){ + Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments); + if(this.source){ + this.setSource(this.source); + } + }, + + + setSource : function(source){ + this.propStore.setSource(source); + }, + + + getSource : function(){ + return this.propStore.getSource(); + }, + + + setProperty : function(prop, value, create){ + this.propStore.setValue(prop, value, create); + }, + + + removeProperty : function(prop){ + this.propStore.remove(prop); + } + + + + + +}); +Ext.reg("propertygrid", Ext.grid.PropertyGrid); + +Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, { + + + groupByText : 'Group By This Field', + + showGroupsText : 'Show in Groups', + + hideGroupedColumn : false, + + showGroupName : true, + + startCollapsed : false, + + enableGrouping : true, + + enableGroupingMenu : true, + + enableNoGroups : true, + + emptyGroupText : '(None)', + + ignoreAdd : false, + + groupTextTpl : '{text}', + + + groupMode: 'value', + + + + + cancelEditOnToggle: true, + + + initTemplates : function(){ + Ext.grid.GroupingView.superclass.initTemplates.call(this); + this.state = {}; + + var sm = this.grid.getSelectionModel(); + sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect', + this.onBeforeRowSelect, this); + + if(!this.startGroup){ + this.startGroup = new Ext.XTemplate( + '
    ', + '
    ', this.groupTextTpl ,'
    ', + '
    ' + ); + } + this.startGroup.compile(); + + if (!this.endGroup) { + this.endGroup = '
    '; + } + }, + + + findGroup : function(el){ + return Ext.fly(el).up('.x-grid-group', this.mainBody.dom); + }, + + + getGroups : function(){ + return this.hasRows() ? this.mainBody.dom.childNodes : []; + }, + + + onAdd : function(ds, records, index) { + if (this.canGroup() && !this.ignoreAdd) { + var ss = this.getScrollState(); + this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1)); + this.refresh(); + this.restoreScroll(ss); + this.fireEvent('rowsinserted', ds, index, index + (records.length-1)); + } else if (!this.canGroup()) { + Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments); + } + }, + + + onRemove : function(ds, record, index, isUpdate){ + Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments); + var g = document.getElementById(record._groupId); + if(g && g.childNodes[1].childNodes.length < 1){ + Ext.removeNode(g); + } + this.applyEmptyText(); + }, + + + refreshRow : function(record){ + if(this.ds.getCount()==1){ + this.refresh(); + }else{ + this.isUpdating = true; + Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments); + this.isUpdating = false; + } + }, + + + beforeMenuShow : function(){ + var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false; + if((item = items.get('groupBy'))){ + item.setDisabled(disabled); + } + if((item = items.get('showGroups'))){ + item.setDisabled(disabled); + item.setChecked(this.canGroup(), true); + } + }, + + + renderUI : function(){ + var markup = Ext.grid.GroupingView.superclass.renderUI.call(this); + + if(this.enableGroupingMenu && this.hmenu){ + this.hmenu.add('-',{ + itemId:'groupBy', + text: this.groupByText, + handler: this.onGroupByClick, + scope: this, + iconCls:'x-group-by-icon' + }); + if(this.enableNoGroups){ + this.hmenu.add({ + itemId:'showGroups', + text: this.showGroupsText, + checked: true, + checkHandler: this.onShowGroupsClick, + scope: this + }); + } + this.hmenu.on('beforeshow', this.beforeMenuShow, this); + } + return markup; + }, + + processEvent: function(name, e){ + Ext.grid.GroupingView.superclass.processEvent.call(this, name, e); + var hd = e.getTarget('.x-grid-group-hd', this.mainBody); + if(hd){ + + var field = this.getGroupField(), + prefix = this.getPrefix(field), + groupValue = hd.id.substring(prefix.length), + emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd'); + + + groupValue = groupValue.substr(0, groupValue.length - 3); + + + if(groupValue || emptyRe.test(hd.id)){ + this.grid.fireEvent('group' + name, this.grid, field, groupValue, e); + } + if(name == 'mousedown' && e.button == 0){ + this.toggleGroup(hd.parentNode); + } + } + + }, + + + onGroupByClick : function(){ + var grid = this.grid; + this.enableGrouping = true; + grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex)); + grid.fireEvent('groupchange', grid, grid.store.getGroupState()); + this.beforeMenuShow(); + this.refresh(); + }, + + + onShowGroupsClick : function(mi, checked){ + this.enableGrouping = checked; + if(checked){ + this.onGroupByClick(); + }else{ + this.grid.store.clearGrouping(); + this.grid.fireEvent('groupchange', this, null); + } + }, + + + toggleRowIndex : function(rowIndex, expanded){ + if(!this.canGroup()){ + return; + } + var row = this.getRow(rowIndex); + if(row){ + this.toggleGroup(this.findGroup(row), expanded); + } + }, + + + toggleGroup : function(group, expanded){ + var gel = Ext.get(group), + id = Ext.util.Format.htmlEncode(gel.id); + + expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed'); + if(this.state[id] !== expanded){ + if (this.cancelEditOnToggle !== false) { + this.grid.stopEditing(true); + } + this.state[id] = expanded; + gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed'); + } + }, + + + toggleAllGroups : function(expanded){ + var groups = this.getGroups(); + for(var i = 0, len = groups.length; i < len; i++){ + this.toggleGroup(groups[i], expanded); + } + }, + + + expandAllGroups : function(){ + this.toggleAllGroups(true); + }, + + + collapseAllGroups : function(){ + this.toggleAllGroups(false); + }, + + + getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){ + var column = this.cm.config[colIndex], + g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v); + if(g === '' || g === ' '){ + g = column.emptyGroupText || this.emptyGroupText; + } + return g; + }, + + + getGroupField : function(){ + return this.grid.store.getGroupState(); + }, + + + afterRender : function(){ + if(!this.ds || !this.cm){ + return; + } + Ext.grid.GroupingView.superclass.afterRender.call(this); + if(this.grid.deferRowRender){ + this.updateGroupWidths(); + } + }, + + afterRenderUI: function () { + Ext.grid.GroupingView.superclass.afterRenderUI.call(this); + + if (this.enableGroupingMenu && this.hmenu) { + this.hmenu.add('-',{ + itemId:'groupBy', + text: this.groupByText, + handler: this.onGroupByClick, + scope: this, + iconCls:'x-group-by-icon' + }); + + if (this.enableNoGroups) { + this.hmenu.add({ + itemId:'showGroups', + text: this.showGroupsText, + checked: true, + checkHandler: this.onShowGroupsClick, + scope: this + }); + } + + this.hmenu.on('beforeshow', this.beforeMenuShow, this); + } + }, + + + renderRows : function(){ + var groupField = this.getGroupField(); + var eg = !!groupField; + + if(this.hideGroupedColumn) { + var colIndex = this.cm.findColumnIndex(groupField), + hasLastGroupField = Ext.isDefined(this.lastGroupField); + if(!eg && hasLastGroupField){ + this.mainBody.update(''); + this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false); + delete this.lastGroupField; + }else if (eg && !hasLastGroupField){ + this.lastGroupField = groupField; + this.cm.setHidden(colIndex, true); + }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) { + this.mainBody.update(''); + var oldIndex = this.cm.findColumnIndex(this.lastGroupField); + this.cm.setHidden(oldIndex, false); + this.lastGroupField = groupField; + this.cm.setHidden(colIndex, true); + } + } + return Ext.grid.GroupingView.superclass.renderRows.apply( + this, arguments); + }, + + + doRender : function(cs, rs, ds, startRow, colCount, stripe){ + if(rs.length < 1){ + return ''; + } + + if(!this.canGroup() || this.isUpdating){ + return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments); + } + + var groupField = this.getGroupField(), + colIndex = this.cm.findColumnIndex(groupField), + g, + gstyle = 'width:' + this.getTotalWidth() + ';', + cfg = this.cm.config[colIndex], + groupRenderer = cfg.groupRenderer || cfg.renderer, + prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '', + groups = [], + curGroup, i, len, gid; + + for(i = 0, len = rs.length; i < len; i++){ + var rowIndex = startRow + i, + r = rs[i], + gvalue = r.data[groupField]; + + g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds); + if(!curGroup || curGroup.group != g){ + gid = this.constructId(gvalue, groupField, colIndex); + + + this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed); + curGroup = { + group: g, + gvalue: gvalue, + text: prefix + g, + groupId: gid, + startRow: rowIndex, + rs: [r], + cls: this.state[gid] ? '' : 'x-grid-group-collapsed', + style: gstyle + }; + groups.push(curGroup); + }else{ + curGroup.rs.push(r); + } + r._groupId = gid; + } + + var buf = []; + for(i = 0, len = groups.length; i < len; i++){ + g = groups[i]; + this.doGroupStart(buf, g, cs, ds, colCount); + buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call( + this, cs, g.rs, ds, g.startRow, colCount, stripe); + + this.doGroupEnd(buf, g, cs, ds, colCount); + } + return buf.join(''); + }, + + + getGroupId : function(value){ + var field = this.getGroupField(); + return this.constructId(value, field, this.cm.findColumnIndex(field)); + }, + + + constructId : function(value, field, idx){ + var cfg = this.cm.config[idx], + groupRenderer = cfg.groupRenderer || cfg.renderer, + val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds); + + return this.getPrefix(field) + Ext.util.Format.htmlEncode(val); + }, + + + canGroup : function(){ + return this.enableGrouping && !!this.getGroupField(); + }, + + + getPrefix: function(field){ + return this.grid.getGridEl().id + '-gp-' + field + '-'; + }, + + + doGroupStart : function(buf, g, cs, ds, colCount){ + buf[buf.length] = this.startGroup.apply(g); + }, + + + doGroupEnd : function(buf, g, cs, ds, colCount){ + buf[buf.length] = this.endGroup; + }, + + + getRows : function(){ + if(!this.canGroup()){ + return Ext.grid.GroupingView.superclass.getRows.call(this); + } + var r = [], + gs = this.getGroups(), + g, + i = 0, + len = gs.length, + j, + jlen; + for(; i < len; ++i){ + g = gs[i].childNodes[1]; + if(g){ + g = g.childNodes; + for(j = 0, jlen = g.length; j < jlen; ++j){ + r[r.length] = g[j]; + } + } + } + return r; + }, + + + updateGroupWidths : function(){ + if(!this.canGroup() || !this.hasRows()){ + return; + } + var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px'; + var gs = this.getGroups(); + for(var i = 0, len = gs.length; i < len; i++){ + gs[i].firstChild.style.width = tw; + } + }, + + + onColumnWidthUpdated : function(col, w, tw){ + Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw); + this.updateGroupWidths(); + }, + + + onAllColumnWidthsUpdated : function(ws, tw){ + Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw); + this.updateGroupWidths(); + }, + + + onColumnHiddenUpdated : function(col, hidden, tw){ + Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw); + this.updateGroupWidths(); + }, + + + onLayout : function(){ + this.updateGroupWidths(); + }, + + + onBeforeRowSelect : function(sm, rowIndex){ + this.toggleRowIndex(rowIndex, true); + } +}); + +Ext.grid.GroupingView.GROUP_ID = 1000; diff --git a/deluge/ui/web/js/extjs/ext-all.js b/deluge/ui/web/js/extjs/ext-all.js new file mode 100644 index 0000000..5f3e5aa --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-all.js @@ -0,0 +1,21 @@ +/* +This file is part of Ext JS 3.4 + +Copyright (c) 2011-2013 Sencha Inc + +Contact: http://www.sencha.com/contact + +GNU General Public License Usage +This file may be used under the terms of the GNU General Public License version 3.0 as +published by the Free Software Foundation and appearing in the file LICENSE included in the +packaging of this file. + +Please review the following information to ensure the GNU General Public License version 3.0 +requirements will be met: http://www.gnu.org/copyleft/gpl.html. + +If you are unsure which license is appropriate for your use, please contact the sales department +at http://www.sencha.com/contact. + +Build date: 2013-04-03 15:07:25 +*/ +(function(){var h=Ext.util,j=Ext.each,g=true,i=false;h.Observable=function(){var k=this,l=k.events;if(k.listeners){k.on(k.listeners);delete k.listeners}k.events=l||{}};h.Observable.prototype={filterOptRe:/^(?:scope|delay|buffer|single)$/,fireEvent:function(){var k=Array.prototype.slice.call(arguments,0),m=k[0].toLowerCase(),n=this,l=g,p=n.events[m],s,o,r;if(n.eventsSuspended===g){if(o=n.eventQueue){o.push(k)}}else{if(typeof p=="object"){if(p.bubble){if(p.fire.apply(p,k.slice(1))===i){return i}r=n.getBubbleTarget&&n.getBubbleTarget();if(r&&r.enableBubble){s=r.events[m];if(!s||typeof s!="object"||!s.bubble){r.enableBubble(m)}return r.fireEvent.apply(r,k)}}else{k.shift();l=p.fire.apply(p,k)}}}return l},addListener:function(k,m,l,r){var n=this,q,s,p;if(typeof k=="object"){r=k;for(q in r){s=r[q];if(!n.filterOptRe.test(q)){n.addListener(q,s.fn||s,s.scope||r.scope,s.fn?s:r)}}}else{k=k.toLowerCase();p=n.events[k]||g;if(typeof p=="boolean"){n.events[k]=p=new h.Event(n,k)}p.addListener(m,l,typeof r=="object"?r:{})}},removeListener:function(k,m,l){var n=this.events[k.toLowerCase()];if(typeof n=="object"){n.removeListener(m,l)}},purgeListeners:function(){var m=this.events,k,l;for(l in m){k=m[l];if(typeof k=="object"){k.clearListeners()}}},addEvents:function(n){var m=this;m.events=m.events||{};if(typeof n=="string"){var k=arguments,l=k.length;while(l--){m.events[k[l]]=m.events[k[l]]||g}}else{Ext.applyIf(m.events,n)}},hasListener:function(k){var l=this.events[k.toLowerCase()];return typeof l=="object"&&l.listeners.length>0},suspendEvents:function(k){this.eventsSuspended=g;if(k&&!this.eventQueue){this.eventQueue=[]}},resumeEvents:function(){var k=this,l=k.eventQueue||[];k.eventsSuspended=i;delete k.eventQueue;j(l,function(m){k.fireEvent.apply(k,m)})}};var d=h.Observable.prototype;d.on=d.addListener;d.un=d.removeListener;h.Observable.releaseCapture=function(k){k.fireEvent=d.fireEvent};function e(l,m,k){return function(){if(m.target==arguments[0]){l.apply(k,Array.prototype.slice.call(arguments,0))}}}function b(n,p,k,m){k.task=new h.DelayedTask();return function(){k.task.delay(p.buffer,n,m,Array.prototype.slice.call(arguments,0))}}function c(m,n,l,k){return function(){n.removeListener(l,k);return m.apply(k,arguments)}}function a(n,p,k,m){return function(){var l=new h.DelayedTask(),o=Array.prototype.slice.call(arguments,0);if(!k.tasks){k.tasks=[]}k.tasks.push(l);l.delay(p.delay||10,function(){k.tasks.remove(l);n.apply(m,o)},m)}}h.Event=function(l,k){this.name=k;this.obj=l;this.listeners=[]};h.Event.prototype={addListener:function(o,n,m){var p=this,k;n=n||p.obj;if(!p.isListening(o,n)){k=p.createListener(o,n,m);if(p.firing){p.listeners=p.listeners.slice(0)}p.listeners.push(k)}},createListener:function(p,n,q){q=q||{};n=n||this.obj;var k={fn:p,scope:n,options:q},m=p;if(q.target){m=e(m,q,n)}if(q.delay){m=a(m,q,k,n)}if(q.single){m=c(m,this,p,n)}if(q.buffer){m=b(m,q,k,n)}k.fireFn=m;return k},findListener:function(o,n){var p=this.listeners,m=p.length,k;n=n||this.obj;while(m--){k=p[m];if(k){if(k.fn==o&&k.scope==n){return m}}}return -1},isListening:function(l,k){return this.findListener(l,k)!=-1},removeListener:function(r,q){var p,m,n,s=this,o=i;if((p=s.findListener(r,q))!=-1){if(s.firing){s.listeners=s.listeners.slice(0)}m=s.listeners[p];if(m.task){m.task.cancel();delete m.task}n=m.tasks&&m.tasks.length;if(n){while(n--){m.tasks[n].cancel()}delete m.tasks}s.listeners.splice(p,1);o=g}return o},clearListeners:function(){var n=this,k=n.listeners,m=k.length;while(m--){n.removeListener(k[m].fn,k[m].scope)}},fire:function(){var q=this,p=q.listeners,k=p.length,o=0,m;if(k>0){q.firing=g;var n=Array.prototype.slice.call(arguments,0);for(;o",i="",b=a+"",j=""+i,l=b+"",w=""+j;function h(B,D,C,E,A,y){var z=r.insertHtml(E,Ext.getDom(B),u(D));return C?Ext.get(z,true):z}function u(D){var z="",y,C,B,E;if(typeof D=="string"){z=D}else{if(Ext.isArray(D)){for(var A=0;A"}}}return z}function g(F,C,B,D){x.innerHTML=[C,B,D].join("");var y=-1,A=x,z;while(++y "'+D+'"'},insertBefore:function(y,A,z){return h(y,A,z,c)},insertAfter:function(y,A,z){return h(y,A,z,p,"nextSibling")},insertFirst:function(y,A,z){return h(y,A,z,n,"firstChild")},append:function(y,A,z){return h(y,A,z,q,"",true)},overwrite:function(y,A,z){y=Ext.getDom(y);y.innerHTML=u(A);return z?Ext.get(y.firstChild):y.firstChild},createHtml:u};return r}();Ext.Template=function(h){var j=this,c=arguments,e=[],d;if(Ext.isArray(h)){h=h.join("")}else{if(c.length>1){for(var g=0,b=c.length;g+~]\s?|\s|$)/,tagTokenRe=/^(#)?([\w\-\*]+)/,nthRe=/(\d*)n\+?(\d*)/,nthRe2=/\D/,isIE=window.ActiveXObject?true:false,key=30803;eval("var batch = 30803;");function child(parent,index){var i=0,n=parent.firstChild;while(n){if(n.nodeType==1){if(++i==index){return n}}n=n.nextSibling}return null}function next(n){while((n=n.nextSibling)&&n.nodeType!=1){}return n}function prev(n){while((n=n.previousSibling)&&n.nodeType!=1){}return n}function children(parent){var n=parent.firstChild,nodeIndex=-1,nextNode;while(n){nextNode=n.nextSibling;if(n.nodeType==3&&!nonSpace.test(n.nodeValue)){parent.removeChild(n)}else{n.nodeIndex=++nodeIndex}n=nextNode}return this}function byClassName(nodeSet,cls){if(!cls){return nodeSet}var result=[],ri=-1;for(var i=0,ci;ci=nodeSet[i];i++){if((" "+ci.className+" ").indexOf(cls)!=-1){result[++ri]=ci}}return result}function attrValue(n,attr){if(!n.tagName&&typeof n.length!="undefined"){n=n[0]}if(!n){return null}if(attr=="for"){return n.htmlFor}if(attr=="class"||attr=="className"){return n.className}return n.getAttribute(attr)||n[attr]}function getNodes(ns,mode,tagName){var result=[],ri=-1,cs;if(!ns){return result}tagName=tagName||"*";if(typeof ns.getElementsByTagName!="undefined"){ns=[ns]}if(!mode){for(var i=0,ni;ni=ns[i];i++){cs=ni.getElementsByTagName(tagName);for(var j=0,ci;ci=cs[j];j++){result[++ri]=ci}}}else{if(mode=="/"||mode==">"){var utag=tagName.toUpperCase();for(var i=0,ni,cn;ni=ns[i];i++){cn=ni.childNodes;for(var j=0,cj;cj=cn[j];j++){if(cj.nodeName==utag||cj.nodeName==tagName||tagName=="*"){result[++ri]=cj}}}}else{if(mode=="+"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(n&&(n.nodeName==utag||n.nodeName==tagName||tagName=="*")){result[++ri]=n}}}else{if(mode=="~"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)){if(n.nodeName==utag||n.nodeName==tagName||tagName=="*"){result[++ri]=n}}}}}}}return result}function concat(a,b){if(b.slice){return a.concat(b)}for(var i=0,l=b.length;i1){return nodup(results)}return results},isXml:function(el){var docEl=(el?el.ownerDocument||el:0).documentElement;return docEl?docEl.nodeName!=="HTML":false},select:document.querySelectorAll?function(path,root,type){root=root||document;if(!Ext.DomQuery.isXml(root)){try{var cs=root.querySelectorAll(path);return Ext.toArray(cs)}catch(ex){}}return Ext.DomQuery.jsSelect.call(this,path,root,type)}:function(path,root,type){return Ext.DomQuery.jsSelect.call(this,path,root,type)},selectNode:function(path,root){return Ext.DomQuery.select(path,root)[0]},selectValue:function(path,root,defaultValue){path=path.replace(trimRe,"");if(!valueCache[path]){valueCache[path]=Ext.DomQuery.compile(path,"select")}var n=valueCache[path](root),v;n=n[0]?n[0]:n;if(typeof n.normalize=="function"){n.normalize()}v=(n&&n.firstChild?n.firstChild.nodeValue:null);return((v===null||v===undefined||v==="")?defaultValue:v)},selectNumber:function(path,root,defaultValue){var v=Ext.DomQuery.selectValue(path,root,defaultValue||0);return parseFloat(v)},is:function(el,ss){if(typeof el=="string"){el=document.getElementById(el)}var isArray=Ext.isArray(el),result=Ext.DomQuery.filter(isArray?el:[el],ss);return isArray?(result.length==el.length):(result.length>0)},filter:function(els,ss,nonMatches){ss=ss.replace(trimRe,"");if(!simpleCache[ss]){simpleCache[ss]=Ext.DomQuery.compile(ss,"simple")}var result=simpleCache[ss](els);return nonMatches?quickDiff(result,els):result},matchers:[{re:/^\.([\w\-]+)/,select:'n = byClassName(n, " {1} ");'},{re:/^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,select:'n = byPseudo(n, "{1}", "{2}");'},{re:/^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,select:'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'},{re:/^#([\w\-]+)/,select:'n = byId(n, "{1}");'},{re:/^@([\w\-]+)/,select:'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'}],operators:{"=":function(a,v){return a==v},"!=":function(a,v){return a!=v},"^=":function(a,v){return a&&a.substr(0,v.length)==v},"$=":function(a,v){return a&&a.substr(a.length-v.length)==v},"*=":function(a,v){return a&&a.indexOf(v)!==-1},"%=":function(a,v){return(a%v)==0},"|=":function(a,v){return a&&(a==v||a.substr(0,v.length+1)==v+"-")},"~=":function(a,v){return a&&(" "+a+" ").indexOf(" "+v+" ")!=-1}},pseudos:{"first-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.previousSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"last-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"nth-child":function(c,a){var r=[],ri=-1,m=nthRe.exec(a=="even"&&"2n"||a=="odd"&&"2n+1"||!nthRe2.test(a)&&"n+"+a||a),f=(m[1]||1)-0,l=m[2]-0;for(var i=0,n;n=c[i];i++){var pn=n.parentNode;if(batch!=pn._batch){var j=0;for(var cn=pn.firstChild;cn;cn=cn.nextSibling){if(cn.nodeType==1){cn.nodeIndex=++j}}pn._batch=batch}if(f==1){if(l==0||n.nodeIndex==l){r[++ri]=n}}else{if((n.nodeIndex+l)%f==0){r[++ri]=n}}}return r},"only-child":function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(!prev(ci)&&!next(ci)){r[++ri]=ci}}return r},empty:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var cns=ci.childNodes,j=0,cn,empty=true;while(cn=cns[j]){++j;if(cn.nodeType==1||cn.nodeType==3){empty=false;break}}if(empty){r[++ri]=ci}}return r},contains:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if((ci.textContent||ci.innerText||"").indexOf(v)!=-1){r[++ri]=ci}}return r},nodeValue:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.firstChild&&ci.firstChild.nodeValue==v){r[++ri]=ci}}return r},checked:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.checked==true){r[++ri]=ci}}return r},not:function(c,ss){return Ext.DomQuery.filter(c,ss,true)},any:function(c,selectors){var ss=selectors.split("|"),r=[],ri=-1,s;for(var i=0,ci;ci=c[i];i++){for(var j=0;s=ss[j];j++){if(Ext.DomQuery.is(ci,s)){r[++ri]=ci;break}}}return r},odd:function(c){return this["nth-child"](c,"odd")},even:function(c){return this["nth-child"](c,"even")},nth:function(c,a){return c[a-1]||[]},first:function(c){return c[0]||[]},last:function(c){return c[c.length-1]||[]},has:function(c,ss){var s=Ext.DomQuery.select,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(s(ss,ci).length>0){r[++ri]=ci}}return r},next:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r},prev:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r}}}}();Ext.query=Ext.DomQuery.select;Ext.util.DelayedTask=function(d,c,a){var e=this,g,b=function(){clearInterval(g);g=null;d.apply(c,a||[])};e.delay=function(i,k,j,h){e.cancel();d=k||d;c=j||c;a=h||a;g=setInterval(b,i)};e.cancel=function(){if(g){clearInterval(g);g=null}}};(function(){var h=document;Ext.Element=function(l,m){var n=typeof l=="string"?h.getElementById(l):l,o;if(!n){return null}o=n.id;if(!m&&o&&Ext.elCache[o]){return Ext.elCache[o].el}this.dom=n;this.id=o||Ext.id(n)};var d=Ext.DomHelper,e=Ext.Element,a=Ext.elCache;e.prototype={set:function(q,m){var n=this.dom,l,p,m=(m!==false)&&!!n.setAttribute;for(l in q){if(q.hasOwnProperty(l)){p=q[l];if(l=="style"){d.applyStyles(n,p)}else{if(l=="cls"){n.className=p}else{if(m){n.setAttribute(l,p)}else{n[l]=p}}}}}return this},defaultUnit:"px",is:function(l){return Ext.DomQuery.is(this.dom,l)},focus:function(o,n){var l=this,n=n||l.dom;try{if(Number(o)){l.focus.defer(o,null,[null,n])}else{n.focus()}}catch(m){}return l},blur:function(){try{this.dom.blur()}catch(l){}return this},getValue:function(l){var m=this.dom.value;return l?parseInt(m,10):m},addListener:function(l,o,n,m){Ext.EventManager.on(this.dom,l,o,n||this,m);return this},removeListener:function(l,n,m){Ext.EventManager.removeListener(this.dom,l,n,m||this);return this},removeAllListeners:function(){Ext.EventManager.removeAll(this.dom);return this},purgeAllListeners:function(){Ext.EventManager.purgeElement(this,true);return this},addUnits:function(l){if(l===""||l=="auto"||l===undefined){l=l||""}else{if(!isNaN(l)||!i.test(l)){l=l+(this.defaultUnit||"px")}}return l},load:function(m,n,l){Ext.Ajax.request(Ext.apply({params:n,url:m.url||m,callback:l,el:this.dom,indicatorText:m.indicatorText||""},Ext.isObject(m)?m:{}));return this},isBorderBox:function(){return Ext.isBorderBox||Ext.isForcedBorderBox||g[(this.dom.tagName||"").toLowerCase()]},remove:function(){var l=this,m=l.dom;if(m){delete l.dom;Ext.removeNode(m)}},hover:function(m,l,o,n){var p=this;p.on("mouseenter",m,o||p.dom,n);p.on("mouseleave",l,o||p.dom,n);return p},contains:function(l){return !l?false:Ext.lib.Dom.isAncestor(this.dom,l.dom?l.dom:l)},getAttributeNS:function(m,l){return this.getAttribute(l,m)},getAttribute:(function(){var p=document.createElement("table"),o=false,m="getAttribute" in p,l=/undefined|unknown/;if(m){try{p.getAttribute("ext:qtip")}catch(n){o=true}return function(q,s){var r=this.dom,t;if(r.getAttributeNS){t=r.getAttributeNS(s,q)||null}if(t==null){if(s){if(o&&r.tagName.toUpperCase()=="TABLE"){try{t=r.getAttribute(s+":"+q)}catch(u){t=""}}else{t=r.getAttribute(s+":"+q)}}else{t=r.getAttribute(q)||r[q]}}return t||""}}else{return function(q,s){var r=this.om,u,t;if(s){t=r[s+":"+q];u=l.test(typeof t)?undefined:t}else{u=r[q]}return u||""}}p=null})(),update:function(l){if(this.dom){this.dom.innerHTML=l}return this}};var k=e.prototype;e.addMethods=function(l){Ext.apply(k,l)};k.on=k.addListener;k.un=k.removeListener;k.autoBoxAdjust=true;var i=/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,c;e.get=function(m){var l,p,o;if(!m){return null}if(typeof m=="string"){if(!(p=h.getElementById(m))){return null}if(a[m]&&a[m].el){l=a[m].el;l.dom=p}else{l=e.addToCache(new e(p))}return l}else{if(m.tagName){if(!(o=m.id)){o=Ext.id(m)}if(a[o]&&a[o].el){l=a[o].el;l.dom=m}else{l=e.addToCache(new e(m))}return l}else{if(m instanceof e){if(m!=c){if(Ext.isIE&&(m.id==undefined||m.id=="")){m.dom=m.dom}else{m.dom=h.getElementById(m.id)||m.dom}}return m}else{if(m.isComposite){return m}else{if(Ext.isArray(m)){return e.select(m)}else{if(m==h){if(!c){var n=function(){};n.prototype=e.prototype;c=new n();c.dom=h}return c}}}}}}return null};e.addToCache=function(l,m){m=m||l.id;a[m]={el:l,data:{},events:{}};return l};e.data=function(m,l,n){m=e.get(m);if(!m){return null}var o=a[m.id].data;if(arguments.length==2){return o[l]}else{return(o[l]=n)}};function j(){if(!Ext.enableGarbageCollector){clearInterval(e.collectorThreadId)}else{var l,n,q,p;for(l in a){p=a[l];if(p.skipGC){Ext.EventManager.removeFromSpecialCache(p.el);continue}n=p.el;q=n.dom;if(!q||!q.parentNode||(!q.offsetParent&&!h.getElementById(l))){if(Ext.enableListenerCollection){Ext.EventManager.removeAll(q)}delete a[l]}}if(Ext.isIE){var m={};for(l in a){m[l]=a[l]}a=Ext.elCache=m}}}e.collectorThreadId=setInterval(j,30000);var b=function(){};b.prototype=e.prototype;e.Flyweight=function(l){this.dom=l};e.Flyweight.prototype=new b();e.Flyweight.prototype.isFlyweight=true;e._flyweights={};e.fly=function(n,l){var m=null;l=l||"_global";if(n=Ext.getDom(n)){(e._flyweights[l]=e._flyweights[l]||new e.Flyweight()).dom=n;m=e._flyweights[l]}return m};Ext.get=e.get;Ext.fly=e.fly;var g=Ext.isStrict?{select:1}:{input:1,select:1,textarea:1};if(Ext.isIE||Ext.isGecko){g.button=1}})();Ext.Element.addMethods(function(){var d="parentNode",b="nextSibling",c="previousSibling",e=Ext.DomQuery,a=Ext.get;return{findParent:function(m,l,h){var j=this.dom,g=document.body,k=0,i;if(Ext.isGecko&&Object.prototype.toString.call(j)=="[object XULElement]"){return null}l=l||50;if(isNaN(l)){i=Ext.getDom(l);l=Number.MAX_VALUE}while(j&&j.nodeType==1&&k "+g,this.dom);return h?i:a(i)},parent:function(g,h){return this.matchNode(d,d,g,h)},next:function(g,h){return this.matchNode(b,b,g,h)},prev:function(g,h){return this.matchNode(c,c,g,h)},first:function(g,h){return this.matchNode(b,"firstChild",g,h)},last:function(g,h){return this.matchNode(c,"lastChild",g,h)},matchNode:function(h,k,g,i){var j=this.dom[k];while(j){if(j.nodeType==1&&(!g||e.is(j,g))){return !i?a(j):j}j=j[h]}return null}}}());Ext.Element.addMethods(function(){var c=Ext.getDom,a=Ext.get,b=Ext.DomHelper;return{appendChild:function(d){return a(d).appendTo(this)},appendTo:function(d){c(d).appendChild(this.dom);return this},insertBefore:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d);return this},insertAfter:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d.nextSibling);return this},insertFirst:function(e,d){e=e||{};if(e.nodeType||e.dom||typeof e=="string"){e=c(e);this.dom.insertBefore(e,this.dom.firstChild);return !d?a(e):e}else{return this.createChild(e,this.dom.firstChild,d)}},replace:function(d){d=a(d);this.insertBefore(d);d.remove();return this},replaceWith:function(d){var e=this;if(d.nodeType||d.dom||typeof d=="string"){d=c(d);e.dom.parentNode.insertBefore(d,e.dom)}else{d=b.insertBefore(e.dom,d)}delete Ext.elCache[e.id];Ext.removeNode(e.dom);e.id=Ext.id(e.dom=d);Ext.Element.addToCache(e.isFlyweight?new Ext.Element(e.dom):e);return e},createChild:function(e,d,g){e=e||{tag:"div"};return d?b.insertBefore(d,e,g!==true):b[!this.dom.firstChild?"overwrite":"append"](this.dom,e,g!==true)},wrap:function(d,e){var g=b.insertBefore(this.dom,d||{tag:"div"},!e);g.dom?g.dom.appendChild(this.dom):g.appendChild(this.dom);return g},insertHtml:function(e,g,d){var h=b.insertHtml(e,this.dom,g);return d?Ext.get(h):h}}}());Ext.Element.addMethods(function(){var A=Ext.supports,h={},x=/(-[a-z])/gi,s=document.defaultView,D=/alpha\(opacity=(.*)\)/i,l=/^\s+|\s+$/g,B=Ext.Element,u=/\s+/,b=/\w/g,d="padding",c="margin",y="border",t="-left",q="-right",w="-top",o="-bottom",j="-width",r=Math,z="hidden",e="isClipped",k="overflow",n="overflow-x",m="overflow-y",C="originalClip",i={l:y+t+j,r:y+q+j,t:y+w+j,b:y+o+j},g={l:d+t,r:d+q,t:d+w,b:d+o},a={l:c+t,r:c+q,t:c+w,b:c+o},E=Ext.Element.data;function p(F,G){return G.charAt(1).toUpperCase()}function v(F){return h[F]||(h[F]=F=="float"?(A.cssFloat?"cssFloat":"styleFloat"):F.replace(x,p))}return{adjustWidth:function(F){var G=this;var H=(typeof F=="number");if(H&&G.autoBoxAdjust&&!G.isBorderBox()){F-=(G.getBorderWidth("lr")+G.getPadding("lr"))}return(H&&F<0)?0:F},adjustHeight:function(F){var G=this;var H=(typeof F=="number");if(H&&G.autoBoxAdjust&&!G.isBorderBox()){F-=(G.getBorderWidth("tb")+G.getPadding("tb"))}return(H&&F<0)?0:F},addClass:function(J){var K=this,I,F,H,G=[];if(!Ext.isArray(J)){if(typeof J=="string"&&!this.hasClass(J)){K.dom.className+=" "+J}}else{for(I=0,F=J.length;I5?H.toLowerCase():G)},setStyle:function(I,H){var F,G;if(typeof I!="object"){F={};F[I]=H;I=F}for(G in I){H=I[G];G=="opacity"?this.setOpacity(H):this.dom.style[v(G)]=H}return this},setOpacity:function(G,F){var J=this,H=J.dom.style;if(!F||!J.anim){if(Ext.isIE9m){var I=G<1?"alpha(opacity="+G*100+")":"",K=H.filter.replace(D,"").replace(l,"");H.zoom=1;H.filter=K+(K.length>0?" ":"")+I}else{H.opacity=G}}else{J.anim({opacity:{to:G}},J.preanim(arguments,1),null,0.35,"easeIn")}return J},clearOpacity:function(){var F=this.dom.style;if(Ext.isIE9m){if(!Ext.isEmpty(F.filter)){F.filter=F.filter.replace(D,"").replace(l,"")}}else{F.opacity=F["-moz-opacity"]=F["-khtml-opacity"]=""}return this},getHeight:function(H){var G=this,J=G.dom,I=Ext.isIE9m&&G.isStyle("display","none"),F=r.max(J.offsetHeight,I?0:J.clientHeight)||0;F=!H?F:F-G.getBorderWidth("tb")-G.getPadding("tb");return F<0?0:F},getWidth:function(G){var H=this,J=H.dom,I=Ext.isIE9m&&H.isStyle("display","none"),F=r.max(J.offsetWidth,I?0:J.clientWidth)||0;F=!G?F:F-H.getBorderWidth("lr")-H.getPadding("lr");return F<0?0:F},setWidth:function(G,F){var H=this;G=H.adjustWidth(G);!F||!H.anim?H.dom.style.width=H.addUnits(G):H.anim({width:{to:G}},H.preanim(arguments,1));return H},setHeight:function(F,G){var H=this;F=H.adjustHeight(F);!G||!H.anim?H.dom.style.height=H.addUnits(F):H.anim({height:{to:F}},H.preanim(arguments,1));return H},getBorderWidth:function(F){return this.addStyles(F,i)},getPadding:function(F){return this.addStyles(F,g)},clip:function(){var F=this,G=F.dom;if(!E(G,e)){E(G,e,true);E(G,C,{o:F.getStyle(k),x:F.getStyle(n),y:F.getStyle(m)});F.setStyle(k,z);F.setStyle(n,z);F.setStyle(m,z)}return F},unclip:function(){var F=this,H=F.dom;if(E(H,e)){E(H,e,false);var G=E(H,C);if(G.o){F.setStyle(k,G.o)}if(G.x){F.setStyle(n,G.x)}if(G.y){F.setStyle(m,G.y)}}return F},addStyles:function(M,L){var J=0,K=M.match(b),I,H,G,F=K.length;for(G=0;Ga.clientHeight||a.scrollWidth>a.clientWidth},scrollTo:function(a,b){this.dom["scroll"+(/top/i.test(a)?"Top":"Left")]=b;return this},getScroll:function(){var i=this.dom,h=document,a=h.body,c=h.documentElement,b,g,e;if(i==h||i==a){if(Ext.isIE&&Ext.isStrict){b=c.scrollLeft;g=c.scrollTop}else{b=window.pageXOffset;g=window.pageYOffset}e={left:b||(a?a.scrollLeft:0),top:g||(a?a.scrollTop:0)}}else{e={left:i.scrollLeft,top:i.scrollTop}}return e}});Ext.Element.VISIBILITY=1;Ext.Element.DISPLAY=2;Ext.Element.OFFSETS=3;Ext.Element.ASCLASS=4;Ext.Element.visibilityCls="x-hide-nosize";Ext.Element.addMethods(function(){var e=Ext.Element,p="opacity",j="visibility",g="display",d="hidden",n="offsets",k="asclass",m="none",a="nosize",b="originalDisplay",c="visibilityMode",h="isVisible",i=e.data,l=function(r){var q=i(r,b);if(q===undefined){i(r,b,q="")}return q},o=function(r){var q=i(r,c);if(q===undefined){i(r,c,q=1)}return q};return{originalDisplay:"",visibilityMode:1,setVisibilityMode:function(q){i(this.dom,c,q);return this},animate:function(r,t,s,u,q){this.anim(r,{duration:t,callback:s,easing:u},q);return this},anim:function(t,u,r,w,s,q){r=r||"run";u=u||{};var v=this,x=Ext.lib.Anim[r](v.dom,t,(u.duration||w)||0.35,(u.easing||s)||"easeOut",function(){if(q){q.call(v)}if(u.callback){u.callback.call(u.scope||v,v,u)}},v);u.anim=x;return x},preanim:function(q,r){return !q[r]?false:(typeof q[r]=="object"?q[r]:{duration:q[r+1],callback:q[r+2],easing:q[r+3]})},isVisible:function(){var q=this,s=q.dom,r=i(s,h);if(typeof r=="boolean"){return r}r=!q.isStyle(j,d)&&!q.isStyle(g,m)&&!((o(s)==e.ASCLASS)&&q.hasClass(q.visibilityCls||e.visibilityCls));i(s,h,r);return r},setVisible:function(t,q){var w=this,r,y,x,v,u=w.dom,s=o(u);if(typeof q=="string"){switch(q){case g:s=e.DISPLAY;break;case j:s=e.VISIBILITY;break;case n:s=e.OFFSETS;break;case a:case k:s=e.ASCLASS;break}w.setVisibilityMode(s);q=false}if(!q||!w.anim){if(s==e.ASCLASS){w[t?"removeClass":"addClass"](w.visibilityCls||e.visibilityCls)}else{if(s==e.DISPLAY){return w.setDisplayed(t)}else{if(s==e.OFFSETS){if(!t){w.hideModeStyles={position:w.getStyle("position"),top:w.getStyle("top"),left:w.getStyle("left")};w.applyStyles({position:"absolute",top:"-10000px",left:"-10000px"})}else{w.applyStyles(w.hideModeStyles||{position:"",top:"",left:""});delete w.hideModeStyles}}else{w.fixDisplay();u.style.visibility=t?"visible":d}}}}else{if(t){w.setOpacity(0.01);w.setVisible(true)}w.anim({opacity:{to:(t?1:0)}},w.preanim(arguments,1),null,0.35,"easeIn",function(){t||w.setVisible(false).setOpacity(1)})}i(u,h,t);return w},hasMetrics:function(){var q=this.dom;return this.isVisible()||(o(q)==e.VISIBILITY)},toggle:function(q){var r=this;r.setVisible(!r.isVisible(),r.preanim(arguments,0));return r},setDisplayed:function(q){if(typeof q=="boolean"){q=q?l(this.dom):m}this.setStyle(g,q);return this},fixDisplay:function(){var q=this;if(q.isStyle(g,m)){q.setStyle(j,d);q.setStyle(g,l(this.dom));if(q.isStyle(g,m)){q.setStyle(g,"block")}}},hide:function(q){if(typeof q=="string"){this.setVisible(false,q);return this}this.setVisible(false,this.preanim(arguments,0));return this},show:function(q){if(typeof q=="string"){this.setVisible(true,q);return this}this.setVisible(true,this.preanim(arguments,0));return this}}}());(function(){var y=null,A=undefined,k=true,t=false,j="setX",h="setY",a="setXY",n="left",l="bottom",s="top",m="right",q="height",g="width",i="points",w="hidden",z="absolute",u="visible",e="motion",o="position",r="easeOut",d=new Ext.Element.Flyweight(),v={},x=function(B){return B||{}},p=function(B){d.dom=B;d.id=Ext.id(B);return d},c=function(B){if(!v[B]){v[B]=[]}return v[B]},b=function(C,B){v[C]=B};Ext.enableFx=k;Ext.Fx={switchStatements:function(C,D,B){return D.apply(this,B[C])},slideIn:function(H,E){E=x(E);var J=this,G=J.dom,M=G.style,O,B,L,D,C,M,I,N,K,F;H=H||"t";J.queueFx(E,function(){O=p(G).getXY();p(G).fixDisplay();B=p(G).getFxRestore();L={x:O[0],y:O[1],0:O[0],1:O[1],width:G.offsetWidth,height:G.offsetHeight};L.right=L.x+L.width;L.bottom=L.y+L.height;p(G).setWidth(L.width).setHeight(L.height);D=p(G).fxWrap(B.pos,E,w);M.visibility=u;M.position=z;function P(){p(G).fxUnwrap(D,B.pos,E);M.width=B.width;M.height=B.height;p(G).afterFx(E)}N={to:[L.x,L.y]};K={to:L.width};F={to:L.height};function Q(U,R,V,S,X,Z,ac,ab,aa,W,T){var Y={};p(U).setWidth(V).setHeight(S);if(p(U)[X]){p(U)[X](Z)}R[ac]=R[ab]="0";if(aa){Y.width=aa}if(W){Y.height=W}if(T){Y.points=T}return Y}I=p(G).switchStatements(H.toLowerCase(),Q,{t:[D,M,L.width,0,y,y,n,l,y,F,y],l:[D,M,0,L.height,y,y,m,s,K,y,y],r:[D,M,L.width,L.height,j,L.right,n,s,y,y,N],b:[D,M,L.width,L.height,h,L.bottom,n,s,y,F,N],tl:[D,M,0,0,y,y,m,l,K,F,N],bl:[D,M,0,0,h,L.y+L.height,m,s,K,F,N],br:[D,M,0,0,a,[L.right,L.bottom],n,s,K,F,N],tr:[D,M,0,0,j,L.x+L.width,n,l,K,F,N]});M.visibility=u;p(D).show();arguments.callee.anim=p(D).fxanim(I,E,e,0.5,r,P)});return J},slideOut:function(F,D){D=x(D);var H=this,E=H.dom,K=E.style,L=H.getXY(),C,B,I,J,G={to:0};F=F||"t";H.queueFx(D,function(){B=p(E).getFxRestore();I={x:L[0],y:L[1],0:L[0],1:L[1],width:E.offsetWidth,height:E.offsetHeight};I.right=I.x+I.width;I.bottom=I.y+I.height;p(E).setWidth(I.width).setHeight(I.height);C=p(E).fxWrap(B.pos,D,u);K.visibility=u;K.position=z;p(C).setWidth(I.width).setHeight(I.height);function M(){D.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).fxUnwrap(C,B.pos,D);K.width=B.width;K.height=B.height;p(E).afterFx(D)}function N(O,W,U,X,S,V,R,T,Q){var P={};O[W]=O[U]="0";P[X]=S;if(V){P[V]=R}if(T){P[T]=Q}return P}J=p(E).switchStatements(F.toLowerCase(),N,{t:[K,n,l,q,G],l:[K,m,s,g,G],r:[K,n,s,g,G,i,{to:[I.right,I.y]}],b:[K,n,s,q,G,i,{to:[I.x,I.bottom]}],tl:[K,m,l,g,G,q,G],bl:[K,m,s,g,G,q,G,i,{to:[I.x,I.bottom]}],br:[K,n,s,g,G,q,G,i,{to:[I.x+I.width,I.bottom]}],tr:[K,n,l,g,G,q,G,i,{to:[I.right,I.y]}]});arguments.callee.anim=p(C).fxanim(J,D,e,0.5,r,M)});return H},puff:function(H){H=x(H);var F=this,G=F.dom,C=G.style,D,B,E;F.queueFx(H,function(){D=p(G).getWidth();B=p(G).getHeight();p(G).clearOpacity();p(G).show();E=p(G).getFxRestore();function I(){H.useDisplay?p(G).setDisplayed(t):p(G).hide();p(G).clearOpacity();p(G).setPositioning(E.pos);C.width=E.width;C.height=E.height;C.fontSize="";p(G).afterFx(H)}arguments.callee.anim=p(G).fxanim({width:{to:p(G).adjustWidth(D*2)},height:{to:p(G).adjustHeight(B*2)},points:{by:[-D*0.5,-B*0.5]},opacity:{to:0},fontSize:{to:200,unit:"%"}},H,e,0.5,r,I)});return F},switchOff:function(F){F=x(F);var D=this,E=D.dom,B=E.style,C;D.queueFx(F,function(){p(E).clearOpacity();p(E).clip();C=p(E).getFxRestore();function G(){F.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).clearOpacity();p(E).setPositioning(C.pos);B.width=C.width;B.height=C.height;p(E).afterFx(F)}p(E).fxanim({opacity:{to:0.3}},y,y,0.1,y,function(){p(E).clearOpacity();(function(){p(E).fxanim({height:{to:1},points:{by:[0,p(E).getHeight()*0.5]}},F,e,0.3,"easeIn",G)}).defer(100)})});return D},highlight:function(D,H){H=x(H);var F=this,G=F.dom,B=H.attr||"backgroundColor",C={},E;F.queueFx(H,function(){p(G).clearOpacity();p(G).show();function I(){G.style[B]=E;p(G).afterFx(H)}E=G.style[B];C[B]={from:D||"ffff9c",to:H.endColor||p(G).getColor(B)||"ffffff"};arguments.callee.anim=p(G).fxanim(C,H,"color",1,"easeIn",I)});return F},frame:function(B,E,H){H=x(H);var D=this,G=D.dom,C,F;D.queueFx(H,function(){B=B||"#C3DAF9";if(B.length==6){B="#"+B}E=E||1;p(G).show();var L=p(G).getXY(),J={x:L[0],y:L[1],0:L[0],1:L[1],width:G.offsetWidth,height:G.offsetHeight},I=function(){C=p(document.body||document.documentElement).createChild({style:{position:z,"z-index":35000,border:"0px solid "+B}});return C.queueFx({},K)};arguments.callee.anim={isAnimated:true,stop:function(){E=0;C.stopFx()}};function K(){var M=Ext.isBorderBox?2:1;F=C.anim({top:{from:J.y,to:J.y-20},left:{from:J.x,to:J.x-20},borderWidth:{from:0,to:10},opacity:{from:1,to:0},height:{from:J.height,to:J.height+20*M},width:{from:J.width,to:J.width+20*M}},{duration:H.duration||1,callback:function(){C.remove();--E>0?I():p(G).afterFx(H)}});arguments.callee.anim={isAnimated:true,stop:function(){F.stop()}}}I()});return D},pause:function(D){var C=this.dom,B;this.queueFx({},function(){B=setTimeout(function(){p(C).afterFx({})},D*1000);arguments.callee.anim={isAnimated:true,stop:function(){clearTimeout(B);p(C).afterFx({})}}});return this},fadeIn:function(D){D=x(D);var B=this,C=B.dom,E=D.endOpacity||1;B.queueFx(D,function(){p(C).setOpacity(0);p(C).fixDisplay();C.style.visibility=u;arguments.callee.anim=p(C).fxanim({opacity:{to:E}},D,y,0.5,r,function(){if(E==1){p(C).clearOpacity()}p(C).afterFx(D)})});return B},fadeOut:function(E){E=x(E);var C=this,D=C.dom,B=D.style,F=E.endOpacity||0;C.queueFx(E,function(){arguments.callee.anim=p(D).fxanim({opacity:{to:F}},E,y,0.5,r,function(){if(F==0){Ext.Element.data(D,"visibilityMode")==Ext.Element.DISPLAY||E.useDisplay?B.display="none":B.visibility=w;p(D).clearOpacity()}p(D).afterFx(E)})});return C},scale:function(B,C,D){this.shift(Ext.apply({},D,{width:B,height:C}));return this},shift:function(D){D=x(D);var C=this.dom,B={};this.queueFx(D,function(){for(var E in D){if(D[E]!=A){B[E]={to:D[E]}}}B.width?B.width.to=p(C).adjustWidth(D.width):B;B.height?B.height.to=p(C).adjustWidth(D.height):B;if(B.x||B.y||B.xy){B.points=B.xy||{to:[B.x?B.x.to:p(C).getX(),B.y?B.y.to:p(C).getY()]}}arguments.callee.anim=p(C).fxanim(B,D,e,0.35,r,function(){p(C).afterFx(D)})});return this},ghost:function(E,C){C=x(C);var G=this,D=G.dom,J=D.style,H={opacity:{to:0},points:{}},K=H.points,B,I,F;E=E||"b";G.queueFx(C,function(){B=p(D).getFxRestore();I=p(D).getWidth();F=p(D).getHeight();function L(){C.useDisplay?p(D).setDisplayed(t):p(D).hide();p(D).clearOpacity();p(D).setPositioning(B.pos);J.width=B.width;J.height=B.height;p(D).afterFx(C)}K.by=p(D).switchStatements(E.toLowerCase(),function(N,M){return[N,M]},{t:[0,-F],l:[-I,0],r:[I,0],b:[0,F],tl:[-I,-F],bl:[-I,F],br:[I,F],tr:[I,-F]});arguments.callee.anim=p(D).fxanim(H,C,e,0.5,r,L)});return G},syncFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:k,stopFx:t});return B},sequenceFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:t,stopFx:t});return B},nextFx:function(){var B=c(this.dom.id)[0];if(B){B.call(this)}},hasActiveFx:function(){return c(this.dom.id)[0]},stopFx:function(B){var C=this,E=C.dom.id;if(C.hasActiveFx()){var D=c(E)[0];if(D&&D.anim){if(D.anim.isAnimated){b(E,[D]);D.anim.stop(B!==undefined?B:k)}else{b(E,[])}}}return C},beforeFx:function(B){if(this.hasActiveFx()&&!B.concurrent){if(B.stopFx){this.stopFx();return k}return t}return k},hasFxBlock:function(){var B=c(this.dom.id);return B&&B[0]&&B[0].block},queueFx:function(E,B){var C=p(this.dom);if(!C.hasFxBlock()){Ext.applyIf(E,C.fxDefaults);if(!E.concurrent){var D=C.beforeFx(E);B.block=E.block;c(C.dom.id).push(B);if(D){C.nextFx()}}else{B.call(C)}}return C},fxWrap:function(H,F,D){var E=this.dom,C,B;if(!F.wrap||!(C=Ext.getDom(F.wrap))){if(F.fixPosition){B=p(E).getXY()}var G=document.createElement("div");G.style.visibility=D;C=E.parentNode.insertBefore(G,E);p(C).setPositioning(H);if(p(C).isStyle(o,"static")){p(C).position("relative")}p(E).clearPositioning("auto");p(C).clip();C.appendChild(E);if(B){p(C).setXY(B)}}return C},fxUnwrap:function(C,F,E){var D=this.dom;p(D).clearPositioning();p(D).setPositioning(F);if(!E.wrap){var B=p(C).dom.parentNode;B.insertBefore(D,C);p(C).remove()}},getFxRestore:function(){var B=this.dom.style;return{pos:this.getPositioning(),width:B.width,height:B.height}},afterFx:function(C){var B=this.dom,D=B.id;if(C.afterStyle){p(B).setStyle(C.afterStyle)}if(C.afterCls){p(B).addClass(C.afterCls)}if(C.remove==k){p(B).remove()}if(C.callback){C.callback.call(C.scope,p(B))}if(!C.concurrent){c(D).shift();p(B).nextFx()}},fxanim:function(E,F,C,G,D,B){C=C||"run";F=F||{};var H=Ext.lib.Anim[C](this.dom,E,(F.duration||G)||0.35,(F.easing||D)||r,B,this);F.anim=H;return H}};Ext.Fx.resize=Ext.Fx.scale;Ext.Element.addMethods(Ext.Fx)})();Ext.CompositeElementLite=function(b,a){this.elements=[];this.add(b,a);this.el=new Ext.Element.Flyweight()};Ext.CompositeElementLite.prototype={isComposite:true,getElement:function(a){var b=this.el;b.dom=a;b.id=a.id;return b},transformElement:function(a){return Ext.getDom(a)},getCount:function(){return this.elements.length},add:function(d,b){var e=this,g=e.elements;if(!d){return this}if(typeof d=="string"){d=Ext.Element.selectorFunction(d,b)}else{if(d.isComposite){d=d.elements}else{if(!Ext.isIterable(d)){d=[d]}}}for(var c=0,a=d.length;c-1){c=Ext.getDom(c);if(a){g=this.elements[b];g.parentNode.insertBefore(c,g);Ext.removeNode(g)}this.elements.splice(b,1,c)}return this},clear:function(){this.elements=[]}};Ext.CompositeElementLite.prototype.on=Ext.CompositeElementLite.prototype.addListener;Ext.CompositeElementLite.importElementMethods=function(){var c,b=Ext.Element.prototype,a=Ext.CompositeElementLite.prototype;for(c in b){if(typeof b[c]=="function"){(function(d){a[d]=a[d]||function(){return this.invoke(d,arguments)}}).call(a,c)}}};Ext.CompositeElementLite.importElementMethods();if(Ext.DomQuery){Ext.Element.selectorFunction=Ext.DomQuery.select}Ext.Element.select=function(a,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;(function(){var b="beforerequest",e="requestcomplete",d="requestexception",h=undefined,c="load",i="POST",a="GET",g=window;Ext.data.Connection=function(j){Ext.apply(this,j);this.addEvents(b,e,d);Ext.data.Connection.superclass.constructor.call(this)};Ext.extend(Ext.data.Connection,Ext.util.Observable,{timeout:30000,autoAbort:false,disableCaching:true,disableCachingParam:"_dc",request:function(n){var s=this;if(s.fireEvent(b,s,n)){if(n.el){if(!Ext.isEmpty(n.indicatorText)){s.indicatorText='
    '+n.indicatorText+"
    "}if(s.indicatorText){Ext.getDom(n.el).innerHTML=s.indicatorText}n.success=(Ext.isFunction(n.success)?n.success:function(){}).createInterceptor(function(o){Ext.getDom(n.el).innerHTML=o.responseText})}var l=n.params,k=n.url||s.url,j,q={success:s.handleResponse,failure:s.handleFailure,scope:s,argument:{options:n},timeout:Ext.num(n.timeout,s.timeout)},m,t;if(Ext.isFunction(l)){l=l.call(n.scope||g,n)}l=Ext.urlEncode(s.extraParams,Ext.isObject(l)?Ext.urlEncode(l):l);if(Ext.isFunction(k)){k=k.call(n.scope||g,n)}if((m=Ext.getDom(n.form))){k=k||m.action;if(n.isUpload||(/multipart\/form-data/i.test(m.getAttribute("enctype")))){return s.doFormUpload.call(s,n,l,k)}t=Ext.lib.Ajax.serializeForm(m);l=l?(l+"&"+t):t}j=n.method||s.method||((l||n.xmlData||n.jsonData)?i:a);if(j===a&&(s.disableCaching&&n.disableCaching!==false)||n.disableCaching===true){var r=n.disableCachingParam||s.disableCachingParam;k=Ext.urlAppend(k,r+"="+(new Date().getTime()))}n.headers=Ext.applyIf(n.headers||{},s.defaultHeaders||{});if(n.autoAbort===true||s.autoAbort){s.abort()}if((j==a||n.xmlData||n.jsonData)&&l){k=Ext.urlAppend(k,l);l=""}return(s.transId=Ext.lib.Ajax.request(j,k,q,l,n))}else{return n.callback?n.callback.apply(n.scope,[n,h,h]):null}},isLoading:function(j){return j?Ext.lib.Ajax.isCallInProgress(j):!!this.transId},abort:function(j){if(j||this.isLoading()){Ext.lib.Ajax.abort(j||this.transId)}},handleResponse:function(j){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(e,this,j,k);if(k.success){k.success.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,true,j)}},handleFailure:function(j,l){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(d,this,j,k,l);if(k.failure){k.failure.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,false,j)}},doFormUpload:function(q,j,k){var l=Ext.id(),v=document,r=v.createElement("iframe"),m=Ext.getDom(q.form),u=[],t,p="multipart/form-data",n={target:m.target,method:m.method,encoding:m.encoding,enctype:m.enctype,action:m.action};Ext.fly(r).set({id:l,name:l,cls:"x-hidden",src:Ext.SSL_SECURE_URL});v.body.appendChild(r);if(Ext.isIE){document.frames[l].name=l}Ext.fly(m).set({target:l,method:i,enctype:p,encoding:p,action:k||n.action});Ext.iterate(Ext.urlDecode(j,false),function(w,o){t=v.createElement("input");Ext.fly(t).set({type:"hidden",value:o,name:w});m.appendChild(t);u.push(t)});function s(){var x=this,w={responseText:"",responseXML:null,argument:q.argument},A,z;try{A=r.contentWindow.document||r.contentDocument||g.frames[l].document;if(A){if(A.body){if(/textarea/i.test((z=A.body.firstChild||{}).tagName)){w.responseText=z.value}else{w.responseText=A.body.innerHTML}}w.responseXML=A.XMLDocument||A}}catch(y){}Ext.EventManager.removeListener(r,c,s,x);x.fireEvent(e,x,w,q);function o(D,C,B){if(Ext.isFunction(D)){D.apply(C,B)}}o(q.success,q.scope,[w,q]);o(q.callback,q.scope,[q,true,w]);if(!x.debugUploads){setTimeout(function(){Ext.removeNode(r)},100)}}Ext.EventManager.on(r,c,s,this);m.submit();Ext.fly(m).set(n);Ext.each(u,function(o){Ext.removeNode(o)})}})})();Ext.Ajax=new Ext.data.Connection({autoAbort:false,serializeForm:function(a){return Ext.lib.Ajax.serializeForm(a)}});Ext.util.JSON=new (function(){var useHasOwn=!!{}.hasOwnProperty,isNative=function(){var useNative=null;return function(){if(useNative===null){useNative=Ext.USE_NATIVE_JSON&&window.JSON&&JSON.toString()=="[object JSON]"}return useNative}}(),pad=function(n){return n<10?"0"+n:n},doDecode=function(json){return json?eval("("+json+")"):""},doEncode=function(o){if(!Ext.isDefined(o)||o===null){return"null"}else{if(Ext.isArray(o)){return encodeArray(o)}else{if(Ext.isDate(o)){return Ext.util.JSON.encodeDate(o)}else{if(Ext.isString(o)){return encodeString(o)}else{if(typeof o=="number"){return isFinite(o)?String(o):"null"}else{if(Ext.isBoolean(o)){return String(o)}else{var a=["{"],b,i,v;for(i in o){if(!o.getElementsByTagName){if(!useHasOwn||o.hasOwnProperty(i)){v=o[i];switch(typeof v){case"undefined":case"function":case"unknown":break;default:if(b){a.push(",")}a.push(doEncode(i),":",v===null?"null":doEncode(v));b=true}}}}a.push("}");return a.join("")}}}}}}},m={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},encodeString=function(s){if(/["\\\x00-\x1f]/.test(s)){return'"'+s.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c}c=b.charCodeAt();return"\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16)})+'"'}return'"'+s+'"'},encodeArray=function(o){var a=["["],b,i,l=o.length,v;for(i=0;i
    ';e.body.appendChild(g);d=g.lastChild;if((c=e.defaultView)){if(c.getComputedStyle(g.firstChild.firstChild,null).marginRight!="0px"){b.correctRightMargin=false}if(c.getComputedStyle(d,null).backgroundColor!="transparent"){b.correctTransparentColor=false}}b.cssFloat=!!d.style.cssFloat;e.body.removeChild(g)};if(Ext.isReady){a()}else{Ext.onReady(a)}})();Ext.EventObject=function(){var b=Ext.lib.Event,c=/(dbl)?click/,a={3:13,63234:37,63235:39,63232:38,63233:40,63276:33,63277:34,63272:46,63273:36,63275:35},d=Ext.isIE?{1:0,4:1,2:2}:{0:0,1:1,2:2};Ext.EventObjectImpl=function(g){if(g){this.setEvent(g.browserEvent||g)}};Ext.EventObjectImpl.prototype={setEvent:function(h){var g=this;if(h==g||(h&&h.browserEvent)){return h}g.browserEvent=h;if(h){g.button=h.button?d[h.button]:(h.which?h.which-1:-1);if(c.test(h.type)&&g.button==-1){g.button=0}g.type=h.type;g.shiftKey=h.shiftKey;g.ctrlKey=h.ctrlKey||h.metaKey||false;g.altKey=h.altKey;g.keyCode=h.keyCode;g.charCode=h.charCode;g.target=b.getTarget(h);g.xy=b.getXY(h)}else{g.button=-1;g.shiftKey=false;g.ctrlKey=false;g.altKey=false;g.keyCode=0;g.charCode=0;g.target=null;g.xy=[0,0]}return g},stopEvent:function(){var e=this;if(e.browserEvent){if(e.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(e)}b.stopEvent(e.browserEvent)}},preventDefault:function(){if(this.browserEvent){b.preventDefault(this.browserEvent)}},stopPropagation:function(){var e=this;if(e.browserEvent){if(e.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(e)}b.stopPropagation(e.browserEvent)}},getCharCode:function(){return this.charCode||this.keyCode},getKey:function(){return this.normalizeKey(this.keyCode||this.charCode)},normalizeKey:function(e){return Ext.isSafari?(a[e]||e):e},getPageX:function(){return this.xy[0]},getPageY:function(){return this.xy[1]},getXY:function(){return this.xy},getTarget:function(g,h,e){return g?Ext.fly(this.target).findParent(g,h,e):(e?Ext.get(this.target):this.target)},getRelatedTarget:function(){return this.browserEvent?b.getRelatedTarget(this.browserEvent):null},getWheelDelta:function(){var g=this.browserEvent;var h=0;if(g.wheelDelta){h=g.wheelDelta/120}else{if(g.detail){h=-g.detail/3}}return h},within:function(h,i,e){if(h){var g=this[i?"getRelatedTarget":"getTarget"]();return g&&((e?(g==Ext.getDom(h)):false)||Ext.fly(h).contains(g))}return false}};return new Ext.EventObjectImpl()}();Ext.Loader=Ext.apply({},{load:function(j,i,k,c){var k=k||this,g=document.getElementsByTagName("head")[0],b=document.createDocumentFragment(),a=j.length,h=0,e=this;var l=function(m){g.appendChild(e.buildScriptTag(j[m],d))};var d=function(){h++;if(a==h&&typeof i=="function"){i.call(k)}else{if(c===true){l(h)}}};if(c===true){l.call(this,0)}else{Ext.each(j,function(n,m){b.appendChild(this.buildScriptTag(n,d))},this);g.appendChild(b)}},buildScriptTag:function(b,c){var a=document.createElement("script");a.type="text/javascript";a.src=b;if(a.readyState){a.onreadystatechange=function(){if(a.readyState=="loaded"||a.readyState=="complete"){a.onreadystatechange=null;c()}}}else{a.onload=c}return a}});Ext.ns("Ext.grid","Ext.list","Ext.dd","Ext.tree","Ext.form","Ext.menu","Ext.state","Ext.layout.boxOverflow","Ext.app","Ext.ux","Ext.chart","Ext.direct","Ext.slider");Ext.apply(Ext,function(){var c=Ext,a=0,b=null;return{emptyFn:function(){},BLANK_IMAGE_URL:Ext.isIE6||Ext.isIE7||Ext.isAir?"http://www.extjs.com/s.gif":"data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",extendX:function(d,e){return Ext.extend(d,e(d.prototype))},getDoc:function(){return Ext.get(document)},num:function(e,d){e=Number(Ext.isEmpty(e)||Ext.isArray(e)||typeof e=="boolean"||(typeof e=="string"&&e.trim().length==0)?NaN:e);return isNaN(e)?d:e},value:function(g,d,e){return Ext.isEmpty(g,e)?d:g},escapeRe:function(d){return d.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")},sequence:function(h,d,g,e){h[d]=h[d].createSequence(g,e)},addBehaviors:function(i){if(!Ext.isReady){Ext.onReady(function(){Ext.addBehaviors(i)})}else{var e={},h,d,g;for(d in i){if((h=d.split("@"))[1]){g=h[0];if(!e[g]){e[g]=Ext.select(g)}e[g].on(h[1],i[d])}}e=null}},getScrollBarWidth:function(g){if(!Ext.isReady){return 0}if(g===true||b===null){var i=Ext.getBody().createChild('
    '),h=i.child("div",true);var e=h.offsetWidth;i.setStyle("overflow",(Ext.isWebKit||Ext.isGecko)?"auto":"scroll");var d=h.offsetWidth;i.remove();b=e-d+2}return b},combine:function(){var g=arguments,e=g.length,j=[];for(var h=0;hh?1:-1};Ext.each(d,function(h){g=e(g,h)==1?g:h});return g},mean:function(d){return d.length>0?Ext.sum(d)/d.length:undefined},sum:function(d){var e=0;Ext.each(d,function(g){e+=g});return e},partition:function(d,e){var g=[[],[]];Ext.each(d,function(j,k,h){g[(e&&e(j,k,h))||(!e&&j)?0:1].push(j)});return g},invoke:function(d,e){var h=[],g=Array.prototype.slice.call(arguments,2);Ext.each(d,function(j,k){if(j&&typeof j[e]=="function"){h.push(j[e].apply(j,g))}else{h.push(undefined)}});return h},pluck:function(d,g){var e=[];Ext.each(d,function(h){e.push(h[g])});return e},zip:function(){var n=Ext.partition(arguments,function(i){return typeof i!="function"}),k=n[0],m=n[1][0],d=Ext.max(Ext.pluck(k,"length")),h=[];for(var l=0;l=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom)},getArea:function(){var a=this;return((a.bottom-a.top)*(a.right-a.left))},intersect:function(h){var g=this,d=Math.max(g.top,h.top),e=Math.min(g.right,h.right),a=Math.min(g.bottom,h.bottom),c=Math.max(g.left,h.left);if(a>=d&&e>=c){return new Ext.lib.Region(d,e,a,c)}},union:function(h){var g=this,d=Math.min(g.top,h.top),e=Math.max(g.right,h.right),a=Math.max(g.bottom,h.bottom),c=Math.min(g.left,h.left);return new Ext.lib.Region(d,e,a,c)},constrainTo:function(b){var a=this;a.top=a.top.constrain(b.top,b.bottom);a.bottom=a.bottom.constrain(b.top,b.bottom);a.left=a.left.constrain(b.left,b.right);a.right=a.right.constrain(b.left,b.right);return a},adjust:function(d,c,a,g){var e=this;e.top+=d;e.left+=c;e.right+=g;e.bottom+=a;return e}};Ext.lib.Region.getRegion=function(e){var h=Ext.lib.Dom.getXY(e),d=h[1],g=h[0]+e.offsetWidth,a=h[1]+e.offsetHeight,c=h[0];return new Ext.lib.Region(d,g,a,c)};Ext.lib.Point=function(a,c){if(Ext.isArray(a)){c=a[1];a=a[0]}var b=this;b.x=b.right=b.left=b[0]=a;b.y=b.top=b.bottom=b[1]=c};Ext.lib.Point.prototype=new Ext.lib.Region();Ext.apply(Ext.DomHelper,function(){var e,a="afterbegin",h="afterend",i="beforebegin",d="beforeend",b=/tag|children|cn|html$/i;function g(m,p,n,q,l,j){m=Ext.getDom(m);var k;if(e.useDom){k=c(p,null);if(j){m.appendChild(k)}else{(l=="firstChild"?m:m.parentNode).insertBefore(k,m[l]||m)}}else{k=Ext.DomHelper.insertHtml(q,m,Ext.DomHelper.createHtml(p))}return n?Ext.get(k,true):k}function c(j,r){var k,u=document,p,s,m,t;if(Ext.isArray(j)){k=u.createDocumentFragment();for(var q=0,n=j.length;q0){return setTimeout(d,c)}d();return 0},createSequence:function(c,b,a){if(!Ext.isFunction(b)){return c}else{return function(){var d=c.apply(this||window,arguments);b.apply(a||this||window,arguments);return d}}}};Ext.defer=Ext.util.Functions.defer;Ext.createInterceptor=Ext.util.Functions.createInterceptor;Ext.createSequence=Ext.util.Functions.createSequence;Ext.createDelegate=Ext.util.Functions.createDelegate;Ext.apply(Ext.util.Observable.prototype,function(){function a(j){var i=(this.methodEvents=this.methodEvents||{})[j],d,c,g,h=this;if(!i){this.methodEvents[j]=i={};i.originalFn=this[j];i.methodName=j;i.before=[];i.after=[];var b=function(l,k,e){if((c=l.apply(k||h,e))!==undefined){if(typeof c=="object"){if(c.returnValue!==undefined){d=c.returnValue}else{d=c}g=!!c.cancel}else{if(c===false){g=true}else{d=c}}}};this[j]=function(){var l=Array.prototype.slice.call(arguments,0),k;d=c=undefined;g=false;for(var m=0,e=i.before.length;m=525:!((Ext.isGecko&&!Ext.isWindows)||Ext.isOpera);return{_unload:function(){Ext.EventManager.un(window,"resize",this.fireWindowResize,this);c.call(Ext.EventManager)},doResizeEvent:function(){var m=a.getViewHeight(),l=a.getViewWidth();if(h!=m||i!=l){d.fire(i=l,h=m)}},onWindowResize:function(n,m,l){if(!d){d=new Ext.util.Event();k=new Ext.util.DelayedTask(this.doResizeEvent);Ext.EventManager.on(window,"resize",this.fireWindowResize,this)}d.addListener(n,m,l)},fireWindowResize:function(){if(d){k.delay(100)}},onTextResize:function(o,n,l){if(!g){g=new Ext.util.Event();var m=new Ext.Element(document.createElement("div"));m.dom.className="x-text-resize";m.dom.innerHTML="X";m.appendTo(document.body);b=m.dom.offsetHeight;setInterval(function(){if(m.dom.offsetHeight!=b){g.fire(b,b=m.dom.offsetHeight)}},this.textResizeInterval)}g.addListener(o,n,l)},removeResizeListener:function(m,l){if(d){d.removeListener(m,l)}},fireResize:function(){if(d){d.fire(a.getViewWidth(),a.getViewHeight())}},textResizeInterval:50,ieDeferSrc:false,getKeyEvent:function(){return e?"keydown":"keypress"},useKeydown:e}}());Ext.EventManager.on=Ext.EventManager.addListener;Ext.apply(Ext.EventObjectImpl.prototype,{BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,RETURN:13,SHIFT:16,CTRL:17,CONTROL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGEUP:33,PAGE_DOWN:34,PAGEDOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,isNavKeyPress:function(){var b=this,a=this.normalizeKey(b.keyCode);return(a>=33&&a<=40)||a==b.RETURN||a==b.TAB||a==b.ESC},isSpecialKey:function(){var a=this.normalizeKey(this.keyCode);return(this.type=="keypress"&&this.ctrlKey)||this.isNavKeyPress()||(a==this.BACKSPACE)||(a>=16&&a<=20)||(a>=44&&a<=46)},getPoint:function(){return new Ext.lib.Point(this.xy[0],this.xy[1])},hasModifier:function(){return((this.ctrlKey||this.altKey)||this.shiftKey)}});Ext.Element.addMethods({swallowEvent:function(a,b){var d=this;function c(g){g.stopPropagation();if(b){g.preventDefault()}}if(Ext.isArray(a)){Ext.each(a,function(g){d.on(g,c)});return d}d.on(a,c);return d},relayEvent:function(a,b){this.on(a,function(c){b.fireEvent(a,c)})},clean:function(b){var d=this,e=d.dom,g=e.firstChild,c=-1;if(Ext.Element.data(e,"isCleaned")&&b!==true){return d}while(g){var a=g.nextSibling;if(g.nodeType==3&&!(/\S/.test(g.nodeValue))){e.removeChild(g)}else{g.nodeIndex=++c}g=a}Ext.Element.data(e,"isCleaned",true);return d},load:function(){var a=this.getUpdater();a.update.apply(a,arguments);return this},getUpdater:function(){return this.updateManager||(this.updateManager=new Ext.Updater(this))},update:function(html,loadScripts,callback){if(!this.dom){return this}html=html||"";if(loadScripts!==true){this.dom.innerHTML=html;if(typeof callback=="function"){callback()}return this}var id=Ext.id(),dom=this.dom;html+='';Ext.lib.Event.onAvailable(id,function(){var DOC=document,hd=DOC.getElementsByTagName("head")[0],re=/(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,srcRe=/\ssrc=([\'\"])(.*?)\1/i,typeRe=/\stype=([\'\"])(.*?)\1/i,match,attrs,srcMatch,typeMatch,el,s;while((match=re.exec(html))){attrs=match[1];srcMatch=attrs?attrs.match(srcRe):false;if(srcMatch&&srcMatch[2]){s=DOC.createElement("script");s.src=srcMatch[2];typeMatch=attrs.match(typeRe);if(typeMatch&&typeMatch[2]){s.type=typeMatch[2]}hd.appendChild(s)}else{if(match[2]&&match[2].length>0){if(window.execScript){window.execScript(match[2])}else{window.eval(match[2])}}}}el=DOC.getElementById(id);if(el){Ext.removeNode(el)}if(typeof callback=="function"){callback()}});dom.innerHTML=html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig,"");return this},removeAllListeners:function(){this.removeAnchor();Ext.EventManager.removeAll(this.dom);return this},createProxy:function(a,e,d){a=(typeof a=="object")?a:{tag:"div",cls:a};var c=this,b=e?Ext.DomHelper.append(e,a,true):Ext.DomHelper.insertBefore(c.dom,a,true);if(d&&c.setBox&&c.getBox){b.setBox(c.getBox())}return b}});Ext.Element.prototype.getUpdateManager=Ext.Element.prototype.getUpdater;Ext.Element.addMethods({getAnchorXY:function(e,l,q){e=(e||"tl").toLowerCase();q=q||{};var k=this,b=k.dom==document.body||k.dom==document,n=q.width||b?Ext.lib.Dom.getViewWidth():k.getWidth(),i=q.height||b?Ext.lib.Dom.getViewHeight():k.getHeight(),p,a=Math.round,c=k.getXY(),m=k.getScroll(),j=b?m.left:!l?c[0]:0,g=b?m.top:!l?c[1]:0,d={c:[a(n*0.5),a(i*0.5)],t:[a(n*0.5),0],l:[0,a(i*0.5)],r:[n,a(i*0.5)],b:[a(n*0.5),i],tl:[0,0],bl:[0,i],br:[n,i],tr:[n,0]};p=d[e];return[p[0]+j,p[1]+g]},anchorTo:function(b,h,c,a,k,l){var i=this,e=i.dom,j=!Ext.isEmpty(k),d=function(){Ext.fly(e).alignTo(b,h,c,a);Ext.callback(l,Ext.fly(e))},g=this.getAnchor();this.removeAnchor();Ext.apply(g,{fn:d,scroll:j});Ext.EventManager.onWindowResize(d,null);if(j){Ext.EventManager.on(window,"scroll",d,null,{buffer:!isNaN(k)?k:50})}d.call(i);return i},removeAnchor:function(){var b=this,a=this.getAnchor();if(a&&a.fn){Ext.EventManager.removeResizeListener(a.fn);if(a.scroll){Ext.EventManager.un(window,"scroll",a.fn)}delete a.fn}return b},getAnchor:function(){var b=Ext.Element.data,c=this.dom;if(!c){return}var a=b(c,"_anchor");if(!a){a=b(c,"_anchor",{})}return a},getAlignToXY:function(g,A,B){g=Ext.get(g);if(!g||!g.dom){throw"Element.alignToXY with an element that doesn't exist"}B=B||[0,0];A=(!A||A=="?"?"tl-bl?":(!(/-/).test(A)&&A!==""?"tl-"+A:A||"tl-bl")).toLowerCase();var K=this,H=K.dom,M,L,n,l,s,F,v,t=Ext.lib.Dom.getViewWidth()-10,G=Ext.lib.Dom.getViewHeight()-10,b,i,j,k,u,z,N=document,J=N.documentElement,q=N.body,E=(J.scrollLeft||q.scrollLeft||0)+5,D=(J.scrollTop||q.scrollTop||0)+5,I=false,e="",a="",C=A.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!C){throw"Element.alignTo with an invalid alignment "+A}e=C[1];a=C[2];I=!!C[3];M=K.getAnchorXY(e,true);L=g.getAnchorXY(a,false);n=L[0]-M[0]+B[0];l=L[1]-M[1]+B[1];if(I){s=K.getWidth();F=K.getHeight();v=g.getRegion();b=e.charAt(0);i=e.charAt(e.length-1);j=a.charAt(0);k=a.charAt(a.length-1);u=((b=="t"&&j=="b")||(b=="b"&&j=="t"));z=((i=="r"&&k=="l")||(i=="l"&&k=="r"));if(n+s>t+E){n=z?v.left-s:t+E-s}if(nG+D){l=u?v.top-F:G+D-F}if(lB){p=B-q;m=true}if((o+C)>g){o=g-C;m=true}if(p"+String.format(Ext.Element.boxMarkup,c)+"
    "));Ext.DomQuery.selectNode("."+c+"-mc",d.dom).appendChild(this.dom);return d},setSize:function(e,c,d){var g=this;if(typeof e=="object"){c=e.height;e=e.width}e=g.adjustWidth(e);c=g.adjustHeight(c);if(!d||!g.anim){g.dom.style.width=g.addUnits(e);g.dom.style.height=g.addUnits(c)}else{g.anim({width:{to:e},height:{to:c}},g.preanim(arguments,2))}return g},getComputedHeight:function(){var d=this,c=Math.max(d.dom.offsetHeight,d.dom.clientHeight);if(!c){c=parseFloat(d.getStyle("height"))||0;if(!d.isBorderBox()){c+=d.getFrameWidth("tb")}}return c},getComputedWidth:function(){var c=Math.max(this.dom.offsetWidth,this.dom.clientWidth);if(!c){c=parseFloat(this.getStyle("width"))||0;if(!this.isBorderBox()){c+=this.getFrameWidth("lr")}}return c},getFrameWidth:function(d,c){return c&&this.isBorderBox()?0:(this.getPadding(d)+this.getBorderWidth(d))},addClassOnOver:function(c){this.hover(function(){Ext.fly(this,a).addClass(c)},function(){Ext.fly(this,a).removeClass(c)});return this},addClassOnFocus:function(c){this.on("focus",function(){Ext.fly(this,a).addClass(c)},this.dom);this.on("blur",function(){Ext.fly(this,a).removeClass(c)},this.dom);return this},addClassOnClick:function(c){var d=this.dom;this.on("mousedown",function(){Ext.fly(d,a).addClass(c);var g=Ext.getDoc(),e=function(){Ext.fly(d,a).removeClass(c);g.removeListener("mouseup",e)};g.on("mouseup",e)});return this},getViewSize:function(){var g=document,h=this.dom,c=(h==g||h==g.body);if(c){var e=Ext.lib.Dom;return{width:e.getViewWidth(),height:e.getViewHeight()}}else{return{width:h.clientWidth,height:h.clientHeight}}},getStyleSize:function(){var j=this,c,i,l=document,m=this.dom,e=(m==l||m==l.body),g=m.style;if(e){var k=Ext.lib.Dom;return{width:k.getViewWidth(),height:k.getViewHeight()}}if(g.width&&g.width!="auto"){c=parseFloat(g.width);if(j.isBorderBox()){c-=j.getFrameWidth("lr")}}if(g.height&&g.height!="auto"){i=parseFloat(g.height);if(j.isBorderBox()){i-=j.getFrameWidth("tb")}}return{width:c||j.getWidth(true),height:i||j.getHeight(true)}},getSize:function(c){return{width:this.getWidth(c),height:this.getHeight(c)}},repaint:function(){var c=this.dom;this.addClass("x-repaint");setTimeout(function(){Ext.fly(c).removeClass("x-repaint")},1);return this},unselectable:function(){this.dom.unselectable="on";return this.swallowEvent("selectstart",true).addClass("x-unselectable")},getMargins:function(d){var e=this,c,g={t:"top",l:"left",r:"right",b:"bottom"},h={};if(!d){for(c in e.margins){h[g[c]]=parseFloat(e.getStyle(e.margins[c]))||0}return h}else{return e.addStyles.call(e,d,e.margins)}}}}());Ext.Element.addMethods({setBox:function(e,g,b){var d=this,a=e.width,c=e.height;if((g&&!d.autoBoxAdjust)&&!d.isBorderBox()){a-=(d.getBorderWidth("lr")+d.getPadding("lr"));c-=(d.getBorderWidth("tb")+d.getPadding("tb"))}d.setBounds(e.x,e.y,a,c,d.animTest.call(d,arguments,b,2));return d},getBox:function(j,p){var m=this,v,e,o,d=m.getBorderWidth,q=m.getPadding,g,a,u,n;if(!p){v=m.getXY()}else{e=parseInt(m.getStyle("left"),10)||0;o=parseInt(m.getStyle("top"),10)||0;v=[e,o]}var c=m.dom,s=c.offsetWidth,i=c.offsetHeight,k;if(!j){k={x:v[0],y:v[1],0:v[0],1:v[1],width:s,height:i}}else{g=d.call(m,"l")+q.call(m,"l");a=d.call(m,"r")+q.call(m,"r");u=d.call(m,"t")+q.call(m,"t");n=d.call(m,"b")+q.call(m,"b");k={x:v[0]+g,y:v[1]+u,0:v[0]+g,1:v[1]+u,width:s-(g+a),height:i-(u+n)}}k.right=k.x+k.width;k.bottom=k.y+k.height;return k},move:function(j,b,c){var g=this,m=g.getXY(),k=m[0],i=m[1],d=[k-b,i],l=[k+b,i],h=[k,i-b],a=[k,i+b],e={l:d,left:d,r:l,right:l,t:h,top:h,up:h,b:a,bottom:a,down:a};j=j.toLowerCase();g.moveTo(e[j][0],e[j][1],g.animTest.call(g,arguments,c,2))},setLeftTop:function(d,c){var b=this,a=b.dom.style;a.left=b.addUnits(d);a.top=b.addUnits(c);return b},getRegion:function(){return Ext.lib.Dom.getRegion(this.dom)},setBounds:function(b,g,d,a,c){var e=this;if(!c||!e.anim){e.setSize(d,a);e.setLocation(b,g)}else{e.anim({points:{to:[b,g]},width:{to:e.adjustWidth(d)},height:{to:e.adjustHeight(a)}},e.preanim(arguments,4),"motion")}return e},setRegion:function(b,a){return this.setBounds(b.left,b.top,b.right-b.left,b.bottom-b.top,this.animTest.call(this,arguments,a,1))}});Ext.Element.addMethods({scrollTo:function(b,d,a){var e=/top/i.test(b),c=this,g=c.dom,h;if(!a||!c.anim){h="scroll"+(e?"Top":"Left");g[h]=d}else{h="scroll"+(e?"Left":"Top");c.anim({scroll:{to:e?[g[h],d]:[d,g[h]]}},c.preanim(arguments,2),"scroll")}return c},scrollIntoView:function(e,i){var p=Ext.getDom(e)||Ext.getBody().dom,h=this.dom,g=this.getOffsetsTo(p),k=g[0]+p.scrollLeft,u=g[1]+p.scrollTop,q=u+h.offsetHeight,d=k+h.offsetWidth,a=p.clientHeight,m=parseInt(p.scrollTop,10),s=parseInt(p.scrollLeft,10),j=m+a,n=s+p.clientWidth;if(h.offsetHeight>a||uj){p.scrollTop=q-a}}p.scrollTop=p.scrollTop;if(i!==false){if(h.offsetWidth>p.clientWidth||kn){p.scrollLeft=d-p.clientWidth}}p.scrollLeft=p.scrollLeft}return this},scrollChildIntoView:function(b,a){Ext.fly(b,"_scrollChildIntoView").scrollIntoView(this,a)},scroll:function(m,b,d){if(!this.isScrollable()){return false}var e=this.dom,g=e.scrollLeft,p=e.scrollTop,n=e.scrollWidth,k=e.scrollHeight,i=e.clientWidth,a=e.clientHeight,c=false,o,j={l:Math.min(g+b,n-i),r:o=Math.max(g-b,0),t:Math.max(p-b,0),b:Math.min(p+b,k-a)};j.d=j.b;j.u=j.t;m=m.substr(0,1);if((o=j[m])>-1){c=true;this.scrollTo(m=="l"||m=="r"?"left":"top",o,this.preanim(arguments,2))}return c}});Ext.Element.addMethods(function(){var d="visibility",b="display",a="hidden",h="none",c="x-masked",g="x-masked-relative",e=Ext.Element.data;return{isVisible:function(i){var j=!this.isStyle(d,a)&&!this.isStyle(b,h),k=this.dom.parentNode;if(i!==true||!j){return j}while(k&&!(/^body/i.test(k.tagName))){if(!Ext.fly(k,"_isVisible").isVisible()){return false}k=k.parentNode}return true},isDisplayed:function(){return !this.isStyle(b,h)},enableDisplayMode:function(i){this.setVisibilityMode(Ext.Element.DISPLAY);if(!Ext.isEmpty(i)){e(this.dom,"originalDisplay",i)}return this},mask:function(j,n){var p=this,l=p.dom,o=Ext.DomHelper,m="ext-el-mask-msg",i,q;if(!/^body/i.test(l.tagName)&&p.getStyle("position")=="static"){p.addClass(g)}if(i=e(l,"maskMsg")){i.remove()}if(i=e(l,"mask")){i.remove()}q=o.append(l,{cls:"ext-el-mask"},true);e(l,"mask",q);p.addClass(c);q.setDisplayed(true);if(typeof j=="string"){var k=o.append(l,{cls:m,cn:{tag:"div"}},true);e(l,"maskMsg",k);k.dom.className=n?m+" "+n:m;k.dom.firstChild.innerHTML=j;k.setDisplayed(true);k.center(p)}if(Ext.isIE&&!(Ext.isIE7&&Ext.isStrict)&&p.getStyle("height")=="auto"){q.setSize(undefined,p.getHeight())}return q},unmask:function(){var k=this,l=k.dom,i=e(l,"mask"),j=e(l,"maskMsg");if(i){if(j){j.remove();e(l,"maskMsg",undefined)}i.remove();e(l,"mask",undefined);k.removeClass([c,g])}},isMasked:function(){var i=e(this.dom,"mask");return i&&i.isVisible()},createShim:function(){var i=document.createElement("iframe"),j;i.frameBorder="0";i.className="ext-shim";i.src=Ext.SSL_SECURE_URL;j=Ext.get(this.dom.parentNode.insertBefore(i,this.dom));j.autoBoxAdjust=false;return j}}}());Ext.Element.addMethods({addKeyListener:function(b,d,c){var a;if(typeof b!="object"||Ext.isArray(b)){a={key:b,fn:d,scope:c}}else{a={key:b.key,shift:b.shift,ctrl:b.ctrl,alt:b.alt,fn:d,scope:c}}return new Ext.KeyMap(this,a)},addKeyMap:function(a){return new Ext.KeyMap(this,a)}});Ext.CompositeElementLite.importElementMethods();Ext.apply(Ext.CompositeElementLite.prototype,{addElements:function(c,a){if(!c){return this}if(typeof c=="string"){c=Ext.Element.selectorFunction(c,a)}var b=this.elements;Ext.each(c,function(d){b.push(Ext.get(d))});return this},first:function(){return this.item(0)},last:function(){return this.item(this.getCount()-1)},contains:function(a){return this.indexOf(a)!=-1},removeElement:function(d,e){var c=this,a=this.elements,b;Ext.each(d,function(g){if((b=(a[g]||a[g=c.indexOf(g)]))){if(e){if(b.dom){b.remove()}else{Ext.removeNode(b)}}a.splice(g,1)}});return this}});Ext.CompositeElement=Ext.extend(Ext.CompositeElementLite,{constructor:function(b,a){this.elements=[];this.add(b,a)},getElement:function(a){return a},transformElement:function(a){return Ext.get(a)}});Ext.Element.select=function(a,d,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return(d===true)?new Ext.CompositeElement(c):new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;Ext.UpdateManager=Ext.Updater=Ext.extend(Ext.util.Observable,function(){var b="beforeupdate",d="update",c="failure";function a(h){var i=this;i.transaction=null;if(h.argument.form&&h.argument.reset){try{h.argument.form.reset()}catch(j){}}if(i.loadScripts){i.renderer.render(i.el,h,i,g.createDelegate(i,[h]))}else{i.renderer.render(i.el,h,i);g.call(i,h)}}function g(h,i,j){this.fireEvent(i||d,this.el,h);if(Ext.isFunction(h.argument.callback)){h.argument.callback.call(h.argument.scope,this.el,Ext.isEmpty(j)?true:false,h,h.argument.options)}}function e(h){g.call(this,h,c,!!(this.transaction=null))}return{constructor:function(i,h){var j=this;i=Ext.get(i);if(!h&&i.updateManager){return i.updateManager}j.el=i;j.defaultUrl=null;j.addEvents(b,d,c);Ext.apply(j,Ext.Updater.defaults);j.transaction=null;j.refreshDelegate=j.refresh.createDelegate(j);j.updateDelegate=j.update.createDelegate(j);j.formUpdateDelegate=(j.formUpdate||function(){}).createDelegate(j);j.renderer=j.renderer||j.getDefaultRenderer();Ext.Updater.superclass.constructor.call(j)},setRenderer:function(h){this.renderer=h},getRenderer:function(){return this.renderer},getDefaultRenderer:function(){return new Ext.Updater.BasicRenderer()},setDefaultUrl:function(h){this.defaultUrl=h},getEl:function(){return this.el},update:function(i,n,p,l){var k=this,h,j;if(k.fireEvent(b,k.el,i,n)!==false){if(Ext.isObject(i)){h=i;i=h.url;n=n||h.params;p=p||h.callback;l=l||h.discardUrl;j=h.scope;if(!Ext.isEmpty(h.nocache)){k.disableCaching=h.nocache}if(!Ext.isEmpty(h.text)){k.indicatorText='
    '+h.text+"
    "}if(!Ext.isEmpty(h.scripts)){k.loadScripts=h.scripts}if(!Ext.isEmpty(h.timeout)){k.timeout=h.timeout}}k.showLoading();if(!l){k.defaultUrl=i}if(Ext.isFunction(i)){i=i.call(k)}var m=Ext.apply({},{url:i,params:(Ext.isFunction(n)&&j)?n.createDelegate(j):n,success:a,failure:e,scope:k,callback:undefined,timeout:(k.timeout*1000),disableCaching:k.disableCaching,argument:{options:h,url:i,form:null,callback:p,scope:j||window,params:n}},h);k.transaction=Ext.Ajax.request(m)}},formUpdate:function(k,h,j,l){var i=this;if(i.fireEvent(b,i.el,k,h)!==false){if(Ext.isFunction(h)){h=h.call(i)}k=Ext.getDom(k);i.transaction=Ext.Ajax.request({form:k,url:h,success:a,failure:e,scope:i,timeout:(i.timeout*1000),argument:{url:h,form:k,callback:l,reset:j}});i.showLoading.defer(1,i)}},startAutoRefresh:function(i,j,l,m,h){var k=this;if(h){k.update(j||k.defaultUrl,l,m,true)}if(k.autoRefreshProcId){clearInterval(k.autoRefreshProcId)}k.autoRefreshProcId=setInterval(k.update.createDelegate(k,[j||k.defaultUrl,l,m,true]),i*1000)},stopAutoRefresh:function(){if(this.autoRefreshProcId){clearInterval(this.autoRefreshProcId);delete this.autoRefreshProcId}},isAutoRefreshing:function(){return !!this.autoRefreshProcId},showLoading:function(){if(this.showLoadIndicator){this.el.dom.innerHTML=this.indicatorText}},abort:function(){if(this.transaction){Ext.Ajax.abort(this.transaction)}},isUpdating:function(){return this.transaction?Ext.Ajax.isLoading(this.transaction):false},refresh:function(h){if(this.defaultUrl){this.update(this.defaultUrl,null,h,true)}}}}());Ext.Updater.defaults={timeout:30,disableCaching:false,showLoadIndicator:true,indicatorText:'
    Loading...
    ',loadScripts:false,sslBlankUrl:Ext.SSL_SECURE_URL};Ext.Updater.updateElement=function(d,c,e,b){var a=Ext.get(d).getUpdater();Ext.apply(a,b);a.update(c,e,b?b.callback:null)};Ext.Updater.BasicRenderer=function(){};Ext.Updater.BasicRenderer.prototype={render:function(c,a,b,d){c.update(a.responseText,b.loadScripts,d)}};(function(){Date.useStrict=false;function b(d){var c=Array.prototype.slice.call(arguments,1);return d.replace(/\{(\d+)\}/g,function(e,g){return c[g]})}Date.formatCodeToRegex=function(d,c){var e=Date.parseCodes[d];if(e){e=typeof e=="function"?e():e;Date.parseCodes[d]=e}return e?Ext.applyIf({c:e.c?b(e.c,c||"{0}"):e.c},e):{g:0,c:null,s:Ext.escapeRe(d)}};var a=Date.formatCodeToRegex;Ext.apply(Date,{parseFunctions:{"M$":function(d,c){var e=new RegExp("\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/");var g=(d||"").match(e);return g?new Date(((g[1]||"")+g[2])*1):null}},parseRegexes:[],formatFunctions:{"M$":function(){return"\\/Date("+this.getTime()+")\\/"}},y2kYear:50,MILLI:"ms",SECOND:"s",MINUTE:"mi",HOUR:"h",DAY:"d",MONTH:"mo",YEAR:"y",defaults:{},dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNumbers:{Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11},getShortMonthName:function(c){return Date.monthNames[c].substring(0,3)},getShortDayName:function(c){return Date.dayNames[c].substring(0,3)},getMonthNumber:function(c){return Date.monthNumbers[c.substring(0,1).toUpperCase()+c.substring(1,3).toLowerCase()]},formatContainsHourInfo:(function(){var d=/(\\.)/g,c=/([gGhHisucUOPZ]|M\$)/;return function(e){return c.test(e.replace(d,""))}})(),formatCodes:{d:"String.leftPad(this.getDate(), 2, '0')",D:"Date.getShortDayName(this.getDay())",j:"this.getDate()",l:"Date.dayNames[this.getDay()]",N:"(this.getDay() ? this.getDay() : 7)",S:"this.getSuffix()",w:"this.getDay()",z:"this.getDayOfYear()",W:"String.leftPad(this.getWeekOfYear(), 2, '0')",F:"Date.monthNames[this.getMonth()]",m:"String.leftPad(this.getMonth() + 1, 2, '0')",M:"Date.getShortMonthName(this.getMonth())",n:"(this.getMonth() + 1)",t:"this.getDaysInMonth()",L:"(this.isLeapYear() ? 1 : 0)",o:"(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",Y:"String.leftPad(this.getFullYear(), 4, '0')",y:"('' + this.getFullYear()).substring(2, 4)",a:"(this.getHours() < 12 ? 'am' : 'pm')",A:"(this.getHours() < 12 ? 'AM' : 'PM')",g:"((this.getHours() % 12) ? this.getHours() % 12 : 12)",G:"this.getHours()",h:"String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",H:"String.leftPad(this.getHours(), 2, '0')",i:"String.leftPad(this.getMinutes(), 2, '0')",s:"String.leftPad(this.getSeconds(), 2, '0')",u:"String.leftPad(this.getMilliseconds(), 3, '0')",O:"this.getGMTOffset()",P:"this.getGMTOffset(true)",T:"this.getTimezone()",Z:"(this.getTimezoneOffset() * -60)",c:function(){for(var k="Y-m-dTH:i:sP",h=[],g=0,d=k.length;g= 0 && y >= 0){","v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);","v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);","}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){","v = null;","}else{","v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);","}","}","}","if(v){","if(zz != null){","v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);","}else if(o){","v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));","}","}","return v;"].join("\n");return function(m){var e=Date.parseRegexes.length,o=1,g=[],l=[],k=false,d="",j=0,h,n;for(;j Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"},a:function(){return a("A")},A:{calcLast:true,g:1,c:"if (/(am)/i.test(results[{0}])) {\nif (!h || h == 12) { h = 0; }\n} else { if (!h || h < 12) { h = (h || 0) + 12; }}",s:"(AM|PM|am|pm)"},g:function(){return a("G")},G:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{1,2})"},h:function(){return a("H")},H:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},i:{g:1,c:"i = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},s:{g:1,c:"s = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},u:{g:1,c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",s:"(\\d+)"},O:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),","mn = o.substring(3,5) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{4})"},P:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),","mn = o.substring(4,6) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{2}:\\d{2})"},T:{g:0,c:null,s:"[A-Z]{1,4}"},Z:{g:1,c:"zz = results[{0}] * 1;\nzz = (-43200 <= zz && zz <= 50400)? zz : null;\n",s:"([+-]?\\d{1,5})"},c:function(){var e=[],c=[a("Y",1),a("m",2),a("d",3),a("h",4),a("i",5),a("s",6),{c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},{c:["if(results[8]) {","if(results[8] == 'Z'){","zz = 0;","}else if (results[8].indexOf(':') > -1){",a("P",8).c,"}else{",a("O",8).c,"}","}"].join("\n")}];for(var g=0,d=c.length;g0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+(a?":":"")+String.leftPad(Math.abs(this.getTimezoneOffset()%60),2,"0")},getDayOfYear:function(){var b=0,e=this.clone(),a=this.getMonth(),c;for(c=0,e.setDate(1),e.setMonth(0);c28){a=Math.min(a,this.getFirstDateOfMonth().add("mo",c).getLastDateOfMonth().getDate())}e.setDate(a);e.setMonth(this.getMonth()+c);break;case Date.YEAR:e.setFullYear(this.getFullYear()+c);break}return e},between:function(c,a){var b=this.getTime();return c.getTime()<=b&&b<=a.getTime()}});Date.prototype.format=Date.prototype.dateFormat;if(Ext.isSafari&&(navigator.userAgent.match(/WebKit\/(\d+)/)[1]||NaN)<420){Ext.apply(Date.prototype,{_xMonth:Date.prototype.setMonth,_xDate:Date.prototype.setDate,setMonth:function(a){if(a<=-1){var d=Math.ceil(-a),c=Math.ceil(d/12),b=(d%12)?12-d%12:0;this.setFullYear(this.getFullYear()-c);return this._xMonth(b)}else{return this._xMonth(a)}},setDate:function(a){return this.setTime(this.getTime()-(this.getDate()-a)*86400000)}})}Ext.util.MixedCollection=function(b,a){this.items=[];this.map={};this.keys=[];this.length=0;this.addEvents("clear","add","replace","remove","sort");this.allowFunctions=b===true;if(a){this.getKey=a}Ext.util.MixedCollection.superclass.constructor.call(this)};Ext.extend(Ext.util.MixedCollection,Ext.util.Observable,{allowFunctions:false,add:function(b,c){if(arguments.length==1){c=arguments[0];b=this.getKey(c)}if(typeof b!="undefined"&&b!==null){var a=this.map[b];if(typeof a!="undefined"){return this.replace(b,c)}this.map[b]=c}this.length++;this.items.push(c);this.keys.push(b);this.fireEvent("add",this.length-1,c,b);return c},getKey:function(a){return a.id},replace:function(c,d){if(arguments.length==1){d=arguments[0];c=this.getKey(d)}var a=this.map[c];if(typeof c=="undefined"||c===null||typeof a=="undefined"){return this.add(c,d)}var b=this.indexOfKey(c);this.items[b]=d;this.map[c]=d;this.fireEvent("replace",c,a,d);return d},addAll:function(e){if(arguments.length>1||Ext.isArray(e)){var b=arguments.length>1?arguments:e;for(var d=0,a=b.length;d=this.length){return this.add(b,c)}this.length++;this.items.splice(a,0,c);if(typeof b!="undefined"&&b!==null){this.map[b]=c}this.keys.splice(a,0,b);this.fireEvent("add",a,c,b);return c},remove:function(a){return this.removeAt(this.indexOf(a))},removeAt:function(a){if(a=0){this.length--;var c=this.items[a];this.items.splice(a,1);var b=this.keys[a];if(typeof b!="undefined"){delete this.map[b]}this.keys.splice(a,1);this.fireEvent("remove",c,b);return c}return false},removeKey:function(a){return this.removeAt(this.indexOfKey(a))},getCount:function(){return this.length},indexOf:function(a){return this.items.indexOf(a)},indexOfKey:function(a){return this.keys.indexOf(a)},item:function(b){var a=this.map[b],c=a!==undefined?a:(typeof b=="number")?this.items[b]:undefined;return typeof c!="function"||this.allowFunctions?c:null},itemAt:function(a){return this.items[a]},key:function(a){return this.map[a]},contains:function(a){return this.indexOf(a)!=-1},containsKey:function(a){return typeof this.map[a]!="undefined"},clear:function(){this.length=0;this.items=[];this.keys=[];this.map={};this.fireEvent("clear")},first:function(){return this.items[0]},last:function(){return this.items[this.length-1]},_sort:function(k,a,j){var d,e,b=String(a).toUpperCase()=="DESC"?-1:1,h=[],l=this.keys,g=this.items;j=j||function(i,c){return i-c};for(d=0,e=g.length;de?1:(g=a;c--){d[d.length]=b[c]}}return d},filter:function(c,b,d,a){if(Ext.isEmpty(b,false)){return this.clone()}b=this.createValueMatcher(b,d,a);return this.filterBy(function(e){return e&&b.test(e[c])})},filterBy:function(g,e){var h=new Ext.util.MixedCollection();h.getKey=this.getKey;var b=this.keys,d=this.items;for(var c=0,a=d.length;c]+>/gi,stripScriptsRe=/(?:)((\n|\r|.)*?)(?:<\/script>)/ig,nl2brRe=/\r?\n/g;return{ellipsis:function(value,len,word){if(value&&value.length>len){if(word){var vs=value.substr(0,len-2),index=Math.max(vs.lastIndexOf(" "),vs.lastIndexOf("."),vs.lastIndexOf("!"),vs.lastIndexOf("?"));if(index==-1||index<(len-15)){return value.substr(0,len-3)+"..."}else{return vs.substr(0,index)+"..."}}else{return value.substr(0,len-3)+"..."}}return value},undef:function(value){return value!==undefined?value:""},defaultValue:function(value,defaultValue){if(!defaultValue&&defaultValue!==0){defaultValue=""}return value!==undefined&&value!==""?value:defaultValue},htmlEncode:function(value){return !value?value:String(value).replace(/&/g,"&").replace(/>/g,">").replace(/").replace(/</g,"<").replace(/"/g,'"').replace(/&/g,"&")},trim:function(value){return String(value).replace(trimRe,"")},substr:function(value,start,length){return String(value).substr(start,length)},lowercase:function(value){return String(value).toLowerCase()},uppercase:function(value){return String(value).toUpperCase()},capitalize:function(value){return !value?value:value.charAt(0).toUpperCase()+value.substr(1).toLowerCase()},call:function(value,fn){if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);args.unshift(value);return eval(fn).apply(window,args)}else{return eval(fn).call(window,value)}},usMoney:function(v){v=(Math.round((v-0)*100))/100;v=(v==Math.floor(v))?v+".00":((v*10==Math.floor(v*10))?v+"0":v);v=String(v);var ps=v.split("."),whole=ps[0],sub=ps[1]?"."+ps[1]:".00",r=/(\d+)(\d{3})/;while(r.test(whole)){whole=whole.replace(r,"$1,$2")}v=whole+sub;if(v.charAt(0)=="-"){return"-$"+v.substr(1)}return"$"+v},date:function(v,format){if(!v){return""}if(!Ext.isDate(v)){v=new Date(Date.parse(v))}return v.dateFormat(format||"m/d/Y")},dateRenderer:function(format){return function(v){return Ext.util.Format.date(v,format)}},stripTags:function(v){return !v?v:String(v).replace(stripTagsRE,"")},stripScripts:function(v){return !v?v:String(v).replace(stripScriptsRe,"")},fileSize:function(size){if(size<1024){return size+" bytes"}else{if(size<1048576){return(Math.round(((size*10)/1024))/10)+" KB"}else{return(Math.round(((size*10)/1048576))/10)+" MB"}}},math:function(){var fns={};return function(v,a){if(!fns[a]){fns[a]=new Function("v","return v "+a+";")}return fns[a](v)}}(),round:function(value,precision){var result=Number(value);if(typeof precision=="number"){precision=Math.pow(10,precision);result=Math.round(value*precision)/precision}return result},number:function(v,format){if(!format){return v}v=Ext.num(v,NaN);if(isNaN(v)){return""}var comma=",",dec=".",i18n=false,neg=v<0;v=Math.abs(v);if(format.substr(format.length-2)=="/i"){format=format.substr(0,format.length-2);i18n=true;comma=".";dec=","}var hasComma=format.indexOf(comma)!=-1,psplit=(i18n?format.replace(/[^\d\,]/g,""):format.replace(/[^\d\.]/g,"")).split(dec);if(1")}}}();Ext.XTemplate=function(){Ext.XTemplate.superclass.constructor.apply(this,arguments);var y=this,j=y.html,q=/]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,d=/^]*?for="(.*?)"/,v=/^]*?if="(.*?)"/,x=/^]*?exec="(.*?)"/,r,p=0,k=[],o="values",w="parent",l="xindex",n="xcount",e="return ",c="with(values){ ";j=["",j,""].join("");while((r=j.match(q))){var b=r[0].match(d),a=r[0].match(v),A=r[0].match(x),g=null,h=null,t=null,z=b&&b[1]?b[1]:"";if(a){g=a&&a[1]?a[1]:null;if(g){h=new Function(o,w,l,n,c+e+(Ext.util.Format.htmlDecode(g))+"; }")}}if(A){g=A&&A[1]?A[1]:null;if(g){t=new Function(o,w,l,n,c+(Ext.util.Format.htmlDecode(g))+"; }")}}if(z){switch(z){case".":z=new Function(o,w,c+e+o+"; }");break;case"..":z=new Function(o,w,c+e+w+"; }");break;default:z=new Function(o,w,c+e+z+"; }")}}k.push({id:p,target:z,exec:t,test:h,body:r[1]||""});j=j.replace(r[0],"{xtpl"+p+"}");++p}for(var u=k.length-1;u>=0;--u){y.compileTpl(k[u])}y.master=k[k.length-1];y.tpls=k};Ext.extend(Ext.XTemplate,Ext.Template,{re:/\{([\w\-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,codeRe:/\{\[((?:\\\]|.|\n)*?)\]\}/g,applySubTemplate:function(a,k,j,d,c){var h=this,g,m=h.tpls[a],l,b=[];if((m.test&&!m.test.call(h,k,j,d,c))||(m.exec&&m.exec.call(h,k,j,d,c))){return""}l=m.target?m.target.call(h,k,j):k;g=l.length;j=m.target?k:j;if(m.target&&Ext.isArray(l)){for(var e=0,g=l.length;e=0;--g){d[k[g].selectorText.toLowerCase()]=k[g]}}catch(i){}},getRules:function(h){if(d===null||h){d={};var k=c.styleSheets;for(var j=0,g=k.length;j=37&&a<=40){b.stopEvent()}},destroy:function(){this.disable()},enable:function(){if(this.disabled){if(Ext.isSafari2){this.el.on("keyup",this.stopKeyUp,this)}this.el.on(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=false}},disable:function(){if(!this.disabled){if(Ext.isSafari2){this.el.un("keyup",this.stopKeyUp,this)}this.el.un(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=true}},setDisabled:function(a){this[a?"disable":"enable"]()},isKeydown:function(){return this.forceKeyDown||Ext.EventManager.useKeydown}};Ext.KeyMap=function(c,b,a){this.el=Ext.get(c);this.eventName=a||"keydown";this.bindings=[];if(b){this.addBinding(b)}this.enable()};Ext.KeyMap.prototype={stopEvent:false,addBinding:function(b){if(Ext.isArray(b)){Ext.each(b,function(j){this.addBinding(j)},this);return}var k=b.key,g=b.fn||b.handler,l=b.scope;if(b.stopEvent){this.stopEvent=b.stopEvent}if(typeof k=="string"){var h=[];var e=k.toUpperCase();for(var c=0,d=e.length;c2)?a[2]:null;var h=(i>3)?a[3]:"/";var d=(i>4)?a[4]:null;var g=(i>5)?a[5]:false;document.cookie=c+"="+escape(e)+((b===null)?"":("; expires="+b.toGMTString()))+((h===null)?"":("; path="+h))+((d===null)?"":("; domain="+d))+((g===true)?"; secure":"")},get:function(d){var b=d+"=";var g=b.length;var a=document.cookie.length;var e=0;var c=0;while(e0){return this.ownerCt.items.itemAt(a-1)}}return null},getBubbleTarget:function(){return this.ownerCt}});Ext.reg("component",Ext.Component);Ext.Action=Ext.extend(Object,{constructor:function(a){this.initialConfig=a;this.itemId=a.itemId=(a.itemId||a.id||Ext.id());this.items=[]},isAction:true,setText:function(a){this.initialConfig.text=a;this.callEach("setText",[a])},getText:function(){return this.initialConfig.text},setIconClass:function(a){this.initialConfig.iconCls=a;this.callEach("setIconClass",[a])},getIconClass:function(){return this.initialConfig.iconCls},setDisabled:function(a){this.initialConfig.disabled=a;this.callEach("setDisabled",[a])},enable:function(){this.setDisabled(false)},disable:function(){this.setDisabled(true)},isDisabled:function(){return this.initialConfig.disabled},setHidden:function(a){this.initialConfig.hidden=a;this.callEach("setVisible",[!a])},show:function(){this.setHidden(false)},hide:function(){this.setHidden(true)},isHidden:function(){return this.initialConfig.hidden},setHandler:function(b,a){this.initialConfig.handler=b;this.initialConfig.scope=a;this.callEach("setHandler",[b,a])},each:function(b,a){Ext.each(this.items,b,a)},callEach:function(e,b){var d=this.items;for(var c=0,a=d.length;cj+o.left){k=j-l-c;g=true}if((i+e)>d+o.top){i=d-e-c;g=true}if(k=m){i=m-e-5}}n=[k,i];this.storeXY(n);a.setXY.call(this,n);this.sync()}}return this},getConstrainOffset:function(){return this.shadowOffset},isVisible:function(){return this.visible},showAction:function(){this.visible=true;if(this.useDisplay===true){this.setDisplayed("")}else{if(this.lastXY){a.setXY.call(this,this.lastXY)}else{if(this.lastLT){a.setLeftTop.call(this,this.lastLT[0],this.lastLT[1])}}}},hideAction:function(){this.visible=false;if(this.useDisplay===true){this.setDisplayed(false)}else{this.setLeftTop(-10000,-10000)}},setVisible:function(i,h,k,l,j){if(i){this.showAction()}if(h&&i){var g=function(){this.sync(true);if(l){l()}}.createDelegate(this);a.setVisible.call(this,true,true,k,g,j)}else{if(!i){this.hideUnders(true)}var g=l;if(h){g=function(){this.hideAction();if(l){l()}}.createDelegate(this)}a.setVisible.call(this,i,h,k,g,j);if(i){this.sync(true)}else{if(!h){this.hideAction()}}}return this},storeXY:function(c){delete this.lastLT;this.lastXY=c},storeLeftTop:function(d,c){delete this.lastXY;this.lastLT=[d,c]},beforeFx:function(){this.beforeAction();return Ext.Layer.superclass.beforeFx.apply(this,arguments)},afterFx:function(){Ext.Layer.superclass.afterFx.apply(this,arguments);this.sync(this.isVisible())},beforeAction:function(){if(!this.updating&&this.shadow){this.shadow.hide()}},setLeft:function(c){this.storeLeftTop(c,this.getTop(true));a.setLeft.apply(this,arguments);this.sync();return this},setTop:function(c){this.storeLeftTop(this.getLeft(true),c);a.setTop.apply(this,arguments);this.sync();return this},setLeftTop:function(d,c){this.storeLeftTop(d,c);a.setLeftTop.apply(this,arguments);this.sync();return this},setXY:function(j,h,k,l,i){this.fixDisplay();this.beforeAction();this.storeXY(j);var g=this.createCB(l);a.setXY.call(this,j,h,k,g,i);if(!h){g()}return this},createCB:function(e){var d=this;return function(){d.constrainXY();d.sync(true);if(e){e()}}},setX:function(g,h,j,k,i){this.setXY([g,this.getY()],h,j,k,i);return this},setY:function(k,g,i,j,h){this.setXY([this.getX(),k],g,i,j,h);return this},setSize:function(j,k,i,m,n,l){this.beforeAction();var g=this.createCB(n);a.setSize.call(this,j,k,i,m,g,l);if(!i){g()}return this},setWidth:function(i,h,k,l,j){this.beforeAction();var g=this.createCB(l);a.setWidth.call(this,i,h,k,g,j);if(!h){g()}return this},setHeight:function(j,i,l,m,k){this.beforeAction();var g=this.createCB(m);a.setHeight.call(this,j,i,l,g,k);if(!i){g()}return this},setBounds:function(o,m,p,i,n,k,l,j){this.beforeAction();var g=this.createCB(l);if(!n){this.storeXY([o,m]);a.setXY.call(this,[o,m]);a.setSize.call(this,p,i,n,k,g,j);g()}else{a.setBounds.call(this,o,m,p,i,n,k,g,j)}return this},setZIndex:function(c){this.zindex=c;this.setStyle("z-index",c+2);if(this.shadow){this.shadow.setZIndex(c+1)}if(this.shim){this.shim.setStyle("z-index",c)}return this}})})();Ext.Shadow=function(d){Ext.apply(this,d);if(typeof this.mode!="string"){this.mode=this.defaultMode}var e=this.offset,c={h:0},b=Math.floor(this.offset/2);switch(this.mode.toLowerCase()){case"drop":c.w=0;c.l=c.t=e;c.t-=1;if(Ext.isIE9m){c.l-=this.offset+b;c.t-=this.offset+b;c.w-=b;c.h-=b;c.t+=1}break;case"sides":c.w=(e*2);c.l=-e;c.t=e-1;if(Ext.isIE9m){c.l-=(this.offset-b);c.t-=this.offset+b;c.l+=1;c.w-=(this.offset-b)*2;c.w-=b+1;c.h-=1}break;case"frame":c.w=c.h=(e*2);c.l=c.t=-e;c.t+=1;c.h-=2;if(Ext.isIE9m){c.l-=(this.offset-b);c.t-=(this.offset-b);c.l+=1;c.w-=(this.offset+b+1);c.h-=(this.offset+b);c.h+=1}break}this.adjusts=c};Ext.Shadow.prototype={offset:4,defaultMode:"drop",show:function(a){a=Ext.get(a);if(!this.el){this.el=Ext.Shadow.Pool.pull();if(this.el.dom.nextSibling!=a.dom){this.el.insertBefore(a)}}this.el.setStyle("z-index",this.zIndex||parseInt(a.getStyle("z-index"),10)-1);if(Ext.isIE9m){this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")"}this.realign(a.getLeft(true),a.getTop(true),a.getWidth(),a.getHeight());this.el.dom.style.display="block"},isVisible:function(){return this.el?true:false},realign:function(b,r,q,g){if(!this.el){return}var n=this.adjusts,k=this.el.dom,u=k.style,i=0,p=(q+n.w),e=(g+n.h),j=p+"px",o=e+"px",m,c;u.left=(b+n.l)+"px";u.top=(r+n.t)+"px";if(u.width!=j||u.height!=o){u.width=j;u.height=o;if(!Ext.isIE9m){m=k.childNodes;c=Math.max(0,(p-12))+"px";m[0].childNodes[1].style.width=c;m[1].childNodes[1].style.width=c;m[2].childNodes[1].style.width=c;m[1].style.height=Math.max(0,(e-12))+"px"}}},hide:function(){if(this.el){this.el.dom.style.display="none";Ext.Shadow.Pool.push(this.el);delete this.el}},setZIndex:function(a){this.zIndex=a;if(this.el){this.el.setStyle("z-index",a)}}};Ext.Shadow.Pool=function(){var b=[],a=Ext.isIE9m?'
    ':'
    ';return{pull:function(){var c=b.shift();if(!c){c=Ext.get(Ext.DomHelper.insertHtml("beforeBegin",document.body.firstChild,a));c.autoBoxAdjust=false}return c},push:function(c){b.push(c)}}}();Ext.BoxComponent=Ext.extend(Ext.Component,{initComponent:function(){Ext.BoxComponent.superclass.initComponent.call(this);this.addEvents("resize","move")},boxReady:false,deferHeight:false,setSize:function(b,d){if(typeof b=="object"){d=b.height;b=b.width}if(Ext.isDefined(b)&&Ext.isDefined(this.boxMinWidth)&&(bthis.boxMaxWidth)){b=this.boxMaxWidth}if(Ext.isDefined(d)&&Ext.isDefined(this.boxMaxHeight)&&(d>this.boxMaxHeight)){d=this.boxMaxHeight}if(!this.boxReady){this.width=b;this.height=d;return this}if(this.cacheSizes!==false&&this.lastSize&&this.lastSize.width==b&&this.lastSize.height==d){return this}this.lastSize={width:b,height:d};var c=this.adjustSize(b,d),g=c.width,a=c.height,e;if(g!==undefined||a!==undefined){e=this.getResizeEl();if(!this.deferHeight&&g!==undefined&&a!==undefined){e.setSize(g,a)}else{if(!this.deferHeight&&a!==undefined){e.setHeight(a)}else{if(g!==undefined){e.setWidth(g)}}}this.onResize(g,a,b,d);this.fireEvent("resize",this,g,a,b,d)}return this},setWidth:function(a){return this.setSize(a)},setHeight:function(a){return this.setSize(undefined,a)},getSize:function(){return this.getResizeEl().getSize()},getWidth:function(){return this.getResizeEl().getWidth()},getHeight:function(){return this.getResizeEl().getHeight()},getOuterSize:function(){var a=this.getResizeEl();return{width:a.getWidth()+a.getMargins("lr"),height:a.getHeight()+a.getMargins("tb")}},getPosition:function(a){var b=this.getPositionEl();if(a===true){return[b.getLeft(true),b.getTop(true)]}return this.xy||b.getXY()},getBox:function(a){var c=this.getPosition(a);var b=this.getSize();b.x=c[0];b.y=c[1];return b},updateBox:function(a){this.setSize(a.width,a.height);this.setPagePosition(a.x,a.y);return this},getResizeEl:function(){return this.resizeEl||this.el},setAutoScroll:function(a){if(this.rendered){this.getContentTarget().setOverflow(a?"auto":"")}this.autoScroll=a;return this},setPosition:function(a,g){if(a&&typeof a[1]=="number"){g=a[1];a=a[0]}this.x=a;this.y=g;if(!this.boxReady){return this}var b=this.adjustPosition(a,g);var e=b.x,d=b.y;var c=this.getPositionEl();if(e!==undefined||d!==undefined){if(e!==undefined&&d!==undefined){c.setLeftTop(e,d)}else{if(e!==undefined){c.setLeft(e)}else{if(d!==undefined){c.setTop(d)}}}this.onPosition(e,d);this.fireEvent("move",this,e,d)}return this},setPagePosition:function(a,c){if(a&&typeof a[1]=="number"){c=a[1];a=a[0]}this.pageX=a;this.pageY=c;if(!this.boxReady){return}if(a===undefined||c===undefined){return}var b=this.getPositionEl().translatePoints(a,c);this.setPosition(b.left,b.top);return this},afterRender:function(){Ext.BoxComponent.superclass.afterRender.call(this);if(this.resizeEl){this.resizeEl=Ext.get(this.resizeEl)}if(this.positionEl){this.positionEl=Ext.get(this.positionEl)}this.boxReady=true;Ext.isDefined(this.autoScroll)&&this.setAutoScroll(this.autoScroll);this.setSize(this.width,this.height);if(this.x||this.y){this.setPosition(this.x,this.y)}else{if(this.pageX||this.pageY){this.setPagePosition(this.pageX,this.pageY)}}},syncSize:function(){delete this.lastSize;this.setSize(this.autoWidth?undefined:this.getResizeEl().getWidth(),this.autoHeight?undefined:this.getResizeEl().getHeight());return this},onResize:function(d,b,a,c){},onPosition:function(a,b){},adjustSize:function(a,b){if(this.autoWidth){a="auto"}if(this.autoHeight){b="auto"}return{width:a,height:b}},adjustPosition:function(a,b){return{x:a,y:b}}});Ext.reg("box",Ext.BoxComponent);Ext.Spacer=Ext.extend(Ext.BoxComponent,{autoEl:"div"});Ext.reg("spacer",Ext.Spacer);Ext.SplitBar=function(c,e,b,d,a){this.el=Ext.get(c,true);this.el.unselectable();this.resizingEl=Ext.get(e,true);this.orientation=b||Ext.SplitBar.HORIZONTAL;this.minSize=0;this.maxSize=2000;this.animate=false;this.useShim=false;this.shim=null;if(!a){this.proxy=Ext.SplitBar.createProxy(this.orientation)}else{this.proxy=Ext.get(a).dom}this.dd=new Ext.dd.DDProxy(this.el.dom.id,"XSplitBars",{dragElId:this.proxy.id});this.dd.b4StartDrag=this.onStartProxyDrag.createDelegate(this);this.dd.endDrag=this.onEndProxyDrag.createDelegate(this);this.dragSpecs={};this.adapter=new Ext.SplitBar.BasicLayoutAdapter();this.adapter.init(this);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.placement=d||(this.el.getX()>this.resizingEl.getX()?Ext.SplitBar.LEFT:Ext.SplitBar.RIGHT);this.el.addClass("x-splitbar-h")}else{this.placement=d||(this.el.getY()>this.resizingEl.getY()?Ext.SplitBar.TOP:Ext.SplitBar.BOTTOM);this.el.addClass("x-splitbar-v")}this.addEvents("resize","moved","beforeresize","beforeapply");Ext.SplitBar.superclass.constructor.call(this)};Ext.extend(Ext.SplitBar,Ext.util.Observable,{onStartProxyDrag:function(a,e){this.fireEvent("beforeresize",this);this.overlay=Ext.DomHelper.append(document.body,{cls:"x-drag-overlay",html:" "},true);this.overlay.unselectable();this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();Ext.get(this.proxy).setDisplayed("block");var c=this.adapter.getElementSize(this);this.activeMinSize=this.getMinimumSize();this.activeMaxSize=this.getMaximumSize();var d=c-this.activeMinSize;var b=Math.max(this.activeMaxSize-c,0);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.dd.resetConstraints();this.dd.setXConstraint(this.placement==Ext.SplitBar.LEFT?d:b,this.placement==Ext.SplitBar.LEFT?b:d,this.tickSize);this.dd.setYConstraint(0,0)}else{this.dd.resetConstraints();this.dd.setXConstraint(0,0);this.dd.setYConstraint(this.placement==Ext.SplitBar.TOP?d:b,this.placement==Ext.SplitBar.TOP?b:d,this.tickSize)}this.dragSpecs.startSize=c;this.dragSpecs.startPoint=[a,e];Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd,a,e)},onEndProxyDrag:function(c){Ext.get(this.proxy).setDisplayed(false);var b=Ext.lib.Event.getXY(c);if(this.overlay){Ext.destroy(this.overlay);delete this.overlay}var a;if(this.orientation==Ext.SplitBar.HORIZONTAL){a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.LEFT?b[0]-this.dragSpecs.startPoint[0]:this.dragSpecs.startPoint[0]-b[0])}else{a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.TOP?b[1]-this.dragSpecs.startPoint[1]:this.dragSpecs.startPoint[1]-b[1])}a=Math.min(Math.max(a,this.activeMinSize),this.activeMaxSize);if(a!=this.dragSpecs.startSize){if(this.fireEvent("beforeapply",this,a)!==false){this.adapter.setElementSize(this,a);this.fireEvent("moved",this,a);this.fireEvent("resize",this,a)}}},getAdapter:function(){return this.adapter},setAdapter:function(a){this.adapter=a;this.adapter.init(this)},getMinimumSize:function(){return this.minSize},setMinimumSize:function(a){this.minSize=a},getMaximumSize:function(){return this.maxSize},setMaximumSize:function(a){this.maxSize=a},setCurrentSize:function(b){var a=this.animate;this.animate=false;this.adapter.setElementSize(this,b);this.animate=a},destroy:function(a){Ext.destroy(this.shim,Ext.get(this.proxy));this.dd.unreg();if(a){this.el.remove()}this.purgeListeners()}});Ext.SplitBar.createProxy=function(b){var c=new Ext.Element(document.createElement("div"));document.body.appendChild(c.dom);c.unselectable();var a="x-splitbar-proxy";c.addClass(a+" "+(b==Ext.SplitBar.HORIZONTAL?a+"-h":a+"-v"));return c.dom};Ext.SplitBar.BasicLayoutAdapter=function(){};Ext.SplitBar.BasicLayoutAdapter.prototype={init:function(a){},getElementSize:function(a){if(a.orientation==Ext.SplitBar.HORIZONTAL){return a.resizingEl.getWidth()}else{return a.resizingEl.getHeight()}},setElementSize:function(b,a,c){if(b.orientation==Ext.SplitBar.HORIZONTAL){if(!b.animate){b.resizingEl.setWidth(a);if(c){c(b,a)}}else{b.resizingEl.setWidth(a,true,0.1,c,"easeOut")}}else{if(!b.animate){b.resizingEl.setHeight(a);if(c){c(b,a)}}else{b.resizingEl.setHeight(a,true,0.1,c,"easeOut")}}}};Ext.SplitBar.AbsoluteLayoutAdapter=function(a){this.basic=new Ext.SplitBar.BasicLayoutAdapter();this.container=Ext.get(a)};Ext.SplitBar.AbsoluteLayoutAdapter.prototype={init:function(a){this.basic.init(a)},getElementSize:function(a){return this.basic.getElementSize(a)},setElementSize:function(b,a,c){this.basic.setElementSize(b,a,this.moveSplitter.createDelegate(this,[b]))},moveSplitter:function(a){var b=Ext.SplitBar;switch(a.placement){case b.LEFT:a.el.setX(a.resizingEl.getRight());break;case b.RIGHT:a.el.setStyle("right",(this.container.getWidth()-a.resizingEl.getLeft())+"px");break;case b.TOP:a.el.setY(a.resizingEl.getBottom());break;case b.BOTTOM:a.el.setY(a.resizingEl.getTop()-a.el.getHeight());break}}};Ext.SplitBar.VERTICAL=1;Ext.SplitBar.HORIZONTAL=2;Ext.SplitBar.LEFT=1;Ext.SplitBar.RIGHT=2;Ext.SplitBar.TOP=3;Ext.SplitBar.BOTTOM=4;Ext.Container=Ext.extend(Ext.BoxComponent,{bufferResize:50,autoDestroy:true,forceLayout:false,defaultType:"panel",resizeEvent:"resize",bubbleEvents:["add","remove"],initComponent:function(){Ext.Container.superclass.initComponent.call(this);this.addEvents("afterlayout","beforeadd","beforeremove","add","remove");var a=this.items;if(a){delete this.items;this.add(a)}},initItems:function(){if(!this.items){this.items=new Ext.util.MixedCollection(false,this.getComponentId);this.getLayout()}},setLayout:function(a){if(this.layout&&this.layout!=a){this.layout.setContainer(null)}this.layout=a;this.initItems();a.setContainer(this)},afterRender:function(){Ext.Container.superclass.afterRender.call(this);if(!this.layout){this.layout="auto"}if(Ext.isObject(this.layout)&&!this.layout.layout){this.layoutConfig=this.layout;this.layout=this.layoutConfig.type}if(Ext.isString(this.layout)){this.layout=new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig)}this.setLayout(this.layout);if(this.activeItem!==undefined&&this.layout.setActiveItem){var a=this.activeItem;delete this.activeItem;this.layout.setActiveItem(a)}if(!this.ownerCt){this.doLayout(false,true)}if(this.monitorResize===true){Ext.EventManager.onWindowResize(this.doLayout,this,[false])}},getLayoutTarget:function(){return this.el},getComponentId:function(a){return a.getItemId()},add:function(b){this.initItems();var e=arguments.length>1;if(e||Ext.isArray(b)){var a=[];Ext.each(e?arguments:b,function(h){a.push(this.add(h))},this);return a}var g=this.lookupComponent(this.applyDefaults(b));var d=this.items.length;if(this.fireEvent("beforeadd",this,g,d)!==false&&this.onBeforeAdd(g)!==false){this.items.add(g);g.onAdded(this,d);this.onAdd(g);this.fireEvent("add",this,g,d)}return g},onAdd:function(a){},onAdded:function(a,b){this.ownerCt=a;this.initRef();this.cascade(function(d){d.initRef()});this.fireEvent("added",this,a,b)},insert:function(e,b){var d=arguments,h=d.length,a=[],g,j;this.initItems();if(h>2){for(g=h-1;g>=1;--g){a.push(this.insert(e,d[g]))}return a}j=this.lookupComponent(this.applyDefaults(b));e=Math.min(e,this.items.length);if(this.fireEvent("beforeadd",this,j,e)!==false&&this.onBeforeAdd(j)!==false){if(j.ownerCt==this){this.items.remove(j)}this.items.insert(e,j);j.onAdded(this,e);this.onAdd(j);this.fireEvent("add",this,j,e)}return j},applyDefaults:function(b){var a=this.defaults;if(a){if(Ext.isFunction(a)){a=a.call(this,b)}if(Ext.isString(b)){b=Ext.ComponentMgr.get(b);Ext.apply(b,a)}else{if(!b.events){Ext.applyIf(b.isAction?b.initialConfig:b,a)}else{Ext.apply(b,a)}}}return b},onBeforeAdd:function(a){if(a.ownerCt){a.ownerCt.remove(a,false)}if(this.hideBorders===true){a.border=(a.border===true)}},remove:function(a,b){this.initItems();var d=this.getComponent(a);if(d&&this.fireEvent("beforeremove",this,d)!==false){this.doRemove(d,b);this.fireEvent("remove",this,d)}return d},onRemove:function(a){},doRemove:function(e,d){var b=this.layout,a=b&&this.rendered;if(a){b.onRemove(e)}this.items.remove(e);e.onRemoved();this.onRemove(e);if(d===true||(d!==false&&this.autoDestroy)){e.destroy()}if(a){b.afterRemove(e)}},removeAll:function(c){this.initItems();var e,g=[],b=[];this.items.each(function(h){g.push(h)});for(var d=0,a=g.length;d','','
    ','
    ',"
    ");a.disableFormats=true;return a.compile()})(),destroy:function(){if(this.resizeTask&&this.resizeTask.cancel){this.resizeTask.cancel()}if(this.container){this.container.un(this.container.resizeEvent,this.onResize,this)}if(!Ext.isEmpty(this.targetCls)){var a=this.container.getLayoutTarget();if(a){a.removeClass(this.targetCls)}}}});Ext.layout.AutoLayout=Ext.extend(Ext.layout.ContainerLayout,{type:"auto",monitorResize:true,onLayout:function(d,g){Ext.layout.AutoLayout.superclass.onLayout.call(this,d,g);var e=this.getRenderedItems(d),a=e.length,b,h;for(b=0;b0){b.setSize(a)}}});Ext.Container.LAYOUTS.fit=Ext.layout.FitLayout;Ext.layout.CardLayout=Ext.extend(Ext.layout.FitLayout,{deferredRender:false,layoutOnCardChange:false,renderHidden:true,type:"card",setActiveItem:function(d){var a=this.activeItem,b=this.container;d=b.getComponent(d);if(d&&a!=d){if(a){a.hide();if(a.hidden!==true){return false}a.fireEvent("deactivate",a)}var c=d.doLayout&&(this.layoutOnCardChange||!d.rendered);this.activeItem=d;delete d.deferLayout;d.show();this.layout();if(c){d.doLayout()}d.fireEvent("activate",d)}},renderAll:function(a,b){if(this.deferredRender){this.renderItem(this.activeItem,undefined,b)}else{Ext.layout.CardLayout.superclass.renderAll.call(this,a,b)}}});Ext.Container.LAYOUTS.card=Ext.layout.CardLayout;Ext.layout.AnchorLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"anchor",defaultAnchor:"100%",parseAnchorRE:/^(r|right|b|bottom)$/i,getLayoutTargetSize:function(){var b=this.container.getLayoutTarget(),a={};if(b){a=b.getViewSize();if(Ext.isIE9m&&Ext.isStrict&&a.width==0){a=b.getStyleSize()}a.width-=b.getPadding("lr");a.height-=b.getPadding("tb")}return a},onLayout:function(m,w){Ext.layout.AnchorLayout.superclass.onLayout.call(this,m,w);var p=this.getLayoutTargetSize(),k=p.width,o=p.height,q=w.getStyle("overflow"),n=this.getRenderedItems(m),t=n.length,g=[],j,a,v,l,h,c,e,d,u=0,s,b;if(k<20&&o<20){return}if(m.anchorSize){if(typeof m.anchorSize=="number"){a=m.anchorSize}else{a=m.anchorSize.width;v=m.anchorSize.height}}else{a=m.initialConfig.width;v=m.initialConfig.height}for(s=0;s ');b.disableFormats=true;b.compile();Ext.layout.BorderLayout.Region.prototype.toolTemplate=b}this.collapsedEl=this.targetEl.createChild({cls:"x-layout-collapsed x-layout-collapsed-"+this.position,id:this.panel.id+"-xcollapsed"});this.collapsedEl.enableDisplayMode("block");if(this.collapseMode=="mini"){this.collapsedEl.addClass("x-layout-cmini-"+this.position);this.miniCollapsedEl=this.collapsedEl.createChild({cls:"x-layout-mini x-layout-mini-"+this.position,html:" "});this.miniCollapsedEl.addClassOnOver("x-layout-mini-over");this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this.onExpandClick,this,{stopEvent:true})}else{if(this.collapsible!==false&&!this.hideCollapseTool){var a=this.expandToolEl=this.toolTemplate.append(this.collapsedEl.dom,{id:"expand-"+this.position},true);a.addClassOnOver("x-tool-expand-"+this.position+"-over");a.on("click",this.onExpandClick,this,{stopEvent:true})}if(this.floatable!==false||this.titleCollapse){this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this[this.floatable?"collapseClick":"onExpandClick"],this)}}}return this.collapsedEl},onExpandClick:function(a){if(this.isSlid){this.panel.expand(false)}else{this.panel.expand()}},onCollapseClick:function(a){this.panel.collapse()},beforeCollapse:function(c,a){this.lastAnim=a;if(this.splitEl){this.splitEl.hide()}this.getCollapsedEl().show();var b=this.panel.getEl();this.originalZIndex=b.getStyle("z-index");b.setStyle("z-index",100);this.isCollapsed=true;this.layout.layout()},onCollapse:function(a){this.panel.el.setStyle("z-index",1);if(this.lastAnim===false||this.panel.animCollapse===false){this.getCollapsedEl().dom.style.visibility="visible"}else{this.getCollapsedEl().slideIn(this.panel.slideAnchor,{duration:0.2})}this.state.collapsed=true;this.panel.saveState()},beforeExpand:function(a){if(this.isSlid){this.afterSlideIn()}var b=this.getCollapsedEl();this.el.show();if(this.position=="east"||this.position=="west"){this.panel.setSize(undefined,b.getHeight())}else{this.panel.setSize(b.getWidth(),undefined)}b.hide();b.dom.style.visibility="hidden";this.panel.el.setStyle("z-index",this.floatingZIndex)},onExpand:function(){this.isCollapsed=false;if(this.splitEl){this.splitEl.show()}this.layout.layout();this.panel.el.setStyle("z-index",this.originalZIndex);this.state.collapsed=false;this.panel.saveState()},collapseClick:function(a){if(this.isSlid){a.stopPropagation();this.slideIn()}else{a.stopPropagation();this.slideOut()}},onHide:function(){if(this.isCollapsed){this.getCollapsedEl().hide()}else{if(this.splitEl){this.splitEl.hide()}}},onShow:function(){if(this.isCollapsed){this.getCollapsedEl().show()}else{if(this.splitEl){this.splitEl.show()}}},isVisible:function(){return !this.panel.hidden},getMargins:function(){return this.isCollapsed&&this.cmargins?this.cmargins:this.margins},getSize:function(){return this.isCollapsed?this.getCollapsedEl().getSize():this.panel.getSize()},setPanel:function(a){this.panel=a},getMinWidth:function(){return this.minWidth},getMinHeight:function(){return this.minHeight},applyLayoutCollapsed:function(a){var b=this.getCollapsedEl();b.setLeftTop(a.x,a.y);b.setSize(a.width,a.height)},applyLayout:function(a){if(this.isCollapsed){this.applyLayoutCollapsed(a)}else{this.panel.setPosition(a.x,a.y);this.panel.setSize(a.width,a.height)}},beforeSlide:function(){this.panel.beforeEffect()},afterSlide:function(){this.panel.afterEffect()},initAutoHide:function(){if(this.autoHide!==false){if(!this.autoHideHd){this.autoHideSlideTask=new Ext.util.DelayedTask(this.slideIn,this);this.autoHideHd={mouseout:function(a){if(!a.within(this.el,true)){this.autoHideSlideTask.delay(500)}},mouseover:function(a){this.autoHideSlideTask.cancel()},scope:this}}this.el.on(this.autoHideHd);this.collapsedEl.on(this.autoHideHd)}},clearAutoHide:function(){if(this.autoHide!==false){this.el.un("mouseout",this.autoHideHd.mouseout);this.el.un("mouseover",this.autoHideHd.mouseover);this.collapsedEl.un("mouseout",this.autoHideHd.mouseout);this.collapsedEl.un("mouseover",this.autoHideHd.mouseover)}},clearMonitor:function(){Ext.getDoc().un("click",this.slideInIf,this)},slideOut:function(){if(this.isSlid||this.el.hasActiveFx()){return}this.isSlid=true;var b=this.panel.tools,c,a;if(b&&b.toggle){b.toggle.hide()}this.el.show();a=this.panel.collapsed;this.panel.collapsed=false;if(this.position=="east"||this.position=="west"){c=this.panel.deferHeight;this.panel.deferHeight=false;this.panel.setSize(undefined,this.collapsedEl.getHeight());this.panel.deferHeight=c}else{this.panel.setSize(this.collapsedEl.getWidth(),undefined)}this.panel.collapsed=a;this.restoreLT=[this.el.dom.style.left,this.el.dom.style.top];this.el.alignTo(this.collapsedEl,this.getCollapseAnchor());this.el.setStyle("z-index",this.floatingZIndex+2);this.panel.el.replaceClass("x-panel-collapsed","x-panel-floating");if(this.animFloat!==false){this.beforeSlide();this.el.slideIn(this.getSlideAnchor(),{callback:function(){this.afterSlide();this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)},scope:this,block:true})}else{this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)}},afterSlideIn:function(){this.clearAutoHide();this.isSlid=false;this.clearMonitor();this.el.setStyle("z-index","");this.panel.el.replaceClass("x-panel-floating","x-panel-collapsed");this.el.dom.style.left=this.restoreLT[0];this.el.dom.style.top=this.restoreLT[1];var a=this.panel.tools;if(a&&a.toggle){a.toggle.show()}},slideIn:function(a){if(!this.isSlid||this.el.hasActiveFx()){Ext.callback(a);return}this.isSlid=false;if(this.animFloat!==false){this.beforeSlide();this.el.slideOut(this.getSlideAnchor(),{callback:function(){this.el.hide();this.afterSlide();this.afterSlideIn();Ext.callback(a)},scope:this,block:true})}else{this.el.hide();this.afterSlideIn()}},slideInIf:function(a){if(!a.within(this.el)){this.slideIn()}},anchors:{west:"left",east:"right",north:"top",south:"bottom"},sanchors:{west:"l",east:"r",north:"t",south:"b"},canchors:{west:"tl-tr",east:"tr-tl",north:"tl-bl",south:"bl-tl"},getAnchor:function(){return this.anchors[this.position]},getCollapseAnchor:function(){return this.canchors[this.position]},getSlideAnchor:function(){return this.sanchors[this.position]},getAlignAdj:function(){var a=this.cmargins;switch(this.position){case"west":return[0,0];break;case"east":return[0,0];break;case"north":return[0,0];break;case"south":return[0,0];break}},getExpandAdj:function(){var b=this.collapsedEl,a=this.cmargins;switch(this.position){case"west":return[-(a.right+b.getWidth()+a.left),0];break;case"east":return[a.right+b.getWidth()+a.left,0];break;case"north":return[0,-(a.top+a.bottom+b.getHeight())];break;case"south":return[0,a.top+a.bottom+b.getHeight()];break}},destroy:function(){if(this.autoHideSlideTask&&this.autoHideSlideTask.cancel){this.autoHideSlideTask.cancel()}Ext.destroyMembers(this,"miniCollapsedEl","collapsedEl","expandToolEl")}};Ext.layout.BorderLayout.SplitRegion=function(b,a,c){Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this,b,a,c);this.applyLayout=this.applyFns[c]};Ext.extend(Ext.layout.BorderLayout.SplitRegion,Ext.layout.BorderLayout.Region,{splitTip:"Drag to resize.",collapsibleSplitTip:"Drag to resize. Double click to hide.",useSplitTips:false,splitSettings:{north:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.TOP,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},south:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.BOTTOM,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},east:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.RIGHT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"},west:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.LEFT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"}},applyFns:{west:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;this.panel.setPosition(c.x,c.y);var a=d.offsetWidth;b.left=(c.x+c.width-a)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},east:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetWidth;this.panel.setPosition(c.x+a,c.y);b.left=(c.x)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},north:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y);b.left=(c.x)+"px";b.top=(c.y+c.height-a)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)},south:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y+a);b.left=(c.x)+"px";b.top=(c.y)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)}},render:function(a,c){Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this,a,c);var d=this.position;this.splitEl=a.createChild({cls:"x-layout-split x-layout-split-"+d,html:" ",id:this.panel.id+"-xsplit"});if(this.collapseMode=="mini"){this.miniSplitEl=this.splitEl.createChild({cls:"x-layout-mini x-layout-mini-"+d,html:" "});this.miniSplitEl.addClassOnOver("x-layout-mini-over");this.miniSplitEl.on("click",this.onCollapseClick,this,{stopEvent:true})}var b=this.splitSettings[d];this.split=new Ext.SplitBar(this.splitEl.dom,c.el,b.orientation);this.split.tickSize=this.tickSize;this.split.placement=b.placement;this.split.getMaximumSize=this[b.maxFn].createDelegate(this);this.split.minSize=this.minSize||this[b.minProp];this.split.on("beforeapply",this.onSplitMove,this);this.split.useShim=this.useShim===true;this.maxSize=this.maxSize||this[b.maxProp];if(c.hidden){this.splitEl.hide()}if(this.useSplitTips){this.splitEl.dom.title=this.collapsible?this.collapsibleSplitTip:this.splitTip}if(this.collapsible){this.splitEl.on("dblclick",this.onCollapseClick,this)}},getSize:function(){if(this.isCollapsed){return this.collapsedEl.getSize()}var a=this.panel.getSize();if(this.position=="north"||this.position=="south"){a.height+=this.splitEl.dom.offsetHeight}else{a.width+=this.splitEl.dom.offsetWidth}return a},getHMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getWidth()+a.el.getWidth())-a.getMinWidth())},getVMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getHeight()+a.el.getHeight())-a.getMinHeight())},onSplitMove:function(b,a){var c=this.panel.getSize();this.lastSplitSize=a;if(this.position=="north"||this.position=="south"){this.panel.setSize(c.width,a);this.state.height=a}else{this.panel.setSize(a,c.height);this.state.width=a}this.layout.layout();this.panel.saveState();return false},getSplitBar:function(){return this.split},destroy:function(){Ext.destroy(this.miniSplitEl,this.split,this.splitEl);Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.border=Ext.layout.BorderLayout;Ext.layout.FormLayout=Ext.extend(Ext.layout.AnchorLayout,{labelSeparator:":",trackLabels:true,type:"form",onRemove:function(d){Ext.layout.FormLayout.superclass.onRemove.call(this,d);if(this.trackLabels){d.un("show",this.onFieldShow,this);d.un("hide",this.onFieldHide,this)}var b=d.getPositionEl(),a=d.getItemCt&&d.getItemCt();if(d.rendered&&a){if(b&&b.dom){b.insertAfter(a)}Ext.destroy(a);Ext.destroyMembers(d,"label","itemCt");if(d.customItemCt){Ext.destroyMembers(d,"getItemCt","customItemCt")}}},setContainer:function(a){Ext.layout.FormLayout.superclass.setContainer.call(this,a);a.labelAlign=a.labelAlign||this.labelAlign;if(a.labelAlign){a.addClass("x-form-label-"+a.labelAlign)}if(a.hideLabels||this.hideLabels){Ext.apply(this,{labelStyle:"display:none",elementStyle:"padding-left:0;",labelAdjust:0})}else{this.labelSeparator=Ext.isDefined(a.labelSeparator)?a.labelSeparator:this.labelSeparator;a.labelWidth=a.labelWidth||this.labelWidth||100;if(Ext.isNumber(a.labelWidth)){var b=a.labelPad||this.labelPad;b=Ext.isNumber(b)?b:5;Ext.apply(this,{labelAdjust:a.labelWidth+b,labelStyle:"width:"+a.labelWidth+"px;",elementStyle:"padding-left:"+(a.labelWidth+b)+"px"})}if(a.labelAlign=="top"){Ext.apply(this,{labelStyle:"width:auto;",labelAdjust:0,elementStyle:"padding-left:0;"})}}},isHide:function(a){return a.hideLabel||this.container.hideLabels},onFieldShow:function(a){a.getItemCt().removeClass("x-hide-"+a.hideMode);if(a.isComposite){a.doLayout()}},onFieldHide:function(a){a.getItemCt().addClass("x-hide-"+a.hideMode)},getLabelStyle:function(e){var b="",c=[this.labelStyle,e];for(var d=0,a=c.length;d=b)||(this.cells[c]&&this.cells[c][a])){if(b&&a>=b){c++;a=0}else{a++}}return[a,c]},renderItem:function(e,a,d){if(!this.table){this.table=d.createChild(Ext.apply({tag:"table",cls:"x-table-layout",cellspacing:0,cn:{tag:"tbody"}},this.tableAttrs),null,true)}if(e&&!e.rendered){e.render(this.getNextCell(e));this.configureItem(e)}else{if(e&&!this.isValidParent(e,d)){var b=this.getNextCell(e);b.insertBefore(e.getPositionEl().dom,null);e.container=Ext.get(b);this.configureItem(e)}}},isValidParent:function(b,a){return b.getPositionEl().up("table",5).dom.parentNode===(a.dom||a)},destroy:function(){delete this.table;Ext.layout.TableLayout.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.table=Ext.layout.TableLayout;Ext.layout.AbsoluteLayout=Ext.extend(Ext.layout.AnchorLayout,{extraCls:"x-abs-layout-item",type:"absolute",onLayout:function(a,b){b.position();this.paddingLeft=b.getPadding("l");this.paddingTop=b.getPadding("t");Ext.layout.AbsoluteLayout.superclass.onLayout.call(this,a,b)},adjustWidthAnchor:function(b,a){return b?b-a.getPosition(true)[0]+this.paddingLeft:b},adjustHeightAnchor:function(b,a){return b?b-a.getPosition(true)[1]+this.paddingTop:b}});Ext.Container.LAYOUTS.absolute=Ext.layout.AbsoluteLayout;Ext.layout.BoxLayout=Ext.extend(Ext.layout.ContainerLayout,{defaultMargins:{left:0,top:0,right:0,bottom:0},padding:"0",pack:"start",monitorResize:true,type:"box",scrollOffset:0,extraCls:"x-box-item",targetCls:"x-box-layout-ct",innerCls:"x-box-inner",constructor:function(a){Ext.layout.BoxLayout.superclass.constructor.call(this,a);if(Ext.isString(this.defaultMargins)){this.defaultMargins=this.parseMargins(this.defaultMargins)}var d=this.overflowHandler;if(typeof d=="string"){d={type:d}}var c="none";if(d&&d.type!=undefined){c=d.type}var b=Ext.layout.boxOverflow[c];if(b[this.type]){b=b[this.type]}this.overflowHandler=new b(this,d)},onLayout:function(b,h){Ext.layout.BoxLayout.superclass.onLayout.call(this,b,h);var d=this.getLayoutTargetSize(),i=this.getVisibleItems(b),c=this.calculateChildBoxes(i,d),g=c.boxes,j=c.meta;if(d.width>0){var k=this.overflowHandler,a=j.tooNarrow?"handleOverflow":"clearOverflow";var e=k[a](c,d);if(e){if(e.targetSize){d=e.targetSize}if(e.recalculate){i=this.getVisibleItems(b);c=this.calculateChildBoxes(i,d);g=c.boxes}}}this.layoutTargetLastSize=d;this.childBoxCache=c;this.updateInnerCtSize(d,c);this.updateChildBoxes(g);this.handleTargetOverflow(d,b,h)},updateChildBoxes:function(c){for(var b=0,e=c.length;b(None)',constructor:function(a){Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this,arguments);this.menuItems=[]},createInnerElements:function(){if(!this.afterCt){this.afterCt=this.layout.innerCt.insertSibling({cls:this.afterCls},"before")}},clearOverflow:function(a,g){var e=g.width+(this.afterCt?this.afterCt.getWidth():0),b=this.menuItems;this.hideTrigger();for(var c=0,d=b.length;ci.width;return l}},handleOverflow:function(d,h){this.showTrigger();var k=h.width-this.afterCt.getWidth(),l=d.boxes,e=0,r=false;for(var o=0,c=l.length;o=0;j--){var q=l[j].component,p=l[j].left+l[j].width;if(p>=k){this.menuItems.unshift({component:q,width:l[j].width});q.hide()}else{break}}}if(this.menuItems.length==0){this.hideTrigger()}return{targetSize:{height:h.height,width:k},recalculate:r}}});Ext.layout.boxOverflow.menu.hbox=Ext.layout.boxOverflow.HorizontalMenu;Ext.layout.boxOverflow.Scroller=Ext.extend(Ext.layout.boxOverflow.None,{animateScroll:true,scrollIncrement:100,wheelIncrement:3,scrollRepeatInterval:400,scrollDuration:0.4,beforeCls:"x-strip-left",afterCls:"x-strip-right",scrollerCls:"x-strip-scroller",beforeScrollerCls:"x-strip-scroller-left",afterScrollerCls:"x-strip-scroller-right",createWheelListener:function(){this.layout.innerCt.on({scope:this,mousewheel:function(a){a.stopEvent();this.scrollBy(a.getWheelDelta()*this.wheelIncrement*-1,false)}})},handleOverflow:function(a,b){this.createInnerElements();this.showScrollers()},clearOverflow:function(){this.hideScrollers()},showScrollers:function(){this.createScrollers();this.beforeScroller.show();this.afterScroller.show();this.updateScrollButtons()},hideScrollers:function(){if(this.beforeScroller!=undefined){this.beforeScroller.hide();this.afterScroller.hide()}},createScrollers:function(){if(!this.beforeScroller&&!this.afterScroller){var a=this.beforeCt.createChild({cls:String.format("{0} {1} ",this.scrollerCls,this.beforeScrollerCls)});var b=this.afterCt.createChild({cls:String.format("{0} {1}",this.scrollerCls,this.afterScrollerCls)});a.addClassOnOver(this.beforeScrollerCls+"-hover");b.addClassOnOver(this.afterScrollerCls+"-hover");a.setVisibilityMode(Ext.Element.DISPLAY);b.setVisibilityMode(Ext.Element.DISPLAY);this.beforeRepeater=new Ext.util.ClickRepeater(a,{interval:this.scrollRepeatInterval,handler:this.scrollLeft,scope:this});this.afterRepeater=new Ext.util.ClickRepeater(b,{interval:this.scrollRepeatInterval,handler:this.scrollRight,scope:this});this.beforeScroller=a;this.afterScroller=b}},destroy:function(){Ext.destroy(this.beforeScroller,this.afterScroller,this.beforeRepeater,this.afterRepeater,this.beforeCt,this.afterCt)},scrollBy:function(b,a){this.scrollTo(this.getScrollPosition()+b,a)},getItem:function(a){if(Ext.isString(a)){a=Ext.getCmp(a)}else{if(Ext.isNumber(a)){a=this.items[a]}}return a},getScrollAnim:function(){return{duration:this.scrollDuration,callback:this.updateScrollButtons,scope:this}},updateScrollButtons:function(){if(this.beforeScroller==undefined||this.afterScroller==undefined){return}var d=this.atExtremeBefore()?"addClass":"removeClass",c=this.atExtremeAfter()?"addClass":"removeClass",a=this.beforeScrollerCls+"-disabled",b=this.afterScrollerCls+"-disabled";this.beforeScroller[d](a);this.afterScroller[c](b);this.scrolling=false},atExtremeBefore:function(){return this.getScrollPosition()===0},scrollLeft:function(a){this.scrollBy(-this.scrollIncrement,a)},scrollRight:function(a){this.scrollBy(this.scrollIncrement,a)},scrollToItem:function(d,b){d=this.getItem(d);if(d!=undefined){var a=this.getItemVisibility(d);if(!a.fullyVisible){var c=d.getBox(true,true),e=c.x;if(a.hiddenRight){e-=(this.layout.innerCt.getWidth()-c.width)}this.scrollTo(e,b)}}},getItemVisibility:function(e){var d=this.getItem(e).getBox(true,true),a=d.x,c=d.x+d.width,g=this.getScrollPosition(),b=this.layout.innerCt.getWidth()+g;return{hiddenLeft:ab,fullyVisible:a>g&&c=this.getMaxScrollBottom()}});Ext.layout.boxOverflow.scroller.vbox=Ext.layout.boxOverflow.VerticalScroller;Ext.layout.boxOverflow.HorizontalScroller=Ext.extend(Ext.layout.boxOverflow.Scroller,{handleOverflow:function(a,b){Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this,arguments);return{targetSize:{height:b.height,width:b.width-(this.beforeCt.getWidth()+this.afterCt.getWidth())}}},createInnerElements:function(){var a=this.layout.innerCt;if(!this.beforeCt){this.afterCt=a.insertSibling({cls:this.afterCls},"before");this.beforeCt=a.insertSibling({cls:this.beforeCls},"before");this.createWheelListener()}},scrollTo:function(a,b){var d=this.getScrollPosition(),c=a.constrain(0,this.getMaxScrollRight());if(c!=d&&!this.scrolling){if(b==undefined){b=this.animateScroll}this.layout.innerCt.scrollTo("left",c,b?this.getScrollAnim():false);if(b){this.scrolling=true}else{this.scrolling=false;this.updateScrollButtons()}}},getScrollPosition:function(){return parseInt(this.layout.innerCt.dom.scrollLeft,10)||0},getMaxScrollRight:function(){return this.layout.innerCt.dom.scrollWidth-this.layout.innerCt.getWidth()},atExtremeAfter:function(){return this.getScrollPosition()>=this.getMaxScrollRight()}});Ext.layout.boxOverflow.scroller.hbox=Ext.layout.boxOverflow.HorizontalScroller;Ext.layout.HBoxLayout=Ext.extend(Ext.layout.BoxLayout,{align:"top",type:"hbox",calculateChildBoxes:function(r,b){var F=r.length,R=this.padding,D=R.top,U=R.left,y=D+R.bottom,O=U+R.right,a=b.width-this.scrollOffset,e=b.height,o=Math.max(0,e-y),P=this.pack=="start",W=this.pack=="center",A=this.pack=="end",L=0,Q=0,T=0,l=0,X=0,H=[],k,J,M,V,w,j,S,I,c,x,q,N;for(S=0;Sa;var n=Math.max(0,a-L-O);if(p){for(S=0;S0){var C=[];for(var E=0,v=F;Ei.available?1:-1});for(var S=0,v=C.length;S0){I.top=D+q+(z/2)}}U+=I.width+w.right}return{boxes:H,meta:{maxHeight:Q,nonFlexWidth:L,desiredWidth:l,minimumWidth:X,shortfall:l-a,tooNarrow:p}}}});Ext.Container.LAYOUTS.hbox=Ext.layout.HBoxLayout;Ext.layout.VBoxLayout=Ext.extend(Ext.layout.BoxLayout,{align:"left",type:"vbox",calculateChildBoxes:function(o,b){var E=o.length,R=this.padding,C=R.top,V=R.left,x=C+R.bottom,O=V+R.right,a=b.width-this.scrollOffset,c=b.height,K=Math.max(0,a-O),P=this.pack=="start",X=this.pack=="center",z=this.pack=="end",k=0,u=0,U=0,L=0,m=0,G=[],h,I,N,W,t,g,T,H,S,w,n,d,r;for(T=0;Tc;var q=Math.max(0,(c-k-x));if(l){for(T=0,r=E;T0){var J=[];for(var D=0,r=E;Di.available?1:-1});for(var T=0,r=J.length;T0){H.left=V+w+(y/2)}}C+=H.height+t.bottom}return{boxes:G,meta:{maxWidth:u,nonFlexHeight:k,desiredHeight:L,minimumHeight:m,shortfall:L-c,tooNarrow:l}}}});Ext.Container.LAYOUTS.vbox=Ext.layout.VBoxLayout;Ext.layout.ToolbarLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"toolbar",triggerWidth:18,noItemsMenuText:'
    (None)
    ',lastOverflow:false,tableHTML:['',"","",'",'","","","
    ','',"",'',"","
    ","
    ','',"","","","","","","
    ",'',"",'',"","
    ","
    ",'',"",'',"","
    ","
    ","
    "].join(""),onLayout:function(e,j){if(!this.leftTr){var h=e.buttonAlign=="center"?"center":"left";j.addClass("x-toolbar-layout-ct");j.insertHtml("beforeEnd",String.format(this.tableHTML,h));this.leftTr=j.child("tr.x-toolbar-left-row",true);this.rightTr=j.child("tr.x-toolbar-right-row",true);this.extrasTr=j.child("tr.x-toolbar-extras-row",true);if(this.hiddenItem==undefined){this.hiddenItems=[]}}var k=e.buttonAlign=="right"?this.rightTr:this.leftTr,l=e.items.items,d=0;for(var b=0,g=l.length,m;b=0&&(d=e[a]);a--){if(!d.firstChild){b.removeChild(d)}}},insertCell:function(e,b,a){var d=document.createElement("td");d.className="x-toolbar-cell";b.insertBefore(d,b.childNodes[a]||null);return d},hideItem:function(a){this.hiddenItems.push(a);a.xtbHidden=true;a.xtbWidth=a.getPositionEl().dom.parentNode.offsetWidth;a.hide()},unhideItem:function(a){a.show();a.xtbHidden=false;this.hiddenItems.remove(a)},getItemWidth:function(a){return a.hidden?(a.xtbWidth||0):a.getPositionEl().dom.parentNode.offsetWidth},fitToSize:function(k){if(this.container.enableOverflow===false){return}var b=k.dom.clientWidth,j=k.dom.firstChild.offsetWidth,m=b-this.triggerWidth,a=this.lastWidth||0,c=this.hiddenItems,e=c.length!=0,n=b>=a;this.lastWidth=b;if(j>b||(e&&n)){var l=this.container.items.items,h=l.length,d=0,o;for(var g=0;gm){if(!(o.hidden||o.xtbHidden)){this.hideItem(o)}}else{if(o.xtbHidden){this.unhideItem(o)}}}}}e=c.length!=0;if(e){this.initMore();if(!this.lastOverflow){this.container.fireEvent("overflowchange",this.container,true);this.lastOverflow=true}}else{if(this.more){this.clearMenu();this.more.destroy();delete this.more;if(this.lastOverflow){this.container.fireEvent("overflowchange",this.container,false);this.lastOverflow=false}}}},createMenuConfig:function(c,a){var b=Ext.apply({},c.initialConfig),d=c.toggleGroup;Ext.copyTo(b,c,["iconCls","icon","itemId","disabled","handler","scope","menu"]);Ext.apply(b,{text:c.overflowText||c.text,hideOnClick:a});if(d||c.enableToggle){Ext.apply(b,{group:d,checked:c.pressed,listeners:{checkchange:function(g,e){c.toggle(e)}}})}delete b.ownerCt;delete b.xtype;delete b.id;return b},addComponentToMenu:function(b,a){if(a instanceof Ext.Toolbar.Separator){b.add("-")}else{if(Ext.isFunction(a.isXType)){if(a.isXType("splitbutton")){b.add(this.createMenuConfig(a,true))}else{if(a.isXType("button")){b.add(this.createMenuConfig(a,!a.menu))}else{if(a.isXType("buttongroup")){a.items.each(function(c){this.addComponentToMenu(b,c)},this)}}}}}},clearMenu:function(){var a=this.moreMenu;if(a&&a.items){a.items.each(function(b){delete b.menu})}},beforeMoreShow:function(h){var b=this.container.items.items,a=b.length,g,e;var c=function(j,i){return j.isXType("buttongroup")&&!(i instanceof Ext.Toolbar.Separator)};this.clearMenu();h.removeAll();for(var d=0;d','','{altText}',"","")}if(g&&!g.rendered){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}var d=this.getItemArgs(g);g.render(g.positionEl=b?this.itemTpl.insertBefore(b,d,true):this.itemTpl.append(e,d,true));g.positionEl.menuItemId=g.getItemId();if(!d.isMenuItem&&d.needsIcon){g.positionEl.addClass("x-menu-list-item-indent")}this.configureItem(g)}else{if(g&&!this.isValidParent(g,e)){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}e.dom.insertBefore(g.getActionEl().dom,b||null)}}},getItemArgs:function(d){var a=d instanceof Ext.menu.Item,b=!(a||d instanceof Ext.menu.Separator);return{isMenuItem:a,needsIcon:b&&(d.icon||d.iconCls),icon:d.icon||Ext.BLANK_IMAGE_URL,iconCls:"x-menu-item-icon "+(d.iconCls||""),itemId:"x-menu-el-"+d.id,itemCls:"x-menu-list-item ",altText:d.altText||""}},isValidParent:function(b,a){return b.el.up("li.x-menu-list-item",5).dom.parentNode===(a.dom||a)},onLayout:function(a,b){Ext.layout.MenuLayout.superclass.onLayout.call(this,a,b);this.doAutoSize()},doAutoSize:function(){var c=this.container,a=c.width;if(c.floating){if(a){c.setWidth(a)}else{if(Ext.isIE9m){c.setWidth(Ext.isStrict&&(Ext.isIE7||Ext.isIE8||Ext.isIE9)?"auto":c.minWidth);var d=c.getEl(),b=d.dom.offsetWidth;c.setWidth(c.getLayoutTarget().getWidth()+d.getFrameWidth("lr"))}}}}});Ext.Container.LAYOUTS.menu=Ext.layout.MenuLayout;Ext.Viewport=Ext.extend(Ext.Container,{initComponent:function(){Ext.Viewport.superclass.initComponent.call(this);document.getElementsByTagName("html")[0].className+=" x-viewport";this.el=Ext.getBody();this.el.setHeight=Ext.emptyFn;this.el.setWidth=Ext.emptyFn;this.el.setSize=Ext.emptyFn;this.el.dom.scroll="no";this.allowDomMove=false;this.autoWidth=true;this.autoHeight=true;Ext.EventManager.onWindowResize(this.fireResize,this);this.renderTo=this.el},fireResize:function(a,b){this.fireEvent("resize",this,a,b,a,b)}});Ext.reg("viewport",Ext.Viewport);Ext.Panel=Ext.extend(Ext.Container,{baseCls:"x-panel",collapsedCls:"x-panel-collapsed",maskDisabled:true,animCollapse:Ext.enableFx,headerAsText:true,buttonAlign:"right",collapsed:false,collapseFirst:true,minButtonWidth:75,elements:"body",preventBodyReset:false,padding:undefined,resizeEvent:"bodyresize",toolTarget:"header",collapseEl:"bwrap",slideAnchor:"t",disabledClass:"",deferHeight:true,expandDefaults:{duration:0.25},collapseDefaults:{duration:0.25},initComponent:function(){Ext.Panel.superclass.initComponent.call(this);this.addEvents("bodyresize","titlechange","iconchange","collapse","expand","beforecollapse","beforeexpand","beforeclose","close","activate","deactivate");if(this.unstyled){this.baseCls="x-plain"}this.toolbars=[];if(this.tbar){this.elements+=",tbar";this.topToolbar=this.createToolbar(this.tbar);this.tbar=null}if(this.bbar){this.elements+=",bbar";this.bottomToolbar=this.createToolbar(this.bbar);this.bbar=null}if(this.header===true){this.elements+=",header";this.header=null}else{if(this.headerCfg||(this.title&&this.header!==false)){this.elements+=",header"}}if(this.footerCfg||this.footer===true){this.elements+=",footer";this.footer=null}if(this.buttons){this.fbar=this.buttons;this.buttons=null}if(this.fbar){this.createFbar(this.fbar)}if(this.autoLoad){this.on("render",this.doAutoLoad,this,{delay:10})}},createFbar:function(b){var a=this.minButtonWidth;this.elements+=",footer";this.fbar=this.createToolbar(b,{buttonAlign:this.buttonAlign,toolbarCls:"x-panel-fbar",enableOverflow:false,defaults:function(d){return{minWidth:d.minWidth||a}}});this.fbar.items.each(function(d){d.minWidth=d.minWidth||this.minButtonWidth},this);this.buttons=this.fbar.items.items},createToolbar:function(b,c){var a;if(Ext.isArray(b)){b={items:b}}a=b.events?Ext.apply(b,c):this.createComponent(Ext.apply({},b,c),"toolbar");this.toolbars.push(a);return a},createElement:function(a,c){if(this[a]){c.appendChild(this[a].dom);return}if(a==="bwrap"||this.elements.indexOf(a)!=-1){if(this[a+"Cfg"]){this[a]=Ext.fly(c).createChild(this[a+"Cfg"])}else{var b=document.createElement("div");b.className=this[a+"Cls"];this[a]=Ext.get(c.appendChild(b))}if(this[a+"CssClass"]){this[a].addClass(this[a+"CssClass"])}if(this[a+"Style"]){this[a].applyStyles(this[a+"Style"])}}},onRender:function(g,e){Ext.Panel.superclass.onRender.call(this,g,e);this.createClasses();var a=this.el,h=a.dom,k,i;if(this.collapsible&&!this.hideCollapseTool){this.tools=this.tools?this.tools.slice(0):[];this.tools[this.collapseFirst?"unshift":"push"]({id:"toggle",handler:this.toggleCollapse,scope:this})}if(this.tools){i=this.tools;this.elements+=(this.header!==false)?",header":""}this.tools={};a.addClass(this.baseCls);if(h.firstChild){this.header=a.down("."+this.headerCls);this.bwrap=a.down("."+this.bwrapCls);var j=this.bwrap?this.bwrap:a;this.tbar=j.down("."+this.tbarCls);this.body=j.down("."+this.bodyCls);this.bbar=j.down("."+this.bbarCls);this.footer=j.down("."+this.footerCls);this.fromMarkup=true}if(this.preventBodyReset===true){a.addClass("x-panel-reset")}if(this.cls){a.addClass(this.cls)}if(this.buttons){this.elements+=",footer"}if(this.frame){a.insertHtml("afterBegin",String.format(Ext.Element.boxMarkup,this.baseCls));this.createElement("header",h.firstChild.firstChild.firstChild);this.createElement("bwrap",h);k=this.bwrap.dom;var c=h.childNodes[1],b=h.childNodes[2];k.appendChild(c);k.appendChild(b);var l=k.firstChild.firstChild.firstChild;this.createElement("tbar",l);this.createElement("body",l);this.createElement("bbar",l);this.createElement("footer",k.lastChild.firstChild.firstChild);if(!this.footer){this.bwrap.dom.lastChild.className+=" x-panel-nofooter"}this.ft=Ext.get(this.bwrap.dom.lastChild);this.mc=Ext.get(l)}else{this.createElement("header",h);this.createElement("bwrap",h);k=this.bwrap.dom;this.createElement("tbar",k);this.createElement("body",k);this.createElement("bbar",k);this.createElement("footer",k);if(!this.header){this.body.addClass(this.bodyCls+"-noheader");if(this.tbar){this.tbar.addClass(this.tbarCls+"-noheader")}}}if(Ext.isDefined(this.padding)){this.body.setStyle("padding",this.body.addUnits(this.padding))}if(this.border===false){this.el.addClass(this.baseCls+"-noborder");this.body.addClass(this.bodyCls+"-noborder");if(this.header){this.header.addClass(this.headerCls+"-noborder")}if(this.footer){this.footer.addClass(this.footerCls+"-noborder")}if(this.tbar){this.tbar.addClass(this.tbarCls+"-noborder")}if(this.bbar){this.bbar.addClass(this.bbarCls+"-noborder")}}if(this.bodyBorder===false){this.body.addClass(this.bodyCls+"-noborder")}this.bwrap.enableDisplayMode("block");if(this.header){this.header.unselectable();if(this.headerAsText){this.header.dom.innerHTML=''+this.header.dom.innerHTML+"";if(this.iconCls){this.setIconClass(this.iconCls)}}}if(this.floating){this.makeFloating(this.floating)}if(this.collapsible&&this.titleCollapse&&this.header){this.mon(this.header,"click",this.toggleCollapse,this);this.header.setStyle("cursor","pointer")}if(i){this.addTool.apply(this,i)}if(this.fbar){this.footer.addClass("x-panel-btns");this.fbar.ownerCt=this;this.fbar.render(this.footer);this.footer.createChild({cls:"x-clear"})}if(this.tbar&&this.topToolbar){this.topToolbar.ownerCt=this;this.topToolbar.render(this.tbar)}if(this.bbar&&this.bottomToolbar){this.bottomToolbar.ownerCt=this;this.bottomToolbar.render(this.bbar)}},setIconClass:function(b){var a=this.iconCls;this.iconCls=b;if(this.rendered&&this.header){if(this.frame){this.header.addClass("x-panel-icon");this.header.replaceClass(a,this.iconCls)}else{var e=this.header,c=e.child("img.x-panel-inline-icon");if(c){Ext.fly(c).replaceClass(a,this.iconCls)}else{var d=e.child("span."+this.headerTextCls);if(d){Ext.DomHelper.insertBefore(d.dom,{tag:"img",alt:"",src:Ext.BLANK_IMAGE_URL,cls:"x-panel-inline-icon "+this.iconCls})}}}}this.fireEvent("iconchange",this,b,a)},makeFloating:function(a){this.floating=true;this.el=new Ext.Layer(Ext.apply({},a,{shadow:Ext.isDefined(this.shadow)?this.shadow:"sides",shadowOffset:this.shadowOffset,constrain:false,shim:this.shim===false?false:undefined}),this.el)},getTopToolbar:function(){return this.topToolbar},getBottomToolbar:function(){return this.bottomToolbar},getFooterToolbar:function(){return this.fbar},addButton:function(a,c,b){if(!this.fbar){this.createFbar([])}if(c){if(Ext.isString(a)){a={text:a}}a=Ext.apply({handler:c,scope:b},a)}return this.fbar.add(a)},addTool:function(){if(!this.rendered){if(!this.tools){this.tools=[]}Ext.each(arguments,function(a){this.tools.push(a)},this);return}if(!this[this.toolTarget]){return}if(!this.toolTemplate){var h=new Ext.Template('
     
    ');h.disableFormats=true;h.compile();Ext.Panel.prototype.toolTemplate=h}for(var g=0,d=arguments,c=d.length;g0){Ext.each(this.toolbars,function(c){c.doLayout(undefined,a)});this.syncHeight()}},syncHeight:function(){var b=this.toolbarHeight,c=this.body,a=this.lastSize.height,d;if(this.autoHeight||!Ext.isDefined(a)||a=="auto"){return}if(b!=this.getToolbarHeight()){b=Math.max(0,a-this.getFrameHeight());c.setHeight(b);d=c.getSize();this.toolbarHeight=this.getToolbarHeight();this.onBodyResize(d.width,d.height)}},onShow:function(){if(this.floating){return this.el.show()}Ext.Panel.superclass.onShow.call(this)},onHide:function(){if(this.floating){return this.el.hide()}Ext.Panel.superclass.onHide.call(this)},createToolHandler:function(c,a,d,b){return function(g){c.removeClass(d);if(a.stopEvent!==false){g.stopEvent()}if(a.handler){a.handler.call(a.scope||c,g,c,b,a)}}},afterRender:function(){if(this.floating&&!this.hidden){this.el.show()}if(this.title){this.setTitle(this.title)}Ext.Panel.superclass.afterRender.call(this);if(this.collapsed){this.collapsed=false;this.collapse(false)}this.initEvents()},getKeyMap:function(){if(!this.keyMap){this.keyMap=new Ext.KeyMap(this.el,this.keys)}return this.keyMap},initEvents:function(){if(this.keys){this.getKeyMap()}if(this.draggable){this.initDraggable()}if(this.toolbars.length>0){Ext.each(this.toolbars,function(a){a.doLayout();a.on({scope:this,afterlayout:this.syncHeight,remove:this.syncHeight})},this);this.syncHeight()}},initDraggable:function(){this.dd=new Ext.Panel.DD(this,Ext.isBoolean(this.draggable)?null:this.draggable)},beforeEffect:function(a){if(this.floating){this.el.beforeAction()}if(a!==false){this.el.addClass("x-panel-animated")}},afterEffect:function(a){this.syncShadow();this.el.removeClass("x-panel-animated")},createEffect:function(c,b,d){var e={scope:d,block:true};if(c===true){e.callback=b;return e}else{if(!c.callback){e.callback=b}else{e.callback=function(){b.call(d);Ext.callback(c.callback,c.scope)}}}return Ext.applyIf(e,c)},collapse:function(b){if(this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforecollapse",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.beforeEffect(a);this.onCollapse(a,b);return this},onCollapse:function(a,b){if(a){this[this.collapseEl].slideOut(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterCollapse,this),this.collapseDefaults))}else{this[this.collapseEl].hide(this.hideMode);this.afterCollapse(false)}},afterCollapse:function(a){this.collapsed=true;this.el.addClass(this.collapsedCls);if(a!==false){this[this.collapseEl].hide(this.hideMode)}this.afterEffect(a);this.cascade(function(b){if(b.lastSize){b.lastSize={width:undefined,height:undefined}}});this.fireEvent("collapse",this)},expand:function(b){if(!this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforeexpand",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.el.removeClass(this.collapsedCls);this.beforeEffect(a);this.onExpand(a,b);return this},onExpand:function(a,b){if(a){this[this.collapseEl].slideIn(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterExpand,this),this.expandDefaults))}else{this[this.collapseEl].show(this.hideMode);this.afterExpand(false)}},afterExpand:function(a){this.collapsed=false;if(a!==false){this[this.collapseEl].show(this.hideMode)}this.afterEffect(a);if(this.deferLayout){delete this.deferLayout;this.doLayout(true)}this.fireEvent("expand",this)},toggleCollapse:function(a){this[this.collapsed?"expand":"collapse"](a);return this},onDisable:function(){if(this.rendered&&this.maskDisabled){this.el.mask()}Ext.Panel.superclass.onDisable.call(this)},onEnable:function(){if(this.rendered&&this.maskDisabled){this.el.unmask()}Ext.Panel.superclass.onEnable.call(this)},onResize:function(g,d,c,e){var a=g,b=d;if(Ext.isDefined(a)||Ext.isDefined(b)){if(!this.collapsed){if(Ext.isNumber(a)){this.body.setWidth(a=this.adjustBodyWidth(a-this.getFrameWidth()))}else{if(a=="auto"){a=this.body.setWidth("auto").dom.offsetWidth}else{a=this.body.dom.offsetWidth}}if(this.tbar){this.tbar.setWidth(a);if(this.topToolbar){this.topToolbar.setSize(a)}}if(this.bbar){this.bbar.setWidth(a);if(this.bottomToolbar){this.bottomToolbar.setSize(a);if(Ext.isIE9m){this.bbar.setStyle("position","static");this.bbar.setStyle("position","")}}}if(this.footer){this.footer.setWidth(a);if(this.fbar){this.fbar.setSize(Ext.isIE9m?(a-this.footer.getFrameWidth("lr")):"auto")}}if(Ext.isNumber(b)){b=Math.max(0,b-this.getFrameHeight());this.body.setHeight(b)}else{if(b=="auto"){this.body.setHeight(b)}}if(this.disabled&&this.el._mask){this.el._mask.setSize(this.el.dom.clientWidth,this.el.getHeight())}}else{this.queuedBodySize={width:a,height:b};if(!this.queuedExpand&&this.allowQueuedExpand!==false){this.queuedExpand=true;this.on("expand",function(){delete this.queuedExpand;this.onResize(this.queuedBodySize.width,this.queuedBodySize.height)},this,{single:true})}}this.onBodyResize(a,b)}this.syncShadow();Ext.Panel.superclass.onResize.call(this,g,d,c,e)},onBodyResize:function(a,b){this.fireEvent("bodyresize",this,a,b)},getToolbarHeight:function(){var a=0;if(this.rendered){Ext.each(this.toolbars,function(b){a+=b.getHeight()},this)}return a},adjustBodyHeight:function(a){return a},adjustBodyWidth:function(a){return a},onPosition:function(){this.syncShadow()},getFrameWidth:function(){var b=this.el.getFrameWidth("lr")+this.bwrap.getFrameWidth("lr");if(this.frame){var a=this.bwrap.dom.firstChild;b+=(Ext.fly(a).getFrameWidth("l")+Ext.fly(a.firstChild).getFrameWidth("r"));b+=this.mc.getFrameWidth("lr")}return b},getFrameHeight:function(){var a=this.el.getFrameWidth("tb")+this.bwrap.getFrameWidth("tb");a+=(this.tbar?this.tbar.getHeight():0)+(this.bbar?this.bbar.getHeight():0);if(this.frame){a+=this.el.dom.firstChild.offsetHeight+this.ft.dom.offsetHeight+this.mc.getFrameWidth("tb")}else{a+=(this.header?this.header.getHeight():0)+(this.footer?this.footer.getHeight():0)}return a},getInnerWidth:function(){return this.getSize().width-this.getFrameWidth()},getInnerHeight:function(){return this.body.getHeight()},syncShadow:function(){if(this.floating){this.el.sync(true)}},getLayoutTarget:function(){return this.body},getContentTarget:function(){return this.body},setTitle:function(b,a){this.title=b;if(this.header&&this.headerAsText){this.header.child("span").update(b)}if(a){this.setIconClass(a)}this.fireEvent("titlechange",this,b);return this},getUpdater:function(){return this.body.getUpdater()},load:function(){var a=this.body.getUpdater();a.update.apply(a,arguments);return this},beforeDestroy:function(){Ext.Panel.superclass.beforeDestroy.call(this);if(this.header){this.header.removeAllListeners()}if(this.tools){for(var a in this.tools){Ext.destroy(this.tools[a])}}if(this.toolbars.length>0){Ext.each(this.toolbars,function(b){b.un("afterlayout",this.syncHeight,this);b.un("remove",this.syncHeight,this)},this)}if(Ext.isArray(this.buttons)){while(this.buttons.length){Ext.destroy(this.buttons[0])}}if(this.rendered){Ext.destroy(this.ft,this.header,this.footer,this.tbar,this.bbar,this.body,this.mc,this.bwrap,this.dd);if(this.fbar){Ext.destroy(this.fbar,this.fbar.el)}}Ext.destroy(this.toolbars)},createClasses:function(){this.headerCls=this.baseCls+"-header";this.headerTextCls=this.baseCls+"-header-text";this.bwrapCls=this.baseCls+"-bwrap";this.tbarCls=this.baseCls+"-tbar";this.bodyCls=this.baseCls+"-body";this.bbarCls=this.baseCls+"-bbar";this.footerCls=this.baseCls+"-footer"},createGhost:function(a,e,b){var d=document.createElement("div");d.className="x-panel-ghost "+(a?a:"");if(this.header){d.appendChild(this.el.dom.firstChild.cloneNode(true))}Ext.fly(d.appendChild(document.createElement("ul"))).setHeight(this.bwrap.getHeight());d.style.width=this.el.dom.offsetWidth+"px";if(!b){this.container.dom.appendChild(d)}else{Ext.getDom(b).appendChild(d)}if(e!==false&&this.el.useShim!==false){var c=new Ext.Layer({shadow:false,useDisplay:true,constrain:false},d);c.show();return c}else{return new Ext.Element(d)}},doAutoLoad:function(){var a=this.body.getUpdater();if(this.renderer){a.setRenderer(this.renderer)}a.update(Ext.isObject(this.autoLoad)?this.autoLoad:{url:this.autoLoad})},getTool:function(a){return this.tools[a]}});Ext.reg("panel",Ext.Panel);Ext.Editor=function(b,a){if(b.field){this.field=Ext.create(b.field,"textfield");a=Ext.apply({},b);delete a.field}else{this.field=b}Ext.Editor.superclass.constructor.call(this,a)};Ext.extend(Ext.Editor,Ext.Component,{allowBlur:true,value:"",alignment:"c-c?",offsets:[0,0],shadow:"frame",constrain:false,swallowKeys:true,completeOnEnter:true,cancelOnEsc:true,updateEl:false,initComponent:function(){Ext.Editor.superclass.initComponent.call(this);this.addEvents("beforestartedit","startedit","beforecomplete","complete","canceledit","specialkey")},onRender:function(b,a){this.el=new Ext.Layer({shadow:this.shadow,cls:"x-editor",parentEl:b,shim:this.shim,shadowOffset:this.shadowOffset||4,id:this.id,constrain:this.constrain});if(this.zIndex){this.el.setZIndex(this.zIndex)}this.el.setStyle("overflow",Ext.isGecko?"auto":"hidden");if(this.field.msgTarget!="title"){this.field.msgTarget="qtip"}this.field.inEditor=true;this.mon(this.field,{scope:this,blur:this.onBlur,specialkey:this.onSpecialKey});if(this.field.grow){this.mon(this.field,"autosize",this.el.sync,this.el,{delay:1})}this.field.render(this.el).show();this.field.getEl().dom.name="";if(this.swallowKeys){this.field.el.swallowEvent(["keypress","keydown"])}},onSpecialKey:function(g,d){var b=d.getKey(),a=this.completeOnEnter&&b==d.ENTER,c=this.cancelOnEsc&&b==d.ESC;if(a||c){d.stopEvent();if(a){this.completeEdit()}else{this.cancelEdit()}if(g.triggerBlur){g.triggerBlur()}}this.fireEvent("specialkey",g,d)},startEdit:function(b,c){if(this.editing){this.completeEdit()}this.boundEl=Ext.get(b);var a=c!==undefined?c:this.boundEl.dom.innerHTML;if(!this.rendered){this.render(this.parentEl||document.body)}if(this.fireEvent("beforestartedit",this,this.boundEl,a)!==false){this.startValue=a;this.field.reset();this.field.setValue(a);this.realign(true);this.editing=true;this.show()}},doAutoSize:function(){if(this.autoSize){var b=this.boundEl.getSize(),a=this.field.getSize();switch(this.autoSize){case"width":this.setSize(b.width,a.height);break;case"height":this.setSize(a.width,b.height);break;case"none":this.setSize(a.width,a.height);break;default:this.setSize(b.width,b.height)}}},setSize:function(a,b){delete this.field.lastSize;this.field.setSize(a,b);if(this.el){if(Ext.isGecko2||Ext.isOpera||(Ext.isIE7&&Ext.isStrict)){this.el.setSize(a,b)}this.el.sync()}},realign:function(a){if(a===true){this.doAutoSize()}this.el.alignTo(this.boundEl,this.alignment,this.offsets)},completeEdit:function(a){if(!this.editing){return}if(this.field.assertValue){this.field.assertValue()}var b=this.getValue();if(!this.field.isValid()){if(this.revertInvalid!==false){this.cancelEdit(a)}return}if(String(b)===String(this.startValue)&&this.ignoreNoChange){this.hideEdit(a);return}if(this.fireEvent("beforecomplete",this,b,this.startValue)!==false){b=this.getValue();if(this.updateEl&&this.boundEl){this.boundEl.update(b)}this.hideEdit(a);this.fireEvent("complete",this,b,this.startValue)}},onShow:function(){this.el.show();if(this.hideEl!==false){this.boundEl.hide()}this.field.show().focus(false,true);this.fireEvent("startedit",this.boundEl,this.startValue)},cancelEdit:function(a){if(this.editing){var b=this.getValue();this.setValue(this.startValue);this.hideEdit(a);this.fireEvent("canceledit",this,b,this.startValue)}},hideEdit:function(a){if(a!==true){this.editing=false;this.hide()}},onBlur:function(){if(this.allowBlur===true&&this.editing&&this.selectSameEditor!==true){this.completeEdit()}},onHide:function(){if(this.editing){this.completeEdit();return}this.field.blur();if(this.field.collapse){this.field.collapse()}this.el.hide();if(this.hideEl!==false){this.boundEl.show()}},setValue:function(a){this.field.setValue(a)},getValue:function(){return this.field.getValue()},beforeDestroy:function(){Ext.destroyMembers(this,"field");delete this.parentEl;delete this.boundEl}});Ext.reg("editor",Ext.Editor);Ext.ColorPalette=Ext.extend(Ext.Component,{itemCls:"x-color-palette",value:null,clickEvent:"click",ctype:"Ext.ColorPalette",allowReselect:false,colors:["000000","993300","333300","003300","003366","000080","333399","333333","800000","FF6600","808000","008000","008080","0000FF","666699","808080","FF0000","FF9900","99CC00","339966","33CCCC","3366FF","800080","969696","FF00FF","FFCC00","FFFF00","00FF00","00FFFF","00CCFF","993366","C0C0C0","FF99CC","FFCC99","FFFF99","CCFFCC","CCFFFF","99CCFF","CC99FF","FFFFFF"],initComponent:function(){Ext.ColorPalette.superclass.initComponent.call(this);this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope,true)}},onRender:function(b,a){this.autoEl={tag:"div",cls:this.itemCls};Ext.ColorPalette.superclass.onRender.call(this,b,a);var c=this.tpl||new Ext.XTemplate(' ');c.overwrite(this.el,this.colors);this.mon(this.el,this.clickEvent,this.handleClick,this,{delegate:"a"});if(this.clickEvent!="click"){this.mon(this.el,"click",Ext.emptyFn,this,{delegate:"a",preventDefault:true})}},afterRender:function(){Ext.ColorPalette.superclass.afterRender.call(this);if(this.value){var a=this.value;this.value=null;this.select(a,true)}},handleClick:function(b,a){b.preventDefault();if(!this.disabled){var d=a.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];this.select(d.toUpperCase())}},select:function(b,a){b=b.replace("#","");if(b!=this.value||this.allowReselect){var c=this.el;if(this.value){c.child("a.color-"+this.value).removeClass("x-color-palette-sel")}c.child("a.color-"+b).addClass("x-color-palette-sel");this.value=b;if(a!==true){this.fireEvent("select",this,b)}}}});Ext.reg("colorpalette",Ext.ColorPalette);Ext.DatePicker=Ext.extend(Ext.BoxComponent,{todayText:"Today",okText:" OK ",cancelText:"Cancel",todayTip:"{0} (Spacebar)",minText:"This date is before the minimum date",maxText:"This date is after the maximum date",format:"m/d/y",disabledDaysText:"Disabled",disabledDatesText:"Disabled",monthNames:Date.monthNames,dayNames:Date.dayNames,nextText:"Next Month (Control+Right)",prevText:"Previous Month (Control+Left)",monthYearText:"Choose a month (Control+Up/Down to move years)",startDay:0,showToday:true,focusOnSelect:true,initHour:12,initComponent:function(){Ext.DatePicker.superclass.initComponent.call(this);this.value=this.value?this.value.clearTime(true):new Date().clearTime();this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope||this)}this.initDisabledDays()},initDisabledDays:function(){if(!this.disabledDatesRE&&this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){if(Ext.isArray(a)){this.disabledDates=a;this.disabledDatesRE=null}else{this.disabledDatesRE=a}this.initDisabledDays();this.update(this.value,true)},setDisabledDays:function(a){this.disabledDays=a;this.update(this.value,true)},setMinDate:function(a){this.minDate=a;this.update(this.value,true)},setMaxDate:function(a){this.maxDate=a;this.update(this.value,true)},setValue:function(a){this.value=a.clearTime(true);this.update(this.value)},getValue:function(){return this.value},focus:function(){this.update(this.activeDate)},onEnable:function(a){Ext.DatePicker.superclass.onEnable.call(this);this.doDisabled(false);this.update(a?this.value:this.activeDate);if(Ext.isIE9m){this.el.repaint()}},onDisable:function(){Ext.DatePicker.superclass.onDisable.call(this);this.doDisabled(true);if(Ext.isIE9m&&!Ext.isIE8){Ext.each([].concat(this.textNodes,this.el.query("th span")),function(a){Ext.fly(a).repaint()})}},doDisabled:function(a){this.keyNav.setDisabled(a);this.prevRepeater.setDisabled(a);this.nextRepeater.setDisabled(a);if(this.showToday){this.todayKeyListener.setDisabled(a);this.todayBtn.setDisabled(a)}},onRender:function(e,b){var a=['','','",this.showToday?'':"",'
      
    '],c=this.dayNames,h;for(h=0;h<7;h++){var k=this.startDay+h;if(k>6){k=k-7}a.push("")}a[a.length]="";for(h=0;h<42;h++){if(h%7===0&&h!==0){a[a.length]=""}a[a.length]=''}a.push("
    ",c[k].substr(0,1),"
    ');var j=document.createElement("div");j.className="x-date-picker";j.innerHTML=a.join("");e.dom.insertBefore(j,b);this.el=Ext.get(j);this.eventEl=Ext.get(j.firstChild);this.prevRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"),{handler:this.showPrevMonth,scope:this,preventDefault:true,stopDefault:true});this.nextRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"),{handler:this.showNextMonth,scope:this,preventDefault:true,stopDefault:true});this.monthPicker=this.el.down("div.x-date-mp");this.monthPicker.enableDisplayMode("block");this.keyNav=new Ext.KeyNav(this.eventEl,{left:function(d){if(d.ctrlKey){this.showPrevMonth()}else{this.update(this.activeDate.add("d",-1))}},right:function(d){if(d.ctrlKey){this.showNextMonth()}else{this.update(this.activeDate.add("d",1))}},up:function(d){if(d.ctrlKey){this.showNextYear()}else{this.update(this.activeDate.add("d",-7))}},down:function(d){if(d.ctrlKey){this.showPrevYear()}else{this.update(this.activeDate.add("d",7))}},pageUp:function(d){this.showNextMonth()},pageDown:function(d){this.showPrevMonth()},enter:function(d){d.stopPropagation();return true},scope:this});this.el.unselectable();this.cells=this.el.select("table.x-date-inner tbody td");this.textNodes=this.el.query("table.x-date-inner tbody span");this.mbtn=new Ext.Button({text:" ",tooltip:this.monthYearText,renderTo:this.el.child("td.x-date-middle",true)});this.mbtn.el.child("em").addClass("x-btn-arrow");if(this.showToday){this.todayKeyListener=this.eventEl.addKeyListener(Ext.EventObject.SPACE,this.selectToday,this);var g=(new Date()).dateFormat(this.format);this.todayBtn=new Ext.Button({renderTo:this.el.child("td.x-date-bottom",true),text:String.format(this.todayText,g),tooltip:String.format(this.todayTip,g),handler:this.selectToday,scope:this})}this.mon(this.eventEl,"mousewheel",this.handleMouseWheel,this);this.mon(this.eventEl,"click",this.handleDateClick,this,{delegate:"a.x-date-date"});this.mon(this.mbtn,"click",this.showMonthPicker,this);this.onEnable(true)},createMonthPicker:function(){if(!this.monthPicker.dom.firstChild){var a=[''];for(var b=0;b<6;b++){a.push('",'",b===0?'':'')}a.push('","
    ',Date.getShortMonthName(b),"',Date.getShortMonthName(b+6),"
    ");this.monthPicker.update(a.join(""));this.mon(this.monthPicker,"click",this.onMonthClick,this);this.mon(this.monthPicker,"dblclick",this.onMonthDblClick,this);this.mpMonths=this.monthPicker.select("td.x-date-mp-month");this.mpYears=this.monthPicker.select("td.x-date-mp-year");this.mpMonths.each(function(c,d,e){e+=1;if((e%2)===0){c.dom.xmonth=5+Math.round(e*0.5)}else{c.dom.xmonth=Math.round((e-1)*0.5)}})}},showMonthPicker:function(){if(!this.disabled){this.createMonthPicker();var a=this.el.getSize();this.monthPicker.setSize(a);this.monthPicker.child("table").setSize(a);this.mpSelMonth=(this.activeDate||this.value).getMonth();this.updateMPMonth(this.mpSelMonth);this.mpSelYear=(this.activeDate||this.value).getFullYear();this.updateMPYear(this.mpSelYear);this.monthPicker.slideIn("t",{duration:0.2})}},updateMPYear:function(e){this.mpyear=e;var c=this.mpYears.elements;for(var b=1;b<=10;b++){var d=c[b-1],a;if((b%2)===0){a=e+Math.round(b*0.5);d.firstChild.innerHTML=a;d.xyear=a}else{a=e-(5-Math.round(b*0.5));d.firstChild.innerHTML=a;d.xyear=a}this.mpYears.item(b-1)[a==this.mpSelYear?"addClass":"removeClass"]("x-date-mp-sel")}},updateMPMonth:function(a){this.mpMonths.each(function(b,c,d){b[b.dom.xmonth==a?"addClass":"removeClass"]("x-date-mp-sel")})},selectMPMonth:function(a){},onMonthClick:function(g,b){g.stopEvent();var c=new Ext.Element(b),a;if(c.is("button.x-date-mp-cancel")){this.hideMonthPicker()}else{if(c.is("button.x-date-mp-ok")){var h=new Date(this.mpSelYear,this.mpSelMonth,(this.activeDate||this.value).getDate());if(h.getMonth()!=this.mpSelMonth){h=new Date(this.mpSelYear,this.mpSelMonth,1).getLastDateOfMonth()}this.update(h);this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-month",2))){this.mpMonths.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelMonth=a.dom.xmonth}else{if((a=c.up("td.x-date-mp-year",2))){this.mpYears.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelYear=a.dom.xyear}else{if(c.is("a.x-date-mp-prev")){this.updateMPYear(this.mpyear-10)}else{if(c.is("a.x-date-mp-next")){this.updateMPYear(this.mpyear+10)}}}}}}},onMonthDblClick:function(d,b){d.stopEvent();var c=new Ext.Element(b),a;if((a=c.up("td.x-date-mp-month",2))){this.update(new Date(this.mpSelYear,a.dom.xmonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-year",2))){this.update(new Date(a.dom.xyear,this.mpSelMonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}}},hideMonthPicker:function(a){if(this.monthPicker){if(a===true){this.monthPicker.hide()}else{this.monthPicker.slideOut("t",{duration:0.2})}}},showPrevMonth:function(a){this.update(this.activeDate.add("mo",-1))},showNextMonth:function(a){this.update(this.activeDate.add("mo",1))},showPrevYear:function(){this.update(this.activeDate.add("y",-1))},showNextYear:function(){this.update(this.activeDate.add("y",1))},handleMouseWheel:function(a){a.stopEvent();if(!this.disabled){var b=a.getWheelDelta();if(b>0){this.showPrevMonth()}else{if(b<0){this.showNextMonth()}}}},handleDateClick:function(b,a){b.stopEvent();if(!this.disabled&&a.dateValue&&!Ext.fly(a.parentNode).hasClass("x-date-disabled")){this.cancelFocus=this.focusOnSelect===false;this.setValue(new Date(a.dateValue));delete this.cancelFocus;this.fireEvent("select",this,this.value)}},selectToday:function(){if(this.todayBtn&&!this.todayBtn.disabled){this.setValue(new Date().clearTime());this.fireEvent("select",this,this.value)}},update:function(G,A){if(this.rendered){var a=this.activeDate,p=this.isVisible();this.activeDate=G;if(!A&&a&&this.el){var o=G.getTime();if(a.getMonth()==G.getMonth()&&a.getFullYear()==G.getFullYear()){this.cells.removeClass("x-date-selected");this.cells.each(function(d){if(d.dom.firstChild.dateValue==o){d.addClass("x-date-selected");if(p&&!this.cancelFocus){Ext.fly(d.dom.firstChild).focus(50)}return false}},this);return}}var k=G.getDaysInMonth(),q=G.getFirstDateOfMonth(),g=q.getDay()-this.startDay;if(g<0){g+=7}k+=g;var B=G.add("mo",-1),h=B.getDaysInMonth()-g,e=this.cells.elements,r=this.textNodes,D=(new Date(B.getFullYear(),B.getMonth(),h,this.initHour)),C=new Date().clearTime().getTime(),v=G.clearTime(true).getTime(),u=this.minDate?this.minDate.clearTime(true):Number.NEGATIVE_INFINITY,y=this.maxDate?this.maxDate.clearTime(true):Number.POSITIVE_INFINITY,F=this.disabledDatesRE,s=this.disabledDatesText,I=this.disabledDays?this.disabledDays.join(""):false,E=this.disabledDaysText,z=this.format;if(this.showToday){var m=new Date().clearTime(),c=(my||(F&&z&&F.test(m.dateFormat(z)))||(I&&I.indexOf(m.getDay())!=-1));if(!this.disabled){this.todayBtn.setDisabled(c);this.todayKeyListener[c?"disable":"enable"]()}}var l=function(J,d){d.title="";var i=D.clearTime(true).getTime();d.firstChild.dateValue=i;if(i==C){d.className+=" x-date-today";d.title=J.todayText}if(i==v){d.className+=" x-date-selected";if(p){Ext.fly(d.firstChild).focus(50)}}if(iy){d.className=" x-date-disabled";d.title=J.maxText;return}if(I){if(I.indexOf(D.getDay())!=-1){d.title=E;d.className=" x-date-disabled"}}if(F&&z){var w=D.dateFormat(z);if(F.test(w)){d.title=s.replace("%0",w);d.className=" x-date-disabled"}}};var x=0;for(;x=a.value){d=a.value}}c.setValue(b,d,false);c.fireEvent("drag",c,g,this)},getNewValue:function(){var a=this.slider,b=a.innerEl.translatePoints(this.tracker.getXY());return Ext.util.Format.round(a.reverseValue(b.left),a.decimalPrecision)},onDragEnd:function(c){var a=this.slider,b=this.value;this.el.removeClass("x-slider-thumb-drag");this.dragging=false;a.fireEvent("dragend",a,c);if(this.dragStartValue!=b){a.fireEvent("changecomplete",a,b,this)}},destroy:function(){Ext.destroyMembers(this,"tracker","el")}});Ext.slider.MultiSlider=Ext.extend(Ext.BoxComponent,{vertical:false,minValue:0,maxValue:100,decimalPrecision:0,keyIncrement:1,increment:0,clickRange:[5,15],clickToChange:true,animate:true,constrainThumbs:true,topThumbZIndex:10000,initComponent:function(){if(!Ext.isDefined(this.value)){this.value=this.minValue}this.thumbs=[];Ext.slider.MultiSlider.superclass.initComponent.call(this);this.keyIncrement=Math.max(this.increment,this.keyIncrement);this.addEvents("beforechange","change","changecomplete","dragstart","drag","dragend");if(this.values==undefined||Ext.isEmpty(this.values)){this.values=[0]}var a=this.values;for(var b=0;bthis.clickRange[0]&&c.top=c){d+=c}else{if(a*2<-c){d-=c}}}return d.constrain(this.minValue,this.maxValue)},afterRender:function(){Ext.slider.MultiSlider.superclass.afterRender.apply(this,arguments);for(var c=0;ce?e:c.value}this.syncThumb()},setValue:function(d,c,b,g){var a=this.thumbs[d],e=a.el;c=this.normalizeValue(c);if(c!==a.value&&this.fireEvent("beforechange",this,c,a.value,a)!==false){a.value=c;if(this.rendered){this.moveThumb(d,this.translateValue(c),b!==false);this.fireEvent("change",this,c,a);if(g){this.fireEvent("changecomplete",this,c,a)}}}},translateValue:function(a){var b=this.getRatio();return(a*b)-(this.minValue*b)-this.halfThumb},reverseValue:function(b){var a=this.getRatio();return(b+(this.minValue*a))/a},moveThumb:function(d,c,b){var a=this.thumbs[d].el;if(!b||this.animate===false){a.setLeft(c)}else{a.shift({left:c,stopFx:true,duration:0.35})}},focus:function(){this.focusEl.focus(10)},onResize:function(c,e){var b=this.thumbs,a=b.length,d=0;for(;dthis.clickRange[0]&&c.left','
    ','
    ','
    ',"
     
    ","
    ","
    ",'
    ',"
     
    ","
    ","
    ","");this.el=a?c.insertBefore(a,{cls:this.baseCls},true):c.append(d,{cls:this.baseCls},true);if(this.id){this.el.dom.id=this.id}var b=this.el.dom.firstChild;this.progressBar=Ext.get(b.firstChild);if(this.textEl){this.textEl=Ext.get(this.textEl);delete this.textTopEl}else{this.textTopEl=Ext.get(this.progressBar.dom.firstChild);var e=Ext.get(b.childNodes[1]);this.textTopEl.setStyle("z-index",99).addClass("x-hidden");this.textEl=new Ext.CompositeElement([this.textTopEl.dom.firstChild,e.dom.firstChild]);this.textEl.setWidth(b.offsetWidth)}this.progressBar.setHeight(b.offsetHeight)},afterRender:function(){Ext.ProgressBar.superclass.afterRender.call(this);if(this.value){this.updateProgress(this.value,this.text)}else{this.updateText(this.text)}},updateProgress:function(c,d,b){this.value=c||0;if(d){this.updateText(d)}if(this.rendered&&!this.isDestroyed){var a=Math.floor(c*this.el.dom.firstChild.offsetWidth);this.progressBar.setWidth(a,b===true||(b!==false&&this.animate));if(this.textTopEl){this.textTopEl.removeClass("x-hidden").setWidth(a)}}this.fireEvent("update",this,c,d);return this},wait:function(b){if(!this.waitTimer){var a=this;b=b||{};this.updateText(b.text);this.waitTimer=Ext.TaskMgr.start({run:function(c){var d=b.increment||10;c-=1;this.updateProgress(((((c+d)%d)+1)*(100/d))*0.01,null,b.animate)},interval:b.interval||1000,duration:b.duration,onStop:function(){if(b.fn){b.fn.apply(b.scope||this)}this.reset()},scope:a})}return this},isWaiting:function(){return this.waitTimer!==null},updateText:function(a){this.text=a||" ";if(this.rendered){this.textEl.update(this.text)}return this},syncProgressBar:function(){if(this.value){this.updateProgress(this.value,this.text)}return this},setSize:function(a,c){Ext.ProgressBar.superclass.setSize.call(this,a,c);if(this.textTopEl){var b=this.el.dom.firstChild;this.textEl.setSize(b.offsetWidth,b.offsetHeight)}this.syncProgressBar();return this},reset:function(a){this.updateProgress(0);if(this.textTopEl){this.textTopEl.addClass("x-hidden")}this.clearTimer();if(a===true){this.hide()}return this},clearTimer:function(){if(this.waitTimer){this.waitTimer.onStop=null;Ext.TaskMgr.stop(this.waitTimer);this.waitTimer=null}},onDestroy:function(){this.clearTimer();if(this.rendered){if(this.textEl.isComposite){this.textEl.clear()}Ext.destroyMembers(this,"textEl","progressBar","textTopEl")}Ext.ProgressBar.superclass.onDestroy.call(this)}});Ext.reg("progress",Ext.ProgressBar);(function(){var a=Ext.EventManager;var b=Ext.lib.Dom;Ext.dd.DragDrop=function(e,c,d){if(e){this.init(e,c,d)}};Ext.dd.DragDrop.prototype={id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true},moveOnly:false,unlock:function(){this.locked=false},isTarget:true,padding:null,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,b4StartDrag:function(c,d){},startDrag:function(c,d){},b4Drag:function(c){},onDrag:function(c){},onDragEnter:function(c,d){},b4DragOver:function(c){},onDragOver:function(c,d){},b4DragOut:function(c){},onDragOut:function(c,d){},b4DragDrop:function(c){},onDragDrop:function(c,d){},onInvalidDrop:function(c){},b4EndDrag:function(c){},endDrag:function(c){},b4MouseDown:function(c){},onMouseDown:function(c){},onMouseUp:function(c){},onAvailable:function(){},defaultPadding:{left:0,right:0,top:0,bottom:0},constrainTo:function(j,h,o){if(Ext.isNumber(h)){h={left:h,right:h,top:h,bottom:h}}h=h||this.defaultPadding;var l=Ext.get(this.getEl()).getBox(),d=Ext.get(j),n=d.getScroll(),k,e=d.dom;if(e==document.body){k={x:n.left,y:n.top,width:Ext.lib.Dom.getViewWidth(),height:Ext.lib.Dom.getViewHeight()}}else{var m=d.getXY();k={x:m[0],y:m[1],width:e.clientWidth,height:e.clientHeight}}var i=l.y-k.y,g=l.x-k.x;this.resetConstraints();this.setXConstraint(g-(h.left||0),k.width-g-l.width-(h.right||0),this.xTickSize);this.setYConstraint(i-(h.top||0),k.height-i-l.height-(h.bottom||0),this.yTickSize)},getEl:function(){if(!this._domRef){this._domRef=Ext.getDom(this.id)}return this._domRef},getDragEl:function(){return Ext.getDom(this.dragElId)},init:function(e,c,d){this.initTarget(e,c,d);a.on(this.id,"mousedown",this.handleMouseDown,this)},initTarget:function(e,c,d){this.config=d||{};this.DDM=Ext.dd.DDM;this.groups={};if(typeof e!=="string"){e=Ext.id(e)}this.id=e;this.addToGroup((c)?c:"default");this.handleElId=e;this.setDragElId(e);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();this.handleOnAvailable()},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false)},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable()},setPadding:function(e,c,g,d){if(!c&&0!==c){this.padding=[e,e,e,e]}else{if(!g&&0!==g){this.padding=[e,c,e,c]}else{this.padding=[e,c,g,d]}}},setInitPosition:function(g,e){var h=this.getEl();if(!this.DDM.verifyEl(h)){return}var d=g||0;var c=e||0;var i=b.getXY(h);this.initPageX=i[0]-d;this.initPageY=i[1]-c;this.lastPageX=i[0];this.lastPageY=i[1];this.setStartPosition(i)},setStartPosition:function(d){var c=d||b.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=c[0];this.startPageY=c[1]},addToGroup:function(c){this.groups[c]=true;this.DDM.regDragDrop(this,c)},removeFromGroup:function(c){if(this.groups[c]){delete this.groups[c]}this.DDM.removeDDFromGroup(this,c)},setDragElId:function(c){this.dragElId=c},setHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.handleElId=c;this.DDM.regHandle(this.id,c)},setOuterHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}a.on(c,"mousedown",this.handleMouseDown,this);this.setHandleElId(c);this.hasOuterHandles=true},unreg:function(){a.un(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this)},destroy:function(){this.unreg()},isLocked:function(){return(this.DDM.isLocked()||this.locked)},handleMouseDown:function(g,d){if(this.primaryButtonOnly&&g.button!=0){return}if(this.isLocked()){return}this.DDM.refreshCache(this.groups);var c=new Ext.lib.Point(Ext.lib.Event.getPageX(g),Ext.lib.Event.getPageY(g));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(c,this)){}else{if(this.clickValidator(g)){this.setStartPosition();this.b4MouseDown(g);this.onMouseDown(g);this.DDM.handleMouseDown(g,this);if(this.preventDefault||this.stopPropagation){if(this.preventDefault){g.preventDefault()}if(this.stopPropagation){g.stopPropagation()}}else{this.DDM.stopEvent(g)}}else{}}},clickValidator:function(d){var c=d.getTarget();return(this.isValidHandleChild(c)&&(this.id==this.handleElId||this.DDM.handleWasClicked(c,this.id)))},addInvalidHandleType:function(c){var d=c.toUpperCase();this.invalidHandleTypes[d]=d},addInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.invalidHandleIds[c]=c},addInvalidHandleClass:function(c){this.invalidHandleClasses.push(c)},removeInvalidHandleType:function(c){var d=c.toUpperCase();delete this.invalidHandleTypes[d]},removeInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}delete this.invalidHandleIds[c]},removeInvalidHandleClass:function(d){for(var e=0,c=this.invalidHandleClasses.length;e=this.minX;d=d-c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}for(d=this.initPageX;d<=this.maxX;d=d+c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}this.xTicks.sort(this.DDM.numericSort)},setYTicks:function(g,c){this.yTicks=[];this.yTickSize=c;var e={};for(var d=this.initPageY;d>=this.minY;d=d-c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}for(d=this.initPageY;d<=this.maxY;d=d+c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}this.yTicks.sort(this.DDM.numericSort)},setXConstraint:function(e,d,c){this.leftConstraint=e;this.rightConstraint=d;this.minX=this.initPageX-e;this.maxX=this.initPageX+d;if(c){this.setXTicks(this.initPageX,c)}this.constrainX=true},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks()},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0},setYConstraint:function(c,e,d){this.topConstraint=c;this.bottomConstraint=e;this.minY=this.initPageY-c;this.maxY=this.initPageY+e;if(d){this.setYTicks(this.initPageY,d)}this.constrainY=true},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var d=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var c=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(d,c)}else{this.setInitPosition()}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize)}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize)}},getTick:function(k,g){if(!g){return k}else{if(g[0]>=k){return g[0]}else{for(var d=0,c=g.length;d=k){var j=k-g[d];var h=g[e]-k;return(h>j)?g[d]:g[e]}}return g[g.length-1]}}},toString:function(){return("DragDrop "+this.id)}}})();if(!Ext.dd.DragDropMgr){Ext.dd.DragDropMgr=function(){var a=Ext.EventManager;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,init:function(){this.initialized=true},POINT:0,INTERSECT:1,mode:0,notifyOccluded:false,_execOnAll:function(d,c){for(var e in this.ids){for(var b in this.ids[e]){var g=this.ids[e][b];if(!this.isTypeOfDD(g)){continue}g[d].apply(g,c)}}},_onLoad:function(){this.init();a.on(document,"mouseup",this.handleMouseUp,this,true);a.on(document,"mousemove",this.handleMouseMove,this,true);a.on(window,"unload",this._onUnload,this,true);a.on(window,"resize",this._onResize,this,true)},_onResize:function(b){this._execOnAll("resetConstraints",[])},lock:function(){this.locked=true},unlock:function(){this.locked=false},isLocked:function(){return this.locked},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:350,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,regDragDrop:function(c,b){if(!this.initialized){this.init()}if(!this.ids[b]){this.ids[b]={}}this.ids[b][c.id]=c},removeDDFromGroup:function(d,b){if(!this.ids[b]){this.ids[b]={}}var c=this.ids[b];if(c&&c[d.id]){delete c[d.id]}},_remove:function(c){for(var b in c.groups){if(b&&this.ids[b]&&this.ids[b][c.id]){delete this.ids[b][c.id]}}delete this.handleIds[c.id]},regHandle:function(c,b){if(!this.handleIds[c]){this.handleIds[c]={}}this.handleIds[c][b]=b},isDragDrop:function(b){return(this.getDDById(b))?true:false},getRelated:function(h,c){var g=[];for(var e in h.groups){for(var d in this.ids[e]){var b=this.ids[e][d];if(!this.isTypeOfDD(b)){continue}if(!c||b.isTarget){g[g.length]=b}}}return g},isLegalTarget:function(g,e){var c=this.getRelated(g,true);for(var d=0,b=c.length;dthis.clickPixelThresh||b>this.clickPixelThresh){this.startDrag(this.startX,this.startY)}}if(this.dragThreshMet){this.dragCurrent.b4Drag(d);this.dragCurrent.onDrag(d);if(!this.dragCurrent.moveOnly){this.fireEvents(d,false)}}this.stopEvent(d);return true},fireEvents:function(o,r){var q=this,l=q.dragCurrent,s=o.getPoint(),c,u,g=[],b=[],h=[],m=[],k=[],d=[],p,j,n,t;if(!l||l.isLocked()){return}for(j in q.dragOvers){c=q.dragOvers[j];if(!q.isTypeOfDD(c)){continue}if(!this.isOverTarget(s,c,q.mode)){h.push(c)}b[j]=true;delete q.dragOvers[j]}for(t in l.groups){if("string"!=typeof t){continue}for(j in q.ids[t]){c=q.ids[t][j];if(q.isTypeOfDD(c)&&(u=c.getEl())&&(c.isTarget)&&(!c.isLocked())&&((c!=l)||(l.ignoreSelf===false))){if((c.zIndex=q.getZIndex(u))!==-1){p=true}g.push(c)}}}if(p){g.sort(q.byZIndex)}for(j=0,n=g.length;j2000){}else{setTimeout(b._addListeners,10);if(document&&document.body){b._timeoutCount+=1}}}},handleWasClicked:function(b,d){if(this.isHandle(d,b.id)){return true}else{var c=b.parentNode;while(c){if(this.isHandle(d,c.id)){return true}else{c=c.parentNode}}}return false}}}();Ext.dd.DDM=Ext.dd.DragDropMgr;Ext.dd.DDM._addListeners()}Ext.dd.DD=function(c,a,b){if(c){this.init(c,a,b)}};Ext.extend(Ext.dd.DD,Ext.dd.DragDrop,{scroll:true,autoOffset:function(c,b){var a=c-this.startPageX;var d=b-this.startPageY;this.setDelta(a,d)},setDelta:function(b,a){this.deltaX=b;this.deltaY=a},setDragElPos:function(c,b){var a=this.getDragEl();this.alignElWithMouse(a,c,b)},alignElWithMouse:function(c,h,g){var e=this.getTargetCoord(h,g);var b=c.dom?c:Ext.fly(c,"_dd");if(!this.deltaSetXY){var i=[e.x,e.y];b.setXY(i);var d=b.getLeft(true);var a=b.getTop(true);this.deltaSetXY=[d-e.x,a-e.y]}else{b.setLeftTop(e.x+this.deltaSetXY[0],e.y+this.deltaSetXY[1])}this.cachePosition(e.x,e.y);this.autoScroll(e.x,e.y,c.offsetHeight,c.offsetWidth);return e},cachePosition:function(b,a){if(b){this.lastPageX=b;this.lastPageY=a}else{var c=Ext.lib.Dom.getXY(this.getEl());this.lastPageX=c[0];this.lastPageY=c[1]}},autoScroll:function(l,k,e,m){if(this.scroll){var n=Ext.lib.Dom.getViewHeight();var b=Ext.lib.Dom.getViewWidth();var p=this.DDM.getScrollTop();var d=this.DDM.getScrollLeft();var j=e+k;var o=m+l;var i=(n+p-k-this.deltaY);var g=(b+d-l-this.deltaX);var c=40;var a=(document.all)?80:30;if(j>n&&i0&&k-pb&&g0&&l-dthis.maxX){a=this.maxX}}if(this.constrainY){if(dthis.maxY){d=this.maxY}}a=this.getTick(a,this.xTicks);d=this.getTick(d,this.yTicks);return{x:a,y:d}},applyConfig:function(){Ext.dd.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false)},b4MouseDown:function(a){this.autoOffset(a.getPageX(),a.getPageY())},b4Drag:function(a){this.setDragElPos(a.getPageX(),a.getPageY())},toString:function(){return("DD "+this.id)}});Ext.dd.DDProxy=function(c,a,b){if(c){this.init(c,a,b);this.initFrame()}};Ext.dd.DDProxy.dragElId="ygddfdiv";Ext.extend(Ext.dd.DDProxy,Ext.dd.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var b=this;var a=document.body;if(!a||!a.firstChild){setTimeout(function(){b.createFrame()},50);return}var d=this.getDragEl();if(!d){d=document.createElement("div");d.id=this.dragElId;var c=d.style;c.position="absolute";c.visibility="hidden";c.cursor="move";c.border="2px solid #aaa";c.zIndex=999;a.insertBefore(d,a.firstChild)}},initFrame:function(){this.createFrame()},applyConfig:function(){Ext.dd.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||Ext.dd.DDProxy.dragElId)},showFrame:function(e,d){var c=this.getEl();var a=this.getDragEl();var b=a.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(b.width,10)/2),Math.round(parseInt(b.height,10)/2))}this.setDragElPos(e,d);Ext.fly(a).show()},_resizeProxy:function(){if(this.resizeFrame){var a=this.getEl();Ext.fly(this.getDragEl()).setSize(a.offsetWidth,a.offsetHeight)}},b4MouseDown:function(b){var a=b.getPageX();var c=b.getPageY();this.autoOffset(a,c);this.setDragElPos(a,c)},b4StartDrag:function(a,b){this.showFrame(a,b)},b4EndDrag:function(a){Ext.fly(this.getDragEl()).hide()},endDrag:function(c){var b=this.getEl();var a=this.getDragEl();a.style.visibility="";this.beforeMove();b.style.visibility="hidden";Ext.dd.DDM.moveToEl(b,a);a.style.visibility="hidden";b.style.visibility="";this.afterDrag()},beforeMove:function(){},afterDrag:function(){},toString:function(){return("DDProxy "+this.id)}});Ext.dd.DDTarget=function(c,a,b){if(c){this.initTarget(c,a,b)}};Ext.extend(Ext.dd.DDTarget,Ext.dd.DragDrop,{getDragEl:Ext.emptyFn,isValidHandleChild:Ext.emptyFn,startDrag:Ext.emptyFn,endDrag:Ext.emptyFn,onDrag:Ext.emptyFn,onDragDrop:Ext.emptyFn,onDragEnter:Ext.emptyFn,onDragOut:Ext.emptyFn,onDragOver:Ext.emptyFn,onInvalidDrop:Ext.emptyFn,onMouseDown:Ext.emptyFn,onMouseUp:Ext.emptyFn,setXConstraint:Ext.emptyFn,setYConstraint:Ext.emptyFn,resetConstraints:Ext.emptyFn,clearConstraints:Ext.emptyFn,clearTicks:Ext.emptyFn,setInitPosition:Ext.emptyFn,setDragElId:Ext.emptyFn,setHandleElId:Ext.emptyFn,setOuterHandleElId:Ext.emptyFn,addInvalidHandleClass:Ext.emptyFn,addInvalidHandleId:Ext.emptyFn,addInvalidHandleType:Ext.emptyFn,removeInvalidHandleClass:Ext.emptyFn,removeInvalidHandleId:Ext.emptyFn,removeInvalidHandleType:Ext.emptyFn,toString:function(){return("DDTarget "+this.id)}});Ext.dd.DragTracker=Ext.extend(Ext.util.Observable,{active:false,tolerance:5,autoStart:false,constructor:function(a){Ext.apply(this,a);this.addEvents("mousedown","mouseup","mousemove","dragstart","dragend","drag");this.dragRegion=new Ext.lib.Region(0,0,0,0);if(this.el){this.initEl(this.el)}Ext.dd.DragTracker.superclass.constructor.call(this,a)},initEl:function(a){this.el=Ext.get(a);a.on("mousedown",this.onMouseDown,this,this.delegate?{delegate:this.delegate}:undefined)},destroy:function(){this.el.un("mousedown",this.onMouseDown,this);delete this.el},onMouseDown:function(b,a){if(this.fireEvent("mousedown",this,b)!==false&&this.onBeforeStart(b)!==false){this.startXY=this.lastXY=b.getXY();this.dragTarget=this.delegate?a:this.el.dom;if(this.preventDefault!==false){b.preventDefault()}Ext.getDoc().on({scope:this,mouseup:this.onMouseUp,mousemove:this.onMouseMove,selectstart:this.stopSelect});if(this.autoStart){this.timer=this.triggerStart.defer(this.autoStart===true?1000:this.autoStart,this,[b])}}},onMouseMove:function(g,d){var b=Ext.isIE6||Ext.isIE7||Ext.isIE8;if(this.active&&b&&!g.browserEvent.button){g.preventDefault();this.onMouseUp(g);return}g.preventDefault();var c=g.getXY(),a=this.startXY;this.lastXY=c;if(!this.active){if(Math.abs(a[0]-c[0])>this.tolerance||Math.abs(a[1]-c[1])>this.tolerance){this.triggerStart(g)}else{return}}this.fireEvent("mousemove",this,g);this.onDrag(g);this.fireEvent("drag",this,g)},onMouseUp:function(c){var b=Ext.getDoc(),a=this.active;b.un("mousemove",this.onMouseMove,this);b.un("mouseup",this.onMouseUp,this);b.un("selectstart",this.stopSelect,this);c.preventDefault();this.clearStart();this.active=false;delete this.elRegion;this.fireEvent("mouseup",this,c);if(a){this.onEnd(c);this.fireEvent("dragend",this,c)}},triggerStart:function(a){this.clearStart();this.active=true;this.onStart(a);this.fireEvent("dragstart",this,a)},clearStart:function(){if(this.timer){clearTimeout(this.timer);delete this.timer}},stopSelect:function(a){a.stopEvent();return false},onBeforeStart:function(a){},onStart:function(a){},onDrag:function(a){},onEnd:function(a){},getDragTarget:function(){return this.dragTarget},getDragCt:function(){return this.el},getXY:function(a){return a?this.constrainModes[a].call(this,this.lastXY):this.lastXY},getOffset:function(c){var b=this.getXY(c),a=this.startXY;return[a[0]-b[0],a[1]-b[1]]},constrainModes:{point:function(b){if(!this.elRegion){this.elRegion=this.getDragCt().getRegion()}var a=this.dragRegion;a.left=b[0];a.top=b[1];a.right=b[0];a.bottom=b[1];a.constrainTo(this.elRegion);return[a.left,a.top]}}});Ext.dd.ScrollManager=function(){var c=Ext.dd.DragDropMgr;var e={};var b=null;var i={};var h=function(l){b=null;a()};var j=function(){if(c.dragCurrent){c.refreshCache(c.dragCurrent.groups)}};var d=function(){if(c.dragCurrent){var l=Ext.dd.ScrollManager;var m=i.el.ddScrollConfig?i.el.ddScrollConfig.increment:l.increment;if(!l.animate){if(i.el.scroll(i.dir,m)){j()}}else{i.el.scroll(i.dir,m,true,l.animDuration,j)}}};var a=function(){if(i.id){clearInterval(i.id)}i.id=0;i.el=null;i.dir=""};var g=function(m,l){a();i.el=m;i.dir=l;var o=m.ddScrollConfig?m.ddScrollConfig.ddGroup:undefined,n=(m.ddScrollConfig&&m.ddScrollConfig.frequency)?m.ddScrollConfig.frequency:Ext.dd.ScrollManager.frequency;if(o===undefined||c.dragCurrent.ddGroup==o){i.id=setInterval(d,n)}};var k=function(o,q){if(q||!c.dragCurrent){return}var s=Ext.dd.ScrollManager;if(!b||b!=c.dragCurrent){b=c.dragCurrent;s.refreshCache()}var t=Ext.lib.Event.getXY(o);var u=new Ext.lib.Point(t[0],t[1]);for(var m in e){var n=e[m],l=n._region;var p=n.ddScrollConfig?n.ddScrollConfig:s;if(l&&l.contains(u)&&n.isScrollable()){if(l.bottom-u.y<=p.vthresh){if(i.el!=n){g(n,"down")}return}else{if(l.right-u.x<=p.hthresh){if(i.el!=n){g(n,"left")}return}else{if(u.y-l.top<=p.vthresh){if(i.el!=n){g(n,"up")}return}else{if(u.x-l.left<=p.hthresh){if(i.el!=n){g(n,"right")}return}}}}}}a()};c.fireEvents=c.fireEvents.createSequence(k,c);c.stopDrag=c.stopDrag.createSequence(h,c);return{register:function(n){if(Ext.isArray(n)){for(var m=0,l=n.length;m]+>/gi,asText:function(a){return String(a).replace(this.stripTagsRE,"")},asUCText:function(a){return String(a).toUpperCase().replace(this.stripTagsRE,"")},asUCString:function(a){return String(a).toUpperCase()},asDate:function(a){if(!a){return 0}if(Ext.isDate(a)){return a.getTime()}return Date.parse(String(a))},asFloat:function(a){var b=parseFloat(String(a).replace(/,/g,""));return isNaN(b)?0:b},asInt:function(a){var b=parseInt(String(a).replace(/,/g,""),10);return isNaN(b)?0:b}};Ext.data.Record=function(a,b){this.id=(b||b===0)?b:Ext.data.Record.id(this);this.data=a||{}};Ext.data.Record.create=function(e){var c=Ext.extend(Ext.data.Record,{});var d=c.prototype;d.fields=new Ext.util.MixedCollection(false,function(g){return g.name});for(var b=0,a=e.length;b-1){a.join(null);this.data.removeAt(b)}if(this.pruneModifiedRecords){this.modified.remove(a)}if(this.snapshot){this.snapshot.remove(a)}if(b>-1){this.fireEvent("remove",this,a,b)}},removeAt:function(a){this.remove(this.getAt(a))},removeAll:function(b){var a=[];this.each(function(c){a.push(c)});this.clearData();if(this.snapshot){this.snapshot.clear()}if(this.pruneModifiedRecords){this.modified=[]}if(b!==true){this.fireEvent("clear",this,a)}},onClear:function(b,a){Ext.each(a,function(d,c){this.destroyRecord(this,d,c)},this)},insert:function(d,c){var e,a,b;c=[].concat(c);for(e=0,a=c.length;e=0;d--){if(b[d].phantom===true){var a=b.splice(d,1).shift();if(a.isValid()){g.push(a)}}else{if(!b[d].isValid()){b.splice(d,1)}}}if(g.length){h.push(["create",g])}if(b.length){h.push(["update",b])}}j=h.length;if(j){e=++this.batchCounter;for(d=0;d=0;b--){this.modified.splice(this.modified.indexOf(a[b]),1)}}else{this.modified.splice(this.modified.indexOf(a),1)}},reMap:function(b){if(Ext.isArray(b)){for(var d=0,a=b.length;d=0;c--){this.insert(b[c].lastIndex,b[c])}}},handleException:function(a){Ext.handleError(a)},reload:function(a){this.load(Ext.applyIf(a||{},this.lastOptions))},loadRecords:function(b,l,h){var e,g;if(this.isDestroyed===true){return}if(!b||h===false){if(h!==false){this.fireEvent("load",this,[],l)}if(l.callback){l.callback.call(l.scope||this,[],l,false,b)}return}var a=b.records,j=b.totalRecords||a.length;if(!l||l.add!==true){if(this.pruneModifiedRecords){this.modified=[]}for(e=0,g=a.length;e-1){this.doUpdate(d)}else{k.push(d);++c}}this.totalLength=Math.max(j,this.data.length+c);this.add(k)}this.fireEvent("load",this,a,l);if(l.callback){l.callback.call(l.scope||this,a,l,true)}},loadData:function(c,a){var b=this.reader.readRecords(c);this.loadRecords(b,{add:a},true)},getCount:function(){return this.data.length||0},getTotalCount:function(){return this.totalLength||0},getSortState:function(){return this.sortInfo},applySort:function(){if((this.sortInfo||this.multiSortInfo)&&!this.remoteSort){this.sortData()}},sortData:function(){var a=this.hasMultiSort?this.multiSortInfo:this.sortInfo,k=a.direction||"ASC",h=a.sorters,c=[];if(!this.hasMultiSort){h=[{direction:k,field:a.field}]}for(var d=0,b=h.length;d1){for(var p=1,o=c.length;ph?1:(i=0;b--){if(Ext.isArray(c)){this.realize(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.realize(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(!this.isData(c)){throw new Ext.data.DataReader.Error("realize",a)}a.phantom=false;a._phid=a.id;a.id=this.getId(c);a.data=c;a.commit();a.store.reMap(a)}},update:function(a,c){if(Ext.isArray(a)){for(var b=a.length-1;b>=0;b--){if(Ext.isArray(c)){this.update(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.update(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(this.isData(c)){a.data=Ext.apply(a.data,c)}a.commit()}},extractData:function(k,a){var j=(this instanceof Ext.data.JsonReader)?"json":"node";var c=[];if(this.isData(k)&&!(this instanceof Ext.data.XmlReader)){k=[k]}var h=this.recordType.prototype.fields,o=h.items,m=h.length,c=[];if(a===true){var l=this.recordType;for(var e=0;e=0){return new Function("obj","return obj"+(b>0?".":"")+c)}return function(d){return d[c]}}}(),extractValues:function(h,d,a){var g,c={};for(var e=0;e<\u003fxml version="{version}" encoding="{encoding}"\u003f><{documentRoot}><{name}>{value}<{root}><{parent.record}><{name}>{value}',render:function(b,c,a){c=this.toArray(c);b.xmlData=this.tpl.applyTemplate({version:this.xmlVersion,encoding:this.xmlEncoding,documentRoot:(c.length>0||this.forceDocumentRoot===true)?this.documentRoot:false,record:this.meta.record,root:this.root,baseParams:c,records:(Ext.isArray(a[0]))?a:[a]})},createRecord:function(a){return this.toArray(this.toHash(a))},updateRecord:function(a){return this.toArray(this.toHash(a))},destroyRecord:function(b){var a={};a[this.meta.idProperty]=b.id;return this.toArray(a)}});Ext.data.XmlReader=function(a,b){a=a||{};Ext.applyIf(a,{idProperty:a.idProperty||a.idPath||a.id,successProperty:a.successProperty||a.success});Ext.data.XmlReader.superclass.constructor.call(this,a,b||a.fields)};Ext.extend(Ext.data.XmlReader,Ext.data.DataReader,{read:function(a){var b=a.responseXML;if(!b){throw {message:"XmlReader.read: XML Document not available"}}return this.readRecords(b)},readRecords:function(d){this.xmlData=d;var a=d.documentElement||d,c=Ext.DomQuery,g=0,e=true;if(this.meta.totalProperty){g=this.getTotal(a,0)}if(this.meta.successProperty){e=this.getSuccess(a)}var b=this.extractData(c.select(this.meta.record,a),true);return{success:e,records:b,totalRecords:g||b.length}},readResponse:function(g,b){var e=Ext.DomQuery,h=b.responseXML,a=h.documentElement||h;var c=new Ext.data.Response({action:g,success:this.getSuccess(a),message:this.getMessage(a),data:this.extractData(e.select(this.meta.record,a)||e.select(this.meta.root,a),false),raw:h});if(Ext.isEmpty(c.success)){throw new Ext.data.DataReader.Error("successProperty-response",this.meta.successProperty)}if(g===Ext.data.Api.actions.create){var d=Ext.isDefined(c.data);if(d&&Ext.isEmpty(c.data)){throw new Ext.data.JsonReader.Error("root-empty",this.meta.root)}else{if(!d){throw new Ext.data.JsonReader.Error("root-undefined-response",this.meta.root)}}}return c},getSuccess:function(){return true},buildExtractors:function(){if(this.ef){return}var l=this.meta,h=this.recordType,e=h.prototype.fields,k=e.items,j=e.length;if(l.totalProperty){this.getTotal=this.createAccessor(l.totalProperty)}if(l.successProperty){this.getSuccess=this.createAccessor(l.successProperty)}if(l.messageProperty){this.getMessage=this.createAccessor(l.messageProperty)}this.getRoot=function(g){return(!Ext.isEmpty(g[this.meta.record]))?g[this.meta.record]:g[this.meta.root]};if(l.idPath||l.idProperty){var d=this.createAccessor(l.idPath||l.idProperty);this.getId=function(g){var i=d(g)||g.id;return(i===undefined||i==="")?null:i}}else{this.getId=function(){return null}}var c=[];for(var b=0;b0&&c[0].field==this.groupField){c.shift()}this.groupField=e;this.groupDir=d;this.applyGroupField();var b=function(){this.fireEvent("groupchange",this,this.getGroupState())};if(this.groupOnSort){this.sort(e,d);b.call(this);return}if(this.remoteGroup){this.on("load",b,this,{single:true});this.reload()}else{this.sort(c);b.call(this)}},sort:function(h,c){if(this.remoteSort){return Ext.data.GroupingStore.superclass.sort.call(this,h,c)}var g=[];if(Ext.isArray(arguments[0])){g=arguments[0]}else{if(h==undefined){g=this.sortInfo?[this.sortInfo]:[]}else{var e=this.fields.get(h);if(!e){return false}var b=e.name,a=this.sortInfo||null,d=this.sortToggle?this.sortToggle[b]:null;if(!c){if(a&&a.field==b){c=(this.sortToggle[b]||"ASC").toggle("ASC","DESC")}else{c=e.sortDir}}this.sortToggle[b]=c;this.sortInfo={field:b,direction:c};g=[this.sortInfo]}}if(this.groupField){g.unshift({direction:this.groupDir,field:this.groupField})}return this.multiSort.call(this,g,c)},applyGroupField:function(){if(this.remoteGroup){if(!this.baseParams){this.baseParams={}}Ext.apply(this.baseParams,{groupBy:this.groupField,groupDir:this.groupDir});var a=this.lastOptions;if(a&&a.params){a.params.groupDir=this.groupDir;delete a.params.groupBy}}},applyGrouping:function(a){if(this.groupField!==false){this.groupBy(this.groupField,true,this.groupDir);return true}else{if(a===true){this.fireEvent("datachanged",this)}return false}},getGroupState:function(){return this.groupOnSort&&this.groupField!==false?(this.sortInfo?this.sortInfo.field:undefined):this.groupField}});Ext.reg("groupingstore",Ext.data.GroupingStore);Ext.data.DirectProxy=function(a){Ext.apply(this,a);if(typeof this.paramOrder=="string"){this.paramOrder=this.paramOrder.split(/[\s,|]/)}Ext.data.DirectProxy.superclass.constructor.call(this,a)};Ext.extend(Ext.data.DirectProxy,Ext.data.DataProxy,{paramOrder:undefined,paramsAsHash:true,directFn:undefined,doRequest:function(b,c,a,e,k,l,n){var j=[],h=this.api[b]||this.directFn;switch(b){case Ext.data.Api.actions.create:j.push(a.jsonData);break;case Ext.data.Api.actions.read:if(h.directCfg.method.len>0){if(this.paramOrder){for(var d=0,g=this.paramOrder.length;d1){for(var d=0,b=c.length;d0){this.doSend(a==1?this.callBuffer[0]:this.callBuffer);this.callBuffer=[]}},queueTransaction:function(a){if(a.form){this.processForm(a);return}this.callBuffer.push(a);if(this.enableBuffer){if(!this.callTask){this.callTask=new Ext.util.DelayedTask(this.combineAndSend,this)}this.callTask.delay(Ext.isNumber(this.enableBuffer)?this.enableBuffer:10)}else{this.combineAndSend()}},doCall:function(i,a,b){var h=null,e=b[a.len],g=b[a.len+1];if(a.len!==0){h=b.slice(0,a.len)}var d=new Ext.Direct.Transaction({provider:this,args:b,action:i,method:a.name,data:h,cb:g&&Ext.isFunction(e)?e.createDelegate(g):e});if(this.fireEvent("beforecall",this,d,a)!==false){Ext.Direct.addTransaction(d);this.queueTransaction(d);this.fireEvent("call",this,d,a)}},doForm:function(j,b,g,i,e){var d=new Ext.Direct.Transaction({provider:this,action:j,method:b.name,args:[g,i,e],cb:e&&Ext.isFunction(i)?i.createDelegate(e):i,isForm:true});if(this.fireEvent("beforecall",this,d,b)!==false){Ext.Direct.addTransaction(d);var a=String(g.getAttribute("enctype")).toLowerCase()=="multipart/form-data",h={extTID:d.tid,extAction:j,extMethod:b.name,extType:"rpc",extUpload:String(a)};Ext.apply(d,{form:Ext.getDom(g),isUpload:a,params:i&&Ext.isObject(i.params)?Ext.apply(h,i.params):h});this.fireEvent("call",this,d,b);this.processForm(d)}},processForm:function(a){Ext.Ajax.request({url:this.url,params:a.params,callback:this.onData,scope:this,form:a.form,isUpload:a.isUpload,ts:a})},createMethod:function(d,a){var b;if(!a.formHandler){b=function(){this.doCall(d,a,Array.prototype.slice.call(arguments,0))}.createDelegate(this)}else{b=function(e,g,c){this.doForm(d,a,e,g,c)}.createDelegate(this)}b.directCfg={action:d,method:a};return b},getTransaction:function(a){return a&&a.tid?Ext.Direct.getTransaction(a.tid):null},doCallback:function(c,g){var d=g.status?"success":"failure";if(c&&c.cb){var b=c.cb,a=Ext.isDefined(g.result)?g.result:g.data;if(Ext.isFunction(b)){b(a,g)}else{Ext.callback(b[d],b.scope,[a,g]);Ext.callback(b.callback,b.scope,[a,g])}}}});Ext.Direct.PROVIDERS.remoting=Ext.direct.RemotingProvider;Ext.Resizable=Ext.extend(Ext.util.Observable,{constructor:function(d,e){this.el=Ext.get(d);if(e&&e.wrap){e.resizeChild=this.el;this.el=this.el.wrap(typeof e.wrap=="object"?e.wrap:{cls:"xresizable-wrap"});this.el.id=this.el.dom.id=e.resizeChild.id+"-rzwrap";this.el.setStyle("overflow","hidden");this.el.setPositioning(e.resizeChild.getPositioning());e.resizeChild.clearPositioning();if(!e.width||!e.height){var g=e.resizeChild.getSize();this.el.setSize(g.width,g.height)}if(e.pinned&&!e.adjustments){e.adjustments="auto"}}this.proxy=this.el.createProxy({tag:"div",cls:"x-resizable-proxy",id:this.el.id+"-rzproxy"},Ext.getBody());this.proxy.unselectable();this.proxy.enableDisplayMode("block");Ext.apply(this,e);if(this.pinned){this.disableTrackOver=true;this.el.addClass("x-resizable-pinned")}var k=this.el.getStyle("position");if(k!="absolute"&&k!="fixed"){this.el.setStyle("position","relative")}if(!this.handles){this.handles="s,e,se";if(this.multiDirectional){this.handles+=",n,w"}}if(this.handles=="all"){this.handles="n s e w ne nw se sw"}var o=this.handles.split(/\s*?[,;]\s*?| /);var c=Ext.Resizable.positions;for(var j=0,l=o.length;j0){if(a>(e/2)){d=c+(e-a)}else{d=c-a}}return Math.max(b,d)},resizeElement:function(){var a=this.proxy.getBox();if(this.updateBox){this.el.setBox(a,false,this.animate,this.duration,null,this.easing)}else{this.el.setSize(a.width,a.height,this.animate,this.duration,null,this.easing)}this.updateChildSize();if(!this.dynamic){this.proxy.hide()}if(this.draggable&&this.constrainTo){this.dd.resetConstraints();this.dd.constrainTo(this.constrainTo)}return a},constrain:function(b,c,a,d){if(b-cd){c=b-d}}return c},onMouseMove:function(z){if(this.enabled&&this.activeHandle){try{if(this.resizeRegion&&!this.resizeRegion.contains(z.getPoint())){return}var t=this.curSize||this.startBox,l=this.startBox.x,k=this.startBox.y,c=l,b=k,m=t.width,u=t.height,d=m,o=u,n=this.minWidth,A=this.minHeight,s=this.maxWidth,D=this.maxHeight,i=this.widthIncrement,a=this.heightIncrement,B=z.getXY(),r=-(this.startPoint[0]-Math.max(this.minX,B[0])),p=-(this.startPoint[1]-Math.max(this.minY,B[1])),j=this.activeHandle.position,E,g;switch(j){case"east":m+=r;m=Math.min(Math.max(n,m),s);break;case"south":u+=p;u=Math.min(Math.max(A,u),D);break;case"southeast":m+=r;u+=p;m=Math.min(Math.max(n,m),s);u=Math.min(Math.max(A,u),D);break;case"north":p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"west":r=this.constrain(m,r,n,s);l+=r;m-=r;break;case"northeast":m+=r;m=Math.min(Math.max(n,m),s);p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"northwest":r=this.constrain(m,r,n,s);p=this.constrain(u,p,A,D);k+=p;u-=p;l+=r;m-=r;break;case"southwest":r=this.constrain(m,r,n,s);u+=p;u=Math.min(Math.max(A,u),D);l+=r;m-=r;break}var q=this.snap(m,i,n);var C=this.snap(u,a,A);if(q!=m||C!=u){switch(j){case"northeast":k-=C-u;break;case"north":k-=C-u;break;case"southwest":l-=q-m;break;case"west":l-=q-m;break;case"northwest":l-=q-m;k-=C-u;break}m=q;u=C}if(this.preserveRatio){switch(j){case"southeast":case"east":u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);break;case"south":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"northeast":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"north":E=m;m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);l+=(E-m)/2;break;case"southwest":u=o*(m/d);u=Math.min(Math.max(A,u),D);E=m;m=d*(u/o);l+=E-m;break;case"west":g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);k+=(g-u)/2;E=m;m=d*(u/o);l+=E-m;break;case"northwest":E=m;g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);k+=g-u;l+=E-m;break}}this.proxy.setBounds(l,k,m,u);if(this.dynamic){this.resizeElement()}}catch(v){}}},handleOver:function(){if(this.enabled){this.el.addClass("x-resizable-over")}},handleOut:function(){if(!this.resizing){this.el.removeClass("x-resizable-over")}},getEl:function(){return this.el},getResizeChild:function(){return this.resizeChild},destroy:function(b){Ext.destroy(this.dd,this.overlay,this.proxy);this.overlay=null;this.proxy=null;var c=Ext.Resizable.positions;for(var a in c){if(typeof c[a]!="function"&&this[c[a]]){this[c[a]].destroy()}}if(b){this.el.update("");Ext.destroy(this.el);this.el=null}this.purgeListeners()},syncHandleHeight:function(){var a=this.el.getHeight(true);if(this.west){this.west.el.setHeight(a)}if(this.east){this.east.el.setHeight(a)}}});Ext.Resizable.positions={n:"north",s:"south",e:"east",w:"west",se:"southeast",sw:"southwest",nw:"northwest",ne:"northeast"};Ext.Resizable.Handle=Ext.extend(Object,{constructor:function(d,g,c,e,a){if(!this.tpl){var b=Ext.DomHelper.createTemplate({tag:"div",cls:"x-resizable-handle x-resizable-handle-{0}"});b.compile();Ext.Resizable.Handle.prototype.tpl=b}this.position=g;this.rz=d;this.el=this.tpl.append(d.el.dom,[this.position],true);this.el.unselectable();if(e){this.el.setOpacity(0)}if(!Ext.isEmpty(a)){this.el.addClass(a)}this.el.on("mousedown",this.onMouseDown,this);if(!c){this.el.on({scope:this,mouseover:this.onMouseOver,mouseout:this.onMouseOut})}},afterResize:function(a){},onMouseDown:function(a){this.rz.onMouseDown(this,a)},onMouseOver:function(a){this.rz.handleOver(this,a)},onMouseOut:function(a){this.rz.handleOut(this,a)},destroy:function(){Ext.destroy(this.el);this.el=null}});Ext.Window=Ext.extend(Ext.Panel,{baseCls:"x-window",resizable:true,draggable:true,closable:true,closeAction:"close",constrain:false,constrainHeader:false,plain:false,minimizable:false,maximizable:false,minHeight:100,minWidth:200,expandOnShow:true,showAnimDuration:0.25,hideAnimDuration:0.25,collapsible:false,initHidden:undefined,hidden:true,elements:"header,body",frame:true,floating:true,initComponent:function(){this.initTools();Ext.Window.superclass.initComponent.call(this);this.addEvents("resize","maximize","minimize","restore");if(Ext.isDefined(this.initHidden)){this.hidden=this.initHidden}if(this.hidden===false){this.hidden=true;this.show()}},getState:function(){return Ext.apply(Ext.Window.superclass.getState.call(this)||{},this.getBox(true))},onRender:function(b,a){Ext.Window.superclass.onRender.call(this,b,a);if(this.plain){this.el.addClass("x-window-plain")}this.focusEl=this.el.createChild({tag:"a",href:"#",cls:"x-dlg-focus",tabIndex:"-1",html:" "});this.focusEl.swallowEvent("click",true);this.proxy=this.el.createProxy("x-window-proxy");this.proxy.enableDisplayMode("block");if(this.modal){this.mask=this.container.createChild({cls:"ext-el-mask"},this.el.dom);this.mask.enableDisplayMode("block");this.mask.hide();this.mon(this.mask,"click",this.focus,this)}if(this.maximizable){this.mon(this.header,"dblclick",this.toggleMaximize,this)}},initEvents:function(){Ext.Window.superclass.initEvents.call(this);if(this.animateTarget){this.setAnimateTarget(this.animateTarget)}if(this.resizable){this.resizer=new Ext.Resizable(this.el,{minWidth:this.minWidth,minHeight:this.minHeight,handles:this.resizeHandles||"all",pinned:true,resizeElement:this.resizerAction,handleCls:"x-window-handle"});this.resizer.window=this;this.mon(this.resizer,"beforeresize",this.beforeResize,this)}if(this.draggable){this.header.addClass("x-window-draggable")}this.mon(this.el,"mousedown",this.toFront,this);this.manager=this.manager||Ext.WindowMgr;this.manager.register(this);if(this.maximized){this.maximized=false;this.maximize()}if(this.closable){var a=this.getKeyMap();a.on(27,this.onEsc,this);a.disable()}},initDraggable:function(){this.dd=new Ext.Window.DD(this)},onEsc:function(a,b){if(this.activeGhost){this.unghost()}b.stopEvent();this[this.closeAction]()},beforeDestroy:function(){if(this.rendered){this.hide();this.clearAnchor();Ext.destroy(this.focusEl,this.resizer,this.dd,this.proxy,this.mask)}Ext.Window.superclass.beforeDestroy.call(this)},onDestroy:function(){if(this.manager){this.manager.unregister(this)}Ext.Window.superclass.onDestroy.call(this)},initTools:function(){if(this.minimizable){this.addTool({id:"minimize",handler:this.minimize.createDelegate(this,[])})}if(this.maximizable){this.addTool({id:"maximize",handler:this.maximize.createDelegate(this,[])});this.addTool({id:"restore",handler:this.restore.createDelegate(this,[]),hidden:true})}if(this.closable){this.addTool({id:"close",handler:this[this.closeAction].createDelegate(this,[])})}},resizerAction:function(){var a=this.proxy.getBox();this.proxy.hide();this.window.handleResize(a);return a},beforeResize:function(){this.resizer.minHeight=Math.max(this.minHeight,this.getFrameHeight()+40);this.resizer.minWidth=Math.max(this.minWidth,this.getFrameWidth()+40);this.resizeBox=this.el.getBox()},updateHandles:function(){if(Ext.isIE9m&&this.resizer){this.resizer.syncHandleHeight();this.el.repaint()}},handleResize:function(b){var a=this.resizeBox;if(a.x!=b.x||a.y!=b.y){this.updateBox(b)}else{this.setSize(b);if(Ext.isIE6&&Ext.isStrict){this.doLayout()}}this.focus();this.updateHandles();this.saveState()},focus:function(){var e=this.focusEl,a=this.defaultButton,c=typeof a,d,b;if(Ext.isDefined(a)){if(Ext.isNumber(a)&&this.fbar){e=this.fbar.items.get(a)}else{if(Ext.isString(a)){e=Ext.getCmp(a)}else{e=a}}d=e.getEl();b=Ext.getDom(this.container);if(d&&b){if(b!=document.body&&!Ext.lib.Region.getRegion(b).contains(Ext.lib.Region.getRegion(d.dom))){return}}}e=e||this.focusEl;e.focus.defer(10,e)},setAnimateTarget:function(a){a=Ext.get(a);this.animateTarget=a},beforeShow:function(){delete this.el.lastXY;delete this.el.lastLT;if(this.x===undefined||this.y===undefined){var a=this.el.getAlignToXY(this.container,"c-c");var b=this.el.translatePoints(a[0],a[1]);this.x=this.x===undefined?b.left:this.x;this.y=this.y===undefined?b.top:this.y}this.el.setLeftTop(this.x,this.y);if(this.expandOnShow){this.expand(false)}if(this.modal){Ext.getBody().addClass("x-body-masked");this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.mask.show()}},show:function(c,a,b){if(!this.rendered){this.render(Ext.getBody())}if(this.hidden===false){this.toFront();return this}if(this.fireEvent("beforeshow",this)===false){return this}if(a){this.on("show",a,b,{single:true})}this.hidden=false;if(Ext.isDefined(c)){this.setAnimateTarget(c)}this.beforeShow();if(this.animateTarget){this.animShow()}else{this.afterShow()}return this},afterShow:function(b){if(this.isDestroyed){return false}this.proxy.hide();this.el.setStyle("display","block");this.el.show();if(this.maximized){this.fitContainer()}if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.onWindowResize(this.onWindowResize,this)}this.doConstrain();this.doLayout();if(this.keyMap){this.keyMap.enable()}this.toFront();this.updateHandles();if(b&&(Ext.isIE||Ext.isWebKit)){var a=this.getSize();this.onResize(a.width,a.height)}this.onShow();this.fireEvent("show",this)},animShow:function(){this.proxy.show();this.proxy.setBox(this.animateTarget.getBox());this.proxy.setOpacity(0);var a=this.getBox();this.el.setStyle("display","none");this.proxy.shift(Ext.apply(a,{callback:this.afterShow.createDelegate(this,[true],false),scope:this,easing:"easeNone",duration:this.showAnimDuration,opacity:0.5}))},hide:function(c,a,b){if(this.hidden||this.fireEvent("beforehide",this)===false){return this}if(a){this.on("hide",a,b,{single:true})}this.hidden=true;if(c!==undefined){this.setAnimateTarget(c)}if(this.modal){this.mask.hide();Ext.getBody().removeClass("x-body-masked")}if(this.animateTarget){this.animHide()}else{this.el.hide();this.afterHide()}return this},afterHide:function(){this.proxy.hide();if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.removeResizeListener(this.onWindowResize,this)}if(this.keyMap){this.keyMap.disable()}this.onHide();this.fireEvent("hide",this)},animHide:function(){this.proxy.setOpacity(0.5);this.proxy.show();var a=this.getBox(false);this.proxy.setBox(a);this.el.hide();this.proxy.shift(Ext.apply(this.animateTarget.getBox(),{callback:this.afterHide,scope:this,duration:this.hideAnimDuration,easing:"easeNone",opacity:0}))},onShow:Ext.emptyFn,onHide:Ext.emptyFn,onWindowResize:function(){if(this.maximized){this.fitContainer()}if(this.modal){this.mask.setSize("100%","100%");var a=this.mask.dom.offsetHeight;this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true))}this.doConstrain()},doConstrain:function(){if(this.constrain||this.constrainHeader){var b;if(this.constrain){b={right:this.el.shadowOffset,left:this.el.shadowOffset,bottom:this.el.shadowOffset}}else{var a=this.getSize();b={right:-(a.width-100),bottom:-(a.height-25+this.el.getConstrainOffset())}}var c=this.el.getConstrainToXY(this.container,true,b);if(c){this.setPosition(c[0],c[1])}}},ghost:function(a){var c=this.createGhost(a);var b=this.getBox(true);c.setLeftTop(b.x,b.y);c.setWidth(b.width);this.el.hide();this.activeGhost=c;return c},unghost:function(b,a){if(!this.activeGhost){return}if(b!==false){this.el.show();this.focus.defer(10,this);if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}}if(a!==false){this.setPosition(this.activeGhost.getLeft(true),this.activeGhost.getTop(true))}this.activeGhost.hide();this.activeGhost.remove();delete this.activeGhost},minimize:function(){this.fireEvent("minimize",this);return this},close:function(){if(this.fireEvent("beforeclose",this)!==false){if(this.hidden){this.doClose()}else{this.hide(null,this.doClose,this)}}},doClose:function(){this.fireEvent("close",this);this.destroy()},maximize:function(){if(!this.maximized){this.expand(false);this.restoreSize=this.getSize();this.restorePos=this.getPosition(true);if(this.maximizable){this.tools.maximize.hide();this.tools.restore.show()}this.maximized=true;this.el.disableShadow();if(this.dd){this.dd.lock()}if(this.collapsible){this.tools.toggle.hide()}this.el.addClass("x-window-maximized");this.container.addClass("x-window-maximized-ct");this.setPosition(0,0);this.fitContainer();this.fireEvent("maximize",this)}return this},restore:function(){if(this.maximized){var a=this.tools;this.el.removeClass("x-window-maximized");if(a.restore){a.restore.hide()}if(a.maximize){a.maximize.show()}this.setPosition(this.restorePos[0],this.restorePos[1]);this.setSize(this.restoreSize.width,this.restoreSize.height);delete this.restorePos;delete this.restoreSize;this.maximized=false;this.el.enableShadow(true);if(this.dd){this.dd.unlock()}if(this.collapsible&&a.toggle){a.toggle.show()}this.container.removeClass("x-window-maximized-ct");this.doConstrain();this.fireEvent("restore",this)}return this},toggleMaximize:function(){return this[this.maximized?"restore":"maximize"]()},fitContainer:function(){var a=this.container.getViewSize(false);this.setSize(a.width,a.height)},setZIndex:function(a){if(this.modal){this.mask.setStyle("z-index",a)}this.el.setZIndex(++a);a+=5;if(this.resizer){this.resizer.proxy.setStyle("z-index",++a)}this.lastZIndex=a},alignTo:function(b,a,c){var d=this.el.getAlignToXY(b,a,c);this.setPagePosition(d[0],d[1]);return this},anchorTo:function(c,e,d,b){this.clearAnchor();this.anchorTarget={el:c,alignment:e,offsets:d};Ext.EventManager.onWindowResize(this.doAnchor,this);var a=typeof b;if(a!="undefined"){Ext.EventManager.on(window,"scroll",this.doAnchor,this,{buffer:a=="number"?b:50})}return this.doAnchor()},doAnchor:function(){var a=this.anchorTarget;this.alignTo(a.el,a.alignment,a.offsets);return this},clearAnchor:function(){if(this.anchorTarget){Ext.EventManager.removeResizeListener(this.doAnchor,this);Ext.EventManager.un(window,"scroll",this.doAnchor,this);delete this.anchorTarget}return this},toFront:function(a){if(this.manager.bringToFront(this)){if(!a||!a.getTarget().focus){this.focus()}}return this},setActive:function(a){if(a){if(!this.maximized){this.el.enableShadow(true)}this.fireEvent("activate",this)}else{this.el.disableShadow();this.fireEvent("deactivate",this)}},toBack:function(){this.manager.sendToBack(this);return this},center:function(){var a=this.el.getAlignToXY(this.container,"c-c");this.setPagePosition(a[0],a[1]);return this}});Ext.reg("window",Ext.Window);Ext.Window.DD=Ext.extend(Ext.dd.DD,{constructor:function(a){this.win=a;Ext.Window.DD.superclass.constructor.call(this,a.el.id,"WindowDD-"+a.id);this.setHandleElId(a.header.id);this.scroll=false},moveOnly:true,headerOffsets:[100,25],startDrag:function(){var a=this.win;this.proxy=a.ghost(a.initialConfig.cls);if(a.constrain!==false){var c=a.el.shadowOffset;this.constrainTo(a.container,{right:c,left:c,bottom:c})}else{if(a.constrainHeader!==false){var b=this.proxy.getSize();this.constrainTo(a.container,{right:-(b.width-this.headerOffsets[0]),bottom:-(b.height-this.headerOffsets[1])})}}},b4Drag:Ext.emptyFn,onDrag:function(a){this.alignElWithMouse(this.proxy,a.getPageX(),a.getPageY())},endDrag:function(a){this.win.unghost();this.win.saveState()}});Ext.WindowGroup=function(){var g={};var d=[];var e=null;var c=function(j,i){return(!j._lastAccess||j._lastAccess0){l.sort(c);var k=l[0].manager.zseed;for(var m=0;m=0;--j){if(!d[j].hidden){b(d[j]);return}}b(null)};return{zseed:9000,register:function(i){if(i.manager){i.manager.unregister(i)}i.manager=this;g[i.id]=i;d.push(i);i.on("hide",a)},unregister:function(i){delete i.manager;delete g[i.id];i.un("hide",a);d.remove(i)},get:function(i){return typeof i=="object"?i:g[i]},bringToFront:function(i){i=this.get(i);if(i!=e){i._lastAccess=new Date().getTime();h();return true}return false},sendToBack:function(i){i=this.get(i);i._lastAccess=-(new Date().getTime());h();return i},hideAll:function(){for(var i in g){if(g[i]&&typeof g[i]!="function"&&g[i].isVisible()){g[i].hide()}}},getActive:function(){return e},getBy:function(l,k){var m=[];for(var j=d.length-1;j>=0;--j){var n=d[j];if(l.call(k||n,n)!==false){m.push(n)}}return m},each:function(j,i){for(var k in g){if(g[k]&&typeof g[k]!="function"){if(j.call(i||g[k],g[k])===false){return}}}}}};Ext.WindowMgr=new Ext.WindowGroup();Ext.MessageBox=function(){var u,b,q,t,h,l,s,a,n,p,j,g,r,v,o,i="",d="",m=["ok","yes","no","cancel"];var c=function(x){r[x].blur();if(u.isVisible()){u.hide();w();Ext.callback(b.fn,b.scope||window,[x,v.dom.value,b],1)}};var w=function(){if(b&&b.cls){u.el.removeClass(b.cls)}n.reset()};var e=function(z,x,y){if(b&&b.closable!==false){u.hide();w()}if(y){y.stopEvent()}};var k=function(x){var z=0,y;if(!x){Ext.each(m,function(A){r[A].hide()});return z}u.footer.dom.style.display="";Ext.iterate(r,function(A,B){y=x[A];if(y){B.show();B.setText(Ext.isString(y)?y:Ext.MessageBox.buttonText[A]);z+=B.getEl().getWidth()+15}else{B.hide()}});return z};return{getDialog:function(x){if(!u){var z=[];r={};Ext.each(m,function(A){z.push(r[A]=new Ext.Button({text:this.buttonText[A],handler:c.createCallback(A),hideMode:"offsets"}))},this);u=new Ext.Window({autoCreate:true,title:x,resizable:false,constrain:true,constrainHeader:true,minimizable:false,maximizable:false,stateful:false,modal:true,shim:true,buttonAlign:"center",width:400,height:100,minHeight:80,plain:true,footer:true,closable:true,close:function(){if(b&&b.buttons&&b.buttons.no&&!b.buttons.cancel){c("no")}else{c("cancel")}},fbar:new Ext.Toolbar({items:z,enableOverflow:false})});u.render(document.body);u.getEl().addClass("x-window-dlg");q=u.mask;h=u.body.createChild({html:'

    '});j=Ext.get(h.dom.firstChild);var y=h.dom.childNodes[1];l=Ext.get(y.firstChild);s=Ext.get(y.childNodes[2].firstChild);s.enableDisplayMode();s.addKeyListener([10,13],function(){if(u.isVisible()&&b&&b.buttons){if(b.buttons.ok){c("ok")}else{if(b.buttons.yes){c("yes")}}}});a=Ext.get(y.childNodes[2].childNodes[1]);a.enableDisplayMode();n=new Ext.ProgressBar({renderTo:h});h.createChild({cls:"x-clear"})}return u},updateText:function(A){if(!u.isVisible()&&!b.width){u.setSize(this.maxWidth,100)}l.update(A?A+" ":" ");var y=d!=""?(j.getWidth()+j.getMargins("lr")):0,C=l.getWidth()+l.getMargins("lr"),z=u.getFrameWidth("lr"),B=u.body.getFrameWidth("lr"),x;x=Math.max(Math.min(b.width||y+C+z+B,b.maxWidth||this.maxWidth),Math.max(b.minWidth||this.minWidth,o||0));if(b.prompt===true){v.setWidth(x-y-z-B)}if(b.progress===true||b.wait===true){n.setSize(x-y-z-B)}if(Ext.isIE9m&&x==o){x+=4}l.update(A||" ");u.setSize(x,"auto").center();return this},updateProgress:function(y,x,z){n.updateProgress(y,x);if(z){this.updateText(z)}return this},isVisible:function(){return u&&u.isVisible()},hide:function(){var x=u?u.activeGhost:null;if(this.isVisible()||x){u.hide();w();if(x){u.unghost(false,false)}}return this},show:function(A){if(this.isVisible()){this.hide()}b=A;var B=this.getDialog(b.title||" ");B.setTitle(b.title||" ");var x=(b.closable!==false&&b.progress!==true&&b.wait!==true);B.tools.close.setDisplayed(x);v=s;b.prompt=b.prompt||(b.multiline?true:false);if(b.prompt){if(b.multiline){s.hide();a.show();a.setHeight(Ext.isNumber(b.multiline)?b.multiline:this.defaultTextHeight);v=a}else{s.show();a.hide()}}else{s.hide();a.hide()}v.dom.value=b.value||"";if(b.prompt){B.focusEl=v}else{var z=b.buttons;var y=null;if(z&&z.ok){y=r.ok}else{if(z&&z.yes){y=r.yes}}if(y){B.focusEl=y}}if(Ext.isDefined(b.iconCls)){B.setIconClass(b.iconCls)}this.setIcon(Ext.isDefined(b.icon)?b.icon:i);o=k(b.buttons);n.setVisible(b.progress===true||b.wait===true);this.updateProgress(0,b.progressText);this.updateText(b.msg);if(b.cls){B.el.addClass(b.cls)}B.proxyDrag=b.proxyDrag===true;B.modal=b.modal!==false;B.mask=b.modal!==false?q:false;if(!B.isVisible()){document.body.appendChild(u.el.dom);B.setAnimateTarget(b.animEl);B.on("show",function(){if(x===true){B.keyMap.enable()}else{B.keyMap.disable()}},this,{single:true});B.show(b.animEl)}if(b.wait===true){n.wait(b.waitConfig)}return this},setIcon:function(x){if(!u){i=x;return}i=undefined;if(x&&x!=""){j.removeClass("x-hidden");j.replaceClass(d,x);h.addClass("x-dlg-icon");d=x}else{j.replaceClass(d,"x-hidden");h.removeClass("x-dlg-icon");d=""}return this},progress:function(z,y,x){this.show({title:z,msg:y,buttons:false,progress:true,closable:false,minWidth:this.minProgressWidth,progressText:x});return this},wait:function(z,y,x){this.show({title:y,msg:z,buttons:false,closable:false,wait:true,modal:true,minWidth:this.minProgressWidth,waitConfig:x});return this},alert:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.OK,fn:y,scope:x,minWidth:this.minWidth});return this},confirm:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.YESNO,fn:y,scope:x,icon:this.QUESTION,minWidth:this.minWidth});return this},prompt:function(C,B,z,y,x,A){this.show({title:C,msg:B,buttons:this.OKCANCEL,fn:z,minWidth:this.minPromptWidth,scope:y,prompt:true,multiline:x,value:A});return this},OK:{ok:true},CANCEL:{cancel:true},OKCANCEL:{ok:true,cancel:true},YESNO:{yes:true,no:true},YESNOCANCEL:{yes:true,no:true,cancel:true},INFO:"ext-mb-info",WARNING:"ext-mb-warning",QUESTION:"ext-mb-question",ERROR:"ext-mb-error",defaultTextHeight:75,maxWidth:600,minWidth:100,minProgressWidth:250,minPromptWidth:250,buttonText:{ok:"OK",cancel:"Cancel",yes:"Yes",no:"No"}}}();Ext.Msg=Ext.MessageBox;Ext.dd.PanelProxy=Ext.extend(Object,{constructor:function(a,b){this.panel=a;this.id=this.panel.id+"-ddproxy";Ext.apply(this,b)},insertProxy:true,setStatus:Ext.emptyFn,reset:Ext.emptyFn,update:Ext.emptyFn,stop:Ext.emptyFn,sync:Ext.emptyFn,getEl:function(){return this.ghost},getGhost:function(){return this.ghost},getProxy:function(){return this.proxy},hide:function(){if(this.ghost){if(this.proxy){this.proxy.remove();delete this.proxy}this.panel.el.dom.style.display="";this.ghost.remove();delete this.ghost}},show:function(){if(!this.ghost){this.ghost=this.panel.createGhost(this.panel.initialConfig.cls,undefined,Ext.getBody());this.ghost.setXY(this.panel.el.getXY());if(this.insertProxy){this.proxy=this.panel.el.insertSibling({cls:"x-panel-dd-spacer"});this.proxy.setSize(this.panel.getSize())}this.panel.el.dom.style.display="none"}},repair:function(b,c,a){this.hide();if(typeof c=="function"){c.call(a||this)}},moveProxy:function(a,b){if(this.proxy){a.insertBefore(this.proxy.dom,b)}}});Ext.Panel.DD=Ext.extend(Ext.dd.DragSource,{constructor:function(b,a){this.panel=b;this.dragData={panel:b};this.proxy=new Ext.dd.PanelProxy(b,a);Ext.Panel.DD.superclass.constructor.call(this,b.el,a);var d=b.header,c=b.body;if(d){this.setHandleElId(d.id);c=b.header}c.setStyle("cursor","move");this.scroll=false},showFrame:Ext.emptyFn,startDrag:Ext.emptyFn,b4StartDrag:function(a,b){this.proxy.show()},b4MouseDown:function(b){var a=b.getPageX(),c=b.getPageY();this.autoOffset(a,c)},onInitDrag:function(a,b){this.onStartDrag(a,b);return true},createFrame:Ext.emptyFn,getDragEl:function(a){return this.proxy.ghost.dom},endDrag:function(a){this.proxy.hide();this.panel.saveState()},autoOffset:function(a,b){a-=this.startPageX;b-=this.startPageY;this.setDelta(a,b)}});Ext.state.Provider=Ext.extend(Ext.util.Observable,{constructor:function(){this.addEvents("statechange");this.state={};Ext.state.Provider.superclass.constructor.call(this)},get:function(b,a){return typeof this.state[b]=="undefined"?a:this.state[b]},clear:function(a){delete this.state[a];this.fireEvent("statechange",this,a,null)},set:function(a,b){this.state[a]=b;this.fireEvent("statechange",this,a,b)},decodeValue:function(b){var e=/^(a|n|d|b|s|o|e)\:(.*)$/,h=e.exec(unescape(b)),d,c,a,g;if(!h||!h[1]){return}c=h[1];a=h[2];switch(c){case"e":return null;case"n":return parseFloat(a);case"d":return new Date(Date.parse(a));case"b":return(a=="1");case"a":d=[];if(a!=""){Ext.each(a.split("^"),function(i){d.push(this.decodeValue(i))},this)}return d;case"o":d={};if(a!=""){Ext.each(a.split("^"),function(i){g=i.split("=");d[g[0]]=this.decodeValue(g[1])},this)}return d;default:return a}},encodeValue:function(c){var b,g="",e=0,a,d;if(c==null){return"e:1"}else{if(typeof c=="number"){b="n:"+c}else{if(typeof c=="boolean"){b="b:"+(c?"1":"0")}else{if(Ext.isDate(c)){b="d:"+c.toGMTString()}else{if(Ext.isArray(c)){for(a=c.length;e-1){var e=this.isSelected(b),c=this.all.elements[b],d=this.bufferRender([a],b)[0];this.all.replaceElement(b,d,true);if(e){this.selected.replaceElement(c,d);this.all.item(b).addClass(this.selectedClass)}this.updateIndexes(b,b)}},onAdd:function(g,d,e){if(this.all.getCount()===0){this.refresh();return}var c=this.bufferRender(d,e),h,b=this.all.elements;if(e0){if(!b){this.selected.removeClass(this.selectedClass)}this.selected.clear();this.last=false;if(!a){this.fireEvent("selectionchange",this,this.selected.elements)}}},isSelected:function(a){return this.selected.contains(this.getNode(a))},deselect:function(a){if(this.isSelected(a)){a=this.getNode(a);this.selected.removeElement(a);if(this.last==a.viewIndex){this.last=false}Ext.fly(a).removeClass(this.selectedClass);this.fireEvent("selectionchange",this,this.selected.elements)}},select:function(d,g,b){if(Ext.isArray(d)){if(!g){this.clearSelections(true)}for(var c=0,a=d.length;c=a&&d[c];c--){b.push(d[c])}}return b},indexOf:function(a){a=this.getNode(a);if(Ext.isNumber(a.viewIndex)){return a.viewIndex}return this.all.indexOf(a)},onBeforeLoad:function(){if(this.loadingText){this.clearSelections(false,true);this.getTemplateTarget().update('
    '+this.loadingText+"
    ");this.all.clear()}},onDestroy:function(){this.all.clear();this.selected.clear();Ext.DataView.superclass.onDestroy.call(this);this.bindStore(null)}});Ext.DataView.prototype.setStore=Ext.DataView.prototype.bindStore;Ext.reg("dataview",Ext.DataView);Ext.list.ListView=Ext.extend(Ext.DataView,{itemSelector:"dl",selectedClass:"x-list-selected",overClass:"x-list-over",scrollOffset:undefined,columnResize:true,columnSort:true,maxColumnWidth:Ext.isIE9m?99:100,initComponent:function(){if(this.columnResize){this.colResizer=new Ext.list.ColumnResizer(this.colResizer);this.colResizer.init(this)}if(this.columnSort){this.colSorter=new Ext.list.Sorter(this.columnSort);this.colSorter.init(this)}if(!this.internalTpl){this.internalTpl=new Ext.XTemplate('
    ','','
    ',"{header}","
    ","
    ",'
    ',"
    ",'
    ',"
    ")}if(!this.tpl){this.tpl=new Ext.XTemplate('',"
    ",'','
    ',' class="{cls}">',"{[values.tpl.apply(parent)]}","
    ","
    ",'
    ',"
    ","
    ")}var l=this.columns,h=0,k=0,m=l.length,b=[];for(var g=0;gthis.maxColumnWidth){n.width-=(h-this.maxColumnWidth)/100}k++}b.push(n)}l=this.columns=b;if(k10)){b.style.width=d;g.style.width=d}else{b.style.width=c+"px";g.style.width=c+"px";setTimeout(function(){if((a.offsetWidth-a.clientWidth)>10){b.style.width=d;g.style.width=d}},10)}}if(Ext.isNumber(e)){a.style.height=Math.max(0,e-g.parentNode.offsetHeight)+"px"}},updateIndexes:function(){Ext.list.ListView.superclass.updateIndexes.apply(this,arguments);this.verifyInternalSize()},findHeaderIndex:function(g){g=g.dom||g;var a=g.parentNode,d=a.parentNode.childNodes,b=0,e;for(;e=d[b];b++){if(e==a){return b}}return -1},setHdWidths:function(){var d=this.innerHd.dom.getElementsByTagName("div"),c=0,b=this.columns,a=b.length;for(;c','','{text}',"");d.disableFormats=true;d.compile();Ext.TabPanel.prototype.itemTpl=d}this.items.each(this.initTab,this)},afterRender:function(){Ext.TabPanel.superclass.afterRender.call(this);if(this.autoTabs){this.readTabs(false)}if(this.activeTab!==undefined){var a=Ext.isObject(this.activeTab)?this.activeTab:this.items.get(this.activeTab);delete this.activeTab;this.setActiveTab(a)}},initEvents:function(){Ext.TabPanel.superclass.initEvents.call(this);this.mon(this.strip,{scope:this,mousedown:this.onStripMouseDown,contextmenu:this.onStripContextMenu});if(this.enableTabScroll){this.mon(this.strip,"mousewheel",this.onWheel,this)}},findTargets:function(c){var b=null,a=c.getTarget("li:not(.x-tab-edge)",this.strip);if(a){b=this.getComponent(a.id.split(this.idDelimiter)[1]);if(b.disabled){return{close:null,item:null,el:null}}}return{close:c.getTarget(".x-tab-strip-close",this.strip),item:b,el:a}},onStripMouseDown:function(b){if(b.button!==0){return}b.preventDefault();var a=this.findTargets(b);if(a.close){if(a.item.fireEvent("beforeclose",a.item)!==false){a.item.fireEvent("close",a.item);this.remove(a.item)}return}if(a.item&&a.item!=this.activeTab){this.setActiveTab(a.item)}},onStripContextMenu:function(b){b.preventDefault();var a=this.findTargets(b);if(a.item){this.fireEvent("contextmenu",this,a.item,b)}},readTabs:function(d){if(d===true){this.items.each(function(h){this.remove(h)},this)}var c=this.el.query(this.autoTabSelector);for(var b=0,a=c.length;b0){this.setActiveTab(0)}else{this.setActiveTab(null)}}}if(!this.destroying){this.delegateUpdates()}},onBeforeShowItem:function(a){if(a!=this.activeTab){this.setActiveTab(a);return false}},onItemDisabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).addClass("x-item-disabled")}this.stack.remove(b)},onItemEnabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).removeClass("x-item-disabled")}},onItemTitleChanged:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).child("span.x-tab-strip-text",true).innerHTML=b.title;this.delegateUpdates()}},onItemIconChanged:function(d,a,c){var b=this.getTabEl(d);if(b){b=Ext.get(b);b.child("span.x-tab-strip-text").replaceClass(c,a);b[Ext.isEmpty(a)?"removeClass":"addClass"]("x-tab-with-icon");this.delegateUpdates()}},getTabEl:function(a){var b=this.getComponent(a);return b?b.tabEl:null},onResize:function(){Ext.TabPanel.superclass.onResize.apply(this,arguments);this.delegateUpdates()},beginUpdate:function(){this.suspendUpdates=true},endUpdate:function(){this.suspendUpdates=false;this.delegateUpdates()},hideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="none";this.delegateUpdates()}this.stack.remove(b)},unhideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="";this.delegateUpdates()}},delegateUpdates:function(){var a=this.rendered;if(this.suspendUpdates){return}if(this.resizeTabs&&a){this.autoSizeTabs()}if(this.enableTabScroll&&a){this.autoScrollTabs()}},autoSizeTabs:function(){var h=this.items.length,b=this.tabPosition!="bottom"?"header":"footer",c=this[b].dom.offsetWidth,a=this[b].dom.clientWidth;if(!this.resizeTabs||h<1||!a){return}var k=Math.max(Math.min(Math.floor((a-4)/h)-this.tabMargin,this.tabWidth),this.minTabWidth);this.lastTabWidth=k;var m=this.strip.query("li:not(.x-tab-edge)");for(var e=0,j=m.length;e20?c:20);if(!this.scrolling){if(!this.scrollLeft){this.createScrollers()}else{this.scrollLeft.show();this.scrollRight.show()}}this.scrolling=true;if(i>(a-c)){e.scrollLeft=a-c}else{this.scrollToTab(this.activeTab,false)}this.updateScrollButtons()}},createScrollers:function(){this.pos.addClass("x-tab-scrolling-"+this.tabPosition);var c=this.stripWrap.dom.offsetHeight;var a=this.pos.insertFirst({cls:"x-tab-scroller-left"});a.setHeight(c);a.addClassOnOver("x-tab-scroller-left-over");this.leftRepeater=new Ext.util.ClickRepeater(a,{interval:this.scrollRepeatInterval,handler:this.onScrollLeft,scope:this});this.scrollLeft=a;var b=this.pos.insertFirst({cls:"x-tab-scroller-right"});b.setHeight(c);b.addClassOnOver("x-tab-scroller-right-over");this.rightRepeater=new Ext.util.ClickRepeater(b,{interval:this.scrollRepeatInterval,handler:this.onScrollRight,scope:this});this.scrollRight=b},getScrollWidth:function(){return this.edge.getOffsetsTo(this.stripWrap)[0]+this.getScrollPos()},getScrollPos:function(){return parseInt(this.stripWrap.dom.scrollLeft,10)||0},getScrollArea:function(){return parseInt(this.stripWrap.dom.clientWidth,10)||0},getScrollAnim:function(){return{duration:this.scrollDuration,callback:this.updateScrollButtons,scope:this}},getScrollIncrement:function(){return this.scrollIncrement||(this.resizeTabs?this.lastTabWidth+2:100)},scrollToTab:function(e,a){if(!e){return}var c=this.getTabEl(e),h=this.getScrollPos(),d=this.getScrollArea(),g=Ext.fly(c).getOffsetsTo(this.stripWrap)[0]+h,b=g+c.offsetWidth;if(g(h+d)){this.scrollTo(b-d,a)}}},scrollTo:function(b,a){this.stripWrap.scrollTo("left",b,a?this.getScrollAnim():false);if(!a){this.updateScrollButtons()}},onWheel:function(g){var h=g.getWheelDelta()*this.wheelIncrement*-1;g.stopEvent();var i=this.getScrollPos(),c=i+h,a=this.getScrollWidth()-this.getScrollArea();var b=Math.max(0,Math.min(a,c));if(b!=i){this.scrollTo(b,false)}},onScrollRight:function(){var a=this.getScrollWidth()-this.getScrollArea(),c=this.getScrollPos(),b=Math.min(a,c+this.getScrollIncrement());if(b!=c){this.scrollTo(b,this.animScroll)}},onScrollLeft:function(){var b=this.getScrollPos(),a=Math.max(0,b-this.getScrollIncrement());if(a!=b){this.scrollTo(a,this.animScroll)}},updateScrollButtons:function(){var a=this.getScrollPos();this.scrollLeft[a===0?"addClass":"removeClass"]("x-tab-scroller-left-disabled");this.scrollRight[a>=(this.getScrollWidth()-this.getScrollArea())?"addClass":"removeClass"]("x-tab-scroller-right-disabled")},beforeDestroy:function(){Ext.destroy(this.leftRepeater,this.rightRepeater);this.deleteMembers("strip","edge","scrollLeft","scrollRight","stripWrap");this.activeTab=null;Ext.TabPanel.superclass.beforeDestroy.apply(this)}});Ext.reg("tabpanel",Ext.TabPanel);Ext.TabPanel.prototype.activate=Ext.TabPanel.prototype.setActiveTab;Ext.TabPanel.AccessStack=function(){var a=[];return{add:function(b){a.push(b);if(a.length>10){a.shift()}},remove:function(e){var d=[];for(var c=0,b=a.length;c','  ','  ','  ',"");Ext.Button.buttonTemplate.compile()}this.template=Ext.Button.buttonTemplate}var b,d=this.getTemplateArgs();if(a){b=this.template.insertBefore(a,d,true)}else{b=this.template.append(c,d,true)}this.btnEl=b.child(this.buttonSelector);this.mon(this.btnEl,{scope:this,focus:this.onFocus,blur:this.onBlur});this.initButtonEl(b,this.btnEl);Ext.ButtonToggleMgr.register(this)},initButtonEl:function(b,c){this.el=b;this.setIcon(this.icon);this.setText(this.text);this.setIconClass(this.iconCls);if(Ext.isDefined(this.tabIndex)){c.dom.tabIndex=this.tabIndex}if(this.tooltip){this.setTooltip(this.tooltip,true)}if(this.handleMouseEvents){this.mon(b,{scope:this,mouseover:this.onMouseOver,mousedown:this.onMouseDown})}if(this.menu){this.mon(this.menu,{scope:this,show:this.onMenuShow,hide:this.onMenuHide})}if(this.repeat){var a=new Ext.util.ClickRepeater(b,Ext.isObject(this.repeat)?this.repeat:{});this.mon(a,"click",this.onRepeatClick,this)}else{this.mon(b,this.clickEvent,this.onClick,this)}},afterRender:function(){Ext.Button.superclass.afterRender.call(this);this.useSetClass=true;this.setButtonClass();this.doc=Ext.getDoc();this.doAutoWidth()},setIconClass:function(a){this.iconCls=a;if(this.el){this.btnEl.dom.className="";this.btnEl.addClass(["x-btn-text",a||""]);this.setButtonClass()}return this},setTooltip:function(b,a){if(this.rendered){if(!a){this.clearTip()}if(Ext.isObject(b)){Ext.QuickTips.register(Ext.apply({target:this.btnEl.id},b));this.tooltip=b}else{this.btnEl.dom[this.tooltipType]=b}}else{this.tooltip=b}return this},clearTip:function(){if(Ext.isObject(this.tooltip)){Ext.QuickTips.unregister(this.btnEl)}},beforeDestroy:function(){if(this.rendered){this.clearTip()}if(this.menu&&this.destroyMenu!==false){Ext.destroy(this.btnEl,this.menu)}Ext.destroy(this.repeater)},onDestroy:function(){if(this.rendered){this.doc.un("mouseover",this.monitorMouseOver,this);this.doc.un("mouseup",this.onMouseUp,this);delete this.doc;delete this.btnEl;Ext.ButtonToggleMgr.unregister(this)}Ext.Button.superclass.onDestroy.call(this)},doAutoWidth:function(){if(this.autoWidth!==false&&this.el&&this.text&&this.width===undefined){this.el.setWidth("auto");if(Ext.isIE7&&Ext.isStrict){var a=this.btnEl;if(a&&a.getWidth()>20){a.clip();a.setWidth(Ext.util.TextMetrics.measure(a,this.text).width+a.getFrameWidth("lr"))}}if(this.minWidth){if(this.el.getWidth()a}else{return c.getPageY()>this.btnEl.getRegion().bottom}},onClick:function(b,a){b.preventDefault();if(!this.disabled){if(this.isClickOnArrow(b)){if(this.menu&&!this.menu.isVisible()&&!this.ignoreNextClick){this.showMenu()}this.fireEvent("arrowclick",this,b);if(this.arrowHandler){this.arrowHandler.call(this.scope||this,this,b)}}else{this.doToggle();this.fireEvent("click",this,b);if(this.handler){this.handler.call(this.scope||this,this,b)}}}},isMenuTriggerOver:function(a){return this.menu&&a.target.tagName==this.arrowSelector},isMenuTriggerOut:function(b,a){return this.menu&&b.target.tagName!=this.arrowSelector}});Ext.reg("splitbutton",Ext.SplitButton);Ext.CycleButton=Ext.extend(Ext.SplitButton,{getItemText:function(a){if(a&&this.showText===true){var b="";if(this.prependText){b+=this.prependText}b+=a.text;return b}return undefined},setActiveItem:function(c,a){if(!Ext.isObject(c)){c=this.menu.getComponent(c)}if(c){if(!this.rendered){this.text=this.getItemText(c);this.iconCls=c.iconCls}else{var b=this.getItemText(c);if(b){this.setText(b)}this.setIconClass(c.iconCls)}this.activeItem=c;if(!c.checked){c.setChecked(true,a)}if(this.forceIcon){this.setIconClass(this.forceIcon)}if(!a){this.fireEvent("change",this,c)}}},getActiveItem:function(){return this.activeItem},initComponent:function(){this.addEvents("change");if(this.changeHandler){this.on("change",this.changeHandler,this.scope||this);delete this.changeHandler}this.itemCount=this.items.length;this.menu={cls:"x-cycle-menu",items:[]};var a=0;Ext.each(this.items,function(c,b){Ext.apply(c,{group:c.group||this.id,itemIndex:b,checkHandler:this.checkHandler,scope:this,checked:c.checked||false});this.menu.items.push(c);if(c.checked){a=b}},this);Ext.CycleButton.superclass.initComponent.call(this);this.on("click",this.toggleSelected,this);this.setActiveItem(a,true)},checkHandler:function(a,b){if(b){this.setActiveItem(a)}},toggleSelected:function(){var a=this.menu;a.render();if(!a.hasLayout){a.doLayout()}var d,b;for(var c=1;c"){b=new a.Fill()}else{b=new a.TextItem(b)}}}this.applyDefaults(b)}else{if(b.isFormField||b.render){b=this.createComponent(b)}else{if(b.tag){b=new a.Item({autoEl:b})}else{if(b.tagName){b=new a.Item({el:b})}else{if(Ext.isObject(b)){b=b.xtype?this.createComponent(b):this.constructButton(b)}}}}}return b},applyDefaults:function(e){if(!Ext.isString(e)){e=Ext.Toolbar.superclass.applyDefaults.call(this,e);var b=this.internalDefaults;if(e.events){Ext.applyIf(e.initialConfig,b);Ext.apply(e,b)}else{Ext.applyIf(e,b)}}return e},addSeparator:function(){return this.add(new a.Separator())},addSpacer:function(){return this.add(new a.Spacer())},addFill:function(){this.add(new a.Fill())},addElement:function(b){return this.addItem(new a.Item({el:b}))},addItem:function(b){return this.add.apply(this,arguments)},addButton:function(c){if(Ext.isArray(c)){var e=[];for(var d=0,b=c.length;d");this.items.push(this.displayItem=new a.TextItem({}))}Ext.PagingToolbar.superclass.initComponent.call(this);this.addEvents("change","beforechange");this.on("afterlayout",this.onFirstLayout,this,{single:true});this.cursor=0;this.bindStore(this.store,true)},onFirstLayout:function(){if(this.dsLoaded){this.onLoad.apply(this,this.dsLoaded)}},updateInfo:function(){if(this.displayItem){var b=this.store.getCount();var c=b==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+b,this.store.getTotalCount());this.displayItem.setText(c)}},onLoad:function(b,e,j){if(!this.rendered){this.dsLoaded=[b,e,j];return}var g=this.getParams();this.cursor=(j.params&&j.params[g.start])?j.params[g.start]:0;var i=this.getPageData(),c=i.activePage,h=i.pages;this.afterTextItem.setText(String.format(this.afterPageText,i.pages));this.inputItem.setValue(c);this.first.setDisabled(c==1);this.prev.setDisabled(c==1);this.next.setDisabled(c==h);this.last.setDisabled(c==h);this.refresh.enable();this.updateInfo();this.fireEvent("change",this,i)},getPageData:function(){var b=this.store.getTotalCount();return{total:b,activePage:Math.ceil((this.cursor+this.pageSize)/this.pageSize),pages:b=1&g<=j.pages){i.setValue(g)}}}}}},getParams:function(){return this.paramNames||this.store.paramNames},beforeLoad:function(){if(this.rendered&&this.refresh){this.refresh.disable()}},doLoad:function(d){var c={},b=this.getParams();c[b.start]=d;c[b.limit]=this.pageSize;if(this.fireEvent("beforechange",this,c)!==false){this.store.load({params:c})}},moveFirst:function(){this.doLoad(0)},movePrevious:function(){this.doLoad(Math.max(0,this.cursor-this.pageSize))},moveNext:function(){this.doLoad(this.cursor+this.pageSize)},moveLast:function(){var c=this.store.getTotalCount(),b=c%this.pageSize;this.doLoad(b?(c-b):c-this.pageSize)},doRefresh:function(){this.doLoad(this.cursor)},bindStore:function(c,d){var b;if(!d&&this.store){if(c!==this.store&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.beforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.onLoadError,this)}if(!c){this.store=null}}if(c){c=Ext.StoreMgr.lookup(c);c.on({scope:this,beforeload:this.beforeLoad,load:this.onLoad,exception:this.onLoadError});b=true}this.store=c;if(b){this.onLoad(c,null,{})}},unbind:function(b){this.bindStore(null)},bind:function(b){this.bindStore(b)},onDestroy:function(){this.bindStore(null);Ext.PagingToolbar.superclass.onDestroy.call(this)}})})();Ext.reg("paging",Ext.PagingToolbar);Ext.History=(function(){var e,c;var k=false;var d;function g(){var l=location.href,m=l.indexOf("#"),n=m>=0?l.substr(m+1):null;if(Ext.isGecko){n=decodeURIComponent(n)}return n}function a(){c.value=d}function h(l){d=l;Ext.History.fireEvent("change",l)}function i(m){var l=['
    ',Ext.util.Format.htmlEncode(m),"
    "].join("");try{var o=e.contentWindow.document;o.open();o.write(l);o.close();return true}catch(n){return false}}function b(){if(!e.contentWindow||!e.contentWindow.document){setTimeout(b,10);return}var o=e.contentWindow.document;var m=o.getElementById("state");var l=m?m.innerText:null;var n=g();setInterval(function(){o=e.contentWindow.document;m=o.getElementById("state");var q=m?m.innerText:null;var p=g();if(q!==l){l=q;h(l);location.hash=l;n=l;a()}else{if(p!==n){n=p;i(p)}}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}function j(){d=c.value?c.value:g();if(Ext.isIE){b()}else{var l=g();setInterval(function(){var m=g();if(m!==l){l=m;h(l);a()}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}}return{fieldId:"x-history-field",iframeId:"x-history-frame",events:{},init:function(m,l){if(k){Ext.callback(m,l,[this]);return}if(!Ext.isReady){Ext.onReady(function(){Ext.History.init(m,l)});return}c=Ext.getDom(Ext.History.fieldId);if(Ext.isIE){e=Ext.getDom(Ext.History.iframeId)}this.addEvents("ready","change");if(m){this.on("ready",m,l,{single:true})}j()},add:function(l,m){if(m!==false){if(this.getToken()==l){return true}}if(Ext.isIE){return i(l)}else{location.hash=l;return true}},back:function(){history.go(-1)},forward:function(){history.go(1)},getToken:function(){return k?d:g()}}})();Ext.apply(Ext.History,new Ext.util.Observable());Ext.Tip=Ext.extend(Ext.Panel,{minWidth:40,maxWidth:300,shadow:"sides",defaultAlign:"tl-bl?",autoRender:true,quickShowInterval:250,frame:true,hidden:true,baseCls:"x-tip",floating:{shadow:true,shim:true,useDisplay:true,constrain:false},autoHeight:true,closeAction:"hide",initComponent:function(){Ext.Tip.superclass.initComponent.call(this);if(this.closable&&!this.title){this.elements+=",header"}},afterRender:function(){Ext.Tip.superclass.afterRender.call(this);if(this.closable){this.addTool({id:"close",handler:this[this.closeAction],scope:this})}},showAt:function(a){Ext.Tip.superclass.show.call(this);if(this.measureWidth!==false&&(!this.initialConfig||typeof this.initialConfig.width!="number")){this.doAutoWidth()}if(this.constrainPosition){a=this.el.adjustForConstraints(a)}this.setPagePosition(a[0],a[1])},doAutoWidth:function(a){a=a||0;var b=this.body.getTextWidth();if(this.title){b=Math.max(b,this.header.child("span").getTextWidth(this.title))}b+=this.getFrameWidth()+(this.closable?20:0)+this.body.getPadding("lr")+a;this.setWidth(b.constrain(this.minWidth,this.maxWidth));if(Ext.isIE7&&!this.repainted){this.el.repaint();this.repainted=true}},showBy:function(a,b){if(!this.rendered){this.render(Ext.getBody())}this.showAt(this.el.getAlignToXY(a,b||this.defaultAlign))},initDraggable:function(){this.dd=new Ext.Tip.DD(this,typeof this.draggable=="boolean"?null:this.draggable);this.header.addClass("x-tip-draggable")}});Ext.reg("tip",Ext.Tip);Ext.Tip.DD=function(b,a){Ext.apply(this,a);this.tip=b;Ext.Tip.DD.superclass.constructor.call(this,b.el.id,"WindowDD-"+b.id);this.setHandleElId(b.header.id);this.scroll=false};Ext.extend(Ext.Tip.DD,Ext.dd.DD,{moveOnly:true,scroll:false,headerOffsets:[100,25],startDrag:function(){this.tip.el.disableShadow()},endDrag:function(a){this.tip.el.enableShadow(true)}});Ext.ToolTip=Ext.extend(Ext.Tip,{showDelay:500,hideDelay:200,dismissDelay:5000,trackMouse:false,anchorToTarget:true,anchorOffset:0,targetCounter:0,constrainPosition:false,initComponent:function(){Ext.ToolTip.superclass.initComponent.call(this);this.lastActive=new Date();this.initTarget(this.target);this.origAnchor=this.anchor},onRender:function(b,a){Ext.ToolTip.superclass.onRender.call(this,b,a);this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl=this.el.createChild({cls:"x-tip-anchor "+this.anchorCls})},afterRender:function(){Ext.ToolTip.superclass.afterRender.call(this);this.anchorEl.setStyle("z-index",this.el.getZIndex()+1).setVisibilityMode(Ext.Element.DISPLAY)},initTarget:function(c){var a;if((a=Ext.get(c))){if(this.target){var b=Ext.get(this.target);this.mun(b,"mouseover",this.onTargetOver,this);this.mun(b,"mouseout",this.onTargetOut,this);this.mun(b,"mousemove",this.onMouseMove,this)}this.mon(a,{mouseover:this.onTargetOver,mouseout:this.onTargetOut,mousemove:this.onMouseMove,scope:this});this.target=a}if(this.anchor){this.anchorTarget=this.target}},onMouseMove:function(b){var a=this.delegate?b.getTarget(this.delegate):this.triggerElement=true;if(a){this.targetXY=b.getXY();if(a===this.triggerElement){if(!this.hidden&&this.trackMouse){this.setPagePosition(this.getTargetXY())}}else{this.hide();this.lastActive=new Date(0);this.onTargetOver(b)}}else{if(!this.closable&&this.isVisible()){this.hide()}}},getTargetXY:function(){if(this.delegate){this.anchorTarget=this.triggerElement}if(this.anchor){this.targetCounter++;var c=this.getOffsets(),l=(this.anchorToTarget&&!this.trackMouse)?this.el.getAlignToXY(this.anchorTarget,this.getAnchorAlign()):this.targetXY,a=Ext.lib.Dom.getViewWidth()-5,h=Ext.lib.Dom.getViewHeight()-5,i=document.documentElement,e=document.body,k=(i.scrollLeft||e.scrollLeft||0)+5,j=(i.scrollTop||e.scrollTop||0)+5,b=[l[0]+c[0],l[1]+c[1]],g=this.getSize();this.anchorEl.removeClass(this.anchorCls);if(this.targetCounter<2){if(b[0]a){if(this.anchorToTarget){this.defaultAlign="r-l";if(this.mouseOffset){this.mouseOffset[0]*=-1}}this.anchor="right";return this.getTargetXY()}if(b[1]h){if(this.anchorToTarget){this.defaultAlign="b-t";if(this.mouseOffset){this.mouseOffset[1]*=-1}}this.anchor="bottom";return this.getTargetXY()}}this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl.addClass(this.anchorCls);this.targetCounter=0;return b}else{var d=this.getMouseOffset();return[this.targetXY[0]+d[0],this.targetXY[1]+d[1]]}},getMouseOffset:function(){var a=this.anchor?[0,0]:[15,18];if(this.mouseOffset){a[0]+=this.mouseOffset[0];a[1]+=this.mouseOffset[1]}return a},getAnchorPosition:function(){if(this.anchor){this.tipAnchor=this.anchor.charAt(0)}else{var a=this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!a){throw"AnchorTip.defaultAlign is invalid"}this.tipAnchor=a[1].charAt(0)}switch(this.tipAnchor){case"t":return"top";case"b":return"bottom";case"r":return"right"}return"left"},getAnchorAlign:function(){switch(this.anchor){case"top":return"tl-bl";case"left":return"tl-tr";case"right":return"tr-tl";default:return"bl-tl"}},getOffsets:function(){var b,a=this.getAnchorPosition().charAt(0);if(this.anchorToTarget&&!this.trackMouse){switch(a){case"t":b=[0,9];break;case"b":b=[0,-13];break;case"r":b=[-13,0];break;default:b=[9,0];break}}else{switch(a){case"t":b=[-15-this.anchorOffset,30];break;case"b":b=[-19-this.anchorOffset,-13-this.el.dom.offsetHeight];break;case"r":b=[-15-this.el.dom.offsetWidth,-13-this.anchorOffset];break;default:b=[25,-13-this.anchorOffset];break}}var c=this.getMouseOffset();b[0]+=c[0];b[1]+=c[1];return b},onTargetOver:function(b){if(this.disabled||b.within(this.target.dom,true)){return}var a=b.getTarget(this.delegate);if(a){this.triggerElement=a;this.clearTimer("hide");this.targetXY=b.getXY();this.delayShow()}},delayShow:function(){if(this.hidden&&!this.showTimer){if(this.lastActive.getElapsed()=c){d=c-b-5}}return{x:a,y:d}},beforeDestroy:function(){this.clearTimers();Ext.destroy(this.anchorEl);delete this.anchorEl;delete this.target;delete this.anchorTarget;delete this.triggerElement;Ext.ToolTip.superclass.beforeDestroy.call(this)},onDestroy:function(){Ext.getDoc().un("mousedown",this.onDocMouseDown,this);Ext.ToolTip.superclass.onDestroy.call(this)}});Ext.reg("tooltip",Ext.ToolTip);Ext.QuickTip=Ext.extend(Ext.ToolTip,{interceptTitles:false,tagConfig:{namespace:"ext",attribute:"qtip",width:"qwidth",target:"target",title:"qtitle",hide:"hide",cls:"qclass",align:"qalign",anchor:"anchor"},initComponent:function(){this.target=this.target||Ext.getDoc();this.targets=this.targets||{};Ext.QuickTip.superclass.initComponent.call(this)},register:function(e){var h=Ext.isArray(e)?e:arguments;for(var g=0,a=h.length;g1){var d=function(i,h){if(i&&h){var j=h.findChild(a,b);if(j){j.select();if(g){g(true,j)}}else{if(g){g(false,j)}}}else{if(g){g(false,j)}}};this.expandPath(c.join(this.pathSeparator),a,d)}else{this.root.select();if(g){g(true,this.root)}}},getTreeEl:function(){return this.body},onRender:function(b,a){Ext.tree.TreePanel.superclass.onRender.call(this,b,a);this.el.addClass("x-tree");this.innerCt=this.body.createChild({tag:"ul",cls:"x-tree-root-ct "+(this.useArrows?"x-tree-arrows":this.lines?"x-tree-lines":"x-tree-no-lines")})},initEvents:function(){Ext.tree.TreePanel.superclass.initEvents.call(this);if(this.containerScroll){Ext.dd.ScrollManager.register(this.body)}if((this.enableDD||this.enableDrop)&&!this.dropZone){this.dropZone=new Ext.tree.TreeDropZone(this,this.dropConfig||{ddGroup:this.ddGroup||"TreeDD",appendOnly:this.ddAppendOnly===true})}if((this.enableDD||this.enableDrag)&&!this.dragZone){this.dragZone=new Ext.tree.TreeDragZone(this,this.dragConfig||{ddGroup:this.ddGroup||"TreeDD",scroll:this.ddScroll})}this.getSelectionModel().init(this)},afterRender:function(){Ext.tree.TreePanel.superclass.afterRender.call(this);this.renderRoot()},beforeDestroy:function(){if(this.rendered){Ext.dd.ScrollManager.unregister(this.body);Ext.destroy(this.dropZone,this.dragZone)}this.destroyRoot();Ext.destroy(this.loader);this.nodeHash=this.root=this.loader=null;Ext.tree.TreePanel.superclass.beforeDestroy.call(this)},destroyRoot:function(){if(this.root&&this.root.destroy){this.root.destroy(true)}}});Ext.tree.TreePanel.nodeTypes={};Ext.reg("treepanel",Ext.tree.TreePanel);Ext.tree.TreeEventModel=function(a){this.tree=a;this.tree.on("render",this.initEvents,this)};Ext.tree.TreeEventModel.prototype={initEvents:function(){var a=this.tree;if(a.trackMouseOver!==false){a.mon(a.innerCt,{scope:this,mouseover:this.delegateOver,mouseout:this.delegateOut})}a.mon(a.getTreeEl(),{scope:this,click:this.delegateClick,dblclick:this.delegateDblClick,contextmenu:this.delegateContextMenu})},getNode:function(b){var a;if(a=b.getTarget(".x-tree-node-el",10)){var c=Ext.fly(a,"_treeEvents").getAttribute("tree-node-id","ext");if(c){return this.tree.getNodeById(c)}}return null},getNodeTarget:function(b){var a=b.getTarget(".x-tree-node-icon",1);if(!a){a=b.getTarget(".x-tree-node-el",6)}return a},delegateOut:function(b,a){if(!this.beforeEvent(b)){return}if(b.getTarget(".x-tree-ec-icon",1)){var c=this.getNode(b);this.onIconOut(b,c);if(c==this.lastEcOver){delete this.lastEcOver}}if((a=this.getNodeTarget(b))&&!b.within(a,true)){this.onNodeOut(b,this.getNode(b))}},delegateOver:function(b,a){if(!this.beforeEvent(b)){return}if(Ext.isGecko&&!this.trackingDoc){Ext.getBody().on("mouseover",this.trackExit,this);this.trackingDoc=true}if(this.lastEcOver){this.onIconOut(b,this.lastEcOver);delete this.lastEcOver}if(b.getTarget(".x-tree-ec-icon",1)){this.lastEcOver=this.getNode(b);this.onIconOver(b,this.lastEcOver)}if(a=this.getNodeTarget(b)){this.onNodeOver(b,this.getNode(b))}},trackExit:function(a){if(this.lastOverNode){if(this.lastOverNode.ui&&!a.within(this.lastOverNode.ui.getEl())){this.onNodeOut(a,this.lastOverNode)}delete this.lastOverNode;Ext.getBody().un("mouseover",this.trackExit,this);this.trackingDoc=false}},delegateClick:function(b,a){if(this.beforeEvent(b)){if(b.getTarget("input[type=checkbox]",1)){this.onCheckboxClick(b,this.getNode(b))}else{if(b.getTarget(".x-tree-ec-icon",1)){this.onIconClick(b,this.getNode(b))}else{if(this.getNodeTarget(b)){this.onNodeClick(b,this.getNode(b))}}}}else{this.checkContainerEvent(b,"click")}},delegateDblClick:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeDblClick(b,this.getNode(b))}}else{this.checkContainerEvent(b,"dblclick")}},delegateContextMenu:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeContextMenu(b,this.getNode(b))}}else{this.checkContainerEvent(b,"contextmenu")}},checkContainerEvent:function(b,a){if(this.disabled){b.stopEvent();return false}this.onContainerEvent(b,a)},onContainerEvent:function(b,a){this.tree.fireEvent("container"+a,this.tree,b)},onNodeClick:function(b,a){a.ui.onClick(b)},onNodeOver:function(b,a){this.lastOverNode=a;a.ui.onOver(b)},onNodeOut:function(b,a){a.ui.onOut(b)},onIconOver:function(b,a){a.ui.addClass("x-tree-ec-over")},onIconOut:function(b,a){a.ui.removeClass("x-tree-ec-over")},onIconClick:function(b,a){a.ui.ecClick(b)},onCheckboxClick:function(b,a){a.ui.onCheckChange(b)},onNodeDblClick:function(b,a){a.ui.onDblClick(b)},onNodeContextMenu:function(b,a){a.ui.onContextMenu(b)},beforeEvent:function(b){var a=this.getNode(b);if(this.disabled||!a||!a.ui){b.stopEvent();return false}return true},disable:function(){this.disabled=true},enable:function(){this.disabled=false}};Ext.tree.DefaultSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNode=null;this.addEvents("selectionchange","beforeselect");Ext.apply(this,a);Ext.tree.DefaultSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){this.select(a)},select:function(c,a){if(!Ext.fly(c.ui.wrap).isVisible()&&a){return a.call(this,c)}var b=this.selNode;if(c==b){c.ui.onSelectedChange(true)}else{if(this.fireEvent("beforeselect",this,c,b)!==false){if(b&&b.ui){b.ui.onSelectedChange(false)}this.selNode=c;c.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,c,b)}}return c},unselect:function(b,a){if(this.selNode==b){this.clearSelections(a)}},clearSelections:function(a){var b=this.selNode;if(b){b.ui.onSelectedChange(false);this.selNode=null;if(a!==true){this.fireEvent("selectionchange",this,null)}}return b},getSelectedNode:function(){return this.selNode},isSelected:function(a){return this.selNode==a},selectPrevious:function(a){if(!(a=a||this.selNode||this.lastSelNode)){return null}var c=a.previousSibling;if(c){if(!c.isExpanded()||c.childNodes.length<1){return this.select(c,this.selectPrevious)}else{var b=c.lastChild;while(b&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()&&b.childNodes.length>0){b=b.lastChild}return this.select(b,this.selectPrevious)}}else{if(a.parentNode&&(this.tree.rootVisible||!a.parentNode.isRoot)){return this.select(a.parentNode,this.selectPrevious)}}return null},selectNext:function(b){if(!(b=b||this.selNode||this.lastSelNode)){return null}if(b.firstChild&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()){return this.select(b.firstChild,this.selectNext)}else{if(b.nextSibling){return this.select(b.nextSibling,this.selectNext)}else{if(b.parentNode){var a=null;b.parentNode.bubble(function(){if(this.nextSibling){a=this.getOwnerTree().selModel.select(this.nextSibling,this.selectNext);return false}});return a}}}return null},onKeyDown:function(c){var b=this.selNode||this.lastSelNode;var d=this;if(!b){return}var a=c.getKey();switch(a){case c.DOWN:c.stopEvent();this.selectNext();break;case c.UP:c.stopEvent();this.selectPrevious();break;case c.RIGHT:c.preventDefault();if(b.hasChildNodes()){if(!b.isExpanded()){b.expand()}else{if(b.firstChild){this.select(b.firstChild,c)}}}break;case c.LEFT:c.preventDefault();if(b.hasChildNodes()&&b.isExpanded()){b.collapse()}else{if(b.parentNode&&(this.tree.rootVisible||b.parentNode!=this.tree.getRootNode())){this.select(b.parentNode,c)}}break}}});Ext.tree.MultiSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNodes=[];this.selMap={};this.addEvents("selectionchange");Ext.apply(this,a);Ext.tree.MultiSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){if(b.ctrlKey&&this.isSelected(a)){this.unselect(a)}else{this.select(a,b,b.ctrlKey)}},select:function(a,c,b){if(b!==true){this.clearSelections(true)}if(this.isSelected(a)){this.lastSelNode=a;return a}this.selNodes.push(a);this.selMap[a.id]=a;this.lastSelNode=a;a.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,this.selNodes);return a},unselect:function(b){if(this.selMap[b.id]){b.ui.onSelectedChange(false);var c=this.selNodes;var a=c.indexOf(b);if(a!=-1){this.selNodes.splice(a,1)}delete this.selMap[b.id];this.fireEvent("selectionchange",this,this.selNodes)}},clearSelections:function(b){var d=this.selNodes;if(d.length>0){for(var c=0,a=d.length;c0},isExpandable:function(){return this.attributes.expandable||this.hasChildNodes()},appendChild:function(e){var g=false;if(Ext.isArray(e)){g=e}else{if(arguments.length>1){g=arguments}}if(g){for(var d=0,a=g.length;d0){var g=d?function(){e.apply(d,arguments)}:e;c.sort(g);for(var b=0;b
    ','',this.indentMarkup,"",'','',g?('':"/>")):"",'',e.text,"
    ",'',""].join("");if(l!==true&&e.nextSibling&&(b=e.nextSibling.ui.getEl())){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",b,d)}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",j,d)}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1];var i=this.elNode.childNodes;this.indentNode=i[0];this.ecNode=i[1];this.iconNode=i[2];var h=3;if(g){this.checkbox=i[3];this.checkbox.defaultChecked=this.checkbox.checked;h++}this.anchor=i[h];this.textNode=i[h].firstChild},getHref:function(a){return Ext.isEmpty(a)?(Ext.isGecko?"":"#"):a},getAnchor:function(){return this.anchor},getTextEl:function(){return this.textNode},getIconEl:function(){return this.iconNode},isChecked:function(){return this.checkbox?this.checkbox.checked:false},updateExpandIcon:function(){if(this.rendered){var g=this.node,d,c,a=g.isLast()?"x-tree-elbow-end":"x-tree-elbow",e=g.hasChildNodes();if(e||g.attributes.expandable){if(g.expanded){a+="-minus";d="x-tree-node-collapsed";c="x-tree-node-expanded"}else{a+="-plus";d="x-tree-node-expanded";c="x-tree-node-collapsed"}if(this.wasLeaf){this.removeClass("x-tree-node-leaf");this.wasLeaf=false}if(this.c1!=d||this.c2!=c){Ext.fly(this.elNode).replaceClass(d,c);this.c1=d;this.c2=c}}else{if(!this.wasLeaf){Ext.fly(this.elNode).replaceClass("x-tree-node-expanded","x-tree-node-collapsed");delete this.c1;delete this.c2;this.wasLeaf=true}}var b="x-tree-ec-icon "+a;if(this.ecc!=b){this.ecNode.className=b;this.ecc=b}}},onIdChange:function(a){if(this.rendered){this.elNode.setAttribute("ext:tree-node-id",a)}},getChildIndent:function(){if(!this.childIndent){var a=[],b=this.node;while(b){if(!b.isRoot||(b.isRoot&&b.ownerTree.rootVisible)){if(!b.isLast()){a.unshift('')}else{a.unshift('')}}b=b.parentNode}this.childIndent=a.join("")}return this.childIndent},renderIndent:function(){if(this.rendered){var a="",b=this.node.parentNode;if(b){a=b.ui.getChildIndent()}if(this.indentMarkup!=a){this.indentNode.innerHTML=a;this.indentMarkup=a}this.updateExpandIcon()}},destroy:function(){if(this.elNode){Ext.dd.Registry.unregister(this.elNode.id)}Ext.each(["textnode","anchor","checkbox","indentNode","ecNode","iconNode","elNode","ctNode","wrap","holder"],function(a){if(this[a]){Ext.fly(this[a]).remove();delete this[a]}},this);delete this.node}});Ext.tree.RootTreeNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{render:function(){if(!this.rendered){var a=this.node.ownerTree.innerCt.dom;this.node.expanded=true;a.innerHTML='
    ';this.wrap=this.ctNode=a.firstChild}},collapse:Ext.emptyFn,expand:Ext.emptyFn});Ext.tree.TreeLoader=function(a){this.baseParams={};Ext.apply(this,a);this.addEvents("beforeload","load","loadexception");Ext.tree.TreeLoader.superclass.constructor.call(this);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}};Ext.extend(Ext.tree.TreeLoader,Ext.util.Observable,{uiProviders:{},clearOnLoad:true,paramOrder:undefined,paramsAsHash:false,nodeParameter:"node",directFn:undefined,load:function(b,c,a){if(this.clearOnLoad){while(b.firstChild){b.removeChild(b.firstChild)}}if(this.doPreload(b)){this.runCallback(c,a||b,[b])}else{if(this.directFn||this.dataUrl||this.url){this.requestData(b,c,a||b)}}},doPreload:function(d){if(d.attributes.children){if(d.childNodes.length<1){var c=d.attributes.children;d.beginUpdate();for(var b=0,a=c.length;b-1){c=[]}for(var d=0,a=b.length;dp){return e?-1:1}}return 0}},doSort:function(a){a.sort(this.sortFn)},updateSort:function(a,b){if(b.childrenRendered){this.doSort.defer(1,this,[b])}},updateSortParent:function(a){var b=a.parentNode;if(b&&b.childrenRendered){this.doSort.defer(1,this,[b])}}});if(Ext.dd.DropZone){Ext.tree.TreeDropZone=function(a,b){this.allowParentInsert=b.allowParentInsert||false;this.allowContainerDrop=b.allowContainerDrop||false;this.appendOnly=b.appendOnly||false;Ext.tree.TreeDropZone.superclass.constructor.call(this,a.getTreeEl(),b);this.tree=a;this.dragOverData={};this.lastInsertClass="x-tree-no-status"};Ext.extend(Ext.tree.TreeDropZone,Ext.dd.DropZone,{ddGroup:"TreeDD",expandDelay:1000,expandNode:function(a){if(a.hasChildNodes()&&!a.isExpanded()){a.expand(false,null,this.triggerCacheRefresh.createDelegate(this))}},queueExpand:function(a){this.expandProcId=this.expandNode.defer(this.expandDelay,this,[a])},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId);this.expandProcId=false}},isValidDropPoint:function(a,k,i,d,c){if(!a||!c){return false}var g=a.node;var h=c.node;if(!(g&&g.isTarget&&k)){return false}if(k=="append"&&g.allowChildren===false){return false}if((k=="above"||k=="below")&&(g.parentNode&&g.parentNode.allowChildren===false)){return false}if(h&&(g==h||h.contains(g))){return false}var b=this.dragOverData;b.tree=this.tree;b.target=g;b.data=c;b.point=k;b.source=i;b.rawEvent=d;b.dropNode=h;b.cancel=false;var j=this.tree.fireEvent("nodedragover",b);return b.cancel===false&&j!==false},getDropPoint:function(h,g,l){var m=g.node;if(m.isRoot){return m.allowChildren!==false?"append":false}var c=g.ddel;var o=Ext.lib.Dom.getY(c),j=o+c.offsetHeight;var i=Ext.lib.Event.getPageY(h);var k=m.allowChildren===false||m.isLeaf();if(this.appendOnly||m.parentNode.allowChildren===false){return k?false:"append"}var d=false;if(!this.allowParentInsert){d=m.hasChildNodes()&&m.isExpanded()}var a=(j-o)/(k?2:3);if(i>=o&&i<(o+a)){return"above"}else{if(!d&&(k||i>=j-a&&i<=j)){return"below"}else{return"append"}}},onNodeEnter:function(d,a,c,b){this.cancelExpand()},onContainerOver:function(a,c,b){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,c,b)){return this.dropAllowed}return this.dropNotAllowed},onNodeOver:function(b,i,h,g){var k=this.getDropPoint(h,b,i);var c=b.node;if(!this.expandProcId&&k=="append"&&c.hasChildNodes()&&!b.node.isExpanded()){this.queueExpand(c)}else{if(k!="append"){this.cancelExpand()}}var d=this.dropNotAllowed;if(this.isValidDropPoint(b,k,i,h,g)){if(k){var a=b.ddel;var j;if(k=="above"){d=b.node.isFirst()?"x-tree-drop-ok-above":"x-tree-drop-ok-between";j="x-tree-drag-insert-above"}else{if(k=="below"){d=b.node.isLast()?"x-tree-drop-ok-below":"x-tree-drop-ok-between";j="x-tree-drag-insert-below"}else{d="x-tree-drop-ok-append";j="x-tree-drag-append"}}if(this.lastInsertClass!=j){Ext.fly(a).replaceClass(this.lastInsertClass,j);this.lastInsertClass=j}}}return d},onNodeOut:function(d,a,c,b){this.cancelExpand();this.removeDropIndicators(d)},onNodeDrop:function(i,b,h,d){var a=this.getDropPoint(h,i,b);var g=i.node;g.ui.startDrop();if(!this.isValidDropPoint(i,a,b,h,d)){g.ui.endDrop();return false}var c=d.node||(b.getTreeNode?b.getTreeNode(d,g,a,h):null);return this.processDrop(g,d,a,b,h,c)},onContainerDrop:function(a,g,c){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,g,c)){var d=this.tree.getRootNode();d.ui.startDrop();var b=c.node||(a.getTreeNode?a.getTreeNode(c,d,"append",g):null);return this.processDrop(d,c,"append",a,g,b)}return false},processDrop:function(j,h,b,a,i,d){var g={tree:this.tree,target:j,data:h,point:b,source:a,rawEvent:i,dropNode:d,cancel:!d,dropStatus:false};var c=this.tree.fireEvent("beforenodedrop",g);if(c===false||g.cancel===true||!g.dropNode){j.ui.endDrop();return g.dropStatus}j=g.target;if(b=="append"&&!j.isExpanded()){j.expand(false,null,function(){this.completeDrop(g)}.createDelegate(this))}else{this.completeDrop(g)}return true},completeDrop:function(h){var d=h.dropNode,e=h.point,c=h.target;if(!Ext.isArray(d)){d=[d]}var g;for(var b=0,a=d.length;bd.offsetLeft){e.scrollLeft=d.offsetLeft}var a=Math.min(this.maxWidth,(e.clientWidth>20?e.clientWidth:e.offsetWidth)-Math.max(0,d.offsetLeft-e.scrollLeft)-5);this.setSize(a,"")},triggerEdit:function(a,c){this.completeEdit();if(a.attributes.editable!==false){this.editNode=a;if(this.tree.autoScroll){Ext.fly(a.ui.getEl()).scrollIntoView(this.tree.body)}var b=a.text||"";if(!Ext.isGecko&&Ext.isEmpty(a.text)){a.setText(" ")}this.autoEditTimer=this.startEdit.defer(this.editDelay,this,[a.ui.textNode,b]);return false}},bindScroll:function(){this.tree.getTreeEl().on("scroll",this.cancelEdit,this)},beforeNodeClick:function(a,b){clearTimeout(this.autoEditTimer);if(this.tree.getSelectionModel().isSelected(a)){b.stopEvent();return this.triggerEdit(a)}},onNodeDblClick:function(a,b){clearTimeout(this.autoEditTimer)},updateNode:function(a,b){this.tree.getTreeEl().un("scroll",this.cancelEdit,this);this.editNode.setText(b)},onHide:function(){Ext.tree.TreeEditor.superclass.onHide.call(this);if(this.editNode){this.editNode.ui.focus.defer(50,this.editNode.ui)}},onSpecialKey:function(c,b){var a=b.getKey();if(a==b.ESC){b.stopEvent();this.cancelEdit()}else{if(a==b.ENTER&&!b.hasModifier()){b.stopEvent();this.completeEdit()}}},onDestroy:function(){clearTimeout(this.autoEditTimer);Ext.tree.TreeEditor.superclass.onDestroy.call(this);var a=this.tree;a.un("beforeclick",this.beforeNodeClick,this);a.un("dblclick",this.onNodeDblClick,this)}});var swfobject=function(){var E="undefined",s="object",T="Shockwave Flash",X="ShockwaveFlash.ShockwaveFlash",r="application/x-shockwave-flash",S="SWFObjectExprInst",y="onreadystatechange",P=window,k=document,u=navigator,U=false,V=[i],p=[],O=[],J=[],m,R,F,C,K=false,a=false,o,H,n=true,N=function(){var ab=typeof k.getElementById!=E&&typeof k.getElementsByTagName!=E&&typeof k.createElement!=E,ai=u.userAgent.toLowerCase(),Z=u.platform.toLowerCase(),af=Z?(/win/).test(Z):/win/.test(ai),ad=Z?(/mac/).test(Z):/mac/.test(ai),ag=/webkit/.test(ai)?parseFloat(ai.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,Y=!+"\v1",ah=[0,0,0],ac=null;if(typeof u.plugins!=E&&typeof u.plugins[T]==s){ac=u.plugins[T].description;if(ac&&!(typeof u.mimeTypes!=E&&u.mimeTypes[r]&&!u.mimeTypes[r].enabledPlugin)){U=true;Y=false;ac=ac.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ah[0]=parseInt(ac.replace(/^(.*)\..*$/,"$1"),10);ah[1]=parseInt(ac.replace(/^.*\.(.*)\s.*$/,"$1"),10);ah[2]=/[a-zA-Z]/.test(ac)?parseInt(ac.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof P.ActiveXObject!=E){try{var ae=new ActiveXObject(X);if(ae){ac=ae.GetVariable("$version");if(ac){Y=true;ac=ac.split(" ")[1].split(",");ah=[parseInt(ac[0],10),parseInt(ac[1],10),parseInt(ac[2],10)]}}}catch(aa){}}}return{w3:ab,pv:ah,wk:ag,ie:Y,win:af,mac:ad}}(),l=function(){if(!N.w3){return}if((typeof k.readyState!=E&&k.readyState=="complete")||(typeof k.readyState==E&&(k.getElementsByTagName("body")[0]||k.body))){g()}if(!K){if(typeof k.addEventListener!=E){k.addEventListener("DOMContentLoaded",g,false)}if(N.ie&&N.win){k.attachEvent(y,function(){if(k.readyState=="complete"){k.detachEvent(y,arguments.callee);g()}});if(P==top){(function(){if(K){return}try{k.documentElement.doScroll("left")}catch(Y){setTimeout(arguments.callee,0);return}g()})()}}if(N.wk){(function(){if(K){return}if(!(/loaded|complete/).test(k.readyState)){setTimeout(arguments.callee,0);return}g()})()}t(g)}}();function g(){if(K){return}try{var aa=k.getElementsByTagName("body")[0].appendChild(D("span"));aa.parentNode.removeChild(aa)}catch(ab){return}K=true;var Y=V.length;for(var Z=0;Z0){for(var ag=0;ag0){var af=c(Z);if(af){if(G(p[ag].swfVersion)&&!(N.wk&&N.wk<312)){x(Z,true);if(ac){ab.success=true;ab.ref=A(Z);ac(ab)}}else{if(p[ag].expressInstall&&B()){var aj={};aj.data=p[ag].expressInstall;aj.width=af.getAttribute("width")||"0";aj.height=af.getAttribute("height")||"0";if(af.getAttribute("class")){aj.styleclass=af.getAttribute("class")}if(af.getAttribute("align")){aj.align=af.getAttribute("align")}var ai={};var Y=af.getElementsByTagName("param");var ad=Y.length;for(var ae=0;ae'}}ab.outerHTML='"+ag+"";O[O.length]=aj.id;Y=c(aj.id)}else{var aa=D(s);aa.setAttribute("type",r);for(var ad in aj){if(aj[ad]!=Object.prototype[ad]){if(ad.toLowerCase()=="styleclass"){aa.setAttribute("class",aj[ad])}else{if(ad.toLowerCase()!="classid"){aa.setAttribute(ad,aj[ad])}}}}for(var ac in ah){if(ah[ac]!=Object.prototype[ac]&&ac.toLowerCase()!="movie"){e(aa,ac,ah[ac])}}ab.parentNode.replaceChild(aa,ab);Y=aa}}return Y}function e(aa,Y,Z){var ab=D("param");ab.setAttribute("name",Y);ab.setAttribute("value",Z);aa.appendChild(ab)}function z(Z){var Y=c(Z);if(Y&&Y.nodeName=="OBJECT"){if(N.ie&&N.win){Y.style.display="none";(function(){if(Y.readyState==4){b(Z)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.removeChild(Y)}}}function b(aa){var Z=c(aa);if(Z){for(var Y in Z){if(typeof Z[Y]=="function"){Z[Y]=null}}Z.parentNode.removeChild(Z)}}function c(aa){var Y=null;try{Y=k.getElementById(aa)}catch(Z){}return Y}function D(Y){return k.createElement(Y)}function j(aa,Y,Z){aa.attachEvent(Y,Z);J[J.length]=[aa,Y,Z]}function G(aa){var Z=N.pv,Y=aa.split(".");Y[0]=parseInt(Y[0],10);Y[1]=parseInt(Y[1],10)||0;Y[2]=parseInt(Y[2],10)||0;return(Z[0]>Y[0]||(Z[0]==Y[0]&&Z[1]>Y[1])||(Z[0]==Y[0]&&Z[1]==Y[1]&&Z[2]>=Y[2]))?true:false}function w(ad,Z,ae,ac){if(N.ie&&N.mac){return}var ab=k.getElementsByTagName("head")[0];if(!ab){return}var Y=(ae&&typeof ae=="string")?ae:"screen";if(ac){o=null;H=null}if(!o||H!=Y){var aa=D("style");aa.setAttribute("type","text/css");aa.setAttribute("media",Y);o=ab.appendChild(aa);if(N.ie&&N.win&&typeof k.styleSheets!=E&&k.styleSheets.length>0){o=k.styleSheets[k.styleSheets.length-1]}H=Y}if(N.ie&&N.win){if(o&&typeof o.addRule==s){o.addRule(ad,Z)}}else{if(o&&typeof k.createTextNode!=E){o.appendChild(k.createTextNode(ad+" {"+Z+"}"))}}}function x(aa,Y){if(!n){return}var Z=Y?"visible":"hidden";if(K&&c(aa)){c(aa).style.visibility=Z}else{w("#"+aa,"visibility:"+Z)}}function M(Z){var aa=/[\\\"<>\.;]/;var Y=aa.exec(Z)!=null;return Y&&typeof encodeURIComponent!=E?encodeURIComponent(Z):Z}var d=function(){if(N.ie&&N.win){window.attachEvent("onunload",function(){var ad=J.length;for(var ac=0;ac0){for(h=0;h-1&&e.position=="left"){e.position="bottom"}return e},onDestroy:function(){Ext.chart.CartesianChart.superclass.onDestroy.call(this);Ext.each(this.labelFn,function(a){this.removeFnProxy(a)},this)}});Ext.reg("cartesianchart",Ext.chart.CartesianChart);Ext.chart.LineChart=Ext.extend(Ext.chart.CartesianChart,{type:"line"});Ext.reg("linechart",Ext.chart.LineChart);Ext.chart.ColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"column"});Ext.reg("columnchart",Ext.chart.ColumnChart);Ext.chart.StackedColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackcolumn"});Ext.reg("stackedcolumnchart",Ext.chart.StackedColumnChart);Ext.chart.BarChart=Ext.extend(Ext.chart.CartesianChart,{type:"bar"});Ext.reg("barchart",Ext.chart.BarChart);Ext.chart.StackedBarChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackbar"});Ext.reg("stackedbarchart",Ext.chart.StackedBarChart);Ext.chart.Axis=function(a){Ext.apply(this,a)};Ext.chart.Axis.prototype={type:null,orientation:"horizontal",reverse:false,labelFunction:null,hideOverlappingLabels:true,labelSpacing:2};Ext.chart.NumericAxis=Ext.extend(Ext.chart.Axis,{type:"numeric",minimum:NaN,maximum:NaN,majorUnit:NaN,minorUnit:NaN,snapToUnits:true,alwaysShowZero:true,scale:"linear",roundMajorUnit:true,calculateByLabelSize:true,position:"left",adjustMaximumByMajorUnit:true,adjustMinimumByMajorUnit:true});Ext.chart.TimeAxis=Ext.extend(Ext.chart.Axis,{type:"time",minimum:null,maximum:null,majorUnit:NaN,majorTimeUnit:null,minorUnit:NaN,minorTimeUnit:null,snapToUnits:true,stackingEnabled:false,calculateByLabelSize:true});Ext.chart.CategoryAxis=Ext.extend(Ext.chart.Axis,{type:"category",categoryNames:null,calculateCategoryCount:false});Ext.chart.Series=function(a){Ext.apply(this,a)};Ext.chart.Series.prototype={type:null,displayName:null};Ext.chart.CartesianSeries=Ext.extend(Ext.chart.Series,{xField:null,yField:null,showInLegend:true,axis:"primary"});Ext.chart.ColumnSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"column"});Ext.chart.LineSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"line"});Ext.chart.BarSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"bar"});Ext.chart.PieSeries=Ext.extend(Ext.chart.Series,{type:"pie",dataField:null,categoryField:null});Ext.menu.Menu=Ext.extend(Ext.Container,{minWidth:120,shadow:"sides",subMenuAlign:"tl-tr?",defaultAlign:"tl-bl?",allowOtherMenus:false,ignoreParentClicks:false,enableScrolling:true,maxHeight:null,scrollIncrement:24,showSeparator:true,defaultOffsets:[0,0],plain:false,floating:true,zIndex:15000,hidden:true,layout:"menu",hideMode:"offsets",scrollerHeight:8,autoLayout:true,defaultType:"menuitem",bufferResize:false,initComponent:function(){if(Ext.isArray(this.initialConfig)){Ext.apply(this,{items:this.initialConfig})}this.addEvents("click","mouseover","mouseout","itemclick");Ext.menu.MenuMgr.register(this);if(this.floating){Ext.EventManager.onWindowResize(this.hide,this)}else{if(this.initialConfig.hidden!==false){this.hidden=false}this.internalDefaults={hideOnClick:false}}Ext.menu.Menu.superclass.initComponent.call(this);if(this.autoLayout){var a=this.doLayout.createDelegate(this,[]);this.on({add:a,remove:a})}},getLayoutTarget:function(){return this.ul},onRender:function(b,a){if(!b){b=Ext.getBody()}var c={id:this.getId(),cls:"x-menu "+((this.floating)?"x-menu-floating x-layer ":"")+(this.cls||"")+(this.plain?" x-menu-plain":"")+(this.showSeparator?"":" x-menu-nosep"),style:this.style,cn:[{tag:"a",cls:"x-menu-focus",href:"#",onclick:"return false;",tabIndex:"-1"},{tag:"ul",cls:"x-menu-list"}]};if(this.floating){this.el=new Ext.Layer({shadow:this.shadow,dh:c,constrain:false,parentEl:b,zindex:this.zIndex})}else{this.el=b.createChild(c)}Ext.menu.Menu.superclass.onRender.call(this,b,a);if(!this.keyNav){this.keyNav=new Ext.menu.MenuNav(this)}this.focusEl=this.el.child("a.x-menu-focus");this.ul=this.el.child("ul.x-menu-list");this.mon(this.ul,{scope:this,click:this.onClick,mouseover:this.onMouseOver,mouseout:this.onMouseOut});if(this.enableScrolling){this.mon(this.el,{scope:this,delegate:".x-menu-scroller",click:this.onScroll,mouseover:this.deactivateActive})}},findTargetItem:function(b){var a=b.getTarget(".x-menu-list-item",this.ul,true);if(a&&a.menuItemId){return this.items.get(a.menuItemId)}},onClick:function(b){var a=this.findTargetItem(b);if(a){if(a.isFormField){this.setActiveItem(a)}else{if(a instanceof Ext.menu.BaseItem){if(a.menu&&this.ignoreParentClicks){a.expandMenu();b.preventDefault()}else{if(a.onClick){a.onClick(b);this.fireEvent("click",this,a,b)}}}}}},setActiveItem:function(a,b){if(a!=this.activeItem){this.deactivateActive();if((this.activeItem=a).isFormField){a.focus()}else{a.activate(b)}}else{if(b){a.expandMenu()}}},deactivateActive:function(){var b=this.activeItem;if(b){if(b.isFormField){if(b.collapse){b.collapse()}}else{b.deactivate()}delete this.activeItem}},tryActivate:function(g,e){var b=this.items;for(var c=g,a=b.length;c>=0&&c=a.scrollHeight){this.onScrollerOut(null,b)}},onScrollerIn:function(d,b){var a=this.ul.dom,c=Ext.fly(b).is(".x-menu-scroller-top");if(c?a.scrollTop>0:a.scrollTop+this.activeMaxc){b=c;a=i-h}else{if(bb&&b>0){this.activeMax=b-this.scrollerHeight*2-this.el.getFrameWidth("tb")-Ext.num(this.el.shadowOffset,0);this.ul.setHeight(this.activeMax);this.createScrollers();this.el.select(".x-menu-scroller").setDisplayed("")}else{this.ul.setHeight(d);this.el.select(".x-menu-scroller").setDisplayed("none")}this.ul.dom.scrollTop=0;return a},createScrollers:function(){if(!this.scroller){this.scroller={pos:0,top:this.el.insertFirst({tag:"div",cls:"x-menu-scroller x-menu-scroller-top",html:" "}),bottom:this.el.createChild({tag:"div",cls:"x-menu-scroller x-menu-scroller-bottom",html:" "})};this.scroller.top.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.topRepeater=new Ext.util.ClickRepeater(this.scroller.top,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.top],false)}});this.scroller.bottom.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.bottomRepeater=new Ext.util.ClickRepeater(this.scroller.bottom,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.bottom],false)}})}},onLayout:function(){if(this.isVisible()){if(this.enableScrolling){this.constrainScroll(this.el.getTop())}if(this.floating){this.el.sync()}}},focus:function(){if(!this.hidden){this.doFocus.defer(50,this)}},doFocus:function(){if(!this.hidden){this.focusEl.focus()}},hide:function(a){if(!this.isDestroyed){this.deepHide=a;Ext.menu.Menu.superclass.hide.call(this);delete this.deepHide}},onHide:function(){Ext.menu.Menu.superclass.onHide.call(this);this.deactivateActive();if(this.el&&this.floating){this.el.hide()}var a=this.parentMenu;if(this.deepHide===true&&a){if(a.floating){a.hide(true)}else{a.deactivateActive()}}},lookupComponent:function(a){if(Ext.isString(a)){a=(a=="separator"||a=="-")?new Ext.menu.Separator():new Ext.menu.TextItem(a);this.applyDefaults(a)}else{if(Ext.isObject(a)){a=this.getMenuItem(a)}else{if(a.tagName||a.el){a=new Ext.BoxComponent({el:a})}}}return a},applyDefaults:function(b){if(!Ext.isString(b)){b=Ext.menu.Menu.superclass.applyDefaults.call(this,b);var a=this.internalDefaults;if(a){if(b.events){Ext.applyIf(b.initialConfig,a);Ext.apply(b,a)}else{Ext.applyIf(b,a)}}}return b},getMenuItem:function(a){a.ownerCt=this;if(!a.isXType){if(!a.xtype&&Ext.isBoolean(a.checked)){return new Ext.menu.CheckItem(a)}return Ext.create(a,this.defaultType)}return a},addSeparator:function(){return this.add(new Ext.menu.Separator())},addElement:function(a){return this.add(new Ext.menu.BaseItem({el:a}))},addItem:function(a){return this.add(a)},addMenuItem:function(a){return this.add(this.getMenuItem(a))},addText:function(a){return this.add(new Ext.menu.TextItem(a))},onDestroy:function(){Ext.EventManager.removeResizeListener(this.hide,this);var a=this.parentMenu;if(a&&a.activeChild==this){delete a.activeChild}delete this.parentMenu;Ext.menu.Menu.superclass.onDestroy.call(this);Ext.menu.MenuMgr.unregister(this);if(this.keyNav){this.keyNav.disable()}var b=this.scroller;if(b){Ext.destroy(b.topRepeater,b.bottomRepeater,b.top,b.bottom)}Ext.destroy(this.el,this.focusEl,this.ul)}});Ext.reg("menu",Ext.menu.Menu);Ext.menu.MenuNav=Ext.extend(Ext.KeyNav,function(){function a(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)-1,-1)){c.tryActivate(c.items.length-1,-1)}}function b(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)+1,1)){c.tryActivate(0,1)}}return{constructor:function(c){Ext.menu.MenuNav.superclass.constructor.call(this,c.el);this.scope=this.menu=c},doRelay:function(g,d){var c=g.getKey();if(this.menu.activeItem&&this.menu.activeItem.isFormField&&c!=g.TAB){return false}if(!this.menu.activeItem&&g.isNavKeyPress()&&c!=g.SPACE&&c!=g.RETURN){this.menu.tryActivate(0,1);return false}return d.call(this.scope||this,g,this.menu)},tab:function(d,c){d.stopEvent();if(d.shiftKey){a(d,c)}else{b(d,c)}},up:a,down:b,right:function(d,c){if(c.activeItem){c.activeItem.expandMenu(true)}},left:function(d,c){c.hide();if(c.parentMenu&&c.parentMenu.activeItem){c.parentMenu.activeItem.activate()}},enter:function(d,c){if(c.activeItem){d.stopPropagation();c.activeItem.onClick(d);c.fireEvent("click",this,c.activeItem);return true}}}}());Ext.menu.MenuMgr=function(){var h,e,b,d={},a=false,l=new Date();function n(){h={};e=new Ext.util.MixedCollection();b=Ext.getDoc().addKeyListener(27,j);b.disable()}function j(){if(e&&e.length>0){var o=e.clone();o.each(function(p){p.hide()});return true}return false}function g(o){e.remove(o);if(e.length<1){b.disable();Ext.getDoc().un("mousedown",m);a=false}}function k(o){var p=e.last();l=new Date();e.add(o);if(!a){b.enable();Ext.getDoc().on("mousedown",m);a=true}if(o.parentMenu){o.getEl().setZIndex(parseInt(o.parentMenu.getEl().getStyle("z-index"),10)+3);o.parentMenu.activeChild=o}else{if(p&&!p.isDestroyed&&p.isVisible()){o.getEl().setZIndex(parseInt(p.getEl().getStyle("z-index"),10)+3)}}}function c(o){if(o.activeChild){o.activeChild.hide()}if(o.autoHideTimer){clearTimeout(o.autoHideTimer);delete o.autoHideTimer}}function i(o){var p=o.parentMenu;if(!p&&!o.allowOtherMenus){j()}else{if(p&&p.activeChild){p.activeChild.hide()}}}function m(o){if(l.getElapsed()>50&&e.length>0&&!o.getTarget(".x-menu")){j()}}return{hideAll:function(){return j()},register:function(o){if(!h){n()}h[o.id]=o;o.on({beforehide:c,hide:g,beforeshow:i,show:k})},get:function(o){if(typeof o=="string"){if(!h){return null}return h[o]}else{if(o.events){return o}else{if(typeof o.length=="number"){return new Ext.menu.Menu({items:o})}else{return Ext.create(o,"menu")}}}},unregister:function(o){delete h[o.id];o.un("beforehide",c);o.un("hide",g);o.un("beforeshow",i);o.un("show",k)},registerCheckable:function(o){var p=o.group;if(p){if(!d[p]){d[p]=[]}d[p].push(o)}},unregisterCheckable:function(o){var p=o.group;if(p){d[p].remove(o)}},onCheckChange:function(q,r){if(q.group&&r){var t=d[q.group],p=0,o=t.length,s;for(;p',' target="{hrefTarget}"',"",">",'{altText}','{text}',"")}var c=this.getTemplateArgs();this.el=b?this.itemTpl.insertBefore(b,c,true):this.itemTpl.append(d,c,true);this.iconEl=this.el.child("img.x-menu-item-icon");this.textEl=this.el.child(".x-menu-item-text");if(!this.href){this.mon(this.el,"click",Ext.emptyFn,null,{preventDefault:true})}Ext.menu.Item.superclass.onRender.call(this,d,b)},getTemplateArgs:function(){return{id:this.id,cls:this.itemCls+(this.menu?" x-menu-item-arrow":"")+(this.cls?" "+this.cls:""),href:this.href||"#",hrefTarget:this.hrefTarget,icon:this.icon||Ext.BLANK_IMAGE_URL,iconCls:this.iconCls||"",text:this.itemText||this.text||" ",altText:this.altText||""}},setText:function(a){this.text=a||" ";if(this.rendered){this.textEl.update(this.text);this.parentMenu.layout.doAutoSize()}},setIconClass:function(a){var b=this.iconCls;this.iconCls=a;if(this.rendered){this.iconEl.replaceClass(b,this.iconCls)}},beforeDestroy:function(){clearTimeout(this.showTimer);clearTimeout(this.hideTimer);if(this.menu){delete this.menu.ownerCt;this.menu.destroy()}Ext.menu.Item.superclass.beforeDestroy.call(this)},handleClick:function(a){if(!this.href){a.stopEvent()}Ext.menu.Item.superclass.handleClick.apply(this,arguments)},activate:function(a){if(Ext.menu.Item.superclass.activate.apply(this,arguments)){this.focus();if(a){this.expandMenu()}}return true},shouldDeactivate:function(a){if(Ext.menu.Item.superclass.shouldDeactivate.call(this,a)){if(this.menu&&this.menu.isVisible()){return !this.menu.getEl().getRegion().contains(a.getPoint())}return true}return false},deactivate:function(){Ext.menu.Item.superclass.deactivate.apply(this,arguments);this.hideMenu()},expandMenu:function(a){if(!this.disabled&&this.menu){clearTimeout(this.hideTimer);delete this.hideTimer;if(!this.menu.isVisible()&&!this.showTimer){this.showTimer=this.deferExpand.defer(this.showDelay,this,[a])}else{if(this.menu.isVisible()&&a){this.menu.tryActivate(0,1)}}}},deferExpand:function(a){delete this.showTimer;this.menu.show(this.container,this.parentMenu.subMenuAlign||"tl-tr?",this.parentMenu);if(a){this.menu.tryActivate(0,1)}},hideMenu:function(){clearTimeout(this.showTimer);delete this.showTimer;if(!this.hideTimer&&this.menu&&this.menu.isVisible()){this.hideTimer=this.deferHide.defer(this.hideDelay,this)}},deferHide:function(){delete this.hideTimer;if(this.menu.over){this.parentMenu.setActiveItem(this,false)}else{this.menu.hide()}}});Ext.reg("menuitem",Ext.menu.Item);Ext.menu.CheckItem=Ext.extend(Ext.menu.Item,{itemCls:"x-menu-item x-menu-check-item",groupClass:"x-menu-group-item",checked:false,ctype:"Ext.menu.CheckItem",initComponent:function(){Ext.menu.CheckItem.superclass.initComponent.call(this);this.addEvents("beforecheckchange","checkchange");if(this.checkHandler){this.on("checkchange",this.checkHandler,this.scope)}Ext.menu.MenuMgr.registerCheckable(this)},onRender:function(a){Ext.menu.CheckItem.superclass.onRender.apply(this,arguments);if(this.group){this.el.addClass(this.groupClass)}if(this.checked){this.checked=false;this.setChecked(true,true)}},destroy:function(){Ext.menu.MenuMgr.unregisterCheckable(this);Ext.menu.CheckItem.superclass.destroy.apply(this,arguments)},setChecked:function(b,a){var c=a===true;if(this.checked!=b&&(c||this.fireEvent("beforecheckchange",this,b)!==false)){Ext.menu.MenuMgr.onCheckChange(this,b);if(this.container){this.container[b?"addClass":"removeClass"]("x-menu-item-checked")}this.checked=b;if(!c){this.fireEvent("checkchange",this,b)}}},handleClick:function(a){if(!this.disabled&&!(this.checked&&this.group)){this.setChecked(!this.checked)}Ext.menu.CheckItem.superclass.handleClick.apply(this,arguments)}});Ext.reg("menucheckitem",Ext.menu.CheckItem);Ext.menu.DateMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,pickerId:null,cls:"x-date-menu",initComponent:function(){this.on("beforeshow",this.onBeforeShow,this);if(this.strict=(Ext.isIE7&&Ext.isStrict)){this.on("show",this.onShow,this,{single:true,delay:20})}Ext.apply(this,{plain:true,showSeparator:false,items:this.picker=new Ext.DatePicker(Ext.applyIf({internalRender:this.strict||!Ext.isIE9m,ctCls:"x-menu-date-item",id:this.pickerId},this.initialConfig))});this.picker.purgeListeners();Ext.menu.DateMenu.superclass.initComponent.call(this);this.relayEvents(this.picker,["select"]);this.on("show",this.picker.focus,this.picker);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}},onBeforeShow:function(){if(this.picker){this.picker.hideMonthPicker(true)}},onShow:function(){var a=this.picker.getEl();a.setWidth(a.getWidth())}});Ext.reg("datemenu",Ext.menu.DateMenu);Ext.menu.ColorMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,cls:"x-color-menu",paletteId:null,initComponent:function(){Ext.apply(this,{plain:true,showSeparator:false,items:this.palette=new Ext.ColorPalette(Ext.applyIf({id:this.paletteId},this.initialConfig))});this.palette.purgeListeners();Ext.menu.ColorMenu.superclass.initComponent.call(this);this.relayEvents(this.palette,["select"]);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}}});Ext.reg("colormenu",Ext.menu.ColorMenu);Ext.form.Field=Ext.extend(Ext.BoxComponent,{invalidClass:"x-form-invalid",invalidText:"The value in this field is invalid",focusClass:"x-form-focus",validationEvent:"keyup",validateOnBlur:true,validationDelay:250,defaultAutoCreate:{tag:"input",type:"text",size:"20",autocomplete:"off"},fieldClass:"x-form-field",msgTarget:"qtip",msgFx:"normal",readOnly:false,disabled:false,submitValue:true,isFormField:true,msgDisplay:"",hasFocus:false,initComponent:function(){Ext.form.Field.superclass.initComponent.call(this);this.addEvents("focus","blur","specialkey","change","invalid","valid")},getName:function(){return this.rendered&&this.el.dom.name?this.el.dom.name:this.name||this.id||""},onRender:function(c,a){if(!this.el){var b=this.getAutoCreate();if(!b.name){b.name=this.name||this.id}if(this.inputType){b.type=this.inputType}this.autoEl=b}Ext.form.Field.superclass.onRender.call(this,c,a);if(this.submitValue===false){this.el.dom.removeAttribute("name")}var d=this.el.dom.type;if(d){if(d=="password"){d="text"}this.el.addClass("x-form-"+d)}if(this.readOnly){this.setReadOnly(true)}if(this.tabIndex!==undefined){this.el.dom.setAttribute("tabIndex",this.tabIndex)}this.el.addClass([this.fieldClass,this.cls])},getItemCt:function(){return this.itemCt},initValue:function(){if(this.value!==undefined){this.setValue(this.value)}else{if(!Ext.isEmpty(this.el.dom.value)&&this.el.dom.value!=this.emptyText){this.setValue(this.el.dom.value)}}this.originalValue=this.getValue()},isDirty:function(){if(this.disabled||!this.rendered){return false}return String(this.getValue())!==String(this.originalValue)},setReadOnly:function(a){if(this.rendered){this.el.dom.readOnly=a}this.readOnly=a},afterRender:function(){Ext.form.Field.superclass.afterRender.call(this);this.initEvents();this.initValue()},fireKey:function(a){if(a.isSpecialKey()){this.fireEvent("specialkey",this,a)}},reset:function(){this.setValue(this.originalValue);this.clearInvalid()},initEvents:function(){this.mon(this.el,Ext.EventManager.getKeyEvent(),this.fireKey,this);this.mon(this.el,"focus",this.onFocus,this);this.mon(this.el,"blur",this.onBlur,this,this.inEditor?{buffer:10}:null)},preFocus:Ext.emptyFn,onFocus:function(){this.preFocus();if(this.focusClass){this.el.addClass(this.focusClass)}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this)}},beforeBlur:Ext.emptyFn,onBlur:function(){this.beforeBlur();if(this.focusClass){this.el.removeClass(this.focusClass)}this.hasFocus=false;if(this.validationEvent!==false&&(this.validateOnBlur||this.validationEvent=="blur")){this.validate()}var a=this.getValue();if(String(a)!==String(this.startValue)){this.fireEvent("change",this,a,this.startValue)}this.fireEvent("blur",this);this.postBlur()},postBlur:Ext.emptyFn,isValid:function(a){if(this.disabled){return true}var c=this.preventMark;this.preventMark=a===true;var b=this.validateValue(this.processValue(this.getRawValue()),a);this.preventMark=c;return b},validate:function(){if(this.disabled||this.validateValue(this.processValue(this.getRawValue()))){this.clearInvalid();return true}return false},processValue:function(a){return a},validateValue:function(b){var a=this.getErrors(b)[0];if(a==undefined){return true}else{this.markInvalid(a);return false}},getErrors:function(){return[]},getActiveError:function(){return this.activeError||""},markInvalid:function(c){if(this.rendered&&!this.preventMark){c=c||this.invalidText;var a=this.getMessageHandler();if(a){a.mark(this,c)}else{if(this.msgTarget){this.el.addClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML=c;b.style.display=this.msgDisplay}}}}this.setActiveError(c)},clearInvalid:function(){if(this.rendered&&!this.preventMark){this.el.removeClass(this.invalidClass);var a=this.getMessageHandler();if(a){a.clear(this)}else{if(this.msgTarget){this.el.removeClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML="";b.style.display="none"}}}}this.unsetActiveError()},setActiveError:function(b,a){this.activeError=b;if(a!==true){this.fireEvent("invalid",this,b)}},unsetActiveError:function(a){delete this.activeError;if(a!==true){this.fireEvent("valid",this)}},getMessageHandler:function(){return Ext.form.MessageTargets[this.msgTarget]},getErrorCt:function(){return this.el.findParent(".x-form-element",5,true)||this.el.findParent(".x-form-field-wrap",5,true)},alignErrorEl:function(){this.errorEl.setWidth(this.getErrorCt().getWidth(true)-20)},alignErrorIcon:function(){this.errorIcon.alignTo(this.el,"tl-tr",[2,0])},getRawValue:function(){var a=this.rendered?this.el.getValue():Ext.value(this.value,"");if(a===this.emptyText){a=""}return a},getValue:function(){if(!this.rendered){return this.value}var a=this.el.getValue();if(a===this.emptyText||a===undefined){a=""}return a},setRawValue:function(a){return this.rendered?(this.el.dom.value=(Ext.isEmpty(a)?"":a)):""},setValue:function(a){this.value=a;if(this.rendered){this.el.dom.value=(Ext.isEmpty(a)?"":a);this.validate()}return this},append:function(a){this.setValue([this.getValue(),a].join(""))}});Ext.form.MessageTargets={qtip:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.qtip=b;a.el.dom.qclass="x-form-invalid-tip";if(Ext.QuickTips){Ext.QuickTips.enable()}},clear:function(a){a.el.removeClass(a.invalidClass);a.el.dom.qtip=""}},title:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.title=b},clear:function(a){a.el.dom.title=""}},under:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorEl){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorEl=a.createChild({cls:"x-form-invalid-msg"});b.on("resize",b.alignErrorEl,b);b.on("destroy",function(){Ext.destroy(this.errorEl)},b)}b.alignErrorEl();b.errorEl.update(c);Ext.form.Field.msgFx[b.msgFx].show(b.errorEl,b)},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorEl){Ext.form.Field.msgFx[a.msgFx].hide(a.errorEl,a)}else{a.el.dom.title=""}}},side:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorIcon){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorIcon=a.createChild({cls:"x-form-invalid-icon"});if(b.ownerCt){b.ownerCt.on("afterlayout",b.alignErrorIcon,b);b.ownerCt.on("expand",b.alignErrorIcon,b)}b.on("resize",b.alignErrorIcon,b);b.on("destroy",function(){Ext.destroy(this.errorIcon)},b)}b.alignErrorIcon();b.errorIcon.dom.qtip=c;b.errorIcon.dom.qclass="x-form-invalid-tip";b.errorIcon.show()},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorIcon){a.errorIcon.dom.qtip="";a.errorIcon.hide()}else{a.el.dom.title=""}}}};Ext.form.Field.msgFx={normal:{show:function(a,b){a.setDisplayed("block")},hide:function(a,b){a.setDisplayed(false).update("")}},slide:{show:function(a,b){a.slideIn("t",{stopFx:true})},hide:function(a,b){a.slideOut("t",{stopFx:true,useDisplay:true})}},slideRight:{show:function(a,b){a.fixDisplay();a.alignTo(b.el,"tl-tr");a.slideIn("l",{stopFx:true})},hide:function(a,b){a.slideOut("l",{stopFx:true,useDisplay:true})}}};Ext.reg("field",Ext.form.Field);Ext.form.TextField=Ext.extend(Ext.form.Field,{grow:false,growMin:30,growMax:800,vtype:null,maskRe:null,disableKeyFilter:false,allowBlank:true,minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",selectOnFocus:false,blankText:"This field is required",validator:null,regex:null,regexText:"",emptyText:null,emptyClass:"x-form-empty-field",initComponent:function(){Ext.form.TextField.superclass.initComponent.call(this);this.addEvents("autosize","keydown","keyup","keypress")},initEvents:function(){Ext.form.TextField.superclass.initEvents.call(this);if(this.validationEvent=="keyup"){this.validationTask=new Ext.util.DelayedTask(this.validate,this);this.mon(this.el,"keyup",this.filterValidation,this)}else{if(this.validationEvent!==false&&this.validationEvent!="blur"){this.mon(this.el,this.validationEvent,this.validate,this,{buffer:this.validationDelay})}}if(this.selectOnFocus||this.emptyText){this.mon(this.el,"mousedown",this.onMouseDown,this);if(this.emptyText){this.applyEmptyText()}}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Ext.form.VTypes[this.vtype+"Mask"]))){this.mon(this.el,"keypress",this.filterKeys,this)}if(this.grow){this.mon(this.el,"keyup",this.onKeyUpBuffered,this,{buffer:50});this.mon(this.el,"click",this.autoSize,this)}if(this.enableKeyEvents){this.mon(this.el,{scope:this,keyup:this.onKeyUp,keydown:this.onKeyDown,keypress:this.onKeyPress})}},onMouseDown:function(a){if(!this.hasFocus){this.mon(this.el,"mouseup",Ext.emptyFn,this,{single:true,preventDefault:true})}},processValue:function(a){if(this.stripCharsRe){var b=a.replace(this.stripCharsRe,"");if(b!==a){this.setRawValue(b);return b}}return a},filterValidation:function(a){if(!a.isNavKeyPress()){this.validationTask.delay(this.validationDelay)}},onDisable:function(){Ext.form.TextField.superclass.onDisable.call(this);if(Ext.isIE){this.el.dom.unselectable="on"}},onEnable:function(){Ext.form.TextField.superclass.onEnable.call(this);if(Ext.isIE){this.el.dom.unselectable=""}},onKeyUpBuffered:function(a){if(this.doAutoSize(a)){this.autoSize()}},doAutoSize:function(a){return !a.isNavKeyPress()},onKeyUp:function(a){this.fireEvent("keyup",this,a)},onKeyDown:function(a){this.fireEvent("keydown",this,a)},onKeyPress:function(a){this.fireEvent("keypress",this,a)},reset:function(){Ext.form.TextField.superclass.reset.call(this);this.applyEmptyText()},applyEmptyText:function(){if(this.rendered&&this.emptyText&&this.getRawValue().length<1&&!this.hasFocus){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass)}},preFocus:function(){var a=this.el,b;if(this.emptyText){if(a.dom.value==this.emptyText){this.setRawValue("");b=true}a.removeClass(this.emptyClass)}if(this.selectOnFocus||b){a.dom.select()}},postBlur:function(){this.applyEmptyText()},filterKeys:function(b){if(b.ctrlKey){return}var a=b.getKey();if(Ext.isGecko&&(b.isNavKeyPress()||a==b.BACKSPACE||(a==b.DELETE&&b.button==-1))){return}var c=String.fromCharCode(b.getCharCode());if(!Ext.isGecko&&b.isSpecialKey()&&!c){return}if(!this.maskRe.test(c)){b.stopEvent()}},setValue:function(a){if(this.emptyText&&this.el&&!Ext.isEmpty(a)){this.el.removeClass(this.emptyClass)}Ext.form.TextField.superclass.setValue.apply(this,arguments);this.applyEmptyText();this.autoSize();return this},getErrors:function(a){var d=Ext.form.TextField.superclass.getErrors.apply(this,arguments);a=Ext.isDefined(a)?a:this.processValue(this.getRawValue());if(Ext.isFunction(this.validator)){var c=this.validator(a);if(c!==true){d.push(c)}}if(a.length<1||a===this.emptyText){if(this.allowBlank){return d}else{d.push(this.blankText)}}if(!this.allowBlank&&(a.length<1||a===this.emptyText)){d.push(this.blankText)}if(a.lengththis.maxLength){d.push(String.format(this.maxLengthText,this.maxLength))}if(this.vtype){var b=Ext.form.VTypes;if(!b[this.vtype](a,this)){d.push(this.vtypeText||b[this.vtype+"Text"])}}if(this.regex&&!this.regex.test(a)){d.push(this.regexText)}return d},selectText:function(h,a){var c=this.getRawValue();var e=false;if(c.length>0){h=h===undefined?0:h;a=a===undefined?c.length:a;var g=this.el.dom;if(g.setSelectionRange){g.setSelectionRange(h,a)}else{if(g.createTextRange){var b=g.createTextRange();b.moveStart("character",h);b.moveEnd("character",a-c.length);b.select()}}e=Ext.isGecko||Ext.isOpera}else{e=true}if(e){this.focus()}},autoSize:function(){if(!this.grow||!this.rendered){return}if(!this.metrics){this.metrics=Ext.util.TextMetrics.createInstance(this.el)}var c=this.el;var b=c.dom.value;var e=document.createElement("div");e.appendChild(document.createTextNode(b));b=e.innerHTML;Ext.removeNode(e);e=null;b+=" ";var a=Math.min(this.growMax,Math.max(this.metrics.getWidth(b)+10,this.growMin));this.el.setWidth(a);this.fireEvent("autosize",this,a)},onDestroy:function(){if(this.validationTask){this.validationTask.cancel();this.validationTask=null}Ext.form.TextField.superclass.onDestroy.call(this)}});Ext.reg("textfield",Ext.form.TextField);Ext.form.TriggerField=Ext.extend(Ext.form.TextField,{defaultAutoCreate:{tag:"input",type:"text",size:"16",autocomplete:"off"},hideTrigger:false,editable:true,readOnly:false,wrapFocusClass:"x-trigger-wrap-focus",autoSize:Ext.emptyFn,monitorTab:true,deferHeight:true,mimicing:false,actionMode:"wrap",defaultTriggerWidth:17,onResize:function(a,c){Ext.form.TriggerField.superclass.onResize.call(this,a,c);var b=this.getTriggerWidth();if(Ext.isNumber(a)){this.el.setWidth(a-b)}this.wrap.setWidth(this.el.getWidth()+b)},getTriggerWidth:function(){var a=this.trigger.getWidth();if(!this.hideTrigger&&!this.readOnly&&a===0){a=this.defaultTriggerWidth}return a},alignErrorIcon:function(){if(this.wrap){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}},onRender:function(b,a){this.doc=Ext.isIE?Ext.getBody():Ext.getDoc();Ext.form.TriggerField.superclass.onRender.call(this,b,a);this.wrap=this.el.wrap({cls:"x-form-field-wrap x-form-field-trigger-wrap"});this.trigger=this.wrap.createChild(this.triggerConfig||{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.triggerClass});this.initTrigger();if(!this.width){this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())}this.resizeEl=this.positionEl=this.wrap},getWidth:function(){return(this.el.getWidth()+this.trigger.getWidth())},updateEditState:function(){if(this.rendered){if(this.readOnly){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this);this.trigger.setDisplayed(false)}else{if(!this.editable){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mon(this.el,"click",this.onTriggerClick,this)}else{this.el.dom.readOnly=false;this.el.removeClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this)}this.trigger.setDisplayed(!this.hideTrigger)}this.onResize(this.width||this.wrap.getWidth())}},setHideTrigger:function(a){if(a!=this.hideTrigger){this.hideTrigger=a;this.updateEditState()}},setEditable:function(a){if(a!=this.editable){this.editable=a;this.updateEditState()}},setReadOnly:function(a){if(a!=this.readOnly){this.readOnly=a;this.updateEditState()}},afterRender:function(){Ext.form.TriggerField.superclass.afterRender.call(this);this.updateEditState()},initTrigger:function(){this.mon(this.trigger,"click",this.onTriggerClick,this,{preventDefault:true});this.trigger.addClassOnOver("x-form-trigger-over");this.trigger.addClassOnClick("x-form-trigger-click")},onDestroy:function(){Ext.destroy(this.trigger,this.wrap);if(this.mimicing){this.doc.un("mousedown",this.mimicBlur,this)}delete this.doc;Ext.form.TriggerField.superclass.onDestroy.call(this)},onFocus:function(){Ext.form.TriggerField.superclass.onFocus.call(this);if(!this.mimicing){this.wrap.addClass(this.wrapFocusClass);this.mimicing=true;this.doc.on("mousedown",this.mimicBlur,this,{delay:10});if(this.monitorTab){this.on("specialkey",this.checkTab,this)}}},checkTab:function(a,b){if(b.getKey()==b.TAB){this.triggerBlur()}},onBlur:Ext.emptyFn,mimicBlur:function(a){if(!this.isDestroyed&&!this.wrap.contains(a.target)&&this.validateBlur(a)){this.triggerBlur()}},triggerBlur:function(){this.mimicing=false;this.doc.un("mousedown",this.mimicBlur,this);if(this.monitorTab&&this.el){this.un("specialkey",this.checkTab,this)}Ext.form.TriggerField.superclass.onBlur.call(this);if(this.wrap){this.wrap.removeClass(this.wrapFocusClass)}},beforeBlur:Ext.emptyFn,validateBlur:function(a){return true},onTriggerClick:Ext.emptyFn});Ext.form.TwinTriggerField=Ext.extend(Ext.form.TriggerField,{initComponent:function(){Ext.form.TwinTriggerField.superclass.initComponent.call(this);this.triggerConfig={tag:"span",cls:"x-form-twin-triggers",cn:[{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.trigger1Class},{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.trigger2Class}]}},getTrigger:function(a){return this.triggers[a]},afterRender:function(){Ext.form.TwinTriggerField.superclass.afterRender.call(this);var c=this.triggers,b=0,a=c.length;for(;b")}}d.innerHTML=a;b=Math.min(this.growMax,Math.max(d.offsetHeight,this.growMin));if(b!=this.lastHeight){this.lastHeight=b;this.el.setHeight(b);this.fireEvent("autosize",this,b)}}});Ext.reg("textarea",Ext.form.TextArea);Ext.form.NumberField=Ext.extend(Ext.form.TextField,{fieldClass:"x-form-field x-form-num-field",allowDecimals:true,decimalSeparator:".",decimalPrecision:2,allowNegative:true,minValue:Number.NEGATIVE_INFINITY,maxValue:Number.MAX_VALUE,minText:"The minimum value for this field is {0}",maxText:"The maximum value for this field is {0}",nanText:"{0} is not a valid number",baseChars:"0123456789",autoStripChars:false,initEvents:function(){var a=this.baseChars+"";if(this.allowDecimals){a+=this.decimalSeparator}if(this.allowNegative){a+="-"}a=Ext.escapeRe(a);this.maskRe=new RegExp("["+a+"]");if(this.autoStripChars){this.stripCharsRe=new RegExp("[^"+a+"]","gi")}Ext.form.NumberField.superclass.initEvents.call(this)},getErrors:function(b){var c=Ext.form.NumberField.superclass.getErrors.apply(this,arguments);b=Ext.isDefined(b)?b:this.processValue(this.getRawValue());if(b.length<1){return c}b=String(b).replace(this.decimalSeparator,".");if(isNaN(b)){c.push(String.format(this.nanText,b))}var a=this.parseValue(b);if(athis.maxValue){c.push(String.format(this.maxText,this.maxValue))}return c},getValue:function(){return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)))},setValue:function(a){a=Ext.isNumber(a)?a:parseFloat(String(a).replace(this.decimalSeparator,"."));a=this.fixPrecision(a);a=isNaN(a)?"":String(a).replace(".",this.decimalSeparator);return Ext.form.NumberField.superclass.setValue.call(this,a)},setMinValue:function(a){this.minValue=Ext.num(a,Number.NEGATIVE_INFINITY)},setMaxValue:function(a){this.maxValue=Ext.num(a,Number.MAX_VALUE)},parseValue:function(a){a=parseFloat(String(a).replace(this.decimalSeparator,"."));return isNaN(a)?"":a},fixPrecision:function(b){var a=isNaN(b);if(!this.allowDecimals||this.decimalPrecision==-1||a||!b){return a?"":b}return parseFloat(parseFloat(b).toFixed(this.decimalPrecision))},beforeBlur:function(){var a=this.parseValue(this.getRawValue());if(!Ext.isEmpty(a)){this.setValue(a)}}});Ext.reg("numberfield",Ext.form.NumberField);Ext.form.DateField=Ext.extend(Ext.form.TriggerField,{format:"m/d/Y",altFormats:"m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",disabledDaysText:"Disabled",disabledDatesText:"Disabled",minText:"The date in this field must be equal to or after {0}",maxText:"The date in this field must be equal to or before {0}",invalidText:"{0} is not a valid date - it must be in the format {1}",triggerClass:"x-form-date-trigger",showToday:true,startDay:0,defaultAutoCreate:{tag:"input",type:"text",size:"10",autocomplete:"off"},initTime:"12",initTimeFormat:"H",safeParse:function(b,c){if(Date.formatContainsHourInfo(c)){return Date.parseDate(b,c)}else{var a=Date.parseDate(b+" "+this.initTime,c+" "+this.initTimeFormat);if(a){return a.clearTime()}}},initComponent:function(){Ext.form.DateField.superclass.initComponent.call(this);this.addEvents("select");if(Ext.isString(this.minValue)){this.minValue=this.parseDate(this.minValue)}if(Ext.isString(this.maxValue)){this.maxValue=this.parseDate(this.maxValue)}this.disabledDatesRE=null;this.initDisabledDays()},initEvents:function(){Ext.form.DateField.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{down:function(a){this.onTriggerClick()},scope:this,forceKeyDown:true})},initDisabledDays:function(){if(this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){this.disabledDates=a;this.initDisabledDays();if(this.menu){this.menu.picker.setDisabledDates(this.disabledDatesRE)}},setDisabledDays:function(a){this.disabledDays=a;if(this.menu){this.menu.picker.setDisabledDays(a)}},setMinValue:function(a){this.minValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMinDate(this.minValue)}},setMaxValue:function(a){this.maxValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMaxDate(this.maxValue)}},getErrors:function(e){var h=Ext.form.DateField.superclass.getErrors.apply(this,arguments);e=this.formatDate(e||this.processValue(this.getRawValue()));if(e.length<1){return h}var c=e;e=this.parseDate(e);if(!e){h.push(String.format(this.invalidText,c,this.format));return h}var g=e.getTime();if(this.minValue&&gthis.maxValue.clearTime().getTime()){h.push(String.format(this.maxText,this.formatDate(this.maxValue)))}if(this.disabledDays){var a=e.getDay();for(var b=0;b
    {'+this.displayField+"}
    "}this.view=new Ext.DataView({applyTo:this.innerList,tpl:this.tpl,singleSelect:true,selectedClass:this.selectedClass,itemSelector:this.itemSelector||"."+a+"-item",emptyText:this.listEmptyText,deferEmptyText:false});this.mon(this.view,{containerclick:this.onViewClick,click:this.onViewClick,scope:this});this.bindStore(this.store,true);if(this.resizable){this.resizer=new Ext.Resizable(this.list,{pinned:true,handles:"se"});this.mon(this.resizer,"resize",function(g,d,e){this.maxHeight=e-this.handleHeight-this.list.getFrameWidth("tb")-this.assetHeight;this.listWidth=d;this.innerList.setWidth(d-this.list.getFrameWidth("lr"));this.restrictHeight()},this);this[this.pageSize?"footer":"innerList"].setStyle("margin-bottom",this.handleHeight+"px")}}},getListParent:function(){return document.body},getStore:function(){return this.store},bindStore:function(a,b){if(this.store&&!b){if(this.store!==a&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.collapse,this)}if(!a){this.store=null;if(this.view){this.view.bindStore(null)}if(this.pageTb){this.pageTb.bindStore(null)}}}if(a){if(!b){this.lastQuery=null;if(this.pageTb){this.pageTb.bindStore(a)}}this.store=Ext.StoreMgr.lookup(a);this.store.on({scope:this,beforeload:this.onBeforeLoad,load:this.onLoad,exception:this.collapse});if(this.view){this.view.bindStore(a)}}},reset:function(){if(this.clearFilterOnReset&&this.mode=="local"){this.store.clearFilter()}Ext.form.ComboBox.superclass.reset.call(this)},initEvents:function(){Ext.form.ComboBox.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{up:function(a){this.inKeyMode=true;this.selectPrev()},down:function(a){if(!this.isExpanded()){this.onTriggerClick()}else{this.inKeyMode=true;this.selectNext()}},enter:function(a){this.onViewClick()},esc:function(a){this.collapse()},tab:function(a){if(this.forceSelection===true){this.collapse()}else{this.onViewClick(false)}return true},scope:this,doRelay:function(c,b,a){if(a=="down"||this.scope.isExpanded()){var d=Ext.KeyNav.prototype.doRelay.apply(this,arguments);if((((Ext.isIE9&&Ext.isStrict)||Ext.isIE10p)||!Ext.isIE)&&Ext.EventManager.useKeydown){this.scope.fireKey(c)}return d}return true},forceKeyDown:true,defaultEventAction:"stopEvent"});this.queryDelay=Math.max(this.queryDelay||10,this.mode=="local"?10:250);this.dqTask=new Ext.util.DelayedTask(this.initQuery,this);if(this.typeAhead){this.taTask=new Ext.util.DelayedTask(this.onTypeAhead,this)}if(!this.enableKeyEvents){this.mon(this.el,"keyup",this.onKeyUp,this)}},onDestroy:function(){if(this.dqTask){this.dqTask.cancel();this.dqTask=null}this.bindStore(null);Ext.destroy(this.resizer,this.view,this.pageTb,this.list);Ext.destroyMembers(this,"hiddenField");Ext.form.ComboBox.superclass.onDestroy.call(this)},fireKey:function(a){if(!this.isExpanded()){Ext.form.ComboBox.superclass.fireKey.call(this,a)}},onResize:function(a,b){Ext.form.ComboBox.superclass.onResize.apply(this,arguments);if(!isNaN(a)&&this.isVisible()&&this.list){this.doResize(a)}else{this.bufferSize=a}},doResize:function(a){if(!Ext.isDefined(this.listWidth)){var b=Math.max(a,this.minListWidth);this.list.setWidth(b);this.innerList.setWidth(b-this.list.getFrameWidth("lr"))}},onEnable:function(){Ext.form.ComboBox.superclass.onEnable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=false}},onDisable:function(){Ext.form.ComboBox.superclass.onDisable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=true}},onBeforeLoad:function(){if(!this.hasFocus){return}this.innerList.update(this.loadingText?'
    '+this.loadingText+"
    ":"");this.restrictHeight();this.selectedIndex=-1},onLoad:function(){if(!this.hasFocus){return}if(this.store.getCount()>0||this.listEmptyText){this.expand();this.restrictHeight();if(this.lastQuery==this.allQuery){if(this.editable){this.el.dom.select()}if(this.autoSelect!==false&&!this.selectByValue(this.value,true)){this.select(0,true)}}else{if(this.autoSelect!==false){this.selectNext()}if(this.typeAhead&&this.lastKey!=Ext.EventObject.BACKSPACE&&this.lastKey!=Ext.EventObject.DELETE){this.taTask.delay(this.typeAheadDelay)}}}else{this.collapse()}},onTypeAhead:function(){if(this.store.getCount()>0){var b=this.store.getAt(0);var c=b.data[this.displayField];var a=c.length;var d=this.getRawValue().length;if(d!=a){this.setRawValue(c);this.selectText(d,c.length)}}},assertValue:function(){var b=this.getRawValue(),a;if(this.valueField&&Ext.isDefined(this.value)){a=this.findRecord(this.valueField,this.value)}if(!a||a.get(this.displayField)!=b){a=this.findRecord(this.displayField,b)}if(!a&&this.forceSelection){if(b.length>0&&b!=this.emptyText){this.el.dom.value=Ext.value(this.lastSelectionText,"");this.applyEmptyText()}else{this.clearValue()}}else{if(a&&this.valueField){if(this.value==b){return}b=a.get(this.valueField||this.displayField)}this.setValue(b)}},onSelect:function(a,b){if(this.fireEvent("beforeselect",this,a,b)!==false){this.setValue(a.data[this.valueField||this.displayField]);this.collapse();this.fireEvent("select",this,a,b)}},getName:function(){var a=this.hiddenField;return a&&a.name?a.name:this.hiddenName||Ext.form.ComboBox.superclass.getName.call(this)},getValue:function(){if(this.valueField){return Ext.isDefined(this.value)?this.value:""}else{return Ext.form.ComboBox.superclass.getValue.call(this)}},clearValue:function(){if(this.hiddenField){this.hiddenField.value=""}this.setRawValue("");this.lastSelectionText="";this.applyEmptyText();this.value=""},setValue:function(a){var c=a;if(this.valueField){var b=this.findRecord(this.valueField,a);if(b){c=b.data[this.displayField]}else{if(Ext.isDefined(this.valueNotFoundText)){c=this.valueNotFoundText}}}this.lastSelectionText=c;if(this.hiddenField){this.hiddenField.value=Ext.value(a,"")}Ext.form.ComboBox.superclass.setValue.call(this,c);this.value=a;return this},findRecord:function(c,b){var a;if(this.store.getCount()>0){this.store.each(function(d){if(d.data[c]==b){a=d;return false}})}return a},onViewMove:function(b,a){this.inKeyMode=false},onViewOver:function(d,b){if(this.inKeyMode){return}var c=this.view.findItemFromChild(b);if(c){var a=this.view.indexOf(c);this.select(a,false)}},onViewClick:function(b){var a=this.view.getSelectedIndexes()[0],c=this.store,d=c.getAt(a);if(d){this.onSelect(d,a)}else{this.collapse()}if(b!==false){this.el.focus()}},restrictHeight:function(){this.innerList.dom.style.height="";var b=this.innerList.dom,e=this.list.getFrameWidth("tb")+(this.resizable?this.handleHeight:0)+this.assetHeight,c=Math.max(b.clientHeight,b.offsetHeight,b.scrollHeight),a=this.getPosition()[1]-Ext.getBody().getScroll().top,g=Ext.lib.Dom.getViewHeight()-a-this.getSize().height,d=Math.max(a,g,this.minHeight||0)-this.list.shadowOffset-e-5;c=Math.min(c,d,this.maxHeight);this.innerList.setHeight(c);this.list.beginUpdate();this.list.setHeight(c+e);this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));this.list.endUpdate()},isExpanded:function(){return this.list&&this.list.isVisible()},selectByValue:function(a,c){if(!Ext.isEmpty(a,true)){var b=this.findRecord(this.valueField||this.displayField,a);if(b){this.select(this.store.indexOf(b),c);return true}}return false},select:function(a,c){this.selectedIndex=a;this.view.select(a);if(c!==false){var b=this.view.getNode(a);if(b){this.innerList.scrollChildIntoView(b,false)}}},selectNext:function(){var a=this.store.getCount();if(a>0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex!==0){this.select(this.selectedIndex-1)}}}},onKeyUp:function(b){var a=b.getKey();if(this.editable!==false&&this.readOnly!==true&&(a==b.BACKSPACE||!b.isSpecialKey())){this.lastKey=a;this.dqTask.delay(this.queryDelay)}Ext.form.ComboBox.superclass.onKeyUp.call(this,b)},validateBlur:function(){return !this.list||!this.list.isVisible()},initQuery:function(){this.doQuery(this.getRawValue())},beforeBlur:function(){this.assertValue()},postBlur:function(){Ext.form.ComboBox.superclass.postBlur.call(this);this.collapse();this.inKeyMode=false},doQuery:function(c,b){c=Ext.isEmpty(c)?"":c;var a={query:c,forceAll:b,combo:this,cancel:false};if(this.fireEvent("beforequery",a)===false||a.cancel){return false}c=a.query;b=a.forceAll;if(b===true||(c.length>=this.minChars)){if(this.lastQuery!==c){this.lastQuery=c;if(this.mode=="local"){this.selectedIndex=-1;if(b){this.store.clearFilter()}else{this.store.filter(this.displayField,c)}this.onLoad()}else{this.store.baseParams[this.queryParam]=c;this.store.load({params:this.getParams(c)});this.expand()}}else{this.selectedIndex=-1;this.onLoad()}}},getParams:function(a){var b={},c=this.store.paramNames;if(this.pageSize){b[c.start]=0;b[c.limit]=this.pageSize}return b},collapse:function(){if(!this.isExpanded()){return}this.list.hide();Ext.getDoc().un("mousewheel",this.collapseIf,this);Ext.getDoc().un("mousedown",this.collapseIf,this);this.fireEvent("collapse",this)},collapseIf:function(a){if(!this.isDestroyed&&!a.within(this.wrap)&&!a.within(this.list)){this.collapse()}},expand:function(){if(this.isExpanded()||!this.hasFocus){return}if(this.title||this.pageSize){this.assetHeight=0;if(this.title){this.assetHeight+=this.header.getHeight()}if(this.pageSize){this.assetHeight+=this.footer.getHeight()}}if(this.bufferSize){this.doResize(this.bufferSize);delete this.bufferSize}this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));this.list.setZIndex(this.getZIndex());this.list.show();if(Ext.isGecko2){this.innerList.setOverflow("auto")}this.mon(Ext.getDoc(),{scope:this,mousewheel:this.collapseIf,mousedown:this.collapseIf});this.fireEvent("expand",this)},onTriggerClick:function(){if(this.readOnly||this.disabled){return}if(this.isExpanded()){this.collapse();this.el.focus()}else{this.onFocus({});if(this.triggerAction=="all"){this.doQuery(this.allQuery,true)}else{this.doQuery(this.getRawValue())}this.el.focus()}}});Ext.reg("combo",Ext.form.ComboBox);Ext.form.Checkbox=Ext.extend(Ext.form.Field,{focusClass:undefined,fieldClass:"x-form-field",checked:false,boxLabel:" ",defaultAutoCreate:{tag:"input",type:"checkbox",autocomplete:"off"},actionMode:"wrap",initComponent:function(){Ext.form.Checkbox.superclass.initComponent.call(this);this.addEvents("check")},onResize:function(){Ext.form.Checkbox.superclass.onResize.apply(this,arguments);if(!this.boxLabel&&!this.fieldLabel){this.el.alignTo(this.wrap,"c-c")}},initEvents:function(){Ext.form.Checkbox.superclass.initEvents.call(this);this.mon(this.el,{scope:this,click:this.onClick,change:this.onClick})},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,onRender:function(b,a){Ext.form.Checkbox.superclass.onRender.call(this,b,a);if(this.inputValue!==undefined){this.el.dom.value=this.inputValue}this.wrap=this.el.wrap({cls:"x-form-check-wrap"});if(this.boxLabel){this.wrap.createChild({tag:"label",htmlFor:this.el.id,cls:"x-form-cb-label",html:this.boxLabel})}if(this.checked){this.setValue(true)}else{this.checked=this.el.dom.checked}if(Ext.isIEQuirks){this.wrap.repaint()}this.resizeEl=this.positionEl=this.wrap},onDestroy:function(){Ext.destroy(this.wrap);Ext.form.Checkbox.superclass.onDestroy.call(this)},initValue:function(){this.originalValue=this.getValue()},getValue:function(){if(this.rendered){return this.el.dom.checked}return this.checked},onClick:function(){if(this.el.dom.checked!=this.checked){this.setValue(this.el.dom.checked)}},setValue:function(a){var c=this.checked,b=this.inputValue;if(a===false){this.checked=false}else{this.checked=(a===true||a==="true"||a=="1"||(b?a==b:String(a).toLowerCase()=="on"))}if(this.rendered){this.el.dom.checked=this.checked;this.el.dom.defaultChecked=this.checked}if(c!=this.checked){this.fireEvent("check",this,this.checked);if(this.handler){this.handler.call(this.scope||this,this,this.checked)}}return this}});Ext.reg("checkbox",Ext.form.Checkbox);Ext.form.CheckboxGroup=Ext.extend(Ext.form.Field,{columns:"auto",vertical:false,allowBlank:true,blankText:"You must select at least one item in this group",defaultType:"checkbox",groupCls:"x-form-check-group",initComponent:function(){this.addEvents("change");this.on("change",this.validate,this);Ext.form.CheckboxGroup.superclass.initComponent.call(this)},onRender:function(j,g){if(!this.el){var p={autoEl:{id:this.id},cls:this.groupCls,layout:"column",renderTo:j,bufferResize:false};var a={xtype:"container",defaultType:this.defaultType,layout:"form",defaults:{hideLabel:true,anchor:"100%"}};if(this.items[0].items){Ext.apply(p,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,m=this.items.length;e0&&e%r==0){o++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}n[o].items.push(this.items[e])}}else{for(var e=0,m=this.items.length;e-1){b.setValue(true)}})},getBox:function(b){var a=null;this.eachItem(function(c){if(b==c||c.dataIndex==b||c.id==b||c.getName()==b){a=c;return false}});return a},getValue:function(){var a=[];this.eachItem(function(b){if(b.checked){a.push(b)}});return a},eachItem:function(b,a){if(this.items&&this.items.each){this.items.each(b,a||this)}},getRawValue:Ext.emptyFn,setRawValue:Ext.emptyFn});Ext.reg("checkboxgroup",Ext.form.CheckboxGroup);Ext.form.CompositeField=Ext.extend(Ext.form.Field,{defaultMargins:"0 5 0 0",skipLastItemMargin:true,isComposite:true,combineErrors:true,labelConnector:", ",initComponent:function(){var g=[],b=this.items,e;for(var d=0,c=b.length;d")},sortErrors:function(){var a=this.items;this.fieldErrors.sort("ASC",function(g,d){var c=function(b){return function(i){return i.getName()==b}};var h=a.findIndexBy(c(g.field)),e=a.findIndexBy(c(d.field));return h1){var a=this.getBox(c);if(a){a.setValue(b);if(a.checked){this.eachItem(function(d){if(d!==a){d.setValue(false)}})}}}else{this.setValueForItem(c)}},setValueForItem:function(a){a=String(a).split(",")[0];this.eachItem(function(b){b.setValue(a==b.inputValue)})},fireChecked:function(){if(!this.checkTask){this.checkTask=new Ext.util.DelayedTask(this.bufferChecked,this)}this.checkTask.delay(10)},bufferChecked:function(){var a=null;this.eachItem(function(b){if(b.checked){a=b;return false}});this.fireEvent("change",this,a)},onDestroy:function(){if(this.checkTask){this.checkTask.cancel();this.checkTask=null}Ext.form.RadioGroup.superclass.onDestroy.call(this)}});Ext.reg("radiogroup",Ext.form.RadioGroup);Ext.form.Hidden=Ext.extend(Ext.form.Field,{inputType:"hidden",shouldLayout:false,onRender:function(){Ext.form.Hidden.superclass.onRender.apply(this,arguments)},initEvents:function(){this.originalValue=this.getValue()},setSize:Ext.emptyFn,setWidth:Ext.emptyFn,setHeight:Ext.emptyFn,setPosition:Ext.emptyFn,setPagePosition:Ext.emptyFn,markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn});Ext.reg("hidden",Ext.form.Hidden);Ext.form.BasicForm=Ext.extend(Ext.util.Observable,{constructor:function(b,a){Ext.apply(this,a);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}this.items=new Ext.util.MixedCollection(false,function(c){return c.getItemId()});this.addEvents("beforeaction","actionfailed","actioncomplete");if(b){this.initEl(b)}Ext.form.BasicForm.superclass.constructor.call(this)},timeout:30,paramOrder:undefined,paramsAsHash:false,waitTitle:"Please Wait...",activeAction:null,trackResetOnLoad:false,initEl:function(a){this.el=Ext.get(a);this.id=this.el.id||Ext.id();if(!this.standardSubmit){this.el.on("submit",this.onSubmit,this)}this.el.addClass("x-form")},getEl:function(){return this.el},onSubmit:function(a){a.stopEvent()},destroy:function(a){if(a!==true){this.items.each(function(b){Ext.destroy(b)});Ext.destroy(this.el)}this.items.clear();this.purgeListeners()},isValid:function(){var a=true;this.items.each(function(b){if(!b.validate()){a=false}});return a},isDirty:function(){var a=false;this.items.each(function(b){if(b.isDirty()){a=true;return false}});return a},doAction:function(b,a){if(Ext.isString(b)){b=new Ext.form.Action.ACTION_TYPES[b](this,a)}if(this.fireEvent("beforeaction",this,b)!==false){this.beforeAction(b);b.run.defer(100,b)}return this},submit:function(b){b=b||{};if(this.standardSubmit){var a=b.clientValidation===false||this.isValid();if(a){var c=this.el.dom;if(this.url&&Ext.isEmpty(c.action)){c.action=this.url}c.submit()}return a}var d=String.format("{0}submit",this.api?"direct":"");this.doAction(d,b);return this},load:function(a){var b=String.format("{0}load",this.api?"direct":"");this.doAction(b,a);return this},updateRecord:function(b){b.beginEdit();var a=b.fields,d,c;a.each(function(e){d=this.findField(e.name);if(d){c=d.getValue();if(Ext.type(c)!==false&&c.getGroupValue){c=c.getGroupValue()}else{if(d.eachItem){c=[];d.eachItem(function(g){c.push(g.getValue())})}}b.set(e.name,c)}},this);b.endEdit();return this},loadRecord:function(a){this.setValues(a.data);return this},beforeAction:function(a){this.items.each(function(c){if(c.isFormField&&c.syncValue){c.syncValue()}});var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.mask(b.waitMsg,"x-mask-loading")}else{if(this.waitMsgTarget){this.waitMsgTarget=Ext.get(this.waitMsgTarget);this.waitMsgTarget.mask(b.waitMsg,"x-mask-loading")}else{Ext.MessageBox.wait(b.waitMsg,b.waitTitle||this.waitTitle)}}}},afterAction:function(a,c){this.activeAction=null;var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.unmask()}else{if(this.waitMsgTarget){this.waitMsgTarget.unmask()}else{Ext.MessageBox.updateProgress(1);Ext.MessageBox.hide()}}}if(c){if(b.reset){this.reset()}Ext.callback(b.success,b.scope,[this,a]);this.fireEvent("actioncomplete",this,a)}else{Ext.callback(b.failure,b.scope,[this,a]);this.fireEvent("actionfailed",this,a)}},findField:function(c){var b=this.items.get(c);if(!Ext.isObject(b)){var a=function(d){if(d.isFormField){if(d.dataIndex==c||d.id==c||d.getName()==c){b=d;return false}else{if(d.isComposite){return d.items.each(a)}else{if(d instanceof Ext.form.CheckboxGroup&&d.rendered){return d.eachItem(a)}}}}};this.items.each(a)}return b||null},markInvalid:function(h){if(Ext.isArray(h)){for(var c=0,a=h.length;c':">"),c,"")}return d.join("")},createToolbar:function(e){var c=[];var a=Ext.QuickTips&&Ext.QuickTips.isEnabled();function d(j,h,i){return{itemId:j,cls:"x-btn-icon",iconCls:"x-edit-"+j,enableToggle:h!==false,scope:e,handler:i||e.relayBtnCmd,clickEvent:"mousedown",tooltip:a?e.buttonTips[j]||undefined:undefined,overflowText:e.buttonTips[j].title||undefined,tabIndex:-1}}if(this.enableFont&&!Ext.isSafari2){var g=new Ext.Toolbar.Item({autoEl:{tag:"select",cls:"x-font-select",html:this.createFontOptions()}});c.push(g,"-")}if(this.enableFormat){c.push(d("bold"),d("italic"),d("underline"))}if(this.enableFontSize){c.push("-",d("increasefontsize",false,this.adjustFont),d("decreasefontsize",false,this.adjustFont))}if(this.enableColors){c.push("-",{itemId:"forecolor",cls:"x-btn-icon",iconCls:"x-edit-forecolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.forecolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({allowReselect:true,focus:Ext.emptyFn,value:"000000",plain:true,listeners:{scope:this,select:function(i,h){this.execCmd("forecolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}},clickEvent:"mousedown"})},{itemId:"backcolor",cls:"x-btn-icon",iconCls:"x-edit-backcolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.backcolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({focus:Ext.emptyFn,value:"FFFFFF",plain:true,allowReselect:true,listeners:{scope:this,select:function(i,h){if(Ext.isGecko){this.execCmd("useCSS",false);this.execCmd("hilitecolor",h);this.execCmd("useCSS",true);this.deferFocus()}else{this.execCmd(Ext.isOpera?"hilitecolor":"backcolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}}},clickEvent:"mousedown"})})}if(this.enableAlignments){c.push("-",d("justifyleft"),d("justifycenter"),d("justifyright"))}if(!Ext.isSafari2){if(this.enableLinks){c.push("-",d("createlink",false,this.createLink))}if(this.enableLists){c.push("-",d("insertorderedlist"),d("insertunorderedlist"))}if(this.enableSourceEdit){c.push("-",d("sourceedit",true,function(h){this.toggleSourceEdit(!this.sourceEditMode)}))}}var b=new Ext.Toolbar({renderTo:this.wrap.dom.firstChild,items:c});if(g){this.fontSelect=g.el;this.mon(this.fontSelect,"change",function(){var h=this.fontSelect.dom.value;this.relayCmd("fontname",h);this.deferFocus()},this)}this.mon(b.el,"click",function(h){h.preventDefault()});this.tb=b;this.tb.doLayout()},onDisable:function(){this.wrap.mask();Ext.form.HtmlEditor.superclass.onDisable.call(this)},onEnable:function(){this.wrap.unmask();Ext.form.HtmlEditor.superclass.onEnable.call(this)},setReadOnly:function(b){Ext.form.HtmlEditor.superclass.setReadOnly.call(this,b);if(this.initialized){if(Ext.isIE){this.getEditorBody().contentEditable=!b}else{this.setDesignMode(!b)}var a=this.getEditorBody();if(a){a.style.cursor=this.readOnly?"default":"text"}this.disableItems(b)}},getDocMarkup:function(){var a=Ext.fly(this.iframe).getHeight()-this.iframePad*2;return String.format('',this.iframePad,a)},getEditorBody:function(){var a=this.getDoc();return a.body||a.documentElement},getDoc:function(){return Ext.isIE?this.getWin().document:(this.iframe.contentDocument||this.getWin().document)},getWin:function(){return Ext.isIE?this.iframe.contentWindow:window.frames[this.iframe.name]},onRender:function(b,a){Ext.form.HtmlEditor.superclass.onRender.call(this,b,a);this.el.dom.style.border="0 none";this.el.dom.setAttribute("tabIndex",-1);this.el.addClass("x-hidden");if(Ext.isIE){this.el.applyStyles("margin-top:-1px;margin-bottom:-1px;")}this.wrap=this.el.wrap({cls:"x-html-editor-wrap",cn:{cls:"x-html-editor-tb"}});this.createToolbar(this);this.disableItems(true);this.tb.doLayout();this.createIFrame();if(!this.width){var c=this.el.getSize();this.setSize(c.width,this.height||c.height)}this.resizeEl=this.positionEl=this.wrap},createIFrame:function(){var a=document.createElement("iframe");a.name=Ext.id();a.frameBorder="0";a.style.overflow="auto";a.src=Ext.SSL_SECURE_URL;this.wrap.dom.appendChild(a);this.iframe=a;this.monitorTask=Ext.TaskMgr.start({run:this.checkDesignMode,scope:this,interval:100})},initFrame:function(){Ext.TaskMgr.stop(this.monitorTask);var a=this.getDoc();this.win=this.getWin();a.open();a.write(this.getDocMarkup());a.close();this.readyTask={run:function(){var b=this.getDoc();if(b.body||b.readyState=="complete"){Ext.TaskMgr.stop(this.readyTask);this.setDesignMode(true);this.initEditor.defer(10,this)}},interval:10,duration:10000,scope:this};Ext.TaskMgr.start(this.readyTask)},checkDesignMode:function(){if(this.wrap&&this.wrap.dom.offsetWidth){var a=this.getDoc();if(!a){return}if(!a.editorInitialized||this.getDesignMode()!="on"){this.initFrame()}}},setDesignMode:function(b){var a=this.getDoc();if(a){if(this.readOnly){b=false}a.designMode=(/on|true/i).test(String(b).toLowerCase())?"on":"off"}},getDesignMode:function(){var a=this.getDoc();if(!a){return""}return String(a.designMode).toLowerCase()},disableItems:function(a){if(this.fontSelect){this.fontSelect.dom.disabled=a}this.tb.items.each(function(b){if(b.getItemId()!="sourceedit"){b.setDisabled(a)}})},onResize:function(b,c){Ext.form.HtmlEditor.superclass.onResize.apply(this,arguments);if(this.el&&this.iframe){if(Ext.isNumber(b)){var e=b-this.wrap.getFrameWidth("lr");this.el.setWidth(e);this.tb.setWidth(e);this.iframe.style.width=Math.max(e,0)+"px"}if(Ext.isNumber(c)){var a=c-this.wrap.getFrameWidth("tb")-this.tb.el.getHeight();this.el.setHeight(a);this.iframe.style.height=Math.max(a,0)+"px";var d=this.getEditorBody();if(d){d.style.height=Math.max((a-(this.iframePad*2)),0)+"px"}}}},toggleSourceEdit:function(b){var d,a;if(b===undefined){b=!this.sourceEditMode}this.sourceEditMode=b===true;var c=this.tb.getComponent("sourceedit");if(c.pressed!==this.sourceEditMode){c.toggle(this.sourceEditMode);if(!c.xtbHidden){return}}if(this.sourceEditMode){this.previousSize=this.getSize();d=Ext.get(this.iframe).getHeight();this.disableItems(true);this.syncValue();this.iframe.className="x-hidden";this.el.removeClass("x-hidden");this.el.dom.removeAttribute("tabIndex");this.el.focus();this.el.dom.style.height=d+"px"}else{a=parseInt(this.el.dom.style.height,10);if(this.initialized){this.disableItems(this.readOnly)}this.pushValue();this.iframe.className="";this.el.addClass("x-hidden");this.el.dom.setAttribute("tabIndex",-1);this.deferFocus();this.setSize(this.previousSize);delete this.previousSize;this.iframe.style.height=a+"px"}this.fireEvent("editmodechange",this,this.sourceEditMode)},createLink:function(){var a=prompt(this.createLinkText,this.defaultLinkValue);if(a&&a!="http://"){this.relayCmd("createlink",a)}},initEvents:function(){this.originalValue=this.getValue()},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,setValue:function(a){Ext.form.HtmlEditor.superclass.setValue.call(this,a);this.pushValue();return this},cleanHtml:function(a){a=String(a);if(Ext.isWebKit){a=a.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,"")}if(a.charCodeAt(0)==this.defaultValue.replace(/\D/g,"")){a=a.substring(1)}return a},syncValue:function(){if(this.initialized){var d=this.getEditorBody();var c=d.innerHTML;if(Ext.isWebKit){var b=d.getAttribute("style");var a=b.match(/text-align:(.*?);/i);if(a&&a[1]){c='
    '+c+"
    "}}c=this.cleanHtml(c);if(this.fireEvent("beforesync",this,c)!==false){this.el.dom.value=c;this.fireEvent("sync",this,c)}}},getValue:function(){this[this.sourceEditMode?"pushValue":"syncValue"]();return Ext.form.HtmlEditor.superclass.getValue.call(this)},pushValue:function(){if(this.initialized){var a=this.el.dom.value;if(!this.activated&&a.length<1){a=this.defaultValue}if(this.fireEvent("beforepush",this,a)!==false){this.getEditorBody().innerHTML=a;if(Ext.isGecko){this.setDesignMode(false);this.setDesignMode(true)}this.fireEvent("push",this,a)}}},deferFocus:function(){this.focus.defer(10,this)},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus()}else{this.el.focus()}},initEditor:function(){try{var c=this.getEditorBody(),a=this.el.getStyles("font-size","font-family","background-image","background-repeat","background-color","color"),g,b;a["background-attachment"]="fixed";c.bgProperties="fixed";Ext.DomHelper.applyStyles(c,a);g=this.getDoc();if(g){try{Ext.EventManager.removeAll(g)}catch(d){}}b=this.onEditorEvent.createDelegate(this);Ext.EventManager.on(g,{mousedown:b,dblclick:b,click:b,keyup:b,buffer:100});if(Ext.isGecko){Ext.EventManager.on(g,"keypress",this.applyCommand,this)}if(Ext.isIE||Ext.isWebKit||Ext.isOpera){Ext.EventManager.on(g,"keydown",this.fixKeys,this)}g.editorInitialized=true;this.initialized=true;this.pushValue();this.setReadOnly(this.readOnly);this.fireEvent("initialize",this)}catch(d){}},beforeDestroy:function(){if(this.monitorTask){Ext.TaskMgr.stop(this.monitorTask)}if(this.readyTask){Ext.TaskMgr.stop(this.readyTask)}if(this.rendered){Ext.destroy(this.tb);var b=this.getDoc();Ext.EventManager.removeFromSpecialCache(b);if(b){try{Ext.EventManager.removeAll(b);for(var c in b){delete b[c]}}catch(a){}}if(this.wrap){this.wrap.dom.innerHTML="";this.wrap.remove()}}Ext.form.HtmlEditor.superclass.beforeDestroy.call(this)},onFirstFocus:function(){this.activated=true;this.disableItems(this.readOnly);if(Ext.isGecko){this.win.focus();var a=this.win.getSelection();if(!a.focusNode||a.focusNode.nodeType!=3){var b=a.getRangeAt(0);b.selectNodeContents(this.getEditorBody());b.collapse(true);this.deferFocus()}try{this.execCmd("useCSS",true);this.execCmd("styleWithCSS",false)}catch(c){}}this.fireEvent("activate",this)},adjustFont:function(b){var d=b.getItemId()=="increasefontsize"?1:-1,c=this.getDoc(),a=parseInt(c.queryCommandValue("FontSize")||2,10);if((Ext.isSafari&&!Ext.isSafari2)||Ext.isChrome||Ext.isAir){if(a<=10){a=1+d}else{if(a<=13){a=2+d}else{if(a<=16){a=3+d}else{if(a<=18){a=4+d}else{if(a<=24){a=5+d}else{a=6+d}}}}}a=a.constrain(1,6)}else{if(Ext.isSafari){d*=2}a=Math.max(1,a+d)+(Ext.isSafari?"px":0)}this.execCmd("FontSize",a)},onEditorEvent:function(a){this.updateToolbar()},updateToolbar:function(){if(this.readOnly){return}if(!this.activated){this.onFirstFocus();return}var b=this.tb.items.map,c=this.getDoc();if(this.enableFont&&!Ext.isSafari2){var a=(c.queryCommandValue("FontName")||this.defaultFont).toLowerCase();if(a!=this.fontSelect.dom.value){this.fontSelect.dom.value=a}}if(this.enableFormat){b.bold.toggle(c.queryCommandState("bold"));b.italic.toggle(c.queryCommandState("italic"));b.underline.toggle(c.queryCommandState("underline"))}if(this.enableAlignments){b.justifyleft.toggle(c.queryCommandState("justifyleft"));b.justifycenter.toggle(c.queryCommandState("justifycenter"));b.justifyright.toggle(c.queryCommandState("justifyright"))}if(!Ext.isSafari2&&this.enableLists){b.insertorderedlist.toggle(c.queryCommandState("insertorderedlist"));b.insertunorderedlist.toggle(c.queryCommandState("insertunorderedlist"))}Ext.menu.MenuMgr.hideAll();this.syncValue()},relayBtnCmd:function(a){this.relayCmd(a.getItemId())},relayCmd:function(b,a){(function(){this.focus();this.execCmd(b,a);this.updateToolbar()}).defer(10,this)},execCmd:function(b,a){var c=this.getDoc();c.execCommand(b,false,a===undefined?null:a);this.syncValue()},applyCommand:function(b){if(b.ctrlKey){var d=b.getCharCode(),a;if(d>0){d=String.fromCharCode(d);switch(d){case"b":a="bold";break;case"i":a="italic";break;case"u":a="underline";break}if(a){this.win.focus();this.execCmd(a);this.deferFocus();b.preventDefault()}}}},insertAtCursor:function(c){if(!this.activated){return}if(Ext.isIE){this.win.focus();var b=this.getDoc(),a=b.selection.createRange();if(a){a.pasteHTML(c);this.syncValue();this.deferFocus()}}else{this.win.focus();this.execCmd("InsertHTML",c);this.deferFocus()}},fixKeys:function(){if(Ext.isIE){return function(g){var a=g.getKey(),d=this.getDoc(),b;if(a==g.TAB){g.stopEvent();b=d.selection.createRange();if(b){b.collapse(true);b.pasteHTML("    ");this.deferFocus()}}else{if(a==g.ENTER){b=d.selection.createRange();if(b){var c=b.parentElement();if(!c||c.tagName.toLowerCase()!="li"){g.stopEvent();b.pasteHTML("
    ");b.collapse(false);b.select()}}}}}}else{if(Ext.isOpera){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.win.focus();this.execCmd("InsertHTML","    ");this.deferFocus()}}}else{if(Ext.isWebKit){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.execCmd("InsertText","\t");this.deferFocus()}else{if(a==b.ENTER){b.stopEvent();this.execCmd("InsertHtml","

    ");this.deferFocus()}}}}}}}(),getToolbar:function(){return this.tb},buttonTips:{bold:{title:"Bold (Ctrl+B)",text:"Make the selected text bold.",cls:"x-html-editor-tip"},italic:{title:"Italic (Ctrl+I)",text:"Make the selected text italic.",cls:"x-html-editor-tip"},underline:{title:"Underline (Ctrl+U)",text:"Underline the selected text.",cls:"x-html-editor-tip"},increasefontsize:{title:"Grow Text",text:"Increase the font size.",cls:"x-html-editor-tip"},decreasefontsize:{title:"Shrink Text",text:"Decrease the font size.",cls:"x-html-editor-tip"},backcolor:{title:"Text Highlight Color",text:"Change the background color of the selected text.",cls:"x-html-editor-tip"},forecolor:{title:"Font Color",text:"Change the color of the selected text.",cls:"x-html-editor-tip"},justifyleft:{title:"Align Text Left",text:"Align text to the left.",cls:"x-html-editor-tip"},justifycenter:{title:"Center Text",text:"Center text in the editor.",cls:"x-html-editor-tip"},justifyright:{title:"Align Text Right",text:"Align text to the right.",cls:"x-html-editor-tip"},insertunorderedlist:{title:"Bullet List",text:"Start a bulleted list.",cls:"x-html-editor-tip"},insertorderedlist:{title:"Numbered List",text:"Start a numbered list.",cls:"x-html-editor-tip"},createlink:{title:"Hyperlink",text:"Make the selected text a hyperlink.",cls:"x-html-editor-tip"},sourceedit:{title:"Source Edit",text:"Switch to source editing mode.",cls:"x-html-editor-tip"}}});Ext.reg("htmleditor",Ext.form.HtmlEditor);Ext.form.TimeField=Ext.extend(Ext.form.ComboBox,{minValue:undefined,maxValue:undefined,minText:"The time in this field must be equal to or after {0}",maxText:"The time in this field must be equal to or before {0}",invalidText:"{0} is not a valid time",format:"g:i A",altFormats:"g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",increment:15,mode:"local",triggerAction:"all",typeAhead:false,initDate:"1/1/2008",initDateFormat:"j/n/Y",initComponent:function(){if(Ext.isDefined(this.minValue)){this.setMinValue(this.minValue,true)}if(Ext.isDefined(this.maxValue)){this.setMaxValue(this.maxValue,true)}if(!this.store){this.generateStore(true)}Ext.form.TimeField.superclass.initComponent.call(this)},setMinValue:function(b,a){this.setLimit(b,true,a);return this},setMaxValue:function(b,a){this.setLimit(b,false,a);return this},generateStore:function(b){var c=this.minValue||new Date(this.initDate).clearTime(),a=this.maxValue||new Date(this.initDate).clearTime().add("mi",(24*60)-1),d=[];while(c<=a){d.push(c.dateFormat(this.format));c=c.add("mi",this.increment)}this.bindStore(d,b)},setLimit:function(b,g,a){var e;if(Ext.isString(b)){e=this.parseDate(b)}else{if(Ext.isDate(b)){e=b}}if(e){var c=new Date(this.initDate).clearTime();c.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds());this[g?"minValue":"maxValue"]=c;if(!a){this.generateStore()}}},getValue:function(){var a=Ext.form.TimeField.superclass.getValue.call(this);return this.formatDate(this.parseDate(a))||""},setValue:function(a){return Ext.form.TimeField.superclass.setValue.call(this,this.formatDate(this.parseDate(a)))},validateValue:Ext.form.DateField.prototype.validateValue,formatDate:Ext.form.DateField.prototype.formatDate,parseDate:function(h){if(!h||Ext.isDate(h)){return h}var j=this.initDate+" ",g=this.initDateFormat+" ",b=Date.parseDate(j+h,g+this.format),c=this.altFormats;if(!b&&c){if(!this.altFormatsArray){this.altFormatsArray=c.split("|")}for(var e=0,d=this.altFormatsArray,a=d.length;e=0){if(!d){c=g-1}d=false;while(c>=0){if(e.call(j||this,k,c,i)===true){return[k,c]}c--}k--}}else{if(c>=g){k++;d=false}while(k','
    ','
    ','
    ','
    {header}
    ',"
    ",'
    ',"
    ",'
    ','
    {body}
    ','',"
    ","
    ",'
     
    ','
     
    ',""),headerTpl:new Ext.Template('',"",'{cells}',"","
    "),bodyTpl:new Ext.Template("{rows}"),cellTpl:new Ext.Template('','
    {value}
    ',""),initTemplates:function(){var c=this.templates||{},d,b,g=new Ext.Template('','
    ',this.grid.enableHdMenu?'':"","{value}",'',"
    ",""),a=['','','
    {body}
    ',"",""].join(""),e=['',"","{cells}",this.enableRowBody?a:"","","
    "].join("");Ext.applyIf(c,{hcell:g,cell:this.cellTpl,body:this.bodyTpl,header:this.headerTpl,master:this.masterTpl,row:new Ext.Template('
    '+e+"
    "),rowInner:new Ext.Template(e)});for(b in c){d=c[b];if(d&&Ext.isFunction(d.compile)&&!d.compiled){d.disableFormats=true;d.compile()}}this.templates=c;this.colRe=new RegExp("x-grid3-td-([^\\s]+)","")},fly:function(a){if(!this._flyweight){this._flyweight=new Ext.Element.Flyweight(document.body)}this._flyweight.dom=a;return this._flyweight},getEditorParent:function(){return this.scroller.dom},initElements:function(){var b=Ext.Element,d=Ext.get(this.grid.getGridEl().dom.firstChild),e=new b(d.child("div.x-grid3-viewport")),c=new b(e.child("div.x-grid3-header")),a=new b(e.child("div.x-grid3-scroller"));if(this.grid.hideHeaders){c.setDisplayed(false)}if(this.forceFit){a.setStyle("overflow-x","hidden")}Ext.apply(this,{el:d,mainWrap:e,scroller:a,mainHd:c,innerHd:c.child("div.x-grid3-header-inner").dom,mainBody:new b(b.fly(a).child("div.x-grid3-body")),focusEl:new b(b.fly(a).child("a")),resizeMarker:new b(d.child("div.x-grid3-resize-marker")),resizeProxy:new b(d.child("div.x-grid3-resize-proxy"))});this.focusEl.swallowEvent("click",true)},getRows:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},findCell:function(a){if(!a){return false}return this.fly(a).findParent(this.cellSelector,this.cellSelectorDepth)},findCellIndex:function(d,c){var b=this.findCell(d),a;if(b){a=this.fly(b).hasClass(c);if(!c||a){return this.getCellIndex(b)}}return false},getCellIndex:function(b){if(b){var a=b.className.match(this.colRe);if(a&&a[1]){return this.cm.getIndexById(a[1])}}return false},findHeaderCell:function(b){var a=this.findCell(b);return a&&this.fly(a).hasClass(this.hdCls)?a:null},findHeaderIndex:function(a){return this.findCellIndex(a,this.hdCls)},findRow:function(a){if(!a){return false}return this.fly(a).findParent(this.rowSelector,this.rowSelectorDepth)},findRowIndex:function(a){var b=this.findRow(a);return b?b.rowIndex:false},findRowBody:function(a){if(!a){return false}return this.fly(a).findParent(this.rowBodySelector,this.rowBodySelectorDepth)},getRow:function(a){return this.getRows()[a]},getCell:function(b,a){return Ext.fly(this.getRow(b)).query(this.cellSelector)[a]},getHeaderCell:function(a){return this.mainHd.dom.getElementsByTagName("td")[a]},addRowClass:function(b,a){var c=this.getRow(b);if(c){this.fly(c).addClass(a)}},removeRowClass:function(c,a){var b=this.getRow(c);if(b){this.fly(b).removeClass(a)}},removeRow:function(a){Ext.removeNode(this.getRow(a));this.syncFocusEl(a)},removeRows:function(c,a){var b=this.mainBody.dom,d;for(d=c;d<=a;d++){Ext.removeNode(b.childNodes[c])}this.syncFocusEl(c)},getScrollState:function(){var a=this.scroller.dom;return{left:a.scrollLeft,top:a.scrollTop}},restoreScroll:function(a){var b=this.scroller.dom;b.scrollLeft=a.left;b.scrollTop=a.top},scrollToTop:function(){var a=this.scroller.dom;a.scrollTop=0;a.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.scroller.dom;this.grid.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerHd,b=this.scroller.dom.scrollLeft;a.scrollLeft=b;a.scrollLeft=b},updateSortIcon:function(d,c){var a=this.sortClasses,b=a[c=="DESC"?1:0],e=this.mainHd.select("td").removeClass(a);e.item(d).addClass(b)},updateAllColumnWidths:function(){var e=this.getTotalWidth(),k=this.cm.getColumnCount(),m=this.getRows(),g=m.length,b=[],l,a,h,d,c;for(d=0;d=this.ds.getCount()){return null}d=(d!==undefined?d:0);var c=this.getRow(h),b=this.cm,e=b.getColumnCount(),a;if(!(g===false&&d===0)){while(dm){n.scrollTop=q-a}}if(e!==false){var l=parseInt(h.offsetLeft,10),j=l+h.offsetWidth,i=parseInt(n.scrollLeft,10),b=i+n.clientWidth;if(lb){n.scrollLeft=j-n.clientWidth}}}return this.getResolvedXY(r)},insertRows:function(a,i,e,h){var d=a.getCount()-1;if(!h&&i===0&&e>=d){this.fireEvent("beforerowsinserted",this,i,e);this.refresh();this.fireEvent("rowsinserted",this,i,e)}else{if(!h){this.fireEvent("beforerowsinserted",this,i,e)}var b=this.renderRows(i,e),g=this.getRow(i);if(g){if(i===0){Ext.fly(this.getRow(0)).removeClass(this.firstRowCls)}Ext.DomHelper.insertHtml("beforeBegin",g,b)}else{var c=this.getRow(d-1);if(c){Ext.fly(c).removeClass(this.lastRowCls)}Ext.DomHelper.insertHtml("beforeEnd",this.mainBody.dom,b)}if(!h){this.processRows(i);this.fireEvent("rowsinserted",this,i,e)}else{if(i===0||i>=d){Ext.fly(this.getRow(i)).addClass(i===0?this.firstRowCls:this.lastRowCls)}}}this.syncFocusEl(i)},deleteRows:function(a,c,b){if(a.getRowCount()<1){this.refresh()}else{this.fireEvent("beforerowsdeleted",this,c,b);this.removeRows(c,b);this.processRows(c);this.fireEvent("rowsdeleted",this,c,b)}},getColumnStyle:function(b,d){var a=this.cm,g=a.config,c=d?"":g[b].css||"",e=g[b].align;c+=String.format("width: {0};",this.getColumnWidth(b));if(a.isHidden(b)){c+="display: none; "}if(e){c+=String.format("text-align: {0};",e)}return c},getColumnWidth:function(b){var c=this.cm.getColumnWidth(b),a=this.borderWidth;if(Ext.isNumber(c)){if(Ext.isBorderBox){return c+"px"}else{return Math.max(c-a,0)+"px"}}else{return c}},getTotalWidth:function(){return this.cm.getTotalWidth()+"px"},fitColumns:function(g,j,h){var a=this.grid,l=this.cm,s=l.getTotalWidth(false),q=this.getGridInnerWidth(),r=q-s,c=[],o=0,n=0,u,d,p;if(q<20||r===0){return false}var e=l.getColumnCount(true),m=l.getColumnCount(false),b=e-(Ext.isNumber(h)?1:0);if(b===0){b=1;h=undefined}for(p=0;pq){var t=(b==e)?o:h,k=Math.max(1,l.getColumnWidth(t)-(s-q));l.setColumnWidth(t,k,true)}if(g!==true){this.updateAllColumnWidths()}return true},autoExpand:function(k){var a=this.grid,i=this.cm,e=this.getGridInnerWidth(),c=i.getTotalWidth(false),g=a.autoExpandColumn;if(!this.userResized&&g){if(e!=c){var j=i.getIndexById(g),b=i.getColumnWidth(j),h=e-c+b,d=Math.min(Math.max(h,a.autoExpandMin),a.autoExpandMax);if(b!=d){i.setColumnWidth(j,d,true);if(k!==true){this.updateColumnWidth(j,d)}}}}},getGridInnerWidth:function(){return this.grid.getGridEl().getWidth(true)-this.getScrollOffset()},getColumnData:function(){var e=[],c=this.cm,g=c.getColumnCount(),a=this.ds.fields,d,b;for(d=0;d'+this.emptyText+"")}},updateHeaderSortState:function(){var b=this.ds.getSortState();if(!b){return}if(!this.sortState||(this.sortState.field!=b.field||this.sortState.direction!=b.direction)){this.grid.fireEvent("sortchange",this.grid,b)}this.sortState=b;var c=this.cm.findColumnIndex(b.field);if(c!=-1){var a=b.direction;this.updateSortIcon(c,a)}},clearHeaderSortState:function(){if(!this.sortState){return}this.grid.fireEvent("sortchange",this.grid,null);this.mainHd.select("td").removeClass(this.sortClasses);delete this.sortState},destroy:function(){var j=this,a=j.grid,d=a.getGridEl(),i=j.dragZone,g=j.splitZone,h=j.columnDrag,e=j.columnDrop,k=j.scrollToTopTask,c,b;if(k&&k.cancel){k.cancel()}Ext.destroyMembers(j,"colMenu","hmenu");j.initData(null,null);j.purgeListeners();Ext.fly(j.innerHd).un("click",j.handleHdDown,j);if(a.enableColumnMove){c=h.dragData;b=h.proxy;Ext.destroy(h.el,b.ghost,b.el,e.el,e.proxyTop,e.proxyBottom,c.ddel,c.header);if(b.anim){Ext.destroy(b.anim)}delete b.ghost;delete c.ddel;delete c.header;h.destroy();delete Ext.dd.DDM.locationCache[h.id];delete h._domRef;delete e.proxyTop;delete e.proxyBottom;e.destroy();delete Ext.dd.DDM.locationCache["gridHeader"+d.id];delete e._domRef;delete Ext.dd.DDM.ids[e.ddGroup]}if(g){g.destroy();delete g._domRef;delete Ext.dd.DDM.ids["gridSplitters"+d.id]}Ext.fly(j.innerHd).removeAllListeners();Ext.removeNode(j.innerHd);delete j.innerHd;Ext.destroy(j.el,j.mainWrap,j.mainHd,j.scroller,j.mainBody,j.focusEl,j.resizeMarker,j.resizeProxy,j.activeHdBtn,j._flyweight,i,g);delete a.container;if(i){i.destroy()}Ext.dd.DDM.currentTarget=null;delete Ext.dd.DDM.locationCache[d.id];Ext.EventManager.removeResizeListener(j.onWindowResize,j)},onDenyColumnHide:function(){},render:function(){if(this.autoFill){var a=this.grid.ownerCt;if(a&&a.getLayout()){a.on("afterlayout",function(){this.fitColumns(true,true);this.updateHeaders();this.updateHeaderSortState()},this,{single:true})}}else{if(this.forceFit){this.fitColumns(true,false)}else{if(this.grid.autoExpandColumn){this.autoExpand(true)}}}this.grid.getGridEl().dom.innerHTML=this.renderUI();this.afterRenderUI()},initData:function(a,e){var b=this;if(b.ds){var d=b.ds;d.un("add",b.onAdd,b);d.un("load",b.onLoad,b);d.un("clear",b.onClear,b);d.un("remove",b.onRemove,b);d.un("update",b.onUpdate,b);d.un("datachanged",b.onDataChange,b);if(d!==a&&d.autoDestroy){d.destroy()}}if(a){a.on({scope:b,load:b.onLoad,add:b.onAdd,remove:b.onRemove,update:b.onUpdate,clear:b.onClear,datachanged:b.onDataChange})}if(b.cm){var c=b.cm;c.un("configchange",b.onColConfigChange,b);c.un("widthchange",b.onColWidthChange,b);c.un("headerchange",b.onHeaderChange,b);c.un("hiddenchange",b.onHiddenChange,b);c.un("columnmoved",b.onColumnMove,b)}if(e){delete b.lastViewWidth;e.on({scope:b,configchange:b.onColConfigChange,widthchange:b.onColWidthChange,headerchange:b.onHeaderChange,hiddenchange:b.onHiddenChange,columnmoved:b.onColumnMove})}b.ds=a;b.cm=e},onDataChange:function(){this.refresh(true);this.updateHeaderSortState();this.syncFocusEl(0)},onClear:function(){this.refresh();this.syncFocusEl(0)},onUpdate:function(b,a){this.refreshRow(a)},onAdd:function(b,a,c){this.insertRows(b,c,c+(a.length-1))},onRemove:function(b,a,c,d){if(d!==true){this.fireEvent("beforerowremoved",this,c,a)}this.removeRow(c);if(d!==true){this.processRows(c);this.applyEmptyText();this.fireEvent("rowremoved",this,c,a)}},onLoad:function(){if(Ext.isGecko){if(!this.scrollToTopTask){this.scrollToTopTask=new Ext.util.DelayedTask(this.scrollToTop,this)}this.scrollToTopTask.delay(1)}else{this.scrollToTop()}},onColWidthChange:function(a,b,c){this.updateColumnWidth(b,c)},onHeaderChange:function(a,b,c){this.updateHeaders()},onHiddenChange:function(a,b,c){this.updateColumnHidden(b,c)},onColumnMove:function(a,c,b){this.indexMap=null;this.refresh(true);this.restoreScroll(this.getScrollState());this.afterMove(b);this.grid.fireEvent("columnmove",c,b)},onColConfigChange:function(){delete this.lastViewWidth;this.indexMap=null;this.refresh(true)},initUI:function(a){a.on("headerclick",this.onHeaderClick,this)},initEvents:Ext.emptyFn,onHeaderClick:function(b,a){if(this.headersDisabled||!this.cm.isSortable(a)){return}b.stopEditing(true);b.store.sort(this.cm.getDataIndex(a))},onRowOver:function(b,a){var c=this.findRowIndex(a);if(c!==false){this.addRowClass(c,this.rowOverCls)}},onRowOut:function(b,a){var c=this.findRowIndex(a);if(c!==false&&!b.within(this.getRow(c),true)){this.removeRowClass(c,this.rowOverCls)}},onRowSelect:function(a){this.addRowClass(a,this.selectedRowClass)},onRowDeselect:function(a){this.removeRowClass(a,this.selectedRowClass)},onCellSelect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).addClass("x-grid3-cell-selected")}},onCellDeselect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).removeClass("x-grid3-cell-selected")}},handleWheel:function(a){a.stopPropagation()},onColumnSplitterMoved:function(a,b){this.userResized=true;this.grid.colModel.setColumnWidth(a,b,true);if(this.forceFit){this.fitColumns(true,false,a);this.updateAllColumnWidths()}else{this.updateColumnWidth(a,b);this.syncHeaderScroll()}this.grid.fireEvent("columnresize",a,b)},beforeColMenuShow:function(){var b=this.cm,d=b.getColumnCount(),a=this.colMenu,c;a.removeAll();for(c=0;c0){if(!this.cm.isHidden(a-1)){return a}a--}return undefined},handleHdOver:function(c,b){var d=this.findHeaderCell(b);if(d&&!this.headersDisabled){var a=this.fly(d);this.activeHdRef=b;this.activeHdIndex=this.getCellIndex(d);this.activeHdRegion=a.getRegion();if(!this.isMenuDisabled(this.activeHdIndex,a)){a.addClass("x-grid3-hd-over");this.activeHdBtn=a.child(".x-grid3-hd-btn");if(this.activeHdBtn){this.activeHdBtn.dom.style.height=(d.firstChild.offsetHeight-1)+"px"}}}},handleHdOut:function(b,a){var c=this.findHeaderCell(a);if(c&&(!Ext.isIE9m||!b.within(c,true))){this.activeHdRef=null;this.fly(c).removeClass("x-grid3-hd-over");c.style.cursor=""}},isMenuDisabled:function(a,b){return this.cm.isMenuDisabled(a)},hasRows:function(){var a=this.mainBody.dom.firstChild;return a&&a.nodeType==1&&a.className!="x-grid-empty"},isHideableColumn:function(a){return !a.hidden},bind:function(a,b){this.initData(a,b)}});Ext.grid.GridView.SplitDragZone=Ext.extend(Ext.dd.DDProxy,{constructor:function(a,b){this.grid=a;this.view=a.getView();this.marker=this.view.resizeMarker;this.proxy=this.view.resizeProxy;Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this,b,"gridSplitters"+this.grid.getGridEl().id,{dragElId:Ext.id(this.proxy.dom),resizeFrame:false});this.scroll=false;this.hw=this.view.splitHandleWidth||5},b4StartDrag:function(a,e){this.dragHeadersDisabled=this.view.headersDisabled;this.view.headersDisabled=true;var d=this.view.mainWrap.getHeight();this.marker.setHeight(d);this.marker.show();this.marker.alignTo(this.view.getHeaderCell(this.cellIndex),"tl-tl",[-2,0]);this.proxy.setHeight(d);var b=this.cm.getColumnWidth(this.cellIndex),c=Math.max(b-this.grid.minColumnWidth,0);this.resetConstraints();this.setXConstraint(c,1000);this.setYConstraint(0,0);this.minX=a-c;this.maxX=a+1000;this.startPos=a;Ext.dd.DDProxy.prototype.b4StartDrag.call(this,a,e)},allowHeaderDrag:function(a){return true},handleMouseDown:function(a){var h=this.view.findHeaderCell(a.getTarget());if(h&&this.allowHeaderDrag(a)){var k=this.view.fly(h).getXY(),c=k[0],i=a.getXY(),b=i[0],g=h.offsetWidth,d=false;if((b-c)<=this.hw){d=-1}else{if((c+g)-b<=this.hw){d=0}}if(d!==false){this.cm=this.grid.colModel;var j=this.view.getCellIndex(h);if(d==-1){if(j+d<0){return}while(this.cm.isHidden(j+d)){--d;if(j+d<0){return}}}this.cellIndex=j+d;this.split=h.dom;if(this.cm.isResizable(this.cellIndex)&&!this.cm.isFixed(this.cellIndex)){Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this,arguments)}}else{if(this.view.columnDrag){this.view.columnDrag.callHandleMouseDown(a)}}}},endDrag:function(g){this.marker.hide();var a=this.view,c=Math.max(this.minX,g.getPageX()),d=c-this.startPos,b=this.dragHeadersDisabled;a.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+d);setTimeout(function(){a.headersDisabled=b},50)},autoOffset:function(){this.setDelta(0,0)}});Ext.grid.PivotGridView=Ext.extend(Ext.grid.GridView,{colHeaderCellCls:"grid-hd-group-cell",title:"",getColumnHeaders:function(){return this.grid.topAxis.buildHeaders()},getRowHeaders:function(){return this.grid.leftAxis.buildHeaders()},renderRows:function(a,t){var b=this.grid,o=b.extractData(),p=o.length,g=this.templates,s=b.renderer,h=typeof s=="function",w=this.getCellCls,n=typeof w=="function",d=g.cell,x=g.row,k=[],q={},c="width:"+this.getGridInnerWidth()+"px;",l,r,e,v,m;a=a||0;t=Ext.isDefined(t)?t:p-1;for(v=0;v','
    ','
    ','
    {title}
    ','
    ','
    ',"
    ",'
    ',"
    ",'
    ','
    ','
    {body}
    ','',"
    ","
    ",'
     
    ','
     
    ',""),initTemplates:function(){Ext.grid.PivotGridView.superclass.initTemplates.apply(this,arguments);var a=this.templates||{};if(!a.gcell){a.gcell=new Ext.XTemplate('','
    ',this.grid.enableHdMenu?'':"","{value}","
    ","")}this.templates=a;this.hrowRe=new RegExp("ux-grid-hd-group-row-(\\d+)","")},initElements:function(){Ext.grid.PivotGridView.superclass.initElements.apply(this,arguments);this.rowHeadersEl=new Ext.Element(this.scroller.child("div.x-grid3-row-headers"));this.headerTitleEl=new Ext.Element(this.mainHd.child("div.x-grid3-header-title"))},getGridInnerWidth:function(){var a=Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this,arguments);return a-this.getTotalRowHeaderWidth()},getTotalRowHeaderWidth:function(){var d=this.getRowHeaders(),c=d.length,b=0,a;for(a=0;a0&&d>0){h=h||o.data[a[g-1].dataIndex]!=l[d-1].data[a[g-1].dataIndex]}if(h){s.push({header:q,span:p,start:b});b+=p;p=0}if(k){s.push({header:n,span:p+1,start:b});b+=p;p=0}q=n;p++}c.push({items:s,width:e.width||this.defaultHeaderWidth});q=undefined}return c}});Ext.grid.HeaderDragZone=Ext.extend(Ext.dd.DragZone,{maxDragWidth:120,constructor:function(a,c,b){this.grid=a;this.view=a.getView();this.ddGroup="gridHeader"+this.grid.getGridEl().id;Ext.grid.HeaderDragZone.superclass.constructor.call(this,c);if(b){this.setHandleElId(Ext.id(c));this.setOuterHandleElId(Ext.id(b))}this.scroll=false},getDragData:function(c){var a=Ext.lib.Event.getTarget(c),b=this.view.findHeaderCell(a);if(b){return{ddel:b.firstChild,header:b}}return false},onInitDrag:function(a){this.dragHeadersDisabled=this.view.headersDisabled;this.view.headersDisabled=true;var b=this.dragData.ddel.cloneNode(true);b.id=Ext.id();b.style.width=Math.min(this.dragData.header.offsetWidth,this.maxDragWidth)+"px";this.proxy.update(b);return true},afterValidDrop:function(){this.completeDrop()},afterInvalidDrop:function(){this.completeDrop()},completeDrop:function(){var a=this.view,b=this.dragHeadersDisabled;setTimeout(function(){a.headersDisabled=b},50)}});Ext.grid.HeaderDropZone=Ext.extend(Ext.dd.DropZone,{proxyOffsets:[-4,-9],fly:Ext.Element.fly,constructor:function(a,c,b){this.grid=a;this.view=a.getView();this.proxyTop=Ext.DomHelper.append(document.body,{cls:"col-move-top",html:" "},true);this.proxyBottom=Ext.DomHelper.append(document.body,{cls:"col-move-bottom",html:" "},true);this.proxyTop.hide=this.proxyBottom.hide=function(){this.setLeftTop(-100,-100);this.setStyle("visibility","hidden")};this.ddGroup="gridHeader"+this.grid.getGridEl().id;Ext.grid.HeaderDropZone.superclass.constructor.call(this,a.getGridEl().dom)},getTargetFromEvent:function(c){var a=Ext.lib.Event.getTarget(c),b=this.view.findCellIndex(a);if(b!==false){return this.view.getHeaderCell(b)}},nextVisible:function(c){var b=this.view,a=this.grid.colModel;c=c.nextSibling;while(c){if(!a.isHidden(b.getCellIndex(c))){return c}c=c.nextSibling}return null},prevVisible:function(c){var b=this.view,a=this.grid.colModel;c=c.prevSibling;while(c){if(!a.isHidden(b.getCellIndex(c))){return c}c=c.prevSibling}return null},positionIndicator:function(d,k,j){var a=Ext.lib.Event.getPageX(j),g=Ext.lib.Dom.getRegion(k.firstChild),c,i,b=g.top+this.proxyOffsets[1];if((g.right-a)<=(g.right-g.left)/2){c=g.right+this.view.borderWidth;i="after"}else{c=g.left;i="before"}if(this.grid.colModel.isFixed(this.view.getCellIndex(k))){return false}c+=this.proxyOffsets[0];this.proxyTop.setLeftTop(c,b);this.proxyTop.show();if(!this.bottomOffset){this.bottomOffset=this.view.mainHd.getHeight()}this.proxyBottom.setLeftTop(c,b+this.proxyTop.dom.offsetHeight+this.bottomOffset);this.proxyBottom.show();return i},onNodeEnter:function(d,a,c,b){if(b.header!=d){this.positionIndicator(b.header,d,c)}},onNodeOver:function(g,b,d,c){var a=false;if(c.header!=g){a=this.positionIndicator(c.header,g,d)}if(!a){this.proxyTop.hide();this.proxyBottom.hide()}return a?this.dropAllowed:this.dropNotAllowed},onNodeOut:function(d,a,c,b){this.proxyTop.hide();this.proxyBottom.hide()},onNodeDrop:function(b,m,g,c){var d=c.header;if(d!=b){var k=this.grid.colModel,j=Ext.lib.Event.getPageX(g),a=Ext.lib.Dom.getRegion(b.firstChild),o=(a.right-j)<=((a.right-a.left)/2)?"after":"before",i=this.view.getCellIndex(d),l=this.view.getCellIndex(b);if(o=="after"){l++}if(i=0&&this.config[a].resizable!==false&&this.config[a].fixed!==true},setHidden:function(a,b){var d=this.config[a];if(d.hidden!==b){d.hidden=b;this.totalWidth=null;this.fireEvent("hiddenchange",this,a,b)}},setEditor:function(a,b){this.config[a].setEditor(b)},destroy:function(){var b=this.config.length,a=0;for(;a0},isSelected:function(a){var b=Ext.isNumber(a)?this.grid.store.getAt(a):a;return(b&&this.selections.key(b.id)?true:false)},isIdSelected:function(a){return(this.selections.key(a)?true:false)},handleMouseDown:function(d,i,h){if(h.button!==0||this.isLocked()){return}var a=this.grid.getView();if(h.shiftKey&&!this.singleSelect&&this.last!==false){var c=this.last;this.selectRange(c,i,h.ctrlKey);this.last=c;a.focusRow(i)}else{var b=this.isSelected(i);if(h.ctrlKey&&b){this.deselectRow(i)}else{if(!b||this.getCount()>1){this.selectRow(i,h.ctrlKey||h.shiftKey);a.focusRow(i)}}}},selectRows:function(c,d){if(!d){this.clearSelections()}for(var b=0,a=c.length;b=a;c--){this.selectRow(c,true)}}},deselectRange:function(c,b,a){if(this.isLocked()){return}for(var d=c;d<=b;d++){this.deselectRow(d,a)}},selectRow:function(b,d,a){if(this.isLocked()||(b<0||b>=this.grid.store.getCount())||(d&&this.isSelected(b))){return}var c=this.grid.store.getAt(b);if(c&&this.fireEvent("beforerowselect",this,b,d,c)!==false){if(!d||this.singleSelect){this.clearSelections()}this.selections.add(c);this.last=this.lastActive=b;if(!a){this.grid.getView().onRowSelect(b)}if(!this.silent){this.fireEvent("rowselect",this,b,c);this.fireEvent("selectionchange",this)}}},deselectRow:function(b,a){if(this.isLocked()){return}if(this.last==b){this.last=false}if(this.lastActive==b){this.lastActive=false}var c=this.grid.store.getAt(b);if(c){this.selections.remove(c);if(!a){this.grid.getView().onRowDeselect(b)}this.fireEvent("rowdeselect",this,b,c);this.fireEvent("selectionchange",this)}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)},onEditorKey:function(n,l){var d=l.getKey(),h,i=this.grid,p=i.lastEdit,j=i.activeEditor,b=l.shiftKey,o,p,a,m;if(d==l.TAB){l.stopEvent();j.completeEdit();if(b){h=i.walkCells(j.row,j.col-1,-1,this.acceptsNav,this)}else{h=i.walkCells(j.row,j.col+1,1,this.acceptsNav,this)}}else{if(d==l.ENTER){if(this.moveEditorOnEnter!==false){if(b){h=i.walkCells(p.row-1,p.col,-1,this.acceptsNav,this)}else{h=i.walkCells(p.row+1,p.col,1,this.acceptsNav,this)}}}}if(h){a=h[0];m=h[1];this.onEditorSelect(a,p.row);if(i.isEditor&&i.editing){o=i.activeEditor;if(o&&o.field.triggerBlur){o.field.triggerBlur()}}i.startEditing(a,m)}},onEditorSelect:function(b,a){if(a!=b){this.selectRow(b)}},destroy:function(){Ext.destroy(this.rowNav);this.rowNav=null;Ext.grid.RowSelectionModel.superclass.destroy.call(this)}});Ext.grid.Column=Ext.extend(Ext.util.Observable,{isColumn:true,constructor:function(b){Ext.apply(this,b);if(Ext.isString(this.renderer)){this.renderer=Ext.util.Format[this.renderer]}else{if(Ext.isObject(this.renderer)){this.scope=this.renderer.scope;this.renderer=this.renderer.fn}}if(!this.scope){this.scope=this}var a=this.editor;delete this.editor;this.setEditor(a);this.addEvents("click","contextmenu","dblclick","mousedown");Ext.grid.Column.superclass.constructor.call(this)},processEvent:function(b,d,c,g,a){return this.fireEvent(b,this,c,g,d)},destroy:function(){if(this.setEditor){this.setEditor(null)}this.purgeListeners()},renderer:function(a){return a},getEditor:function(a){return this.editable!==false?this.editor:null},setEditor:function(b){var a=this.editor;if(a){if(a.gridEditor){a.gridEditor.destroy();delete a.gridEditor}else{a.destroy()}}this.editor=null;if(b){if(!b.isXType){b=Ext.create(b,"textfield")}this.editor=b}},getCellEditor:function(b){var a=this.getEditor(b);if(a){if(!a.startEdit){if(!a.gridEditor){a.gridEditor=new Ext.grid.GridEditor(a)}a=a.gridEditor}}return a}});Ext.grid.BooleanColumn=Ext.extend(Ext.grid.Column,{trueText:"true",falseText:"false",undefinedText:" ",constructor:function(a){Ext.grid.BooleanColumn.superclass.constructor.call(this,a);var c=this.trueText,d=this.falseText,b=this.undefinedText;this.renderer=function(e){if(e===undefined){return b}if(!e||e==="false"){return d}return c}}});Ext.grid.NumberColumn=Ext.extend(Ext.grid.Column,{format:"0,000.00",constructor:function(a){Ext.grid.NumberColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.numberRenderer(this.format)}});Ext.grid.DateColumn=Ext.extend(Ext.grid.Column,{format:"m/d/Y",constructor:function(a){Ext.grid.DateColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.dateRenderer(this.format)}});Ext.grid.TemplateColumn=Ext.extend(Ext.grid.Column,{constructor:function(a){Ext.grid.TemplateColumn.superclass.constructor.call(this,a);var b=(!Ext.isPrimitive(this.tpl)&&this.tpl.compile)?this.tpl:new Ext.XTemplate(this.tpl);this.renderer=function(d,e,c){return b.apply(c.data)};this.tpl=b}});Ext.grid.ActionColumn=Ext.extend(Ext.grid.Column,{header:" ",actionIdRe:/x-action-col-(\d+)/,altText:"",constructor:function(b){var g=this,c=b.items||(g.items=[g]),a=c.length,d,e;Ext.grid.ActionColumn.superclass.constructor.call(g,b);g.renderer=function(h,i){h=Ext.isFunction(b.renderer)?b.renderer.apply(this,arguments)||"":"";i.css+=" x-action-col-cell";for(d=0;d"}return h}},destroy:function(){delete this.items;delete this.renderer;return Ext.grid.ActionColumn.superclass.destroy.apply(this,arguments)},processEvent:function(c,i,d,j,b){var a=i.getTarget().className.match(this.actionIdRe),h,g;if(a&&(h=this.items[parseInt(a[1],10)])){if(c=="click"){(g=h.handler||this.handler)&&g.call(h.scope||this.scope||this,d,j,b,h,i)}else{if((c=="mousedown")&&(h.stopSelection!==false)){return false}}}return Ext.grid.ActionColumn.superclass.processEvent.apply(this,arguments)}});Ext.grid.Column.types={gridcolumn:Ext.grid.Column,booleancolumn:Ext.grid.BooleanColumn,numbercolumn:Ext.grid.NumberColumn,datecolumn:Ext.grid.DateColumn,templatecolumn:Ext.grid.TemplateColumn,actioncolumn:Ext.grid.ActionColumn};Ext.grid.RowNumberer=Ext.extend(Object,{header:"",width:23,sortable:false,constructor:function(a){Ext.apply(this,a);if(this.rowspan){this.renderer=this.renderer.createDelegate(this)}},fixed:true,hideable:false,menuDisabled:true,dataIndex:"",id:"numberer",rowspan:undefined,renderer:function(b,c,a,d){if(this.rowspan){c.cellAttr='rowspan="'+this.rowspan+'"'}return d+1}});Ext.grid.CheckboxSelectionModel=Ext.extend(Ext.grid.RowSelectionModel,{header:'
     
    ',width:20,sortable:false,menuDisabled:true,fixed:true,hideable:false,dataIndex:"",id:"checker",isColumn:true,constructor:function(){Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this,arguments);if(this.checkOnly){this.handleMouseDown=Ext.emptyFn}},initEvents:function(){Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);this.grid.on("render",function(){Ext.fly(this.grid.getView().innerHd).on("mousedown",this.onHdMouseDown,this)},this)},processEvent:function(b,d,c,g,a){if(b=="mousedown"){this.onMouseDown(d,d.getTarget());return false}else{return Ext.grid.Column.prototype.processEvent.apply(this,arguments)}},onMouseDown:function(c,b){if(c.button===0&&b.className=="x-grid3-row-checker"){c.stopEvent();var d=c.getTarget(".x-grid3-row");if(d){var a=d.rowIndex;if(this.isSelected(a)){this.deselectRow(a)}else{this.selectRow(a,true);this.grid.getView().focusRow(a)}}}},onHdMouseDown:function(c,a){if(a.className=="x-grid3-hd-checker"){c.stopEvent();var b=Ext.fly(a.parentNode);var d=b.hasClass("x-grid3-hd-checker-on");if(d){b.removeClass("x-grid3-hd-checker-on");this.clearSelections()}else{b.addClass("x-grid3-hd-checker-on");this.selectAll()}}},renderer:function(b,c,a){return'
     
    '},onEditorSelect:function(b,a){if(a!=b&&!this.checkOnly){this.selectRow(b)}}});Ext.grid.CellSelectionModel=Ext.extend(Ext.grid.AbstractSelectionModel,{constructor:function(a){Ext.apply(this,a);this.selection=null;this.addEvents("beforecellselect","cellselect","selectionchange");Ext.grid.CellSelectionModel.superclass.constructor.call(this)},initEvents:function(){this.grid.on("cellmousedown",this.handleMouseDown,this);this.grid.on(Ext.EventManager.getKeyEvent(),this.handleKeyDown,this);this.grid.getView().on({scope:this,refresh:this.onViewChange,rowupdated:this.onRowUpdated,beforerowremoved:this.clearSelections,beforerowsinserted:this.clearSelections});if(this.grid.isEditor){this.grid.on("beforeedit",this.beforeEdit,this)}},beforeEdit:function(a){this.select(a.row,a.column,false,true,a.record)},onRowUpdated:function(a,b,c){if(this.selection&&this.selection.record==c){a.onCellSelect(b,this.selection.cell[1])}},onViewChange:function(){this.clearSelections(true)},getSelectedCell:function(){return this.selection?this.selection.cell:null},clearSelections:function(b){var a=this.selection;if(a){if(b!==true){this.grid.view.onCellDeselect(a.cell[0],a.cell[1])}this.selection=null;this.fireEvent("selectionchange",this,null)}},hasSelection:function(){return this.selection?true:false},handleMouseDown:function(b,d,a,c){if(c.button!==0||this.isLocked()){return}this.select(d,a)},select:function(g,c,b,e,d){if(this.fireEvent("beforecellselect",this,g,c)!==false){this.clearSelections();d=d||this.grid.store.getAt(g);this.selection={record:d,cell:[g,c]};if(!b){var a=this.grid.getView();a.onCellSelect(g,c);if(e!==true){a.focusCell(g,c)}}this.fireEvent("cellselect",this,g,c);this.fireEvent("selectionchange",this,this.selection)}},isSelectable:function(c,b,a){return !a.isHidden(b)},onEditorKey:function(b,a){if(a.getKey()==a.TAB){this.handleKeyDown(a)}},handleKeyDown:function(j){if(!j.isNavKeyPress()){return}var d=j.getKey(),i=this.grid,p=this.selection,b=this,m=function(g,c,e){return i.walkCells(g,c,e,i.isEditor&&i.editing?b.acceptsNav:b.isSelectable,b)},o,h,a,l,n;switch(d){case j.ESC:case j.PAGE_UP:case j.PAGE_DOWN:break;default:j.stopEvent();break}if(!p){o=m(0,0,1);if(o){this.select(o[0],o[1])}return}o=p.cell;a=o[0];l=o[1];switch(d){case j.TAB:if(j.shiftKey){h=m(a,l-1,-1)}else{h=m(a,l+1,1)}break;case j.DOWN:h=m(a+1,l,1);break;case j.UP:h=m(a-1,l,-1);break;case j.RIGHT:h=m(a,l+1,1);break;case j.LEFT:h=m(a,l-1,-1);break;case j.ENTER:if(i.isEditor&&!i.editing){i.startEditing(a,l);return}break}if(h){a=h[0];l=h[1];this.select(a,l);if(i.isEditor&&i.editing){n=i.activeEditor;if(n&&n.field.triggerBlur){n.field.triggerBlur()}i.startEditing(a,l)}}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)}});Ext.grid.EditorGridPanel=Ext.extend(Ext.grid.GridPanel,{clicksToEdit:2,forceValidation:false,isEditor:true,detectEdit:false,autoEncode:false,trackMouseOver:false,initComponent:function(){Ext.grid.EditorGridPanel.superclass.initComponent.call(this);if(!this.selModel){this.selModel=new Ext.grid.CellSelectionModel()}this.activeEditor=null;this.addEvents("beforeedit","afteredit","validateedit")},initEvents:function(){Ext.grid.EditorGridPanel.superclass.initEvents.call(this);this.getGridEl().on("mousewheel",this.stopEditing.createDelegate(this,[true]),this);this.on("columnresize",this.stopEditing,this,[true]);if(this.clicksToEdit==1){this.on("cellclick",this.onCellDblClick,this)}else{var a=this.getView();if(this.clicksToEdit=="auto"&&a.mainBody){a.mainBody.on("mousedown",this.onAutoEditClick,this)}this.on("celldblclick",this.onCellDblClick,this)}},onResize:function(){Ext.grid.EditorGridPanel.superclass.onResize.apply(this,arguments);var a=this.activeEditor;if(this.editing&&a){a.realign(true)}},onCellDblClick:function(b,c,a){this.startEditing(c,a)},onAutoEditClick:function(c,b){if(c.button!==0){return}var g=this.view.findRowIndex(b),a=this.view.findCellIndex(b);if(g!==false&&a!==false){this.stopEditing();if(this.selModel.getSelectedCell){var d=this.selModel.getSelectedCell();if(d&&d[0]===g&&d[1]===a){this.startEditing(g,a)}}else{if(this.selModel.isSelected(g)){this.startEditing(g,a)}}}},onEditComplete:function(b,d,a){this.editing=false;this.lastActiveEditor=this.activeEditor;this.activeEditor=null;var c=b.record,h=this.colModel.getDataIndex(b.col);d=this.postEditValue(d,a,c,h);if(this.forceValidation===true||String(d)!==String(a)){var g={grid:this,record:c,field:h,originalValue:a,value:d,row:b.row,column:b.col,cancel:false};if(this.fireEvent("validateedit",g)!==false&&!g.cancel&&String(d)!==String(a)){c.set(h,g.value);delete g.cancel;this.fireEvent("afteredit",g)}}this.view.focusCell(b.row,b.col)},startEditing:function(i,c){this.stopEditing();if(this.colModel.isCellEditable(c,i)){this.view.ensureVisible(i,c,true);var d=this.store.getAt(i),h=this.colModel.getDataIndex(c),g={grid:this,record:d,field:h,value:d.data[h],row:i,column:c,cancel:false};if(this.fireEvent("beforeedit",g)!==false&&!g.cancel){this.editing=true;var b=this.colModel.getCellEditor(c,i);if(!b){return}if(!b.rendered){b.parentEl=this.view.getEditorParent(b);b.on({scope:this,render:{fn:function(e){e.field.focus(false,true)},single:true,scope:this},specialkey:function(k,j){this.getSelectionModel().onEditorKey(k,j)},complete:this.onEditComplete,canceledit:this.stopEditing.createDelegate(this,[true])})}Ext.apply(b,{row:i,col:c,record:d});this.lastEdit={row:i,col:c};this.activeEditor=b;if(b.field.isXType("checkbox")){b.allowBlur=false;this.setupCheckbox(b.field)}b.selectSameEditor=(this.activeEditor==this.lastActiveEditor);var a=this.preEditValue(d,h);b.startEdit(this.view.getCell(i,c).firstChild,Ext.isDefined(a)?a:"");(function(){delete b.selectSameEditor}).defer(50)}}},setupCheckbox:function(c){var b=this,a=function(){c.el.on("click",b.onCheckClick,b,{single:true})};if(c.rendered){a()}else{c.on("render",a,null,{single:true})}},onCheckClick:function(){var a=this.activeEditor;a.allowBlur=true;a.field.focus(false,10)},preEditValue:function(a,c){var b=a.data[c];return this.autoEncode&&Ext.isString(b)?Ext.util.Format.htmlDecode(b):b},postEditValue:function(c,a,b,d){return this.autoEncode&&Ext.isString(c)?Ext.util.Format.htmlEncode(c):c},stopEditing:function(b){if(this.editing){var a=this.lastActiveEditor=this.activeEditor;if(a){a[b===true?"cancelEdit":"completeEdit"]();this.view.focusCell(a.row,a.col)}this.activeEditor=null}this.editing=false}});Ext.reg("editorgrid",Ext.grid.EditorGridPanel);Ext.grid.GridEditor=function(b,a){Ext.grid.GridEditor.superclass.constructor.call(this,b,a);b.monitorTab=false};Ext.extend(Ext.grid.GridEditor,Ext.Editor,{alignment:"tl-tl",autoSize:"width",hideEl:false,cls:"x-small-editor x-grid-editor",shim:false,shadow:false});Ext.grid.PropertyRecord=Ext.data.Record.create([{name:"name",type:"string"},"value"]);Ext.grid.PropertyStore=Ext.extend(Ext.util.Observable,{constructor:function(a,b){this.grid=a;this.store=new Ext.data.Store({recordType:Ext.grid.PropertyRecord});this.store.on("update",this.onUpdate,this);if(b){this.setSource(b)}Ext.grid.PropertyStore.superclass.constructor.call(this)},setSource:function(c){this.source=c;this.store.removeAll();var b=[];for(var a in c){if(this.isEditableValue(c[a])){b.push(new Ext.grid.PropertyRecord({name:a,value:c[a]},a))}}this.store.loadRecords({records:b},{},true)},onUpdate:function(e,a,d){if(d==Ext.data.Record.EDIT){var b=a.data.value;var c=a.modified.value;if(this.grid.fireEvent("beforepropertychange",this.source,a.id,b,c)!==false){this.source[a.id]=b;a.commit();this.grid.fireEvent("propertychange",this.source,a.id,b,c)}else{a.reject()}}},getProperty:function(a){return this.store.getAt(a)},isEditableValue:function(a){return Ext.isPrimitive(a)||Ext.isDate(a)},setValue:function(d,c,a){var b=this.getRec(d);if(b){b.set("value",c);this.source[d]=c}else{if(a){this.source[d]=c;b=new Ext.grid.PropertyRecord({name:d,value:c},d);this.store.add(b)}}},remove:function(b){var a=this.getRec(b);if(a){this.store.remove(a);delete this.source[b]}},getRec:function(a){return this.store.getById(a)},getSource:function(){return this.source}});Ext.grid.PropertyColumnModel=Ext.extend(Ext.grid.ColumnModel,{nameText:"Name",valueText:"Value",dateFormat:"m/j/Y",trueText:"true",falseText:"false",constructor:function(c,b){var d=Ext.grid,e=Ext.form;this.grid=c;d.PropertyColumnModel.superclass.constructor.call(this,[{header:this.nameText,width:50,sortable:true,dataIndex:"name",id:"name",menuDisabled:true},{header:this.valueText,width:50,resizable:false,dataIndex:"value",id:"value",menuDisabled:true}]);this.store=b;var a=new e.Field({autoCreate:{tag:"select",children:[{tag:"option",value:"true",html:this.trueText},{tag:"option",value:"false",html:this.falseText}]},getValue:function(){return this.el.dom.value=="true"}});this.editors={date:new d.GridEditor(new e.DateField({selectOnFocus:true})),string:new d.GridEditor(new e.TextField({selectOnFocus:true})),number:new d.GridEditor(new e.NumberField({selectOnFocus:true,style:"text-align:left;"})),"boolean":new d.GridEditor(a,{autoSize:"both"})};this.renderCellDelegate=this.renderCell.createDelegate(this);this.renderPropDelegate=this.renderProp.createDelegate(this)},renderDate:function(a){return a.dateFormat(this.dateFormat)},renderBool:function(a){return this[a?"trueText":"falseText"]},isCellEditable:function(a,b){return a==1},getRenderer:function(a){return a==1?this.renderCellDelegate:this.renderPropDelegate},renderProp:function(a){return this.getPropertyName(a)},renderCell:function(d,b,c){var a=this.grid.customRenderers[c.get("name")];if(a){return a.apply(this,arguments)}var e=d;if(Ext.isDate(d)){e=this.renderDate(d)}else{if(typeof d=="boolean"){e=this.renderBool(d)}}return Ext.util.Format.htmlEncode(e)},getPropertyName:function(b){var a=this.grid.propertyNames;return a&&a[b]?a[b]:b},getCellEditor:function(a,e){var b=this.store.getProperty(e),d=b.data.name,c=b.data.value;if(this.grid.customEditors[d]){return this.grid.customEditors[d]}if(Ext.isDate(c)){return this.editors.date}else{if(typeof c=="number"){return this.editors.number}else{if(typeof c=="boolean"){return this.editors["boolean"]}else{return this.editors.string}}}},destroy:function(){Ext.grid.PropertyColumnModel.superclass.destroy.call(this);this.destroyEditors(this.editors);this.destroyEditors(this.grid.customEditors)},destroyEditors:function(b){for(var a in b){Ext.destroy(b[a])}}});Ext.grid.PropertyGrid=Ext.extend(Ext.grid.EditorGridPanel,{enableColumnMove:false,stripeRows:false,trackMouseOver:false,clicksToEdit:1,enableHdMenu:false,viewConfig:{forceFit:true},initComponent:function(){this.customRenderers=this.customRenderers||{};this.customEditors=this.customEditors||{};this.lastEditRow=null;var b=new Ext.grid.PropertyStore(this);this.propStore=b;var a=new Ext.grid.PropertyColumnModel(this,b);b.store.sort("name","ASC");this.addEvents("beforepropertychange","propertychange");this.cm=a;this.ds=b.store;Ext.grid.PropertyGrid.superclass.initComponent.call(this);this.mon(this.selModel,"beforecellselect",function(e,d,c){if(c===0){this.startEditing.defer(200,this,[d,1]);return false}},this)},onRender:function(){Ext.grid.PropertyGrid.superclass.onRender.apply(this,arguments);this.getGridEl().addClass("x-props-grid")},afterRender:function(){Ext.grid.PropertyGrid.superclass.afterRender.apply(this,arguments);if(this.source){this.setSource(this.source)}},setSource:function(a){this.propStore.setSource(a)},getSource:function(){return this.propStore.getSource()},setProperty:function(c,b,a){this.propStore.setValue(c,b,a)},removeProperty:function(a){this.propStore.remove(a)}});Ext.reg("propertygrid",Ext.grid.PropertyGrid);Ext.grid.GroupingView=Ext.extend(Ext.grid.GridView,{groupByText:"Group By This Field",showGroupsText:"Show in Groups",hideGroupedColumn:false,showGroupName:true,startCollapsed:false,enableGrouping:true,enableGroupingMenu:true,enableNoGroups:true,emptyGroupText:"(None)",ignoreAdd:false,groupTextTpl:"{text}",groupMode:"value",cancelEditOnToggle:true,initTemplates:function(){Ext.grid.GroupingView.superclass.initTemplates.call(this);this.state={};var a=this.grid.getSelectionModel();a.on(a.selectRow?"beforerowselect":"beforecellselect",this.onBeforeRowSelect,this);if(!this.startGroup){this.startGroup=new Ext.XTemplate('
    ','
    ',this.groupTextTpl,"
    ",'
    ')}this.startGroup.compile();if(!this.endGroup){this.endGroup="
    "}},findGroup:function(a){return Ext.fly(a).up(".x-grid-group",this.mainBody.dom)},getGroups:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},onAdd:function(d,a,b){if(this.canGroup()&&!this.ignoreAdd){var c=this.getScrollState();this.fireEvent("beforerowsinserted",d,b,b+(a.length-1));this.refresh();this.restoreScroll(c);this.fireEvent("rowsinserted",d,b,b+(a.length-1))}else{if(!this.canGroup()){Ext.grid.GroupingView.superclass.onAdd.apply(this,arguments)}}},onRemove:function(e,a,b,d){Ext.grid.GroupingView.superclass.onRemove.apply(this,arguments);var c=document.getElementById(a._groupId);if(c&&c.childNodes[1].childNodes.length<1){Ext.removeNode(c)}this.applyEmptyText()},refreshRow:function(a){if(this.ds.getCount()==1){this.refresh()}else{this.isUpdating=true;Ext.grid.GroupingView.superclass.refreshRow.apply(this,arguments);this.isUpdating=false}},beforeMenuShow:function(){var c,a=this.hmenu.items,b=this.cm.config[this.hdCtxIndex].groupable===false;if((c=a.get("groupBy"))){c.setDisabled(b)}if((c=a.get("showGroups"))){c.setDisabled(b);c.setChecked(this.canGroup(),true)}},renderUI:function(){var a=Ext.grid.GroupingView.superclass.renderUI.call(this);if(this.enableGroupingMenu&&this.hmenu){this.hmenu.add("-",{itemId:"groupBy",text:this.groupByText,handler:this.onGroupByClick,scope:this,iconCls:"x-group-by-icon"});if(this.enableNoGroups){this.hmenu.add({itemId:"showGroups",text:this.showGroupsText,checked:true,checkHandler:this.onShowGroupsClick,scope:this})}this.hmenu.on("beforeshow",this.beforeMenuShow,this)}return a},processEvent:function(b,i){Ext.grid.GroupingView.superclass.processEvent.call(this,b,i);var h=i.getTarget(".x-grid-group-hd",this.mainBody);if(h){var g=this.getGroupField(),d=this.getPrefix(g),a=h.id.substring(d.length),c=new RegExp("gp-"+Ext.escapeRe(g)+"--hd");a=a.substr(0,a.length-3);if(a||c.test(h.id)){this.grid.fireEvent("group"+b,this.grid,g,a,i)}if(b=="mousedown"&&i.button==0){this.toggleGroup(h.parentNode)}}},onGroupByClick:function(){var a=this.grid;this.enableGrouping=true;a.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));a.fireEvent("groupchange",a,a.store.getGroupState());this.beforeMenuShow();this.refresh()},onShowGroupsClick:function(a,b){this.enableGrouping=b;if(b){this.onGroupByClick()}else{this.grid.store.clearGrouping();this.grid.fireEvent("groupchange",this,null)}},toggleRowIndex:function(c,a){if(!this.canGroup()){return}var b=this.getRow(c);if(b){this.toggleGroup(this.findGroup(b),a)}},toggleGroup:function(c,b){var a=Ext.get(c),d=Ext.util.Format.htmlEncode(a.id);b=Ext.isDefined(b)?b:a.hasClass("x-grid-group-collapsed");if(this.state[d]!==b){if(this.cancelEditOnToggle!==false){this.grid.stopEditing(true)}this.state[d]=b;a[b?"removeClass":"addClass"]("x-grid-group-collapsed")}},toggleAllGroups:function(c){var b=this.getGroups();for(var d=0,a=b.length;d'about:blank', except for IE in secure mode, which is 'javascript:""'). + * @type String + */ + SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank', + /** + * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode + * @type Boolean + */ + isStrict : isStrict, + /** + * True if the page is running over SSL + * @type Boolean + */ + isSecure : isSecure, + /** + * True when the document is fully initialized and ready for action + * @type Boolean + */ + isReady : false, + + /** + * True if the {@link Ext.Fx} Class is available + * @type Boolean + * @property enableFx + */ + + /** + * HIGHLY EXPERIMENTAL + * True to force css based border-box model override and turning off javascript based adjustments. This is a + * runtime configuration and must be set before onReady. + * @type Boolean + */ + enableForcedBoxModel : false, + + /** + * True to automatically uncache orphaned Ext.Elements periodically (defaults to true) + * @type Boolean + */ + enableGarbageCollector : true, + + /** + * True to automatically purge event listeners during garbageCollection (defaults to false). + * @type Boolean + */ + enableListenerCollection : false, + + /** + * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed. + * Currently not optimized for performance. + * @type Boolean + */ + enableNestedListenerRemoval : false, + + /** + * Indicates whether to use native browser parsing for JSON methods. + * This option is ignored if the browser does not support native JSON methods. + * Note: Native JSON methods will not work with objects that have functions. + * Also, property names must be quoted, otherwise the data will not parse. (Defaults to false) + * @type Boolean + */ + USE_NATIVE_JSON : false, + + /** + * Copies all the properties of config to obj if they don't already exist. + * @param {Object} obj The receiver of the properties + * @param {Object} config The source of the properties + * @return {Object} returns obj + */ + applyIf : function(o, c){ + if(o){ + for(var p in c){ + if(!Ext.isDefined(o[p])){ + o[p] = c[p]; + } + } + } + return o; + }, + + /** + * Generates unique ids. If the element already has an id, it is unchanged + * @param {Mixed} el (optional) The element to generate an id for + * @param {String} prefix (optional) Id prefix (defaults "ext-gen") + * @return {String} The generated Id. + */ + id : function(el, prefix){ + el = Ext.getDom(el, true) || {}; + if (!el.id) { + el.id = (prefix || "ext-gen") + (++idSeed); + } + return el.id; + }, + + /** + *

    Extends one class to create a subclass and optionally overrides members with the passed literal. This method + * also adds the function "override()" to the subclass that can be used to override members of the class.

    + * For example, to create a subclass of Ext GridPanel: + *
    
    +MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
    +    constructor: function(config) {
    +
    +//      Create configuration for this Grid.
    +        var store = new Ext.data.Store({...});
    +        var colModel = new Ext.grid.ColumnModel({...});
    +
    +//      Create a new config object containing our computed properties
    +//      *plus* whatever was in the config parameter.
    +        config = Ext.apply({
    +            store: store,
    +            colModel: colModel
    +        }, config);
    +
    +        MyGridPanel.superclass.constructor.call(this, config);
    +
    +//      Your postprocessing here
    +    },
    +
    +    yourMethod: function() {
    +        // etc.
    +    }
    +});
    +
    + * + *

    This function also supports a 3-argument call in which the subclass's constructor is + * passed as an argument. In this form, the parameters are as follows:

    + *
      + *
    • subclass : Function
      The subclass constructor.
    • + *
    • superclass : Function
      The constructor of class being extended
    • + *
    • overrides : Object
      A literal with members which are copied into the subclass's + * prototype, and are therefore shared among all instances of the new class.
    • + *
    + * + * @param {Function} superclass The constructor of class being extended. + * @param {Object} overrides

    A literal with members which are copied into the subclass's + * prototype, and are therefore shared between all instances of the new class.

    + *

    This may contain a special member named constructor. This is used + * to define the constructor of the new class, and is returned. If this property is + * not specified, a constructor is generated and returned which just calls the + * superclass's constructor passing on its parameters.

    + *

    It is essential that you call the superclass constructor in any provided constructor. See example code.

    + * @return {Function} The subclass constructor from the overrides parameter, or a generated one if not provided. + */ + extend : function(){ + // inline overrides + var io = function(o){ + for(var m in o){ + this[m] = o[m]; + } + }; + var oc = Object.prototype.constructor; + + return function(sb, sp, overrides){ + if(typeof sp == 'object'){ + overrides = sp; + sp = sb; + sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; + } + var F = function(){}, + sbp, + spp = sp.prototype; + + F.prototype = spp; + sbp = sb.prototype = new F(); + sbp.constructor=sb; + sb.superclass=spp; + if(spp.constructor == oc){ + spp.constructor=sp; + } + sb.override = function(o){ + Ext.override(sb, o); + }; + sbp.superclass = sbp.supr = (function(){ + return spp; + }); + sbp.override = io; + Ext.override(sb, overrides); + sb.extend = function(o){return Ext.extend(sb, o);}; + return sb; + }; + }(), + + global: (function () { + return this; + })(), + + Base: Base, + + namespaceCache: {}, + + createNamespace: function (namespaceOrClass, isClass) { + var cache = Ext.namespaceCache, + namespace = isClass ? namespaceOrClass.substring(0, namespaceOrClass.lastIndexOf('.')) + : namespaceOrClass, + ns = cache[namespace], + i, n, part, parts, partials; + + if (!ns) { + ns = Ext.global; + if (namespace) { + partials = []; + parts = namespace.split('.'); + + for (i = 0, n = parts.length; i < n; ++i) { + part = parts[i]; + + ns = ns[part] || (ns[part] = {}); + partials.push(part); + + cache[partials.join('.')] = ns; // build up prefixes as we go + } + } + } + + return ns; + }, + + getClassByName: function (className) { + var parts = className.split('.'), + cls = Ext.global, + n = parts.length, + i; + + for (i = 0; cls && i < n; ++i) { + cls = cls[parts[i]]; + } + + return cls || null; + }, + + addMembers: function (cls, target, members, handleNonEnumerables) { + var i, name, member; + + for (name in members) { + if (members.hasOwnProperty(name)) { + member = members[name]; + if (typeof member == 'function') { + member.$owner = cls; + member.$name = name; + } + + target[name] = member; + } + } + + if (handleNonEnumerables && nonEnumerables) { + for (i = nonEnumerables.length; i-- > 0; ) { + name = nonEnumerables[i]; + if (members.hasOwnProperty(name)) { + member = members[name]; + if (typeof member == 'function') { + member.$owner = cls; + member.$name = name; + } + + target[name] = member; + } + } + } + }, + + /** + * @method + * Defines a class or override. A basic class is defined like this: + * + * Ext.define('My.awesome.Class', { + * someProperty: 'something', + * + * someMethod: function(s) { + * alert(s + this.someProperty); + * } + * + * ... + * }); + * + * var obj = new My.awesome.Class(); + * + * obj.someMethod('Say '); // alerts 'Say something' + * + * To create an anonymous class, pass `null` for the `className`: + * + * Ext.define(null, { + * constructor: function () { + * // ... + * } + * }); + * + * In some cases, it is helpful to create a nested scope to contain some private + * properties. The best way to do this is to pass a function instead of an object + * as the second parameter. This function will be called to produce the class + * body: + * + * Ext.define('MyApp.foo.Bar', function () { + * var id = 0; + * + * return { + * nextId: function () { + * return ++id; + * } + * }; + * }); + * + * When using this form of `Ext.define`, the function is passed a reference to its + * class. This can be used as an efficient way to access any static properties you + * may have: + * + * Ext.define('MyApp.foo.Bar', function (Bar) { + * return { + * statics: { + * staticMethod: function () { + * // ... + * } + * }, + * + * method: function () { + * return Bar.staticMethod(); + * } + * }; + * }); + * + * To define an override, include the `override` property. The content of an + * override is aggregated with the specified class in order to extend or modify + * that class. This can be as simple as setting default property values or it can + * extend and/or replace methods. This can also extend the statics of the class. + * + * One use for an override is to break a large class into manageable pieces. + * + * // File: /src/app/Panel.js + * + * Ext.define('My.app.Panel', { + * extend: 'Ext.panel.Panel', + * + * constructor: function (config) { + * this.callParent(arguments); // calls Ext.panel.Panel's constructor + * //... + * }, + * + * statics: { + * method: function () { + * return 'abc'; + * } + * } + * }); + * + * // File: /src/app/PanelPart2.js + * Ext.define('My.app.PanelPart2', { + * override: 'My.app.Panel', + * + * constructor: function (config) { + * this.callParent(arguments); // calls My.app.Panel's constructor + * //... + * } + * }); + * + * Another use of overrides is to provide optional parts of classes that can be + * independently required. In this case, the class may even be unaware of the + * override altogether. + * + * Ext.define('My.ux.CoolTip', { + * override: 'Ext.tip.ToolTip', + * + * constructor: function (config) { + * this.callParent(arguments); // calls Ext.tip.ToolTip's constructor + * //... + * } + * }); + * + * Overrides can also contain statics: + * + * Ext.define('My.app.BarMod', { + * override: 'Ext.foo.Bar', + * + * statics: { + * method: function (x) { + * return this.callParent([x * 2]); // call Ext.foo.Bar.method + * } + * } + * }); + * + * @param {String} className The class name to create in string dot-namespaced format, for example: + * 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager' + * It is highly recommended to follow this simple convention: + * - The root and the class name are 'CamelCased' + * - Everything else is lower-cased + * Pass `null` to create an anonymous class. + * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid + * strings, except those in the reserved listed below: + * - `mixins` + * - `statics` + * - `config` + * - `alias` + * - `self` + * - `singleton` + * - `alternateClassName` + * - `override` + * + * @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which + * (`this`) will be the newly created class itself. + * @return {Ext.Base} + * @markdown + * @member Ext + * @method define + */ + define: function (className, body, createdFn) { + var override = body.override, + cls, extend, name, namespace; + + if (override) { + delete body.override; + cls = Ext.getClassByName(override); + Ext.override(cls, body); + } else { + if (className) { + namespace = Ext.createNamespace(className, true); + name = className.substring(className.lastIndexOf('.')+1); + } + + cls = function ctor () { + this.constructor.apply(this, arguments); + } + + if (className) { + cls.displayName = className; + } + cls.$isClass = true; + cls.callParent = Ext.Base.callParent; + + if (typeof body == 'function') { + body = body(cls); + } + + extend = body.extend; + if (extend) { + delete body.extend; + if (typeof extend == 'string') { + extend = Ext.getClassByName(extend); + } + } else { + extend = Base; + } + + Ext.extend(cls, extend, body); + if (cls.prototype.constructor === cls) { + delete cls.prototype.constructor; + } + + // Not extending a class which derives from Base... + if (!cls.prototype.$isClass) { + Ext.applyIf(cls.prototype, Base.prototype); + } + cls.prototype.self = cls; + + if (body.xtype) { + Ext.reg(body.xtype, cls); + } + cls = body.singleton ? new cls() : cls; + if (className) { + namespace[name] = cls; + } + } + + if (createdFn) { + createdFn.call(cls); + } + + return cls; + }, + + /** + * Overrides members of the specified `target` with the given values. + * + * If the `target` is a function, it is assumed to be a constructor and the contents + * of `overrides` are applied to its `prototype` using {@link Ext#apply Ext.apply}. + * + * If the `target` is an instance of a class created using {@link #define}, + * the `overrides` are applied to only that instance. In this case, methods are + * specially processed to allow them to use {@link Ext.Base#callParent}. + * + * var panel = new Ext.Panel({ ... }); + * + * Ext.override(panel, { + * initComponent: function () { + * // extra processing... + * + * this.callParent(); + * } + * }); + * + * If the `target` is none of these, the `overrides` are applied to the `target` + * using {@link Ext#apply Ext.apply}. + * + * Please refer to {@link Ext#define Ext.define} for further details. + * + * @param {Object} target The target to override. + * @param {Object} overrides The properties to add or replace on `target`. + * @method override + */ + override: function (target, overrides) { + var proto, statics; + + if (overrides) { + if (target.$isClass) { + statics = overrides.statics; + if (statics) { + delete overrides.statics; + } + + Ext.addMembers(target, target.prototype, overrides, true); + if (statics) { + Ext.addMembers(target, target, statics); + } + } else if (typeof target == 'function') { + proto = target.prototype; + Ext.apply(proto, overrides); + if(Ext.isIE && overrides.hasOwnProperty('toString')){ + proto.toString = overrides.toString; + } + } else { + var owner = target.self, + name, value; + + if (owner && owner.$isClass) { + for (name in overrides) { + if (overrides.hasOwnProperty(name)) { + value = overrides[name]; + + if (typeof value == 'function') { + // + if (owner.$className) { + value.displayName = owner.$className + '#' + name; + } + // + + value.$name = name; + value.$owner = owner; + value.$previous = target.hasOwnProperty(name) + ? target[name] // already hooked, so call previous hook + : callOverrideParent; // calls by name on prototype + } + + target[name] = value; + } + } + } else { + Ext.apply(target, overrides); + + if (!target.constructor.$isClass) { + target.constructor.prototype.callParent = Base.prototype.callParent; + target.constructor.callParent = Base.callParent; + } + } + } + } + }, + + /** + * Creates namespaces to be used for scoping variables and classes so that they are not global. + * Specifying the last node of a namespace implicitly creates all other nodes. Usage: + *
    
    +Ext.namespace('Company', 'Company.data');
    +Ext.namespace('Company.data'); // equivalent and preferable to above syntax
    +Company.Widget = function() { ... }
    +Company.data.CustomStore = function(config) { ... }
    +
    + * @param {String} namespace1 + * @param {String} namespace2 + * @param {String} etc + * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created) + * @method namespace + */ + namespace : function(){ + var len1 = arguments.length, + i = 0, + len2, + j, + main, + ns, + sub, + current; + + for(; i < len1; ++i) { + main = arguments[i]; + ns = arguments[i].split('.'); + current = window[ns[0]]; + if (current === undefined) { + current = window[ns[0]] = {}; + } + sub = ns.slice(1); + len2 = sub.length; + for(j = 0; j < len2; ++j) { + current = current[sub[j]] = current[sub[j]] || {}; + } + } + return current; + }, + + /** + * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value. + * @param {Object} o + * @param {String} pre (optional) A prefix to add to the url encoded string + * @return {String} + */ + urlEncode : function(o, pre){ + var empty, + buf = [], + e = encodeURIComponent; + + Ext.iterate(o, function(key, item){ + empty = Ext.isEmpty(item); + Ext.each(empty ? key : item, function(val){ + buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : ''); + }); + }); + if(!pre){ + buf.shift(); + pre = ''; + } + return pre + buf.join(''); + }, + + /** + * Takes an encoded URL and and converts it to an object. Example:
    
    +Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
    +Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
    +
    + * @param {String} string + * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false). + * @return {Object} A literal with members + */ + urlDecode : function(string, overwrite){ + if(Ext.isEmpty(string)){ + return {}; + } + var obj = {}, + pairs = string.split('&'), + d = decodeURIComponent, + name, + value; + Ext.each(pairs, function(pair) { + pair = pair.split('='); + name = d(pair[0]); + value = d(pair[1]); + obj[name] = overwrite || !obj[name] ? value : + [].concat(obj[name]).concat(value); + }); + return obj; + }, + + /** + * Appends content to the query string of a URL, handling logic for whether to place + * a question mark or ampersand. + * @param {String} url The URL to append to. + * @param {String} s The content to append to the URL. + * @return (String) The resulting URL + */ + urlAppend : function(url, s){ + if(!Ext.isEmpty(s)){ + return url + (url.indexOf('?') === -1 ? '?' : '&') + s; + } + return url; + }, + + /** + * Converts any iterable (numeric indices and a length property) into a true array + * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on. + * For strings, use this instead: "abc".match(/./g) => [a,b,c]; + * @param {Iterable} the iterable object to be turned into a true Array. + * @return (Array) array + */ + toArray : function(){ + return isIE ? + function(a, i, j, res){ + res = []; + for(var x = 0, len = a.length; x < len; x++) { + res.push(a[x]); + } + return res.slice(i || 0, j || res.length); + } : + function(a, i, j){ + return Array.prototype.slice.call(a, i || 0, j || a.length); + }; + }(), + + isIterable : function(v){ + //check for array or arguments + if(Ext.isArray(v) || v.callee){ + return true; + } + //check for node list type + if(/NodeList|HTMLCollection/.test(toString.call(v))){ + return true; + } + //NodeList has an item and length property + //IXMLDOMNodeList has nextNode method, needs to be checked first. + return ((typeof v.nextNode != 'undefined' || v.item) && Ext.isNumber(v.length)); + }, + + /** + * Iterates an array calling the supplied function. + * @param {Array/NodeList/Mixed} array The array to be iterated. If this + * argument is not really an array, the supplied function is called once. + * @param {Function} fn The function to be called with each item. If the + * supplied function returns false, iteration stops and this method returns + * the current index. This function is called with + * the following arguments: + *
      + *
    • item : Mixed + *
      The item at the current index + * in the passed array
    • + *
    • index : Number + *
      The current index within the array
    • + *
    • allItems : Array + *
      The array passed as the first + * argument to Ext.each.
    • + *
    + * @param {Object} scope The scope (this reference) in which the specified function is executed. + * Defaults to the item at the current index + * within the passed array. + * @return See description for the fn parameter. + */ + each : function(array, fn, scope){ + if(Ext.isEmpty(array, true)){ + return; + } + if(!Ext.isIterable(array) || Ext.isPrimitive(array)){ + array = [array]; + } + for(var i = 0, len = array.length; i < len; i++){ + if(fn.call(scope || array[i], array[i], i, array) === false){ + return i; + }; + } + }, + + /** + * Iterates either the elements in an array, or each of the properties in an object. + * Note: If you are only iterating arrays, it is better to call {@link #each}. + * @param {Object/Array} object The object or array to be iterated + * @param {Function} fn The function to be called for each iteration. + * The iteration will stop if the supplied function returns false, or + * all array elements / object properties have been covered. The signature + * varies depending on the type of object being interated: + *
      + *
    • Arrays : (Object item, Number index, Array allItems) + *
      + * When iterating an array, the supplied function is called with each item.
    • + *
    • Objects : (String key, Object value, Object) + *
      + * When iterating an object, the supplied function is called with each key-value pair in + * the object, and the iterated object
    • + *
    + * @param {Object} scope The scope (this reference) in which the specified function is executed. Defaults to + * the object being iterated. + */ + iterate : function(obj, fn, scope){ + if(Ext.isEmpty(obj)){ + return; + } + if(Ext.isIterable(obj)){ + Ext.each(obj, fn, scope); + return; + }else if(typeof obj == 'object'){ + for(var prop in obj){ + if(obj.hasOwnProperty(prop)){ + if(fn.call(scope || obj, prop, obj[prop], obj) === false){ + return; + }; + } + } + } + }, + + /** + * Return the dom node for the passed String (id), dom node, or Ext.Element. + * Optional 'strict' flag is needed for IE since it can return 'name' and + * 'id' elements by using getElementById. + * Here are some examples: + *
    
    +// gets dom node based on id
    +var elDom = Ext.getDom('elId');
    +// gets dom node based on the dom node
    +var elDom1 = Ext.getDom(elDom);
    +
    +// If we don't know if we are working with an
    +// Ext.Element or a dom node use Ext.getDom
    +function(el){
    +    var dom = Ext.getDom(el);
    +    // do something with the dom node
    +}
    +         * 
    + * Note: the dom node to be found actually needs to exist (be rendered, etc) + * when this method is called to be successful. + * @param {Mixed} el + * @return HTMLElement + */ + getDom : function(el, strict){ + if(!el || !DOC){ + return null; + } + if (el.dom){ + return el.dom; + } else { + if (typeof el == 'string') { + var e = DOC.getElementById(el); + // IE returns elements with the 'name' and 'id' attribute. + // we do a strict check to return the element with only the id attribute + if (e && isIE && strict) { + if (el == e.getAttribute('id')) { + return e; + } else { + return null; + } + } + return e; + } else { + return el; + } + } + }, + + /** + * Returns the current document body as an {@link Ext.Element}. + * @return Ext.Element The document body + */ + getBody : function(){ + return Ext.get(DOC.body || DOC.documentElement); + }, + + /** + * Returns the current document body as an {@link Ext.Element}. + * @return Ext.Element The document body + * @method + */ + getHead : function() { + var head; + + return function() { + if (head == undefined) { + head = Ext.get(DOC.getElementsByTagName("head")[0]); + } + + return head; + }; + }(), + + /** + *

    Removes this element from the document, removes all DOM event listeners, and deletes the cache reference. + * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval} is + * true, then DOM event listeners are also removed from all child nodes. The body node + * will be ignored if passed in.

    + * @param {HTMLElement} node The node to remove + * @method + */ + removeNode : isIE && !isIE8 ? function(){ + var d; + return function(n){ + if(n && n.tagName != 'BODY'){ + (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n); + d = d || DOC.createElement('div'); + d.appendChild(n); + d.innerHTML = ''; + delete Ext.elCache[n.id]; + } + }; + }() : function(n){ + if(n && n.parentNode && n.tagName != 'BODY'){ + (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n); + n.parentNode.removeChild(n); + delete Ext.elCache[n.id]; + } + }, + + /** + *

    Returns true if the passed value is empty.

    + *

    The value is deemed to be empty if it is

      + *
    • null
    • + *
    • undefined
    • + *
    • an empty array
    • + *
    • a zero length string (Unless the allowBlank parameter is true)
    • + *
    + * @param {Mixed} value The value to test + * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false) + * @return {Boolean} + */ + isEmpty : function(v, allowBlank){ + return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false); + }, + + /** + * Returns true if the passed value is a JavaScript array, otherwise false. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isArray : function(v){ + return toString.apply(v) === '[object Array]'; + }, + + /** + * Returns true if the passed object is a JavaScript date object, otherwise false. + * @param {Object} object The object to test + * @return {Boolean} + */ + isDate : function(v){ + return toString.apply(v) === '[object Date]'; + }, + + /** + * Returns true if the passed value is a JavaScript Object, otherwise false. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isObject : function(v){ + return !!v && Object.prototype.toString.call(v) === '[object Object]'; + }, + + /** + * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isPrimitive : function(v){ + return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v); + }, + + /** + * Returns true if the passed value is a JavaScript Function, otherwise false. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isFunction : function(v){ + return toString.apply(v) === '[object Function]'; + }, + + /** + * Returns true if the passed value is a number. Returns false for non-finite numbers. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isNumber : function(v){ + return typeof v === 'number' && isFinite(v); + }, + + /** + * Returns true if the passed value is a string. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isString : function(v){ + return typeof v === 'string'; + }, + + /** + * Returns true if the passed value is a boolean. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isBoolean : function(v){ + return typeof v === 'boolean'; + }, + + /** + * Returns true if the passed value is an HTMLElement + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isElement : function(v) { + return v ? !!v.tagName : false; + }, + + /** + * Returns true if the passed value is not undefined. + * @param {Mixed} value The value to test + * @return {Boolean} + */ + isDefined : function(v){ + return typeof v !== 'undefined'; + }, + + /** + * True if the detected browser is Opera. + * @type Boolean + */ + isOpera : isOpera, + /** + * True if the detected browser uses WebKit. + * @type Boolean + */ + isWebKit : isWebKit, + /** + * True if the detected browser is Chrome. + * @type Boolean + */ + isChrome : isChrome, + /** + * True if the detected browser is Safari. + * @type Boolean + */ + isSafari : isSafari, + /** + * True if the detected browser is Safari 3.x. + * @type Boolean + */ + isSafari3 : isSafari3, + /** + * True if the detected browser is Safari 4.x. + * @type Boolean + */ + isSafari4 : isSafari4, + /** + * True if the detected browser is Safari 2.x. + * @type Boolean + */ + isSafari2 : isSafari2, + /** + * True if the detected browser is Internet Explorer. + * @type Boolean + */ + isIE : isIE, + /** + * True if the detected browser is Internet Explorer 6.x. + * @type Boolean + */ + isIE6 : isIE6, + /** + * True if the detected browser is Internet Explorer 7.x. + * @type Boolean + */ + isIE7 : isIE7, + /** + * True if the detected browser is Internet Explorer 8.x. + * @type Boolean + */ + isIE8 : isIE8, + /** + * True if the detected browser is Internet Explorer 9.x. + * @type Boolean + */ + isIE9 : isIE9, + + /** + * True if the detected browser is Internet Explorer 10.x + * @type Boolean + */ + isIE10 : isIE10, + + /** + * True if the detected browser is Internet Explorer 9.x or lower + * @type Boolean + */ + isIE9m : isIE9m, + + /** + * True if the detected browser is Internet Explorer 10.x or higher + * @type Boolean + */ + isIE10p : isIE && !(isIE6 || isIE7 || isIE8 || isIE9), + + // IE10 quirks behaves like Gecko/WebKit quirks, so don't include it here + // Used internally + isIEQuirks: isIE && (!isStrict && (isIE6 || isIE7 || isIE8 || isIE9)), + + /** + * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox). + * @type Boolean + */ + isGecko : isGecko, + /** + * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x). + * @type Boolean + */ + isGecko2 : isGecko2, + /** + * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x). + * @type Boolean + */ + isGecko3 : isGecko3, + /** + * True if the detected browser is Internet Explorer running in non-strict mode. + * @type Boolean + */ + isBorderBox : isBorderBox, + /** + * True if the detected platform is Linux. + * @type Boolean + */ + isLinux : isLinux, + /** + * True if the detected platform is Windows. + * @type Boolean + */ + isWindows : isWindows, + /** + * True if the detected platform is Mac OS. + * @type Boolean + */ + isMac : isMac, + /** + * True if the detected platform is Adobe Air. + * @type Boolean + */ + isAir : isAir + }); + + /** + * Creates namespaces to be used for scoping variables and classes so that they are not global. + * Specifying the last node of a namespace implicitly creates all other nodes. Usage: + *
    
    +Ext.namespace('Company', 'Company.data');
    +Ext.namespace('Company.data'); // equivalent and preferable to above syntax
    +Company.Widget = function() { ... }
    +Company.data.CustomStore = function(config) { ... }
    +
    + * @param {String} namespace1 + * @param {String} namespace2 + * @param {String} etc + * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created) + * @method ns + */ + Ext.ns = Ext.namespace; +})(); + +Ext.ns('Ext.util', 'Ext.lib', 'Ext.data', 'Ext.supports'); + +Ext.elCache = {}; + +/** + * @class Function + * These functions are available on every Function object (any JavaScript function). + */ +Ext.apply(Function.prototype, { + /** + * Creates an interceptor function. The passed function is called before the original one. If it returns false, + * the original one is not called. The resulting function returns the results of the original function. + * The passed function is called with the parameters of the original function. Example usage: + *
    
    +var sayHi = function(name){
    +    alert('Hi, ' + name);
    +}
    +
    +sayHi('Fred'); // alerts "Hi, Fred"
    +
    +// create a new function that validates input without
    +// directly modifying the original function:
    +var sayHiToFriend = sayHi.createInterceptor(function(name){
    +    return name == 'Brian';
    +});
    +
    +sayHiToFriend('Fred');  // no alert
    +sayHiToFriend('Brian'); // alerts "Hi, Brian"
    +
    + * @param {Function} fcn The function to call before the original + * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. + * If omitted, defaults to the scope in which the original function is called or the browser window. + * @return {Function} The new function + */ + createInterceptor : function(fcn, scope){ + var method = this; + return !Ext.isFunction(fcn) ? + this : + function() { + var me = this, + args = arguments; + fcn.target = me; + fcn.method = method; + return (fcn.apply(scope || me || window, args) !== false) ? + method.apply(me || window, args) : + null; + }; + }, + + /** + * Creates a callback that passes arguments[0], arguments[1], arguments[2], ... + * Call directly on any function. Example: myFunction.createCallback(arg1, arg2) + * Will create a function that is bound to those 2 args. If a specific scope is required in the + * callback, use {@link #createDelegate} instead. The function returned by createCallback always + * executes in the window scope. + *

    This method is required when you want to pass arguments to a callback function. If no arguments + * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn). + * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function + * would simply execute immediately when the code is parsed. Example usage: + *

    
    +var sayHi = function(name){
    +    alert('Hi, ' + name);
    +}
    +
    +// clicking the button alerts "Hi, Fred"
    +new Ext.Button({
    +    text: 'Say Hi',
    +    renderTo: Ext.getBody(),
    +    handler: sayHi.createCallback('Fred')
    +});
    +
    + * @return {Function} The new function + */ + createCallback : function(/*args...*/){ + // make args available, in function below + var args = arguments, + method = this; + return function() { + return method.apply(window, args); + }; + }, + + /** + * Creates a delegate (callback) that sets the scope to obj. + * Call directly on any function. Example: this.myFunction.createDelegate(this, [arg1, arg2]) + * Will create a function that is automatically scoped to obj so that the this variable inside the + * callback points to obj. Example usage: + *
    
    +var sayHi = function(name){
    +    // Note this use of "this.text" here.  This function expects to
    +    // execute within a scope that contains a text property.  In this
    +    // example, the "this" variable is pointing to the btn object that
    +    // was passed in createDelegate below.
    +    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
    +}
    +
    +var btn = new Ext.Button({
    +    text: 'Say Hi',
    +    renderTo: Ext.getBody()
    +});
    +
    +// This callback will execute in the scope of the
    +// button instance. Clicking the button alerts
    +// "Hi, Fred. You clicked the "Say Hi" button."
    +btn.on('click', sayHi.createDelegate(btn, ['Fred']));
    +
    + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Function} The new function + */ + createDelegate : function(obj, args, appendArgs){ + var method = this; + return function() { + var callArgs = args || arguments; + if (appendArgs === true){ + callArgs = Array.prototype.slice.call(arguments, 0); + callArgs = callArgs.concat(args); + }else if (Ext.isNumber(appendArgs)){ + callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first + var applyArgs = [appendArgs, 0].concat(args); // create method call params + Array.prototype.splice.apply(callArgs, applyArgs); // splice them in + } + return method.apply(obj || window, callArgs); + }; + }, + + /** + * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: + *
    
    +var sayHi = function(name){
    +    alert('Hi, ' + name);
    +}
    +
    +// executes immediately:
    +sayHi('Fred');
    +
    +// executes after 2 seconds:
    +sayHi.defer(2000, this, ['Fred']);
    +
    +// this syntax is sometimes useful for deferring
    +// execution of an anonymous function:
    +(function(){
    +    alert('Anonymous');
    +}).defer(100);
    +
    + * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) + * @param {Object} scope (optional) The scope (this reference) in which the function is executed. + * If omitted, defaults to the browser window. + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Number} The timeout id that can be used with clearTimeout + */ + defer : function(millis, obj, args, appendArgs){ + var fn = this.createDelegate(obj, args, appendArgs); + if(millis > 0){ + return setTimeout(fn, millis); + } + fn(); + return 0; + } +}); + +/** + * @class String + * These functions are available on every String object. + */ +Ext.applyIf(String, { + /** + * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each + * token must be unique, and must increment in the format {0}, {1}, etc. Example usage: + *
    
    +var cls = 'my-class', text = 'Some text';
    +var s = String.format('<div class="{0}">{1}</div>', cls, text);
    +// s now contains the string: '<div class="my-class">Some text</div>'
    +     * 
    + * @param {String} string The tokenized string to be formatted + * @param {String} value1 The value to replace token {0} + * @param {String} value2 Etc... + * @return {String} The formatted string + * @static + */ + format : function(format){ + var args = Ext.toArray(arguments, 1); + return format.replace(/\{(\d+)\}/g, function(m, i){ + return args[i]; + }); + } +}); + +/** + * @class Array + */ +Ext.applyIf(Array.prototype, { + /** + * Checks whether or not the specified object exists in the array. + * @param {Object} o The object to check for + * @param {Number} from (Optional) The index at which to begin the search + * @return {Number} The index of o in the array (or -1 if it is not found) + */ + indexOf : function(o, from){ + var len = this.length; + from = from || 0; + from += (from < 0) ? len : 0; + for (; from < len; ++from){ + if(this[from] === o){ + return from; + } + } + return -1; + }, + + /** + * Removes the specified object from the array. If the object is not found nothing happens. + * @param {Object} o The object to remove + * @return {Array} this array + */ + remove : function(o){ + var index = this.indexOf(o); + if(index != -1){ + this.splice(index, 1); + } + return this; + } +}); +/** + * @class Ext.util.TaskRunner + * Provides the ability to execute one or more arbitrary tasks in a multithreaded + * manner. Generally, you can use the singleton {@link Ext.TaskMgr} instead, but + * if needed, you can create separate instances of TaskRunner. Any number of + * separate tasks can be started at any time and will run independently of each + * other. Example usage: + *
    
    +// Start a simple clock task that updates a div once per second
    +var updateClock = function(){
    +    Ext.fly('clock').update(new Date().format('g:i:s A'));
    +}
    +var task = {
    +    run: updateClock,
    +    interval: 1000 //1 second
    +}
    +var runner = new Ext.util.TaskRunner();
    +runner.start(task);
    +
    +// equivalent using TaskMgr
    +Ext.TaskMgr.start({
    +    run: updateClock,
    +    interval: 1000
    +});
    +
    + * 
    + *

    See the {@link #start} method for details about how to configure a task object.

    + * Also see {@link Ext.util.DelayedTask}. + * + * @constructor + * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance + * (defaults to 10) + */ +Ext.util.TaskRunner = function(interval){ + interval = interval || 10; + var tasks = [], + removeQueue = [], + id = 0, + running = false, + + // private + stopThread = function(){ + running = false; + clearInterval(id); + id = 0; + }, + + // private + startThread = function(){ + if(!running){ + running = true; + id = setInterval(runTasks, interval); + } + }, + + // private + removeTask = function(t){ + removeQueue.push(t); + if(t.onStop){ + t.onStop.apply(t.scope || t); + } + }, + + // private + runTasks = function(){ + var rqLen = removeQueue.length, + now = new Date().getTime(); + + if(rqLen > 0){ + for(var i = 0; i < rqLen; i++){ + tasks.remove(removeQueue[i]); + } + removeQueue = []; + if(tasks.length < 1){ + stopThread(); + return; + } + } + for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){ + t = tasks[i]; + itime = now - t.taskRunTime; + if(t.interval <= itime){ + rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]); + t.taskRunTime = now; + if(rt === false || t.taskRunCount === t.repeat){ + removeTask(t); + return; + } + } + if(t.duration && t.duration <= (now - t.taskStartTime)){ + removeTask(t); + } + } + }; + + /** + * Starts a new task. + * @method start + * @param {Object} task

    A config object that supports the following properties:

      + *
    • run : Function

      The function to execute each time the task is invoked. The + * function will be called at each interval and passed the args argument if specified, and the + * current invocation count if not.

      + *

      If a particular scope (this reference) is required, be sure to specify it using the scope argument.

      + *

      Return false from this function to terminate the task.

    • + *
    • interval : Number
      The frequency in milliseconds with which the task + * should be invoked.
    • + *
    • args : Array
      (optional) An array of arguments to be passed to the function + * specified by run. If not specified, the current invocation count is passed.
    • + *
    • scope : Object
      (optional) The scope (this reference) in which to execute the + * run function. Defaults to the task config object.
    • + *
    • duration : Number
      (optional) The length of time in milliseconds to invoke + * the task before stopping automatically (defaults to indefinite).
    • + *
    • repeat : Number
      (optional) The number of times to invoke the task before + * stopping automatically (defaults to indefinite).
    • + *

    + *

    Before each invocation, Ext injects the property taskRunCount into the task object so + * that calculations based on the repeat count can be performed.

    + * @return {Object} The task + */ + this.start = function(task){ + tasks.push(task); + task.taskStartTime = new Date().getTime(); + task.taskRunTime = 0; + task.taskRunCount = 0; + startThread(); + return task; + }; + + /** + * Stops an existing running task. + * @method stop + * @param {Object} task The task to stop + * @return {Object} The task + */ + this.stop = function(task){ + removeTask(task); + return task; + }; + + /** + * Stops all tasks that are currently running. + * @method stopAll + */ + this.stopAll = function(){ + stopThread(); + for(var i = 0, len = tasks.length; i < len; i++){ + if(tasks[i].onStop){ + tasks[i].onStop(); + } + } + tasks = []; + removeQueue = []; + }; +}; + +/** + * @class Ext.TaskMgr + * @extends Ext.util.TaskRunner + * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks. See + * {@link Ext.util.TaskRunner} for supported methods and task config properties. + *
    
    +// Start a simple clock task that updates a div once per second
    +var task = {
    +    run: function(){
    +        Ext.fly('clock').update(new Date().format('g:i:s A'));
    +    },
    +    interval: 1000 //1 second
    +}
    +Ext.TaskMgr.start(task);
    +
    + *

    See the {@link #start} method for details about how to configure a task object.

    + * @singleton + */ +Ext.TaskMgr = new Ext.util.TaskRunner();(function(){ + var libFlyweight; + + function fly(el) { + if (!libFlyweight) { + libFlyweight = new Ext.Element.Flyweight(); + } + libFlyweight.dom = el; + return libFlyweight; + } + + (function(){ + var doc = document, + isCSS1 = doc.compatMode == "CSS1Compat", + MAX = Math.max, + ROUND = Math.round, + PARSEINT = parseInt; + + Ext.lib.Dom = { + isAncestor : function(p, c) { + var ret = false; + + p = Ext.getDom(p); + c = Ext.getDom(c); + if (p && c) { + if (p.contains) { + return p.contains(c); + } else if (p.compareDocumentPosition) { + return !!(p.compareDocumentPosition(c) & 16); + } else { + while (c = c.parentNode) { + ret = c == p || ret; + } + } + } + return ret; + }, + + getViewWidth : function(full) { + return full ? this.getDocumentWidth() : this.getViewportWidth(); + }, + + getViewHeight : function(full) { + return full ? this.getDocumentHeight() : this.getViewportHeight(); + }, + + getDocumentHeight: function() { + return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight()); + }, + + getDocumentWidth: function() { + return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth()); + }, + + getViewportHeight: function(){ + return Ext.isIE9m ? + (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) : + self.innerHeight; + }, + + getViewportWidth : function() { + return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth : + Ext.isIE9m ? doc.documentElement.clientWidth : self.innerWidth; + }, + + getY : function(el) { + return this.getXY(el)[1]; + }, + + getX : function(el) { + return this.getXY(el)[0]; + }, + + getXY : function(el) { + var p, + pe, + b, + bt, + bl, + dbd, + x = 0, + y = 0, + scroll, + hasAbsolute, + bd = (doc.body || doc.documentElement), + ret = [0,0]; + + el = Ext.getDom(el); + + if(el != bd){ + if (el.getBoundingClientRect) { + b = el.getBoundingClientRect(); + scroll = fly(document).getScroll(); + ret = [ROUND(b.left + scroll.left), ROUND(b.top + scroll.top)]; + } else { + p = el; + hasAbsolute = fly(el).isStyle("position", "absolute"); + + while (p) { + pe = fly(p); + x += p.offsetLeft; + y += p.offsetTop; + + hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute"); + + if (Ext.isGecko) { + y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0; + x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0; + + if (p != el && !pe.isStyle('overflow','visible')) { + x += bl; + y += bt; + } + } + p = p.offsetParent; + } + + if (Ext.isSafari && hasAbsolute) { + x -= bd.offsetLeft; + y -= bd.offsetTop; + } + + if (Ext.isGecko && !hasAbsolute) { + dbd = fly(bd); + x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0; + y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0; + } + + p = el.parentNode; + while (p && p != bd) { + if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) { + x -= p.scrollLeft; + y -= p.scrollTop; + } + p = p.parentNode; + } + ret = [x,y]; + } + } + return ret; + }, + + setXY : function(el, xy) { + (el = Ext.fly(el, '_setXY')).position(); + + var pts = el.translatePoints(xy), + style = el.dom.style, + pos; + + for (pos in pts) { + if (!isNaN(pts[pos])) { + style[pos] = pts[pos] + "px"; + } + } + }, + + setX : function(el, x) { + this.setXY(el, [x, false]); + }, + + setY : function(el, y) { + this.setXY(el, [false, y]); + } + }; +})();Ext.lib.Event = function() { + var loadComplete = false, + unloadListeners = {}, + retryCount = 0, + onAvailStack = [], + _interval, + locked = false, + win = window, + doc = document, + + // constants + POLL_RETRYS = 200, + POLL_INTERVAL = 20, + TYPE = 0, + FN = 1, + OBJ = 2, + ADJ_SCOPE = 3, + SCROLLLEFT = 'scrollLeft', + SCROLLTOP = 'scrollTop', + UNLOAD = 'unload', + MOUSEOVER = 'mouseover', + MOUSEOUT = 'mouseout', + // private + doAdd = function() { + var ret; + if (win.addEventListener) { + ret = function(el, eventName, fn, capture) { + if (eventName == 'mouseenter') { + fn = fn.createInterceptor(checkRelatedTarget); + el.addEventListener(MOUSEOVER, fn, (capture)); + } else if (eventName == 'mouseleave') { + fn = fn.createInterceptor(checkRelatedTarget); + el.addEventListener(MOUSEOUT, fn, (capture)); + } else { + el.addEventListener(eventName, fn, (capture)); + } + return fn; + }; + } else if (win.attachEvent) { + ret = function(el, eventName, fn, capture) { + el.attachEvent("on" + eventName, fn); + return fn; + }; + } else { + ret = function(){}; + } + return ret; + }(), + // private + doRemove = function(){ + var ret; + if (win.removeEventListener) { + ret = function (el, eventName, fn, capture) { + if (eventName == 'mouseenter') { + eventName = MOUSEOVER; + } else if (eventName == 'mouseleave') { + eventName = MOUSEOUT; + } + el.removeEventListener(eventName, fn, (capture)); + }; + } else if (win.detachEvent) { + ret = function (el, eventName, fn) { + el.detachEvent("on" + eventName, fn); + }; + } else { + ret = function(){}; + } + return ret; + }(); + + function checkRelatedTarget(e) { + return !elContains(e.currentTarget, pub.getRelatedTarget(e)); + } + + function elContains(parent, child) { + if(parent && parent.firstChild){ + while(child) { + if(child === parent) { + return true; + } + child = child.parentNode; + if(child && (child.nodeType != 1)) { + child = null; + } + } + } + return false; + } + + // private + function _tryPreloadAttach() { + var ret = false, + notAvail = [], + element, i, v, override, + tryAgain = !loadComplete || (retryCount > 0); + + if(!locked){ + locked = true; + + for(i = 0; i < onAvailStack.length; ++i){ + v = onAvailStack[i]; + if(v && (element = doc.getElementById(v.id))){ + if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) { + override = v.override; + element = override ? (override === true ? v.obj : override) : element; + v.fn.call(element, v.obj); + onAvailStack.remove(v); + --i; + }else{ + notAvail.push(v); + } + } + } + + retryCount = (notAvail.length === 0) ? 0 : retryCount - 1; + + if (tryAgain) { + startInterval(); + } else { + clearInterval(_interval); + _interval = null; + } + ret = !(locked = false); + } + return ret; + } + + // private + function startInterval() { + if(!_interval){ + var callback = function() { + _tryPreloadAttach(); + }; + _interval = setInterval(callback, POLL_INTERVAL); + } + } + + // private + function getScroll() { + var dd = doc.documentElement, + db = doc.body; + if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){ + return [dd[SCROLLLEFT], dd[SCROLLTOP]]; + }else if(db){ + return [db[SCROLLLEFT], db[SCROLLTOP]]; + }else{ + return [0, 0]; + } + } + + // private + function getPageCoord (ev, xy) { + ev = ev.browserEvent || ev; + var coord = ev['page' + xy]; + if (!coord && coord !== 0) { + coord = ev['client' + xy] || 0; + + if (Ext.isIE) { + coord += getScroll()[xy == "X" ? 0 : 1]; + } + } + + return coord; + } + + var pub = { + extAdapter: true, + onAvailable : function(p_id, p_fn, p_obj, p_override) { + onAvailStack.push({ + id: p_id, + fn: p_fn, + obj: p_obj, + override: p_override, + checkReady: false }); + + retryCount = POLL_RETRYS; + startInterval(); + }, + + // This function should ALWAYS be called from Ext.EventManager + addListener: function(el, eventName, fn) { + el = Ext.getDom(el); + if (el && fn) { + if (eventName == UNLOAD) { + if (unloadListeners[el.id] === undefined) { + unloadListeners[el.id] = []; + } + unloadListeners[el.id].push([eventName, fn]); + return fn; + } + return doAdd(el, eventName, fn, false); + } + return false; + }, + + // This function should ALWAYS be called from Ext.EventManager + removeListener: function(el, eventName, fn) { + el = Ext.getDom(el); + var i, len, li, lis; + if (el && fn) { + if(eventName == UNLOAD){ + if((lis = unloadListeners[el.id]) !== undefined){ + for(i = 0, len = lis.length; i < len; i++){ + if((li = lis[i]) && li[TYPE] == eventName && li[FN] == fn){ + unloadListeners[el.id].splice(i, 1); + } + } + } + return; + } + doRemove(el, eventName, fn, false); + } + }, + + getTarget : function(ev) { + ev = ev.browserEvent || ev; + return this.resolveTextNode(ev.target || ev.srcElement); + }, + + resolveTextNode : Ext.isGecko ? function(node){ + if(!node){ + return; + } + // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197 + var s = HTMLElement.prototype.toString.call(node); + if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){ + return; + } + return node.nodeType == 3 ? node.parentNode : node; + } : function(node){ + return node && node.nodeType == 3 ? node.parentNode : node; + }, + + getRelatedTarget : function(ev) { + ev = ev.browserEvent || ev; + return this.resolveTextNode(ev.relatedTarget || + (/(mouseout|mouseleave)/.test(ev.type) ? ev.toElement : + /(mouseover|mouseenter)/.test(ev.type) ? ev.fromElement : null)); + }, + + getPageX : function(ev) { + return getPageCoord(ev, "X"); + }, + + getPageY : function(ev) { + return getPageCoord(ev, "Y"); + }, + + + getXY : function(ev) { + return [this.getPageX(ev), this.getPageY(ev)]; + }, + + stopEvent : function(ev) { + this.stopPropagation(ev); + this.preventDefault(ev); + }, + + stopPropagation : function(ev) { + ev = ev.browserEvent || ev; + if (ev.stopPropagation) { + ev.stopPropagation(); + } else { + ev.cancelBubble = true; + } + }, + + preventDefault : function(ev) { + ev = ev.browserEvent || ev; + if (ev.preventDefault) { + ev.preventDefault(); + } else { + if (ev.keyCode) { + ev.keyCode = 0; + } + ev.returnValue = false; + } + }, + + getEvent : function(e) { + e = e || win.event; + if (!e) { + var c = this.getEvent.caller; + while (c) { + e = c.arguments[0]; + if (e && Event == e.constructor) { + break; + } + c = c.caller; + } + } + return e; + }, + + getCharCode : function(ev) { + ev = ev.browserEvent || ev; + return ev.charCode || ev.keyCode || 0; + }, + + //clearCache: function() {}, + // deprecated, call from EventManager + getListeners : function(el, eventName) { + Ext.EventManager.getListeners(el, eventName); + }, + + // deprecated, call from EventManager + purgeElement : function(el, recurse, eventName) { + Ext.EventManager.purgeElement(el, recurse, eventName); + }, + + _load : function(e) { + loadComplete = true; + + if (Ext.isIE9m && e !== true) { + // IE8 complains that _load is null or not an object + // so lets remove self via arguments.callee + doRemove(win, "load", arguments.callee); + } + }, + + _unload : function(e) { + var EU = Ext.lib.Event, + i, v, ul, id, len, scope; + + for (id in unloadListeners) { + ul = unloadListeners[id]; + for (i = 0, len = ul.length; i < len; i++) { + v = ul[i]; + if (v) { + try{ + scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win; + v[FN].call(scope, EU.getEvent(e), v[OBJ]); + }catch(ex){} + } + } + }; + + Ext.EventManager._unload(); + + doRemove(win, UNLOAD, EU._unload); + } + }; + + // Initialize stuff. + pub.on = pub.addListener; + pub.un = pub.removeListener; + if (doc && doc.body) { + pub._load(true); + } else { + doAdd(win, "load", pub._load); + } + doAdd(win, UNLOAD, pub._unload); + _tryPreloadAttach(); + + return pub; +}(); +/* +* Portions of this file are based on pieces of Yahoo User Interface Library +* Copyright (c) 2007, Yahoo! Inc. All rights reserved. +* YUI licensed under the BSD License: +* http://developer.yahoo.net/yui/license.txt +*/ +Ext.lib.Ajax = function() { + var activeX = ['Msxml2.XMLHTTP.3.0', + 'Msxml2.XMLHTTP'], + CONTENTTYPE = 'Content-Type'; + + // private + function setHeader(o) { + var conn = o.conn, + prop, + headers = {}; + + function setTheHeaders(conn, headers){ + for (prop in headers) { + if (headers.hasOwnProperty(prop)) { + conn.setRequestHeader(prop, headers[prop]); + } + } + } + + Ext.apply(headers, pub.headers, pub.defaultHeaders); + setTheHeaders(conn, headers); + delete pub.headers; + } + + // private + function createExceptionObject(tId, callbackArg, isAbort, isTimeout) { + return { + tId : tId, + status : isAbort ? -1 : 0, + statusText : isAbort ? 'transaction aborted' : 'communication failure', + isAbort: isAbort, + isTimeout: isTimeout, + argument : callbackArg + }; + } + + // private + function initHeader(label, value) { + (pub.headers = pub.headers || {})[label] = value; + } + + // private + function createResponseObject(o, callbackArg) { + var headerObj = {}, + headerStr, + conn = o.conn, + t, + s, + // see: https://prototype.lighthouseapp.com/projects/8886/tickets/129-ie-mangles-http-response-status-code-204-to-1223 + isBrokenStatus = conn.status == 1223; + + try { + headerStr = o.conn.getAllResponseHeaders(); + Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){ + t = v.indexOf(':'); + if(t >= 0){ + s = v.substr(0, t).toLowerCase(); + if(v.charAt(t + 1) == ' '){ + ++t; + } + headerObj[s] = v.substr(t + 1); + } + }); + } catch(e) {} + + return { + tId : o.tId, + // Normalize the status and statusText when IE returns 1223, see the above link. + status : isBrokenStatus ? 204 : conn.status, + statusText : isBrokenStatus ? 'No Content' : conn.statusText, + getResponseHeader : function(header){return headerObj[header.toLowerCase()];}, + getAllResponseHeaders : function(){return headerStr;}, + responseText : conn.responseText, + responseXML : conn.responseXML, + argument : callbackArg + }; + } + + // private + function releaseObject(o) { + if (o.tId) { + pub.conn[o.tId] = null; + } + o.conn = null; + o = null; + } + + // private + function handleTransactionResponse(o, callback, isAbort, isTimeout) { + if (!callback) { + releaseObject(o); + return; + } + + var httpStatus, responseObject; + + try { + if (o.conn.status !== undefined && o.conn.status != 0) { + httpStatus = o.conn.status; + } + else { + httpStatus = 13030; + } + } + catch(e) { + httpStatus = 13030; + } + + if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) { + responseObject = createResponseObject(o, callback.argument); + if (callback.success) { + if (!callback.scope) { + callback.success(responseObject); + } + else { + callback.success.apply(callback.scope, [responseObject]); + } + } + } + else { + switch (httpStatus) { + case 12002: + case 12029: + case 12030: + case 12031: + case 12152: + case 13030: + responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout); + if (callback.failure) { + if (!callback.scope) { + callback.failure(responseObject); + } + else { + callback.failure.apply(callback.scope, [responseObject]); + } + } + break; + default: + responseObject = createResponseObject(o, callback.argument); + if (callback.failure) { + if (!callback.scope) { + callback.failure(responseObject); + } + else { + callback.failure.apply(callback.scope, [responseObject]); + } + } + } + } + + releaseObject(o); + responseObject = null; + } + + function checkResponse(o, callback, conn, tId, poll, cbTimeout){ + if (conn && conn.readyState == 4) { + clearInterval(poll[tId]); + poll[tId] = null; + + if (cbTimeout) { + clearTimeout(pub.timeout[tId]); + pub.timeout[tId] = null; + } + handleTransactionResponse(o, callback); + } + } + + function checkTimeout(o, callback){ + pub.abort(o, callback, true); + } + + + // private + function handleReadyState(o, callback){ + callback = callback || {}; + var conn = o.conn, + tId = o.tId, + poll = pub.poll, + cbTimeout = callback.timeout || null; + + if (cbTimeout) { + pub.conn[tId] = conn; + pub.timeout[tId] = setTimeout(checkTimeout.createCallback(o, callback), cbTimeout); + } + poll[tId] = setInterval(checkResponse.createCallback(o, callback, conn, tId, poll, cbTimeout), pub.pollInterval); + } + + // private + function asyncRequest(method, uri, callback, postData) { + var o = getConnectionObject() || null; + + if (o) { + o.conn.open(method, uri, true); + + if (pub.useDefaultXhrHeader) { + initHeader('X-Requested-With', pub.defaultXhrHeader); + } + + if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){ + initHeader(CONTENTTYPE, pub.defaultPostHeader); + } + + if (pub.defaultHeaders || pub.headers) { + setHeader(o); + } + + handleReadyState(o, callback); + o.conn.send(postData || null); + } + return o; + } + + // private + function getConnectionObject() { + var o; + + try { + if (o = createXhrObject(pub.transactionId)) { + pub.transactionId++; + } + } catch(e) { + } finally { + return o; + } + } + + // private + function createXhrObject(transactionId) { + var http; + + try { + http = new XMLHttpRequest(); + } catch(e) { + for (var i = Ext.isIE6 ? 1 : 0; i < activeX.length; ++i) { + try { + http = new ActiveXObject(activeX[i]); + break; + } catch(e) {} + } + } finally { + return {conn : http, tId : transactionId}; + } + } + + var pub = { + request : function(method, uri, cb, data, options) { + if(options){ + var me = this, + xmlData = options.xmlData, + jsonData = options.jsonData, + hs; + + Ext.applyIf(me, options); + + if(xmlData || jsonData){ + hs = me.headers; + if(!hs || !hs[CONTENTTYPE]){ + initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json'); + } + data = xmlData || (!Ext.isPrimitive(jsonData) ? Ext.encode(jsonData) : jsonData); + } + } + return asyncRequest(method || options.method || "POST", uri, cb, data); + }, + + serializeForm : function(form) { + var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, + hasSubmit = false, + encoder = encodeURIComponent, + name, + data = '', + type, + hasValue; + + Ext.each(fElements, function(element){ + name = element.name; + type = element.type; + + if (!element.disabled && name) { + if (/select-(one|multiple)/i.test(type)) { + Ext.each(element.options, function(opt){ + if (opt.selected) { + hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified; + data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text)); + } + }); + } else if (!(/file|undefined|reset|button/i.test(type))) { + if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) { + data += encoder(name) + '=' + encoder(element.value) + '&'; + hasSubmit = /submit/i.test(type); + } + } + } + }); + return data.substr(0, data.length - 1); + }, + + useDefaultHeader : true, + defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', + useDefaultXhrHeader : true, + defaultXhrHeader : 'XMLHttpRequest', + poll : {}, + timeout : {}, + conn: {}, + pollInterval : 50, + transactionId : 0, + +// This is never called - Is it worth exposing this? +// setProgId : function(id) { +// activeX.unshift(id); +// }, + +// This is never called - Is it worth exposing this? +// setDefaultPostHeader : function(b) { +// this.useDefaultHeader = b; +// }, + +// This is never called - Is it worth exposing this? +// setDefaultXhrHeader : function(b) { +// this.useDefaultXhrHeader = b; +// }, + +// This is never called - Is it worth exposing this? +// setPollingInterval : function(i) { +// if (typeof i == 'number' && isFinite(i)) { +// this.pollInterval = i; +// } +// }, + +// This is never called - Is it worth exposing this? +// resetDefaultHeaders : function() { +// this.defaultHeaders = null; +// }, + + abort : function(o, callback, isTimeout) { + var me = this, + tId = o.tId, + isAbort = false; + + if (me.isCallInProgress(o)) { + o.conn.abort(); + clearInterval(me.poll[tId]); + me.poll[tId] = null; + clearTimeout(pub.timeout[tId]); + me.timeout[tId] = null; + + handleTransactionResponse(o, callback, (isAbort = true), isTimeout); + } + return isAbort; + }, + + isCallInProgress : function(o) { + // if there is a connection and readyState is not 0 or 4 + return o.conn && !{0:true,4:true}[o.conn.readyState]; + } + }; + return pub; +}();(function(){ + var EXTLIB = Ext.lib, + noNegatives = /width|height|opacity|padding/i, + offsetAttribute = /^((width|height)|(top|left))$/, + defaultUnit = /width|height|top$|bottom$|left$|right$/i, + offsetUnit = /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i, + isset = function(v){ + return typeof v !== 'undefined'; + }, + now = function(){ + return new Date(); + }; + + EXTLIB.Anim = { + motion : function(el, args, duration, easing, cb, scope) { + return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion); + }, + + run : function(el, args, duration, easing, cb, scope, type) { + type = type || Ext.lib.AnimBase; + if (typeof easing == "string") { + easing = Ext.lib.Easing[easing]; + } + var anim = new type(el, args, duration, easing); + anim.animateX(function() { + if(Ext.isFunction(cb)){ + cb.call(scope); + } + }); + return anim; + } + }; + + EXTLIB.AnimBase = function(el, attributes, duration, method) { + if (el) { + this.init(el, attributes, duration, method); + } + }; + + EXTLIB.AnimBase.prototype = { + doMethod: function(attr, start, end) { + var me = this; + return me.method(me.curFrame, start, end - start, me.totalFrames); + }, + + + setAttr: function(attr, val, unit) { + if (noNegatives.test(attr) && val < 0) { + val = 0; + } + Ext.fly(this.el, '_anim').setStyle(attr, val + unit); + }, + + + getAttr: function(attr) { + var el = Ext.fly(this.el), + val = el.getStyle(attr), + a = offsetAttribute.exec(attr) || []; + + if (val !== 'auto' && !offsetUnit.test(val)) { + return parseFloat(val); + } + + return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0; + }, + + + getDefaultUnit: function(attr) { + return defaultUnit.test(attr) ? 'px' : ''; + }, + + animateX : function(callback, scope) { + var me = this, + f = function() { + me.onComplete.removeListener(f); + if (Ext.isFunction(callback)) { + callback.call(scope || me, me); + } + }; + me.onComplete.addListener(f, me); + me.animate(); + }, + + + setRunAttr: function(attr) { + var me = this, + a = this.attributes[attr], + to = a.to, + by = a.by, + from = a.from, + unit = a.unit, + ra = (this.runAttrs[attr] = {}), + end; + + if (!isset(to) && !isset(by)){ + return false; + } + + var start = isset(from) ? from : me.getAttr(attr); + if (isset(to)) { + end = to; + }else if(isset(by)) { + if (Ext.isArray(start)){ + end = []; + for(var i=0,len=start.length; i 0 && isFinite(tweak)){ + if(tween.curFrame + tweak >= frames){ + tweak = frames - (frame + 1); + } + tween.curFrame += tweak; + } + }; + }; + + EXTLIB.Bezier = new function() { + + this.getPosition = function(points, t) { + var n = points.length, + tmp = [], + c = 1 - t, + i, + j; + + for (i = 0; i < n; ++i) { + tmp[i] = [points[i][0], points[i][1]]; + } + + for (j = 1; j < n; ++j) { + for (i = 0; i < n - j; ++i) { + tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0]; + tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; + } + } + + return [ tmp[0][0], tmp[0][1] ]; + + }; + }; + + + EXTLIB.Easing = { + easeNone: function (t, b, c, d) { + return c * t / d + b; + }, + + + easeIn: function (t, b, c, d) { + return c * (t /= d) * t + b; + }, + + + easeOut: function (t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + } + }; + + (function() { + EXTLIB.Motion = function(el, attributes, duration, method) { + if (el) { + EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method); + } + }; + + Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase); + + var superclass = EXTLIB.Motion.superclass, + pointsRe = /^points$/i; + + Ext.apply(EXTLIB.Motion.prototype, { + setAttr: function(attr, val, unit){ + var me = this, + setAttr = superclass.setAttr; + + if (pointsRe.test(attr)) { + unit = unit || 'px'; + setAttr.call(me, 'left', val[0], unit); + setAttr.call(me, 'top', val[1], unit); + } else { + setAttr.call(me, attr, val, unit); + } + }, + + getAttr: function(attr){ + var me = this, + getAttr = superclass.getAttr; + + return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr); + }, + + doMethod: function(attr, start, end){ + var me = this; + + return pointsRe.test(attr) + ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100) + : superclass.doMethod.call(me, attr, start, end); + }, + + setRunAttr: function(attr){ + if(pointsRe.test(attr)){ + + var me = this, + el = this.el, + points = this.attributes.points, + control = points.control || [], + from = points.from, + to = points.to, + by = points.by, + DOM = EXTLIB.Dom, + start, + i, + end, + len, + ra; + + + if(control.length > 0 && !Ext.isArray(control[0])){ + control = [control]; + }else{ + /* + var tmp = []; + for (i = 0,len = control.length; i < len; ++i) { + tmp[i] = control[i]; + } + control = tmp; + */ + } + + Ext.fly(el, '_anim').position(); + DOM.setXY(el, isset(from) ? from : DOM.getXY(el)); + start = me.getAttr('points'); + + + if(isset(to)){ + end = translateValues.call(me, to, start); + for (i = 0,len = control.length; i < len; ++i) { + control[i] = translateValues.call(me, control[i], start); + } + } else if (isset(by)) { + end = [start[0] + by[0], start[1] + by[1]]; + + for (i = 0,len = control.length; i < len; ++i) { + control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ]; + } + } + + ra = this.runAttrs[attr] = [start]; + if (control.length > 0) { + ra = ra.concat(control); + } + + ra[ra.length] = end; + }else{ + superclass.setRunAttr.call(this, attr); + } + } + }); + + var translateValues = function(val, start) { + var pageXY = EXTLIB.Dom.getXY(this.el); + return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]]; + }; + })(); +})();// Easing functions +(function(){ + // shortcuts to aid compression + var abs = Math.abs, + pi = Math.PI, + asin = Math.asin, + pow = Math.pow, + sin = Math.sin, + EXTLIB = Ext.lib; + + Ext.apply(EXTLIB.Easing, { + + easeBoth: function (t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + + easeInStrong: function (t, b, c, d) { + return c * (t /= d) * t * t * t + b; + }, + + easeOutStrong: function (t, b, c, d) { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + }, + + easeBothStrong: function (t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b; + }, + + elasticIn: function (t, b, c, d, a, p) { + if (t == 0 || (t /= d) == 1) { + return t == 0 ? b : b + c; + } + p = p || (d * .3); + + var s; + if (a >= abs(c)) { + s = p / (2 * pi) * asin(c / a); + } else { + a = c; + s = p / 4; + } + + return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b; + + }, + + elasticOut: function (t, b, c, d, a, p) { + if (t == 0 || (t /= d) == 1) { + return t == 0 ? b : b + c; + } + p = p || (d * .3); + + var s; + if (a >= abs(c)) { + s = p / (2 * pi) * asin(c / a); + } else { + a = c; + s = p / 4; + } + + return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b; + }, + + elasticBoth: function (t, b, c, d, a, p) { + if (t == 0 || (t /= d / 2) == 2) { + return t == 0 ? b : b + c; + } + + p = p || (d * (.3 * 1.5)); + + var s; + if (a >= abs(c)) { + s = p / (2 * pi) * asin(c / a); + } else { + a = c; + s = p / 4; + } + + return t < 1 ? + -.5 * (a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b : + a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b; + }, + + backIn: function (t, b, c, d, s) { + s = s || 1.70158; + return c * (t /= d) * t * ((s + 1) * t - s) + b; + }, + + + backOut: function (t, b, c, d, s) { + if (!s) { + s = 1.70158; + } + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + }, + + + backBoth: function (t, b, c, d, s) { + s = s || 1.70158; + + return ((t /= d / 2 ) < 1) ? + c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : + c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + }, + + + bounceIn: function (t, b, c, d) { + return c - EXTLIB.Easing.bounceOut(d - t, 0, c, d) + b; + }, + + + bounceOut: function (t, b, c, d) { + if ((t /= d) < (1 / 2.75)) { + return c * (7.5625 * t * t) + b; + } else if (t < (2 / 2.75)) { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; + } else if (t < (2.5 / 2.75)) { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; + } + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; + }, + + + bounceBoth: function (t, b, c, d) { + return (t < d / 2) ? + EXTLIB.Easing.bounceIn(t * 2, 0, c, d) * .5 + b : + EXTLIB.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + }); +})(); + +(function() { + var EXTLIB = Ext.lib; + // Color Animation + EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) { + return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim); + }; + + EXTLIB.ColorAnim = function(el, attributes, duration, method) { + EXTLIB.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method); + }; + + Ext.extend(EXTLIB.ColorAnim, EXTLIB.AnimBase); + + var superclass = EXTLIB.ColorAnim.superclass, + colorRE = /color$/i, + transparentRE = /^transparent|rgba\(0, 0, 0, 0\)$/, + rgbRE = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i, + hexRE= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i, + hex3RE = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i, + isset = function(v){ + return typeof v !== 'undefined'; + }; + + // private + function parseColor(s) { + var pi = parseInt, + base, + out = null, + c; + + if (s.length == 3) { + return s; + } + + Ext.each([hexRE, rgbRE, hex3RE], function(re, idx){ + base = (idx % 2 == 0) ? 16 : 10; + c = re.exec(s); + if(c && c.length == 4){ + out = [pi(c[1], base), pi(c[2], base), pi(c[3], base)]; + return false; + } + }); + return out; + } + + Ext.apply(EXTLIB.ColorAnim.prototype, { + getAttr : function(attr) { + var me = this, + el = me.el, + val; + if(colorRE.test(attr)){ + while(el && transparentRE.test(val = Ext.fly(el).getStyle(attr))){ + el = el.parentNode; + val = "fff"; + } + }else{ + val = superclass.getAttr.call(me, attr); + } + return val; + }, + + doMethod : function(attr, start, end) { + var me = this, + val, + floor = Math.floor, + i, + len, + v; + + if(colorRE.test(attr)){ + val = []; + end = end || []; + + for(i = 0, len = start.length; i < len; i++) { + v = start[i]; + val[i] = superclass.doMethod.call(me, attr, v, end[i]); + } + val = 'rgb(' + floor(val[0]) + ',' + floor(val[1]) + ',' + floor(val[2]) + ')'; + }else{ + val = superclass.doMethod.call(me, attr, start, end); + } + return val; + }, + + setRunAttr : function(attr) { + var me = this, + a = me.attributes[attr], + to = a.to, + by = a.by, + ra; + + superclass.setRunAttr.call(me, attr); + ra = me.runAttrs[attr]; + if(colorRE.test(attr)){ + var start = parseColor(ra.start), + end = parseColor(ra.end); + + if(!isset(to) && isset(by)){ + end = parseColor(by); + for(var i=0,len=start.length; i0;){O=w[P];if(N.hasOwnProperty(O)){R=N[O];if(typeof R=="function"){R.$owner=t;R.$name=O}Q[O]=R}}}},define:function(R,P,N){var t=P.override,T,Q,e,O;if(t){delete P.override;T=Ext.getClassByName(t);Ext.override(T,P)}else{if(R){O=Ext.createNamespace(R,true);e=R.substring(R.lastIndexOf(".")+1)}T=function S(){this.constructor.apply(this,arguments)};if(R){T.displayName=R}T.$isClass=true;T.callParent=Ext.Base.callParent;if(typeof P=="function"){P=P(T)}Q=P.extend;if(Q){delete P.extend;if(typeof Q=="string"){Q=Ext.getClassByName(Q)}}else{Q=k}Ext.extend(T,Q,P);if(T.prototype.constructor===T){delete T.prototype.constructor}if(!T.prototype.$isClass){Ext.applyIf(T.prototype,k.prototype)}T.prototype.self=T;if(P.xtype){Ext.reg(P.xtype,T)}T=P.singleton?new T():T;if(R){O[e]=T}}if(N){N.call(T)}return T},override:function(P,R){var N,Q;if(R){if(P.$isClass){Q=R.statics;if(Q){delete R.statics}Ext.addMembers(P,P.prototype,R,true);if(Q){Ext.addMembers(P,P,Q)}}else{if(typeof P=="function"){N=P.prototype;Ext.apply(N,R);if(Ext.isIE&&R.hasOwnProperty("toString")){N.toString=R.toString}}else{var e=P.self,t,O;if(e&&e.$isClass){for(t in R){if(R.hasOwnProperty(t)){O=R[t];if(typeof O=="function"){if(e.$className){O.displayName=e.$className+"#"+t}O.$name=t;O.$owner=e;O.$previous=P.hasOwnProperty(t)?P[t]:l}P[t]=O}}}else{Ext.apply(P,R);if(!P.constructor.$isClass){P.constructor.prototype.callParent=k.prototype.callParent;P.constructor.callParent=k.callParent}}}}}},namespace:function(){var O=arguments.length,P=0,t,N,e,R,Q,S;for(;P0){return setTimeout(d,c)}d();return 0}});Ext.applyIf(String,{format:function(b){var a=Ext.toArray(arguments,1);return b.replace(/\{(\d+)\}/g,function(c,d){return a[d]})}});Ext.applyIf(Array.prototype,{indexOf:function(b,c){var a=this.length;c=c||0;c+=(c<0)?a:0;for(;c0){for(var p=0;p0);if(!A){A=true;for(I=0;I=0){B=s.substr(0,A).toLowerCase();if(s.charAt(A+1)==" "){++A}C[B]=s.substr(A+1)}})}catch(z){}return{tId:u.tId,status:v?204:w.status,statusText:v?"No Content":w.statusText,getResponseHeader:function(s){return C[s.toLowerCase()]},getAllResponseHeaders:function(){return x},responseText:w.responseText,responseXML:w.responseXML,argument:y}}function o(s){if(s.tId){k.conn[s.tId]=null}s.conn=null;s=null}function f(x,y,t,s){if(!y){o(x);return}var v,u;try{if(x.conn.status!==undefined&&x.conn.status!=0){v=x.conn.status}else{v=13030}}catch(w){v=13030}if((v>=200&&v<300)||(Ext.isIE&&v==1223)){u=p(x,y.argument);if(y.success){if(!y.scope){y.success(u)}else{y.success.apply(y.scope,[u])}}}else{switch(v){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:u=e(x.tId,y.argument,(t?t:false),s);if(y.failure){if(!y.scope){y.failure(u)}else{y.failure.apply(y.scope,[u])}}break;default:u=p(x,y.argument);if(y.failure){if(!y.scope){y.failure(u)}else{y.failure.apply(y.scope,[u])}}}}o(x);u=null}function m(u,x,s,w,t,v){if(s&&s.readyState==4){clearInterval(t[w]);t[w]=null;if(v){clearTimeout(k.timeout[w]);k.timeout[w]=null}f(u,x)}}function r(s,t){k.abort(s,t,true)}function n(u,x){x=x||{};var s=u.conn,w=u.tId,t=k.poll,v=x.timeout||null;if(v){k.conn[w]=s;k.timeout[w]=setTimeout(r.createCallback(u,x),v)}t[w]=setInterval(m.createCallback(u,x,s,w,t,v),k.pollInterval)}function i(w,t,v,s){var u=l()||null;if(u){u.conn.open(w,t,true);if(k.useDefaultXhrHeader){j("X-Requested-With",k.defaultXhrHeader)}if(s&&k.useDefaultHeader&&(!k.headers||!k.headers[d])){j(d,k.defaultPostHeader)}if(k.defaultHeaders||k.headers){h(u)}n(u,v);u.conn.send(s||null)}return u}function l(){var t;try{if(t=q(k.transactionId)){k.transactionId++}}catch(s){}finally{return t}}function q(v){var s;try{s=new XMLHttpRequest()}catch(u){for(var t=Ext.isIE6?1:0;t0&&isFinite(w)){if(r.curFrame+w>=v){w=v-(u+1)}r.curFrame+=w}}};g.Bezier=new function(){this.getPosition=function(p,o){var r=p.length,m=[],q=1-o,l,k;for(l=0;l0&&!Ext.isArray(s[0])){s=[s]}else{}Ext.fly(p,"_anim").position();A.setXY(p,j(x)?x:A.getXY(p));o=w.getAttr("points");if(j(y)){q=k.call(w,y,o);for(r=0,t=s.length;r0){n=n.concat(s)}n[n.length]=q}else{m.setRunAttr.call(this,u)}}});var k=function(n,p){var o=g.Dom.getXY(this.el);return[n[0]-o[0]+p[0],n[1]-o[1]+p[1]]}})()})();(function(){var d=Math.abs,i=Math.PI,h=Math.asin,g=Math.pow,e=Math.sin,f=Ext.lib;Ext.apply(f.Easing,{easeBoth:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k+j:-m/2*((--k)*(k-2)-1)+j},easeInStrong:function(k,j,m,l){return m*(k/=l)*k*k*k+j},easeOutStrong:function(k,j,m,l){return -m*((k=k/l-1)*k*k*k-1)+j},easeBothStrong:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k*k*k+j:-m/2*((k-=2)*k*k*k-2)+j},elasticIn:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return -(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j},elasticOut:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return k*g(2,-10*l)*e((l*o-m)*(2*i)/n)+q+j},elasticBoth:function(l,j,q,o,k,n){if(l==0||(l/=o/2)==2){return l==0?j:j+q}n=n||(o*(0.3*1.5));var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return l<1?-0.5*(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j:k*g(2,-10*(l-=1))*e((l*o-m)*(2*i)/n)*0.5+q+j},backIn:function(k,j,n,m,l){l=l||1.70158;return n*(k/=m)*k*((l+1)*k-l)+j},backOut:function(k,j,n,m,l){if(!l){l=1.70158}return n*((k=k/m-1)*k*((l+1)*k+l)+1)+j},backBoth:function(k,j,n,m,l){l=l||1.70158;return((k/=m/2)<1)?n/2*(k*k*(((l*=(1.525))+1)*k-l))+j:n/2*((k-=2)*k*(((l*=(1.525))+1)*k+l)+2)+j},bounceIn:function(k,j,m,l){return m-f.Easing.bounceOut(l-k,0,m,l)+j},bounceOut:function(k,j,m,l){if((k/=l)<(1/2.75)){return m*(7.5625*k*k)+j}else{if(k<(2/2.75)){return m*(7.5625*(k-=(1.5/2.75))*k+0.75)+j}else{if(k<(2.5/2.75)){return m*(7.5625*(k-=(2.25/2.75))*k+0.9375)+j}}}return m*(7.5625*(k-=(2.625/2.75))*k+0.984375)+j},bounceBoth:function(k,j,m,l){return(k middle && + this.tmpHoverClass == 'x-form-spinner-overup') || + (Ext.EventObject.getPageY() < middle && + this.tmpHoverClass == 'x-form-spinner-overdown') + ) { + } + }, + + //private + onMouseDown: function () { + if (this.disabled) { + return; + } + var middle = this.getMiddle(); + this.tmpClickClass = + Ext.EventObject.getPageY() < middle + ? 'x-form-spinner-clickup' + : 'x-form-spinner-clickdown'; + this.trigger.addClass(this.tmpClickClass); + }, + + //private + onMouseUp: function () { + this.trigger.removeClass(this.tmpClickClass); + }, + + //private + onTriggerClick: function () { + if (this.disabled || this.el.dom.readOnly) { + return; + } + var middle = this.getMiddle(); + var ud = Ext.EventObject.getPageY() < middle ? 'Up' : 'Down'; + this['onSpin' + ud](); + }, + + //private + getMiddle: function () { + var t = this.trigger.getTop(); + var h = this.trigger.getHeight(); + var middle = t + h / 2; + return middle; + }, + + //private + //checks if control is allowed to spin + isSpinnable: function () { + if (this.disabled || this.el.dom.readOnly) { + Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly + return false; + } + return true; + }, + + handleMouseWheel: function (e) { + //disable scrolling when not focused + if (this.wrap.hasClass('x-trigger-wrap-focus') == false) { + return; + } + + var delta = e.getWheelDelta(); + if (delta > 0) { + this.onSpinUp(); + e.stopEvent(); + } else if (delta < 0) { + this.onSpinDown(); + e.stopEvent(); + } + }, + + //private + startDrag: function () { + this.proxy.show(); + this._previousY = Ext.fly(this.dd.getDragEl()).getTop(); + }, + + //private + endDrag: function () { + this.proxy.hide(); + }, + + //private + onDrag: function () { + if (this.disabled) { + return; + } + var y = Ext.fly(this.dd.getDragEl()).getTop(); + var ud = ''; + + if (this._previousY > y) { + ud = 'Up'; + } //up + if (this._previousY < y) { + ud = 'Down'; + } //down + if (ud != '') { + this['onSpin' + ud](); + } + + this._previousY = y; + }, + + //private + onSpinUp: function () { + if (this.isSpinnable() == false) { + return; + } + if (Ext.EventObject.shiftKey == true) { + this.onSpinUpAlternate(); + return; + } else { + this.spin(false, false); + } + this.field.fireEvent('spin', this); + this.field.fireEvent('spinup', this); + }, + + //private + onSpinDown: function () { + if (this.isSpinnable() == false) { + return; + } + if (Ext.EventObject.shiftKey == true) { + this.onSpinDownAlternate(); + return; + } else { + this.spin(true, false); + } + this.field.fireEvent('spin', this); + this.field.fireEvent('spindown', this); + }, + + //private + onSpinUpAlternate: function () { + if (this.isSpinnable() == false) { + return; + } + this.spin(false, true); + this.field.fireEvent('spin', this); + this.field.fireEvent('spinup', this); + }, + + //private + onSpinDownAlternate: function () { + if (this.isSpinnable() == false) { + return; + } + this.spin(true, true); + this.field.fireEvent('spin', this); + this.field.fireEvent('spindown', this); + }, + + spin: function (down, alternate) { + var v = parseFloat(this.field.getValue()); + var incr = + alternate == true + ? this.alternateIncrementValue + : this.incrementValue; + down == true ? (v -= incr) : (v += incr); + + v = isNaN(v) ? this.defaultValue : v; + v = this.fixBoundries(v); + this.field.setRawValue(v); + }, + + fixBoundries: function (value) { + var v = value; + + if (this.field.minValue != undefined && v < this.field.minValue) { + v = this.field.minValue; + } + if (this.field.maxValue != undefined && v > this.field.maxValue) { + v = this.field.maxValue; + } + + return this.fixPrecision(v); + }, + + // private + fixPrecision: function (value) { + var nan = isNaN(value); + if ( + !this.field.allowDecimals || + this.field.decimalPrecision == -1 || + nan || + !value + ) { + return nan ? '' : value; + } + return parseFloat( + parseFloat(value).toFixed(this.field.decimalPrecision) + ); + }, + + doDestroy: function () { + if (this.trigger) { + this.trigger.remove(); + } + if (this.wrap) { + this.wrap.remove(); + delete this.field.wrap; + } + + if (this.splitter) { + this.splitter.remove(); + } + + if (this.dd) { + this.dd.unreg(); + this.dd = null; + } + + if (this.proxy) { + this.proxy.remove(); + } + + if (this.repeater) { + this.repeater.purgeListeners(); + } + if (this.mimicing) { + Ext.get(Ext.isIE ? document.body : document).un( + 'mousedown', + this.mimicBlur, + this + ); + } + }, +}); + +//backwards compat +Ext.form.Spinner = Ext.ux.Spinner; diff --git a/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js b/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js new file mode 100644 index 0000000..1f6a5f0 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js @@ -0,0 +1,422 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/** + * @class Ext.ux.StatusBar + *

    Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}. In addition to + * supporting the standard {@link Ext.Toolbar} interface for adding buttons, menus and other items, the StatusBar + * provides a greedy status element that can be aligned to either side and has convenient methods for setting the + * status text and icon. You can also indicate that something is processing using the {@link #showBusy} method.

    + *
    
    +new Ext.Panel({
    +    title: 'StatusBar',
    +    // etc.
    +    bbar: new Ext.ux.StatusBar({
    +        id: 'my-status',
    +
    +        // defaults to use when the status is cleared:
    +        defaultText: 'Default status text',
    +        defaultIconCls: 'default-icon',
    +
    +        // values to set initially:
    +        text: 'Ready',
    +        iconCls: 'ready-icon',
    +
    +        // any standard Toolbar items:
    +        items: [{
    +            text: 'A Button'
    +        }, '-', 'Plain Text']
    +    })
    +});
    +
    +// Update the status bar later in code:
    +var sb = Ext.getCmp('my-status');
    +sb.setStatus({
    +    text: 'OK',
    +    iconCls: 'ok-icon',
    +    clear: true // auto-clear after a set interval
    +});
    +
    +// Set the status bar to show that something is processing:
    +sb.showBusy();
    +
    +// processing....
    +
    +sb.clearStatus(); // once completeed
    +
    + * @extends Ext.Toolbar + * @constructor + * Creates a new StatusBar + * @param {Object/Array} config A config object + */ +Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, { + /** + * @cfg {String} statusAlign + * The alignment of the status element within the overall StatusBar layout. When the StatusBar is rendered, + * it creates an internal div containing the status text and icon. Any additional Toolbar items added in the + * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be + * rendered, in added order, to the opposite side. The status element is greedy, so it will automatically + * expand to take up all sapce left over by any other items. Example usage: + *
    
    +// Create a left-aligned status bar containing a button,
    +// separator and text item that will be right-aligned (default):
    +new Ext.Panel({
    +    title: 'StatusBar',
    +    // etc.
    +    bbar: new Ext.ux.StatusBar({
    +        defaultText: 'Default status text',
    +        id: 'status-id',
    +        items: [{
    +            text: 'A Button'
    +        }, '-', 'Plain Text']
    +    })
    +});
    +
    +// By adding the statusAlign config, this will create the
    +// exact same toolbar, except the status and toolbar item
    +// layout will be reversed from the previous example:
    +new Ext.Panel({
    +    title: 'StatusBar',
    +    // etc.
    +    bbar: new Ext.ux.StatusBar({
    +        defaultText: 'Default status text',
    +        id: 'status-id',
    +        statusAlign: 'right',
    +        items: [{
    +            text: 'A Button'
    +        }, '-', 'Plain Text']
    +    })
    +});
    +
    + */ + /** + * @cfg {String} defaultText + * The default {@link #text} value. This will be used anytime the status bar is cleared with the + * useDefaults:true option (defaults to ''). + */ + /** + * @cfg {String} defaultIconCls + * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon). + * This will be used anytime the status bar is cleared with the useDefaults:true option (defaults to ''). + */ + /** + * @cfg {String} text + * A string that will be initially set as the status message. This string + * will be set as innerHTML (html tags are accepted) for the toolbar item. + * If not specified, the value set for {@link #defaultText} + * will be used. + */ + /** + * @cfg {String} iconCls + * A CSS class that will be initially set as the status bar icon and is + * expected to provide a background image (defaults to ''). + * Example usage:
    
    +// Example CSS rule:
    +.x-statusbar .x-status-custom {
    +    padding-left: 25px;
    +    background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
    +}
    +
    +// Setting a default icon:
    +var sb = new Ext.ux.StatusBar({
    +    defaultIconCls: 'x-status-custom'
    +});
    +
    +// Changing the icon:
    +sb.setStatus({
    +    text: 'New status',
    +    iconCls: 'x-status-custom'
    +});
    +
    + */ + + /** + * @cfg {String} cls + * The base class applied to the containing element for this component on render (defaults to 'x-statusbar') + */ + cls: 'x-statusbar', + /** + * @cfg {String} busyIconCls + * The default {@link #iconCls} applied when calling + * {@link #showBusy} (defaults to 'x-status-busy'). + * It can be overridden at any time by passing the iconCls + * argument into {@link #showBusy}. + */ + busyIconCls: 'x-status-busy', + /** + * @cfg {String} busyText + * The default {@link #text} applied when calling + * {@link #showBusy} (defaults to 'Loading...'). + * It can be overridden at any time by passing the text + * argument into {@link #showBusy}. + */ + busyText: 'Loading...', + /** + * @cfg {Number} autoClear + * The number of milliseconds to wait after setting the status via + * {@link #setStatus} before automatically clearing the status + * text and icon (defaults to 5000). Note that this only applies + * when passing the clear argument to {@link #setStatus} + * since that is the only way to defer clearing the status. This can + * be overridden by specifying a different wait value in + * {@link #setStatus}. Calls to {@link #clearStatus} + * always clear the status bar immediately and ignore this value. + */ + autoClear: 5000, + + /** + * @cfg {String} emptyText + * The text string to use if no text has been set. Defaults to + * ' '). If there are no other items in the toolbar using + * an empty string ('') for this value would end up in the toolbar + * height collapsing since the empty string will not maintain the toolbar + * height. Use '' if the toolbar should collapse in height + * vertically when no text is specified and there are no other items in + * the toolbar. + */ + emptyText: ' ', + + // private + activeThreadId: 0, + + // private + initComponent: function () { + if (this.statusAlign == 'right') { + this.cls += ' x-status-right'; + } + Ext.ux.StatusBar.superclass.initComponent.call(this); + }, + + // private + afterRender: function () { + Ext.ux.StatusBar.superclass.afterRender.call(this); + + var right = this.statusAlign == 'right'; + this.currIconCls = this.iconCls || this.defaultIconCls; + this.statusEl = new Ext.Toolbar.TextItem({ + cls: 'x-status-text ' + (this.currIconCls || ''), + text: this.text || this.defaultText || '', + }); + + if (right) { + this.add('->'); + this.add(this.statusEl); + } else { + this.insert(0, this.statusEl); + this.insert(1, '->'); + } + this.doLayout(); + }, + + /** + * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the + * status that was set after a specified interval. + * @param {Object/String} config A config object specifying what status to set, or a string assumed + * to be the status text (and all other options are defaulted as explained below). A config + * object containing any or all of the following properties can be passed:
      + *
    • text {String} : (optional) The status text to display. If not specified, any current + * status text will remain unchanged.
    • + *
    • iconCls {String} : (optional) The CSS class used to customize the status icon (see + * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.
    • + *
    • clear {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will + * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not + * specified, the new status will not be auto-cleared and will stay until updated again or cleared using + * {@link #clearStatus}. If true is passed, the status will be cleared using {@link #autoClear}, + * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed, + * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value. + * All other options will be defaulted as with the boolean option. To customize any other options, + * you can pass an object in the format:
        + *
      • wait {Number} : (optional) The number of milliseconds to wait before clearing + * (defaults to {@link #autoClear}).
      • + *
      • anim {Number} : (optional) False to clear the status immediately once the callback + * executes (defaults to true which fades the status out).
      • + *
      • useDefaults {Number} : (optional) False to completely clear the status text and iconCls + * (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).
      • + *
    + * Example usage:
    
    +// Simple call to update the text
    +statusBar.setStatus('New status');
    +
    +// Set the status and icon, auto-clearing with default options:
    +statusBar.setStatus({
    +    text: 'New status',
    +    iconCls: 'x-status-custom',
    +    clear: true
    +});
    +
    +// Auto-clear with custom options:
    +statusBar.setStatus({
    +    text: 'New status',
    +    iconCls: 'x-status-custom',
    +    clear: {
    +        wait: 8000,
    +        anim: false,
    +        useDefaults: false
    +    }
    +});
    +
    + * @return {Ext.ux.StatusBar} this + */ + setStatus: function (o) { + o = o || {}; + + if (typeof o == 'string') { + o = { text: o }; + } + if (o.text !== undefined) { + this.setText(o.text); + } + if (o.iconCls !== undefined) { + this.setIcon(o.iconCls); + } + + if (o.clear) { + var c = o.clear, + wait = this.autoClear, + defaults = { useDefaults: true, anim: true }; + + if (typeof c == 'object') { + c = Ext.applyIf(c, defaults); + if (c.wait) { + wait = c.wait; + } + } else if (typeof c == 'number') { + wait = c; + c = defaults; + } else if (typeof c == 'boolean') { + c = defaults; + } + + c.threadId = this.activeThreadId; + this.clearStatus.defer(wait, this, [c]); + } + return this; + }, + + /** + * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation. + * @param {Object} config (optional) A config object containing any or all of the following properties. If this + * object is not specified the status will be cleared using the defaults below:
      + *
    • anim {Boolean} : (optional) True to clear the status by fading out the status element (defaults + * to false which clears immediately).
    • + *
    • useDefaults {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and + * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).
    • + *
    + * @return {Ext.ux.StatusBar} this + */ + clearStatus: function (o) { + o = o || {}; + + if (o.threadId && o.threadId !== this.activeThreadId) { + // this means the current call was made internally, but a newer + // thread has set a message since this call was deferred. Since + // we don't want to overwrite a newer message just ignore. + return this; + } + + var text = o.useDefaults ? this.defaultText : this.emptyText, + iconCls = o.useDefaults + ? this.defaultIconCls + ? this.defaultIconCls + : '' + : ''; + + if (o.anim) { + // animate the statusEl Ext.Element + this.statusEl.el.fadeOut({ + remove: false, + useDisplay: true, + scope: this, + callback: function () { + this.setStatus({ + text: text, + iconCls: iconCls, + }); + + this.statusEl.el.show(); + }, + }); + } else { + // hide/show the el to avoid jumpy text or icon + this.statusEl.hide(); + this.setStatus({ + text: text, + iconCls: iconCls, + }); + this.statusEl.show(); + } + return this; + }, + + /** + * Convenience method for setting the status text directly. For more flexible options see {@link #setStatus}. + * @param {String} text (optional) The text to set (defaults to '') + * @return {Ext.ux.StatusBar} this + */ + setText: function (text) { + this.activeThreadId++; + this.text = text || ''; + if (this.rendered) { + this.statusEl.setText(this.text); + } + return this; + }, + + /** + * Returns the current status text. + * @return {String} The status text + */ + getText: function () { + return this.text; + }, + + /** + * Convenience method for setting the status icon directly. For more flexible options see {@link #setStatus}. + * See {@link #iconCls} for complete details about customizing the icon. + * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed) + * @return {Ext.ux.StatusBar} this + */ + setIcon: function (cls) { + this.activeThreadId++; + cls = cls || ''; + + if (this.rendered) { + if (this.currIconCls) { + this.statusEl.removeClass(this.currIconCls); + this.currIconCls = null; + } + if (cls.length > 0) { + this.statusEl.addClass(cls); + this.currIconCls = cls; + } + } else { + this.currIconCls = cls; + } + return this; + }, + + /** + * Convenience method for setting the status text and icon to special values that are pre-configured to indicate + * a "busy" state, usually for loading or processing activities. + * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a + * string to use as the status text (in which case all other options for setStatus will be defaulted). Use the + * text and/or iconCls properties on the config to override the default {@link #busyText} + * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and + * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}. + * @return {Ext.ux.StatusBar} this + */ + showBusy: function (o) { + if (typeof o == 'string') { + o = { text: o }; + } + o = Ext.applyIf(o || {}, { + text: this.busyText, + iconCls: this.busyIconCls, + }); + return this.setStatus(o); + }, +}); +Ext.reg('statusbar', Ext.ux.StatusBar); diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js b/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js new file mode 100644 index 0000000..3ab2347 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js @@ -0,0 +1,208 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +Ext.ns('Ext.ux.form'); + +/** + * @class Ext.ux.form.FileUploadField + * @extends Ext.form.TextField + * Creates a file upload field. + * @xtype fileuploadfield + */ +Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField, { + /** + * @cfg {String} buttonText The button text to display on the upload button (defaults to + * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text + * value will be used instead if available. + */ + buttonText: 'Browse...', + /** + * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible + * text field (defaults to false). If true, all inherited TextField members will still be available. + */ + buttonOnly: false, + /** + * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field + * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false. + */ + buttonOffset: 3, + + /** + * @cfg {Boolean} multiple True to select more than one file. (defaults to false). + * Note that this only applies if the HTML doc is using HTML5. + */ + multiple: false, + + /** + * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object. + */ + + // private + readOnly: true, + + /** + * @hide + * @method autoSize + */ + autoSize: Ext.emptyFn, + + // private + initComponent: function () { + Ext.ux.form.FileUploadField.superclass.initComponent.call(this); + + this.addEvents( + /** + * @event fileselected + * Fires when the underlying file input field's value has changed from the user + * selecting a new file from the system file selection dialog. + * @param {Ext.ux.form.FileUploadField} this + * @param {String} value The file value returned by the underlying file input field + */ + 'fileselected' + ); + }, + + // private + onRender: function (ct, position) { + Ext.ux.form.FileUploadField.superclass.onRender.call( + this, + ct, + position + ); + + this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' }); + this.el.addClass('x-form-file-text'); + this.el.dom.removeAttribute('name'); + this.createFileInput(); + + var btnCfg = Ext.applyIf(this.buttonCfg || {}, { + text: this.buttonText, + }); + this.button = new Ext.Button( + Ext.apply(btnCfg, { + renderTo: this.wrap, + cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : ''), + }) + ); + + if (this.buttonOnly) { + this.el.hide(); + this.wrap.setWidth(this.button.getEl().getWidth()); + } + + this.bindListeners(); + this.resizeEl = this.positionEl = this.wrap; + }, + + bindListeners: function () { + this.fileInput.on({ + scope: this, + mouseenter: function () { + this.button.addClass(['x-btn-over', 'x-btn-focus']); + }, + mouseleave: function () { + this.button.removeClass([ + 'x-btn-over', + 'x-btn-focus', + 'x-btn-click', + ]); + }, + mousedown: function () { + this.button.addClass('x-btn-click'); + }, + mouseup: function () { + this.button.removeClass([ + 'x-btn-over', + 'x-btn-focus', + 'x-btn-click', + ]); + }, + change: function () { + var value = this.fileInput.dom.files; + // Fallback to value. + if (!value) value = this.fileInput.dom.value; + this.setValue(value); + this.fireEvent('fileselected', this, value); + }, + }); + }, + + createFileInput: function () { + this.fileInput = this.wrap.createChild({ + id: this.getFileInputId(), + name: this.name || this.getId(), + cls: 'x-form-file', + tag: 'input', + type: 'file', + size: 1, + }); + this.fileInput.dom.multiple = this.multiple; + }, + + reset: function () { + if (this.rendered) { + this.fileInput.remove(); + this.createFileInput(); + this.bindListeners(); + } + Ext.ux.form.FileUploadField.superclass.reset.call(this); + }, + + // private + getFileInputId: function () { + return this.id + '-file'; + }, + + // private + onResize: function (w, h) { + Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h); + + this.wrap.setWidth(w); + + if (!this.buttonOnly) { + var w = + this.wrap.getWidth() - + this.button.getEl().getWidth() - + this.buttonOffset; + this.el.setWidth(w); + } + }, + + // private + onDestroy: function () { + Ext.ux.form.FileUploadField.superclass.onDestroy.call(this); + Ext.destroy(this.fileInput, this.button, this.wrap); + }, + + onDisable: function () { + Ext.ux.form.FileUploadField.superclass.onDisable.call(this); + this.doDisable(true); + }, + + onEnable: function () { + Ext.ux.form.FileUploadField.superclass.onEnable.call(this); + this.doDisable(false); + }, + + // private + doDisable: function (disabled) { + this.fileInput.dom.disabled = disabled; + this.button.setDisabled(disabled); + }, + + // private + preFocus: Ext.emptyFn, + + // private + alignErrorIcon: function () { + this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); + }, +}); + +Ext.reg('fileuploadfield', Ext.ux.form.FileUploadField); + +// backwards compat +Ext.form.FileUploadField = Ext.ux.form.FileUploadField; diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js b/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js new file mode 100644 index 0000000..416c098 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js @@ -0,0 +1,50 @@ +/** + * Ext.ux.form.RadioGroup.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +// Allow radiogroups to be treated as a single form element. +Ext.override(Ext.form.RadioGroup, { + afterRender: function () { + this.items.each(function (i) { + this.relayEvents(i, ['check']); + }, this); + if (this.lazyValue) { + this.setValue(this.value); + delete this.value; + delete this.lazyValue; + } + Ext.form.RadioGroup.superclass.afterRender.call(this); + }, + + getName: function () { + return this.items.first().getName(); + }, + + getValue: function () { + return this.items.first().getGroupValue(); + }, + + setValue: function (v) { + if (!this.items.each) { + this.value = v; + this.lazyValue = true; + return; + } + this.items.each(function (item) { + if (item.rendered) { + var checked = item.el.getValue() == String(v); + item.el.dom.checked = checked; + item.el.dom.defaultChecked = checked; + item.wrap[checked ? 'addClass' : 'removeClass']( + item.checkedCls + ); + } + }); + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js new file mode 100644 index 0000000..890fb5b --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js @@ -0,0 +1,68 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +Ext.ns('Ext.ux.form'); + +/** + * @class Ext.ux.form.SpinnerField + * @extends Ext.form.NumberField + * Creates a field utilizing Ext.ux.Spinner + * @xtype spinnerfield + */ +Ext.ux.form.SpinnerField = Ext.extend(Ext.form.NumberField, { + actionMode: 'wrap', + deferHeight: true, + autoSize: Ext.emptyFn, + onBlur: Ext.emptyFn, + adjustSize: Ext.BoxComponent.prototype.adjustSize, + + constructor: function (config) { + var spinnerConfig = Ext.copyTo( + {}, + config, + 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass' + ); + + var spl = (this.spinner = new Ext.ux.Spinner(spinnerConfig)); + + var plugins = config.plugins + ? Ext.isArray(config.plugins) + ? config.plugins.push(spl) + : [config.plugins, spl] + : spl; + + Ext.ux.form.SpinnerField.superclass.constructor.call( + this, + Ext.apply(config, { plugins: plugins }) + ); + }, + + // private + getResizeEl: function () { + return this.wrap; + }, + + // private + getPositionEl: function () { + return this.wrap; + }, + + // private + alignErrorIcon: function () { + if (this.wrap) { + this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); + } + }, + + validateBlur: function () { + return true; + }, +}); + +Ext.reg('spinnerfield', Ext.ux.form.SpinnerField); + +//backwards compat +Ext.form.SpinnerField = Ext.ux.form.SpinnerField; diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js new file mode 100644 index 0000000..6784ae0 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js @@ -0,0 +1,13 @@ +/** + * Ext.ux.form.SpinnerField.js + * + * Copyright (c) Damien Churchill 2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.override(Ext.ux.form.SpinnerField, { + onBlur: Ext.form.Field.prototype.onBlur, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js new file mode 100644 index 0000000..ee761aa --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js @@ -0,0 +1,205 @@ +/** + * Ext.ux.form.SpinnerGroup.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.ns('Ext.ux.form'); + +/** + * + */ +Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, { + // private + defaultType: 'spinnerfield', + anchor: '98%', + + // private + groupCls: 'x-form-spinner-group', + + colCfg: {}, + + // private + onRender: function (ct, position) { + if (!this.el) { + var panelCfg = { + cls: this.groupCls, + layout: 'column', + border: false, + renderTo: ct, + }; + var colCfg = Ext.apply( + { + defaultType: this.defaultType, + layout: 'form', + border: false, + labelWidth: 60, + defaults: { + hideLabel: true, + anchor: '60%', + }, + }, + this.colCfg + ); + + if (this.items[0].items) { + // The container has standard ColumnLayout configs, so pass them in directly + + Ext.apply(panelCfg, { + layoutConfig: { columns: this.items.length }, + defaults: this.defaults, + items: this.items, + }); + for (var i = 0, len = this.items.length; i < len; i++) { + Ext.applyIf(this.items[i], colCfg); + } + } else { + // The container has field item configs, so we have to generate the column + // panels first then move the items into the columns as needed. + + var numCols, + cols = []; + + if (typeof this.columns == 'string') { + // 'auto' so create a col per item + this.columns = this.items.length; + } + if (!Ext.isArray(this.columns)) { + var cs = []; + for (var i = 0; i < this.columns; i++) { + cs.push((100 / this.columns) * 0.01); // distribute by even % + } + this.columns = cs; + } + + numCols = this.columns.length; + + // Generate the column configs with the correct width setting + for (var i = 0; i < numCols; i++) { + var cc = Ext.apply({ items: [] }, colCfg); + cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = + this.columns[i]; + if (this.defaults) { + cc.defaults = Ext.apply( + cc.defaults || {}, + this.defaults + ); + } + cols.push(cc); + } + + // Distribute the original items into the columns + if (this.vertical) { + var rows = Math.ceil(this.items.length / numCols), + ri = 0; + for (var i = 0, len = this.items.length; i < len; i++) { + if (i > 0 && i % rows == 0) { + ri++; + } + if (this.items[i].fieldLabel) { + this.items[i].hideLabel = false; + } + cols[ri].items.push(this.items[i]); + } + } else { + for (var i = 0, len = this.items.length; i < len; i++) { + var ci = i % numCols; + if (this.items[i].fieldLabel) { + this.items[i].hideLabel = false; + } + cols[ci].items.push(this.items[i]); + } + } + + Ext.apply(panelCfg, { + layoutConfig: { columns: numCols }, + items: cols, + }); + } + + this.panel = new Ext.Panel(panelCfg); + this.el = this.panel.getEl(); + + if (this.forId && this.itemCls) { + var l = this.el.up(this.itemCls).child('label', true); + if (l) { + l.setAttribute('htmlFor', this.forId); + } + } + + var fields = this.panel.findBy(function (c) { + return c.isFormField; + }, this); + + this.items = new Ext.util.MixedCollection(); + this.items.addAll(fields); + + this.items.each(function (field) { + field.on('spin', this.onFieldChange, this); + field.on('change', this.onFieldChange, this); + }, this); + + if (this.lazyValueSet) { + this.setValue(this.value); + delete this.value; + delete this.lazyValueSet; + } + + if (this.lazyRawValueSet) { + this.setRawValue(this.rawValue); + delete this.rawValue; + delete this.lazyRawValueSet; + } + } + + Ext.ux.form.SpinnerGroup.superclass.onRender.call(this, ct, position); + }, + + onFieldChange: function (spinner) { + this.fireEvent('change', this, this.getValue()); + }, + + initValue: Ext.emptyFn, + + getValue: function () { + var value = [this.items.getCount()]; + this.items.each(function (item, i) { + value[i] = Number(item.getValue()); + }); + return value; + }, + + getRawValue: function () { + var value = [this.items.getCount()]; + this.items.each(function (item, i) { + value[i] = Number(item.getRawValue()); + }); + return value; + }, + + setValue: function (value) { + if (!this.rendered) { + this.value = value; + this.lazyValueSet = true; + } else { + this.items.each(function (item, i) { + item.setValue(value[i]); + }); + } + }, + + setRawValue: function (value) { + if (!this.rendered) { + this.rawValue = value; + this.lazyRawValueSet = true; + } else { + this.items.each(function (item, i) { + item.setRawValue(value[i]); + }); + } + }, +}); +Ext.reg('spinnergroup', Ext.ux.form.SpinnerGroup); diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js b/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js new file mode 100644 index 0000000..eb60c3b --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js @@ -0,0 +1,72 @@ +/** + * Ext.ux.form.ToggleField.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ +Ext.namespace('Ext.ux.form'); + +/** + * Ext.ux.form.ToggleField class + * + * @author Damien Churchill + * @version v0.1 + * + * @class Ext.ux.form.ToggleField + * @extends Ext.form.TriggerField + */ +Ext.ux.form.ToggleField = Ext.extend(Ext.form.Field, { + cls: 'x-toggle-field', + + initComponent: function () { + Ext.ux.form.ToggleField.superclass.initComponent.call(this); + + this.toggle = new Ext.form.Checkbox(); + this.toggle.on('check', this.onToggleCheck, this); + + this.input = new Ext.form.TextField({ + disabled: true, + }); + }, + + onRender: function (ct, position) { + if (!this.el) { + this.panel = new Ext.Panel({ + cls: this.groupCls, + layout: 'table', + layoutConfig: { + columns: 2, + }, + border: false, + renderTo: ct, + }); + this.panel.ownerCt = this; + this.el = this.panel.getEl(); + + this.panel.add(this.toggle); + this.panel.add(this.input); + this.panel.doLayout(); + + this.toggle.getEl().parent().setStyle('padding-right', '10px'); + } + Ext.ux.form.ToggleField.superclass.onRender.call(this, ct, position); + }, + + // private + onResize: function (w, h) { + this.panel.setSize(w, h); + this.panel.doLayout(); + + // we substract 10 for the padding :-) + var inputWidth = w - this.toggle.getSize().width - 25; + this.input.setSize(inputWidth, h); + }, + + onToggleCheck: function (toggle, checked) { + this.input.setDisabled(!checked); + }, +}); +Ext.reg('togglefield', Ext.ux.form.ToggleField); diff --git a/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js b/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js new file mode 100644 index 0000000..0fce3b4 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js @@ -0,0 +1,270 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +Ext.ns('Ext.ux.grid'); + +/** + * @class Ext.ux.grid.BufferView + * @extends Ext.grid.GridView + * A custom GridView which renders rows on an as-needed basis. + */ +Ext.ux.grid.BufferView = Ext.extend(Ext.grid.GridView, { + /** + * @cfg {Number} rowHeight + * The height of a row in the grid. + */ + rowHeight: 19, + + /** + * @cfg {Number} borderHeight + * The combined height of border-top and border-bottom of a row. + */ + borderHeight: 2, + + /** + * @cfg {Boolean/Number} scrollDelay + * The number of milliseconds before rendering rows out of the visible + * viewing area. Defaults to 100. Rows will render immediately with a config + * of false. + */ + scrollDelay: 100, + + /** + * @cfg {Number} cacheSize + * The number of rows to look forward and backwards from the currently viewable + * area. The cache applies only to rows that have been rendered already. + */ + cacheSize: 20, + + /** + * @cfg {Number} cleanDelay + * The number of milliseconds to buffer cleaning of extra rows not in the + * cache. + */ + cleanDelay: 500, + + initTemplates: function () { + Ext.ux.grid.BufferView.superclass.initTemplates.call(this); + var ts = this.templates; + // empty div to act as a place holder for a row + ts.rowHolder = new Ext.Template( + '
    ' + ); + ts.rowHolder.disableFormats = true; + ts.rowHolder.compile(); + + ts.rowBody = new Ext.Template( + '', + '{cells}', + this.enableRowBody + ? '' + : '', + '
    {body}
    ' + ); + ts.rowBody.disableFormats = true; + ts.rowBody.compile(); + }, + + getStyleRowHeight: function () { + return Ext.isBorderBox + ? this.rowHeight + this.borderHeight + : this.rowHeight; + }, + + getCalculatedRowHeight: function () { + return this.rowHeight + this.borderHeight; + }, + + getVisibleRowCount: function () { + var rh = this.getCalculatedRowHeight(), + visibleHeight = this.scroller.dom.clientHeight; + return visibleHeight < 1 ? 0 : Math.ceil(visibleHeight / rh); + }, + + getVisibleRows: function () { + var count = this.getVisibleRowCount(), + sc = this.scroller.dom.scrollTop, + start = + sc === 0 + ? 0 + : Math.floor(sc / this.getCalculatedRowHeight()) - 1; + return { + first: Math.max(start, 0), + last: Math.min(start + count + 2, this.ds.getCount() - 1), + }; + }, + + doRender: function (cs, rs, ds, startRow, colCount, stripe, onlyBody) { + var ts = this.templates, + ct = ts.cell, + rt = ts.row, + rb = ts.rowBody, + last = colCount - 1, + rh = this.getStyleRowHeight(), + vr = this.getVisibleRows(), + tstyle = 'width:' + this.getTotalWidth() + ';height:' + rh + 'px;', + // buffers + buf = [], + cb, + c, + p = {}, + rp = { tstyle: tstyle }, + r; + for (var j = 0, len = rs.length; j < len; j++) { + r = rs[j]; + cb = []; + var rowIndex = j + startRow, + visible = rowIndex >= vr.first && rowIndex <= vr.last; + if (visible) { + for (var i = 0; i < colCount; i++) { + c = cs[i]; + p.id = c.id; + p.css = + i === 0 + ? 'x-grid3-cell-first ' + : i == last + ? 'x-grid3-cell-last ' + : ''; + p.attr = p.cellAttr = ''; + p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds); + p.style = c.style; + if (p.value === undefined || p.value === '') { + p.value = ' '; + } + if (r.dirty && typeof r.modified[c.name] !== 'undefined') { + p.css += ' x-grid3-dirty-cell'; + } + cb[cb.length] = ct.apply(p); + } + } + var alt = []; + if (stripe && (rowIndex + 1) % 2 === 0) { + alt[0] = 'x-grid3-row-alt'; + } + if (r.dirty) { + alt[1] = ' x-grid3-dirty-row'; + } + rp.cols = colCount; + if (this.getRowClass) { + alt[2] = this.getRowClass(r, rowIndex, rp, ds); + } + rp.alt = alt.join(' '); + rp.cells = cb.join(''); + buf[buf.length] = !visible + ? ts.rowHolder.apply(rp) + : onlyBody + ? rb.apply(rp) + : rt.apply(rp); + } + return buf.join(''); + }, + + isRowRendered: function (index) { + var row = this.getRow(index); + return row && row.childNodes.length > 0; + }, + + syncScroll: function () { + Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments); + this.update(); + }, + + // a (optionally) buffered method to update contents of gridview + update: function () { + if (this.scrollDelay) { + if (!this.renderTask) { + this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this); + } + this.renderTask.delay(this.scrollDelay); + } else { + this.doUpdate(); + } + }, + + onRemove: function (ds, record, index, isUpdate) { + Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments); + if (isUpdate !== true) { + this.update(); + } + }, + + doUpdate: function () { + if (this.getVisibleRowCount() > 0) { + var g = this.grid, + cm = g.colModel, + ds = g.store, + cs = this.getColumnData(), + vr = this.getVisibleRows(), + row; + for (var i = vr.first; i <= vr.last; i++) { + // if row is NOT rendered and is visible, render it + if (!this.isRowRendered(i) && (row = this.getRow(i))) { + var html = this.doRender( + cs, + [ds.getAt(i)], + ds, + i, + cm.getColumnCount(), + g.stripeRows, + true + ); + row.innerHTML = html; + } + } + this.clean(); + } + }, + + // a buffered method to clean rows + clean: function () { + if (!this.cleanTask) { + this.cleanTask = new Ext.util.DelayedTask(this.doClean, this); + } + this.cleanTask.delay(this.cleanDelay); + }, + + doClean: function () { + if (this.getVisibleRowCount() > 0) { + var vr = this.getVisibleRows(); + vr.first -= this.cacheSize; + vr.last += this.cacheSize; + + var i = 0, + rows = this.getRows(); + // if first is less than 0, all rows have been rendered + // so lets clean the end... + if (vr.first <= 0) { + i = vr.last + 1; + } + for (var len = this.ds.getCount(); i < len; i++) { + // if current row is outside of first and last and + // has content, update the innerHTML to nothing + if ((i < vr.first || i > vr.last) && rows[i].innerHTML) { + rows[i].innerHTML = ''; + } + } + } + }, + + removeTask: function (name) { + var task = this[name]; + if (task && task.cancel) { + task.cancel(); + this[name] = null; + } + }, + + destroy: function () { + this.removeTask('cleanTask'); + this.removeTask('renderTask'); + Ext.ux.grid.BufferView.superclass.destroy.call(this); + }, + + layout: function () { + Ext.ux.grid.BufferView.superclass.layout.call(this); + this.update(); + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js b/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js new file mode 100644 index 0000000..3ccce2b --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js @@ -0,0 +1,39 @@ +/** + * Ext.ux.layout.FormLayoutFix.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +// Taken from http://extjs.com/forum/showthread.php?t=75273 +// remove spaces for hidden elements and make show(), hide(), enable() and disable() act on +// the label. don't use hideLabel with this. +Ext.override(Ext.layout.FormLayout, { + renderItem: function (c, position, target) { + if ( + c && + !c.rendered && + (c.isFormField || c.fieldLabel) && + c.inputType != 'hidden' + ) { + var args = this.getTemplateArgs(c); + if (typeof position == 'number') { + position = target.dom.childNodes[position] || null; + } + if (position) { + c.formItem = this.fieldTpl.insertBefore(position, args, true); + } else { + c.formItem = this.fieldTpl.append(target, args, true); + } + c.actionMode = 'formItem'; + c.render('x-form-el-' + c.id); + c.container = c.formItem; + c.actionMode = 'container'; + } else { + Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments); + } + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js b/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js new file mode 100644 index 0000000..ba26a72 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js @@ -0,0 +1,68 @@ +/** + * Ext.ux.tree.MultiSelectionModelFix.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +/** + * This enhances the MSM to allow for shift selecting in tree grids etc. + * @author Damien Churchill + */ +Ext.override(Ext.tree.MultiSelectionModel, { + onNodeClick: function (node, e) { + if (e.ctrlKey && this.isSelected(node)) { + this.unselect(node); + } else if (e.shiftKey && !this.isSelected(node)) { + var parentNode = node.parentNode; + // We can only shift select files in the same node + if (this.lastSelNode.parentNode.id != parentNode.id) return; + + // Get the node indexes + var fi = parentNode.indexOf(node), + li = parentNode.indexOf(this.lastSelNode); + + // Select the last clicked node and wipe old selections + this.select(this.lastSelNode, e, false, true); + + // Swap the values if required + if (fi > li) { + (fi = fi + li), (li = fi - li), (fi = fi - li); + } + + // Select all the nodes + parentNode.eachChild(function (n) { + var i = parentNode.indexOf(n); + if (fi < i && i < li) { + this.select(n, e, true, true); + } + }, this); + + // Select the clicked node + this.select(node, e, true); + } else { + this.select(node, e, e.ctrlKey); + } + }, + + select: function (node, e, keepExisting, suppressEvent) { + if (keepExisting !== true) { + this.clearSelections(true); + } + if (this.isSelected(node)) { + this.lastSelNode = node; + return node; + } + this.selNodes.push(node); + this.selMap[node.id] = node; + this.lastSelNode = node; + node.ui.onSelectedChange(true); + if (suppressEvent !== true) { + this.fireEvent('selectionchange', this, this.selNodes); + } + return node; + }, +}); 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..7a74360 --- /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( + '
    ', + '
    ', + '
    ', + '', + '', + '', + '', + '', + '
    ', + '
    ', + this.enableHdMenu + ? '' + : '', + '{header}', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ); + } + + if (!this.colgroupTpl) { + this.colgroupTpl = new Ext.XTemplate( + '' + ); + } + }, + + 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); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js new file mode 100644 index 0000000..de73608 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js @@ -0,0 +1,123 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/** + * @class Ext.tree.ColumnResizer + * @extends Ext.util.Observable + */ +Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, { + /** + * @cfg {Number} minWidth The minimum width the column can be dragged to. + * Defaults to 14. + */ + minWidth: 14, + + constructor: function (config) { + Ext.apply(this, config); + Ext.tree.ColumnResizer.superclass.constructor.call(this); + }, + + init: function (tree) { + this.tree = tree; + tree.on('render', this.initEvents, this); + }, + + initEvents: function (tree) { + tree.mon(tree.innerHd, 'mousemove', this.handleHdMove, this); + this.tracker = new Ext.dd.DragTracker({ + onBeforeStart: this.onBeforeStart.createDelegate(this), + onStart: this.onStart.createDelegate(this), + onDrag: this.onDrag.createDelegate(this), + onEnd: this.onEnd.createDelegate(this), + tolerance: 3, + autoStart: 300, + }); + this.tracker.initEl(tree.innerHd); + tree.on('beforedestroy', this.tracker.destroy, this.tracker); + }, + + handleHdMove: function (e, t) { + var hw = 5, + x = e.getPageX(), + hd = e.getTarget('.x-treegrid-hd', 3, true); + + if (hd) { + var r = hd.getRegion(), + ss = hd.dom.style, + pn = hd.dom.parentNode; + + if (x - r.left <= hw && hd.dom !== pn.firstChild) { + var ps = hd.dom.previousSibling; + while (ps && Ext.fly(ps).hasClass('x-treegrid-hd-hidden')) { + ps = ps.previousSibling; + } + if (ps) { + this.activeHd = Ext.get(ps); + ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize'; + } + } else if (r.right - x <= hw) { + var ns = hd.dom; + while (ns && Ext.fly(ns).hasClass('x-treegrid-hd-hidden')) { + ns = ns.previousSibling; + } + if (ns) { + this.activeHd = Ext.get(ns); + ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize'; + } + } else { + delete this.activeHd; + ss.cursor = ''; + } + } + }, + + onBeforeStart: function (e) { + this.dragHd = this.activeHd; + return !!this.dragHd; + }, + + onStart: function (e) { + this.dragHeadersDisabled = this.tree.headersDisabled; + this.tree.headersDisabled = true; + this.proxy = this.tree.body.createChild({ cls: 'x-treegrid-resizer' }); + this.proxy.setHeight(this.tree.body.getHeight()); + + var x = this.tracker.getXY()[0]; + + this.hdX = this.dragHd.getX(); + this.hdIndex = this.tree.findHeaderIndex(this.dragHd); + + this.proxy.setX(this.hdX); + this.proxy.setWidth(x - this.hdX); + + this.maxWidth = + this.tree.outerCt.getWidth() - + this.tree.innerBody.translatePoints(this.hdX).left; + }, + + onDrag: function (e) { + var cursorX = this.tracker.getXY()[0]; + this.proxy.setWidth( + (cursorX - this.hdX).constrain(this.minWidth, this.maxWidth) + ); + }, + + onEnd: function (e) { + var nw = this.proxy.getWidth(), + tree = this.tree, + disabled = this.dragHeadersDisabled; + + this.proxy.remove(); + delete this.dragHd; + + tree.columns[this.hdIndex].width = nw; + tree.updateColumnWidths(); + + setTimeout(function () { + tree.headersDisabled = disabled; + }, 100); + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js new file mode 100644 index 0000000..0c88f17 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js @@ -0,0 +1,40 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +(function () { + Ext.override(Ext.list.Column, { + init: function () { + var types = Ext.data.Types, + st = this.sortType; + + if (this.type) { + if (Ext.isString(this.type)) { + this.type = + Ext.data.Types[this.type.toUpperCase()] || types.AUTO; + } + } else { + this.type = types.AUTO; + } + + // named sortTypes are supported, here we look them up + if (Ext.isString(st)) { + this.sortType = Ext.data.SortTypes[st]; + } else if (Ext.isEmpty(st)) { + this.sortType = this.type.sortType; + } + }, + }); + + Ext.tree.Column = Ext.extend(Ext.list.Column, {}); + Ext.tree.NumberColumn = Ext.extend(Ext.list.NumberColumn, {}); + Ext.tree.DateColumn = Ext.extend(Ext.list.DateColumn, {}); + Ext.tree.BooleanColumn = Ext.extend(Ext.list.BooleanColumn, {}); + + Ext.reg('tgcolumn', Ext.tree.Column); + Ext.reg('tgnumbercolumn', Ext.tree.NumberColumn); + Ext.reg('tgdatecolumn', Ext.tree.DateColumn); + Ext.reg('tgbooleancolumn', Ext.tree.BooleanColumn); +})(); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js new file mode 100644 index 0000000..db14848 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js @@ -0,0 +1,18 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/** + * @class Ext.ux.tree.TreeGridLoader + * @extends Ext.tree.TreeLoader + */ +Ext.ux.tree.TreeGridLoader = Ext.extend(Ext.tree.TreeLoader, { + createNode: function (attr) { + if (!attr.uiProvider) { + attr.uiProvider = Ext.ux.tree.TreeGridNodeUI; + } + return Ext.tree.TreeLoader.prototype.createNode.call(this, attr); + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js new file mode 100644 index 0000000..09b1718 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js @@ -0,0 +1,149 @@ +/** + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/** + * @class Ext.ux.tree.TreeGridNodeUI + * @extends Ext.tree.TreeNodeUI + */ +Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { + isTreeGridNodeUI: true, + + renderElements: function (n, a, targetNode, bulkRender) { + var t = n.getOwnerTree(), + cols = t.columns, + c = cols[0], + i, + buf, + len; + + this.indentMarkup = n.parentNode + ? n.parentNode.ui.getChildIndent() + : ''; + + buf = [ + '', + '', + '', + '', + this.indentMarkup, + '', + '', + '', + '', + '', + c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text, + '', + '', + ]; + + for (i = 1, len = cols.length; i < len; i++) { + c = cols[i]; + buf.push( + '', + '
    ', + c.tpl ? c.tpl.apply(a) : a[c.dataIndex], + '
    ', + '' + ); + } + + buf.push( + '', + '' + ); + for (i = 0, len = cols.length; i < len; i++) { + buf.push( + '' + ); + } + buf.push(''); + + if (bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()) { + this.wrap = Ext.DomHelper.insertHtml( + 'beforeBegin', + n.nextSibling.ui.getEl(), + buf.join('') + ); + } else { + this.wrap = Ext.DomHelper.insertHtml( + 'beforeEnd', + targetNode, + buf.join('') + ); + } + + this.elNode = this.wrap.childNodes[0]; + this.ctNode = this.wrap.childNodes[1].firstChild.firstChild; + var cs = this.elNode.firstChild.childNodes; + this.indentNode = cs[0]; + this.ecNode = cs[1]; + this.iconNode = cs[2]; + this.anchor = cs[3]; + this.textNode = cs[3].firstChild; + }, + + // private + animExpand: function (cb) { + this.ctNode.style.display = ''; + Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb); + }, +}); + +Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { + isTreeGridNodeUI: true, + + // private + render: function () { + if (!this.rendered) { + this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom; + this.node.expanded = true; + } + + if (Ext.isWebKit) { + // weird table-layout: fixed issue in webkit + var ct = this.ctNode; + ct.style.tableLayout = null; + (function () { + ct.style.tableLayout = 'fixed'; + }.defer(1)); + } + }, + + destroy: function () { + if (this.elNode) { + Ext.dd.Registry.unregister(this.elNode.id); + } + delete this.node; + }, + + collapse: Ext.emptyFn, + expand: Ext.emptyFn, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js new file mode 100644 index 0000000..7708bd7 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js @@ -0,0 +1,33 @@ +/** + * Ext.ux.tree.TreeGridNodeUIFix.js + * + * Copyright (c) Damien Churchill 2009-2010 + * + * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with + * the additional special exception to link portions of this program with the OpenSSL library. + * See LICENSE for more details. + */ + +Ext.override(Ext.ux.tree.TreeGridNodeUI, { + updateColumns: function () { + if (!this.rendered) return; + + var a = this.node.attributes, + t = this.node.getOwnerTree(), + cols = t.columns, + c = cols[0]; + + // Update the first column + this.anchor.firstChild.innerHTML = c.tpl + ? c.tpl.apply(a) + : a[c.dataIndex] || c.text; + + // Update the remaining columns + for (i = 1, len = cols.length; i < len; i++) { + c = cols[i]; + this.elNode.childNodes[i].firstChild.innerHTML = c.tpl + ? c.tpl.apply(a) + : a[c.dataIndex] || c.text; + } + }, +}); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js new file mode 100644 index 0000000..ed95d95 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js @@ -0,0 +1,9 @@ +Ext.tree.RenderColumn = Ext.extend(Ext.tree.Column, { + constructor: function (c) { + c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}'); + c.tpl.format = c.renderer; + c.tpl.col = this; + Ext.tree.RenderColumn.superclass.constructor.call(this, c); + }, +}); +Ext.reg('tgrendercolumn', Ext.tree.RenderColumn); diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js new file mode 100644 index 0000000..fdf1f38 --- /dev/null +++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js @@ -0,0 +1,158 @@ +/** + * 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.TreeGridSorter + * @extends Ext.tree.TreeSorter + * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}. The TreeGridSorter automatically monitors events on the + * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange). + * Example usage:
    + *
    
    + new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
    +     folderSort: true,
    +     dir: "desc",
    +     sortType: function(node) {
    +         // sort by a custom, typed attribute:
    +         return parseInt(node.id, 10);
    +     }
    + });
    + 
    + * @constructor + * @param {TreeGrid} tree + * @param {Object} config + */ +Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, { + /** + * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to ['sort-asc', 'sort-desc']) + */ + sortClasses: ['sort-asc', 'sort-desc'], + /** + * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to 'Sort Ascending') + */ + sortAscText: 'Sort Ascending', + /** + * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to 'Sort Descending') + */ + sortDescText: 'Sort Descending', + + constructor: function (tree, config) { + if (!Ext.isObject(config)) { + config = { + property: tree.columns[0].dataIndex || 'text', + folderSort: true, + }; + } + + Ext.ux.tree.TreeGridSorter.superclass.constructor.apply( + this, + arguments + ); + + this.tree = tree; + tree.on('headerclick', this.onHeaderClick, this); + tree.ddAppendOnly = true; + + var me = this; + this.defaultSortFn = function (n1, n2) { + var desc = me.dir && me.dir.toLowerCase() == 'desc', + prop = me.property || 'text', + sortType = me.sortType, + caseSensitive = me.caseSensitive === true, + leafAttr = me.leafAttr || 'leaf', + attr1 = n1.attributes, + attr2 = n2.attributes; + + if (me.folderSort) { + if (attr1[leafAttr] && !attr2[leafAttr]) { + return 1; + } + if (!attr1[leafAttr] && attr2[leafAttr]) { + return -1; + } + } + var prop1 = attr1[prop], + prop2 = attr2[prop], + v1 = sortType + ? sortType(prop1) + : caseSensitive + ? prop1 + : prop1.toUpperCase(); + v2 = sortType + ? sortType(prop2) + : caseSensitive + ? prop2 + : prop2.toUpperCase(); + + if (v1 < v2) { + return desc ? +1 : -1; + } else if (v1 > v2) { + return desc ? -1 : +1; + } else { + return 0; + } + }; + + tree.on('afterrender', this.onAfterTreeRender, this, { single: true }); + tree.on('headermenuclick', this.onHeaderMenuClick, this); + }, + + onAfterTreeRender: function () { + if (this.tree.hmenu) { + this.tree.hmenu.insert( + 0, + { + itemId: 'asc', + text: this.sortAscText, + cls: 'xg-hmenu-sort-asc', + }, + { + itemId: 'desc', + text: this.sortDescText, + cls: 'xg-hmenu-sort-desc', + } + ); + } + this.updateSortIcon(0, 'asc'); + }, + + onHeaderMenuClick: function (c, id, index) { + if (id === 'asc' || id === 'desc') { + this.onHeaderClick(c, null, index); + return false; + } + }, + + onHeaderClick: function (c, el, i) { + if (c && !this.tree.headersDisabled) { + var me = this; + + me.property = c.dataIndex; + me.dir = c.dir = c.dir === 'desc' ? 'asc' : 'desc'; + me.sortType = c.sortType; + me.caseSensitive === Ext.isBoolean(c.caseSensitive) + ? c.caseSensitive + : this.caseSensitive; + me.sortFn = c.sortFn || this.defaultSortFn; + + this.tree.root.cascade(function (n) { + if (!n.isLeaf()) { + me.updateSort(me.tree, n); + } + }); + + this.updateSortIcon(i, c.dir); + } + }, + + // private + updateSortIcon: function (col, dir) { + var sc = this.sortClasses, + hds = this.tree.innerHd.select('td').removeClass(sc); + hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]); + }, +}); -- cgit v1.2.3