/** * 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 ); }, });