1 /* 2 Script: deluge-bars.js 3 Contains all objects and functions related to the statusbar, toolbar and 4 sidebar. 5 6 Copyright: 7 (C) Damien Churchill 2009 <damoxc@gmail.com> 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, write to: 20 The Free Software Foundation, Inc., 21 51 Franklin Street, Fifth Floor 22 Boston, MA 02110-1301, USA. 23 24 In addition, as a special exception, the copyright holders give 25 permission to link the code of portions of this program with the OpenSSL 26 library. 27 You must obey the GNU General Public License in all respects for all of 28 the code used other than OpenSSL. If you modify file(s) with this 29 exception, you may extend this exception to your version of the file(s), 30 but you are not obligated to do so. If you do not wish to do so, delete 31 this exception statement from your version. If you delete this exception 32 statement from all source files in the program, then also delete it here. 33 34 */ 35 36 // These are just so gen_gettext.py will pick up the strings 37 // _('State') 38 // _('Tracker Host') 39 40 (function() { 41 // Renderer for the items in the filter grids. 42 function filterRenderer(value, p, r) { 43 var lname = value.toLowerCase().replace('.', '_'); 44 45 var image = ''; 46 if (r.store.id == 'tracker_host') { 47 if (value != 'Error') { 48 image = String.format('url(/tracker/{0})', value); 49 } else { 50 lname = null; 51 } 52 } 53 if (image) { 54 return String.format('<div class="x-deluge-filter" style="background-image: {2};">{0} ({1})</div>', value, r.data['count'], image); 55 } else if (lname) { 56 return String.format('<div class="x-deluge-filter x-deluge-{2}">{0} ({1})</div>', value, r.data['count'], lname); 57 } else { 58 return String.format('<div class="x-deluge-filter">{0} ({1})</div>', value, r.data['count']); 59 } 60 } 61 62 Ext.deluge.Sidebar = Ext.extend(Ext.Panel, { 63 64 // private 65 panels: {}, 66 67 // private 68 selected: null, 69 70 constructor: function(config) { 71 config = Ext.apply({ 72 id: 'sidebar', 73 region: 'west', 74 cls: 'deluge-sidebar', 75 title: _('Filters'), 76 layout: 'accordion', 77 split: true, 78 width: 200, 79 minSize: 175, 80 collapsible: true, 81 margins: '5 0 0 5', 82 cmargins: '5 0 0 5' 83 }, config); 84 Ext.deluge.Sidebar.superclass.constructor.call(this, config); 85 }, 86 87 // private 88 initComponent: function() { 89 Ext.deluge.Sidebar.superclass.initComponent.call(this); 90 Deluge.Events.on("disconnect", this.onDisconnect, this); 91 }, 92 93 createFilter: function(filter, states) { 94 var store = new Ext.data.SimpleStore({ 95 id: filter, 96 fields: [ 97 {name: 'filter'}, 98 {name: 'count'} 99 ] 100 }); 101 102 var title = filter.replace('_', ' '); 103 var parts = title.split(' '); 104 title = ''; 105 Ext.each(parts, function(part) { 106 firstLetter = part.substring(0, 1); 107 firstLetter = firstLetter.toUpperCase(); 108 part = firstLetter + part.substring(1); 109 title += part + ' '; 110 }); 111 112 var panel = new Ext.grid.GridPanel({ 113 id: filter + '-panel', 114 store: store, 115 title: _(title), 116 columns: [ 117 {id: 'filter', sortable: false, renderer: filterRenderer, dataIndex: 'filter'} 118 ], 119 stripeRows: false, 120 selModel: new Ext.grid.RowSelectionModel({ 121 singleSelect: true, 122 listeners: { 123 'rowselect': {fn: this.onFilterSelect, scope: this} 124 } 125 }), 126 hideHeaders: true, 127 autoExpandColumn: 'filter', 128 deferredRender: false, 129 autoScroll: true 130 }); 131 132 if (Deluge.config['sidebar_show_zero'] == false) { 133 states = this.removeZero(states); 134 } 135 136 store.loadData(states); 137 this.add(panel); 138 139 this.doLayout(); 140 this.panels[filter] = panel; 141 142 if (!this.selected) { 143 panel.getSelectionModel().selectFirstRow(); 144 this.selected = { 145 row: 0, 146 filter: states[0][0], 147 panel: panel 148 } 149 } 150 }, 151 152 getFilters: function() { 153 var filters = {} 154 if (!this.selected) { 155 return filters; 156 } 157 if (!this.selected.filter || !this.selected.panel) { 158 return filters; 159 } 160 var filterType = this.selected.panel.store.id; 161 if (filterType == "state" && this.selected.filter == "All") { 162 return filters; 163 } 164 165 filters[filterType] = this.selected.filter; 166 return filters; 167 }, 168 169 // private 170 onDisconnect: function() { 171 Ext.each(Ext.getKeys(this.panels), function(filter) { 172 this.remove(filter + '-panel'); 173 }, this); 174 this.panels = {}; 175 this.selected = null; 176 }, 177 178 onFilterSelect: function(selModel, rowIndex, record) { 179 if (!this.selected) needsUpdate = true; 180 else if (this.selected.row != rowIndex) needsUpdate = true; 181 else needsUpdate = false; 182 this.selected = { 183 row: rowIndex, 184 filter: record.get('filter'), 185 panel: this.panels[record.store.id] 186 } 187 188 if (needsUpdate) Deluge.UI.update(); 189 }, 190 191 /** 192 * Remove the states with zero torrents in them. 193 */ 194 removeZero: function(states) { 195 var newStates = []; 196 Ext.each(states, function(state) { 197 if (state[1] > 0) { 198 newStates.push(state); 199 } 200 }); 201 return newStates; 202 }, 203 204 update: function(filters) { 205 for (var filter in filters) { 206 var states = filters[filter]; 207 if (Ext.getKeys(this.panels).indexOf(filter) > -1) { 208 this.updateFilter(filter, states); 209 } else { 210 this.createFilter(filter, states); 211 } 212 } 213 214 // Perform a cleanup of fitlers that aren't enabled any more 215 Ext.each(Ext.keys(this.panels), function(filter) { 216 if (Ext.keys(filters).indexOf(filter) == -1) { 217 // We need to remove the panel 218 this.panels[filter] 219 } 220 }); 221 }, 222 223 updateFilter: function(filter, states) { 224 if (Deluge.config['sidebar_show_zero'] == false) { 225 states = this.removeZero(states); 226 } 227 228 this.panels[filter].store.loadData(states); 229 if (this.selected && this.selected.panel == this.panels[filter]) { 230 this.panels[filter].getSelectionModel().selectRow(this.selected.row); 231 } 232 } 233 234 }); 235 Deluge.Sidebar = new Ext.deluge.Sidebar(); 236 })();