2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2019 Thomas Piccirello <thomas.piccirello@gmail.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
31 window.qBittorrent ??= {};
32 window.qBittorrent.FileTree ??= (() => {
33 const exports = () => {
35 FilePriority: FilePriority,
39 FolderNode: FolderNode,
43 const FilePriority = {
50 Object.freeze(FilePriority);
57 Object.freeze(TriState);
59 const FileTree = new Class({
63 setRoot: function(root) {
65 this.generateNodeMap(root);
67 if (this.root.isFolder)
68 this.root.calculateSize();
75 generateNodeMap: function(node) {
76 // don't store root node in map
77 if (node.root !== null)
78 this.nodeMap[node.rowId] = node;
80 node.children.each((child) => {
81 this.generateNodeMap(child);
85 getNode: function(rowId) {
86 return (this.nodeMap[rowId] === undefined)
88 : this.nodeMap[rowId];
91 getRowId: function(node) {
96 * Returns the nodes in dfs order
100 this.root.children.each((node) => {
101 this._getArrayOfNodes(node, nodes);
106 _getArrayOfNodes: function(node, array) {
108 node.children.each((child) => {
109 this._getArrayOfNodes(child, array);
114 const FileNode = new Class({
119 checked: TriState.Unchecked,
122 priority: FilePriority.Normal,
131 const FolderNode = new Class({
135 * Will automatically tick the checkbox for a folder if all subfolders and files are also ticked
137 autoCheckFolders: true,
139 initialize: function() {
140 this.isFolder = true;
144 this.children.push(node);
148 * Recursively calculate size of node and its children
150 calculateSize: function() {
154 let availability = 0;
155 let checked = TriState.Unchecked;
156 let priority = FilePriority.Normal;
158 let isFirstFile = true;
160 this.children.each((node) => {
162 node.calculateSize();
167 priority = node.priority;
168 checked = node.checked;
172 if (priority !== node.priority)
173 priority = FilePriority.Mixed;
174 if (checked !== node.checked)
175 checked = TriState.Partial;
178 const isIgnored = (node.priority === FilePriority.Ignored);
180 remaining += node.remaining;
181 progress += (node.progress * node.size);
182 availability += (node.availability * node.size);
187 this.remaining = remaining;
188 this.checked = this.autoCheckFolders ? checked : TriState.Checked;
189 this.progress = (progress / size);
190 this.priority = priority;
191 this.availability = (availability / size);
197 Object.freeze(window.qBittorrent.FileTree);