1 /* 2 Script: Deluge.Details.Files.js 3 The files tab displayed in the details panel. 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 (function() { 34 /* Renderers for the column tree */ 35 function fileProgressRenderer(value) { 36 var progress = value * 100; 37 return Deluge.progressBar(progress, this.width - 50, progress.toFixed(2) + '%', 0); 38 } 39 function priorityRenderer(value) { 40 return String.format('<div class="{0}">{1}</div>', FILE_PRIORITY_CSS[value], _(FILE_PRIORITY[value])); 41 } 42 43 Ext.deluge.details.FilesTab = Ext.extend(Ext.tree.ColumnTree, { 44 45 constructor: function(config) { 46 config = Ext.apply({ 47 title: _('Files'), 48 rootVisible: false, 49 autoScroll: true, 50 selModel: new Ext.tree.MultiSelectionModel(), 51 52 columns: [{ 53 header: _('Filename'), 54 width: 330, 55 dataIndex: 'filename' 56 }, { 57 header: _('Size'), 58 width: 150, 59 dataIndex: 'size', 60 renderer: fsize 61 }, { 62 header: _('Progress'), 63 width: 150, 64 dataIndex: 'progress', 65 renderer: fileProgressRenderer 66 }, { 67 header: _('Priority'), 68 width: 150, 69 dataIndex: 'priority', 70 renderer: priorityRenderer 71 }], 72 73 root: new Ext.tree.TreeNode({ 74 text: 'Files' 75 }) 76 }, config); 77 Ext.deluge.details.FilesTab.superclass.constructor.call(this, config); 78 }, 79 80 onRender: function(ct, position) { 81 Ext.deluge.details.FilesTab.superclass.onRender.call(this, ct, position); 82 Deluge.Menus.FilePriorities.on('itemclick', this.onItemClick, this); 83 this.on('contextmenu', this.onContextMenu, this); 84 this.sorter = new Ext.tree.TreeSorter(this, { 85 folderSort: true 86 }); 87 }, 88 89 clear: function() { 90 var root = this.getRootNode(); 91 if (!root.hasChildNodes()) return; 92 root.cascade(function(node) { 93 var parent = node.parentNode; 94 if (!parent) return; 95 if (!parent.ownerTree) return; 96 parent.removeChild(node); 97 }); 98 }, 99 100 update: function(torrentId) { 101 if (this.torrentId != torrentId) { 102 this.clear(); 103 this.torrentId = torrentId; 104 } 105 106 Deluge.Client.web.get_torrent_files(torrentId, { 107 success: this.onRequestComplete, 108 scope: this, 109 torrentId: torrentId 110 }); 111 }, 112 113 onContextMenu: function(node, e) { 114 e.stopEvent(); 115 var selModel = this.getSelectionModel(); 116 if (selModel.getSelectedNodes().length < 2) { 117 selModel.clearSelections(); 118 node.select(); 119 } 120 Deluge.Menus.FilePriorities.showAt(e.getPoint()); 121 }, 122 123 onItemClick: function(baseItem, e) { 124 switch (baseItem.id) { 125 case 'expandAll': 126 this.expandAll(); 127 break; 128 default: 129 var indexes = {}; 130 function walk(node) { 131 if (Ext.isEmpty(node.attributes.fileIndex)) return; 132 indexes[node.attributes.fileIndex] = node.attributes.priority; 133 } 134 this.getRootNode().cascade(walk); 135 136 var nodes = this.getSelectionModel().getSelectedNodes(); 137 Ext.each(nodes, function(node) { 138 if (Ext.isEmpty(node.attributes.fileIndex)) return; 139 indexes[node.attributes.fileIndex] = baseItem.filePriority; 140 }); 141 142 var priorities = new Array(Ext.keys(indexes).length); 143 for (var index in indexes) { 144 priorities[index] = indexes[index]; 145 } 146 147 Deluge.Client.core.set_torrent_file_priorities(this.torrentId, priorities, { 148 success: function() { 149 Ext.each(nodes, function(node) { 150 node.setColumnValue(3, baseItem.filePriority); 151 }); 152 }, 153 scope: this 154 }); 155 break; 156 } 157 }, 158 159 onRequestComplete: function(files, options) { 160 function walk(files, parent) { 161 for (var file in files) { 162 var item = files[file]; 163 var child = parent.findChild('id', file); 164 if (Ext.type(item) == 'object') { 165 if (!child) { 166 child = new Ext.tree.TreeNode({ 167 id: file, 168 text: file 169 }); 170 parent.appendChild(child); 171 } 172 walk(item, child); 173 } else { 174 if (!child) { 175 child = new Ext.tree.ColumnTreeNode({ 176 id: file, 177 filename: file, 178 text: file, // this needs to be here for sorting 179 fileIndex: item[0], 180 size: item[1], 181 progress: item[2], 182 priority: item[3], 183 leaf: true, 184 iconCls: 'x-deluge-file', 185 uiProvider: Ext.tree.ColumnNodeUI 186 }); 187 parent.appendChild(child); 188 } 189 child.setColumnValue(1, item[1]); 190 child.setColumnValue(2, item[2]); 191 child.setColumnValue(3, item[3]); 192 } 193 } 194 } 195 var root = this.getRootNode(); 196 walk(files, root); 197 root.firstChild.expand(); 198 } 199 }); 200 Deluge.Details.add(new Ext.deluge.details.FilesTab()); 201 })(); 202