1 /* 2 Script: 3 Deluge.OptionsManager.js 4 5 Copyright: 6 (C) Damien Churchill 2009 <damoxc@gmail.com> 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, write to: 19 The Free Software Foundation, Inc., 20 51 Franklin Street, Fifth Floor 21 Boston, MA 02110-1301, USA. 22 23 In addition, as a special exception, the copyright holders give 24 permission to link the code of portions of this program with the OpenSSL 25 library. 26 You must obey the GNU General Public License in all respects for all of 27 the code used other than OpenSSL. If you modify file(s) with this 28 exception, you may extend this exception to your version of the file(s), 29 but you are not obligated to do so. If you do not wish to do so, delete 30 this exception statement from your version. If you delete this exception 31 statement from all source files in the program, then also delete it here. 32 */ 33 34 /** 35 * @description A class that can be used to manage options throughout the ui. 36 * @namespace Deluge 37 * @class Deluge.OptionsManager 38 */ 39 Deluge.OptionsManager = Ext.extend(Ext.util.Observable, { 40 41 constructor: function(config) { 42 this.binds = {}; 43 this.changed = {}; 44 this.defaults = config['defaults'] || {}; 45 this.options = {}; 46 this.currentId = null; 47 48 this.addEvents({ 49 'add': true, 50 'changed': true, 51 'reset': true 52 }); 53 this.on('changed', this.onChange, this); 54 55 Deluge.OptionsManager.superclass.constructor.call(this); 56 }, 57 58 /** 59 * Add a set of default options and values to the options manager 60 * @param {String} id 61 * @param {Object} options The default options. 62 */ 63 addOptions: function(id, options) { 64 this.options[id] = options; 65 }, 66 67 /** 68 * Binds a form field to the specified option. 69 * @param {String} option 70 * @param {Ext.form.Field} field 71 */ 72 bind: function(option, field) { 73 this.binds[option] = field; 74 this.binds[field] = option; 75 76 switch (field.getXType()) { 77 case 'checkbox': 78 case 'radiogroup': 79 field.on('check', this.onFieldChange, this); 80 break; 81 case 'uxspinner': 82 field.on('spin', this.onFieldChange, this); 83 field.on('keypress', this.onFieldChange, this); 84 break; 85 default: 86 break; 87 } 88 }, 89 90 /** 91 * Changes bound fields to use the specified id. 92 * @param {String} id 93 */ 94 changeId: function(id) { 95 this.currentId = id; 96 for (var option in this.defaults) { 97 if (!this.binds[option]) continue; 98 this.binds[option].setValue(this.get(id, option)); 99 } 100 }, 101 102 /** 103 * Get the value for an option 104 * @param {String} id 105 * @param {String|Array} [option] A single option or an array of options to return. 106 * @returns {Object} the options value. 107 */ 108 get: function(id, option) { 109 if (!option) { 110 var values = {}; 111 for (var key in this.defaults) { 112 values[key] = this.get(id, key); 113 } 114 return values; 115 } else { 116 return (this.hasChanged(id, option)) ? this.changed[id][option] : this.getDefault(id, option); 117 } 118 }, 119 120 /** 121 * Returns the changed values. 122 * @param {String} id 123 * @returns {Object} the changed options 124 */ 125 getChanged: function(id) { 126 return (this.changed[id]) ? this.changed[id] : {}; 127 }, 128 129 /** 130 * Get the default value for an option. 131 * @param {String} id 132 * @param {String|Array} [option] A single option or an array of options to return. 133 * @returns {Object} the value of the option 134 */ 135 getDefault: function(id, option) { 136 return (this.hasOption(id, option)) ? this.options[id][option] : this.defaults[option]; 137 }, 138 139 /** 140 * Check to see if the option has been changed. 141 * @param {String} id 142 * @param {String} option 143 * @returns {Boolean} true if the option has been changed, else false. 144 */ 145 hasChanged: function(id, option) { 146 return (this.changed[id] && !Ext.isEmpty(this.changed[id][option])); 147 }, 148 149 /** 150 * Check to see if an id has had an option set to something other than the 151 * default value. 152 * @param {String} id 153 * @param {String} option 154 * @returns {Boolean} true if the id has an option, else false. 155 */ 156 hasOption: function(id, option) { 157 return (this.options[id] && !Ext.isEmpty(this.options[id][option])); 158 }, 159 160 /** 161 * Reset the options back to the default values for the specified id. 162 * @param {String} id 163 */ 164 reset: function(id) { 165 if (!this.changed[id]) return; 166 delete this.changed[id]; 167 }, 168 169 /** 170 * Sets the value of specified option for the passed in id. 171 * @param {String} id 172 * @param {String} option 173 * @param {Object} value The value for the option 174 */ 175 set: function(id, option, value) { 176 if (typeof value === undefined) { 177 for (var key in option) { 178 this.set(id, key, option[key]); 179 } 180 } else { 181 if (!this.options[id]) this.options[id] = {}; 182 this.options[id][option] = value; 183 } 184 }, 185 186 /** 187 * Update the value for the specified option and id. 188 * @param {String} id 189 * @param {String|Object} option or options to update 190 * @param {Object} [value]; 191 */ 192 update: function(id, option, value) { 193 if (typeof value === undefined) { 194 for (var key in option) { 195 this.update(id, key, option[key]); 196 } 197 } else { 198 if (!this.changed[id]) this.changed[id] = {}; 199 200 var oldValue = this.get(id, option); 201 if (oldValue == value) return; 202 203 var defaultValue = this.getDefault(id, option); 204 if (defaultValue == value) { 205 if (this.hasChanged(id, option)) delete this.changed[id][option]; 206 this.fireEvent('changed', id, option, value, oldValue); 207 return; 208 } 209 210 if (Ext.type(defaultValue) != Ext.type(value)) { 211 switch (Ext.type(defaultValue)) { 212 case 'string': 213 value = String(value); 214 break; 215 case 'number': 216 value = Number(value); 217 break; 218 case 'boolean': 219 value = Boolean(value); 220 break; 221 } 222 } 223 224 this.changed[id][option] = value; 225 this.fireEvent('changed', id, option, value, oldValue); 226 } 227 }, 228 229 /* Event Handlers */ 230 231 /** 232 * Stops a form fields value from being blocked by the change functions 233 * @param {Ext.form.Field} field 234 * @private 235 */ 236 onFieldChange: function(field) { 237 var option = this.binds[field]; 238 this.update(this.currentId, option, field.getValue()); 239 }, 240 241 onChange: function(id, option, newValue, oldValue) { 242 // If we don't have a bind there's nothing to do. 243 if (Ext.isEmpty(this.binds[option])) return; 244 245 // Set the form field to the new value. 246 this.binds[option].setValue(newValue); 247 } 248 }); 249