WebUI: Add ability to toggle alternating row colors in tables
[qBittorrent.git] / src / webui / www / private / scripts / file-tree.js
blob7ccc46513f148c4a99c22828446a11f737f00760
1 /*
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.
29 "use strict";
31 window.qBittorrent ??= {};
32 window.qBittorrent.FileTree ??= (() => {
33 const exports = () => {
34 return {
35 FilePriority: FilePriority,
36 TriState: TriState,
37 FileTree: FileTree,
38 FileNode: FileNode,
39 FolderNode: FolderNode,
43 const FilePriority = {
44 "Ignored": 0,
45 "Normal": 1,
46 "High": 6,
47 "Maximum": 7,
48 "Mixed": -1
50 Object.freeze(FilePriority);
52 const TriState = {
53 "Unchecked": 0,
54 "Checked": 1,
55 "Partial": 2
57 Object.freeze(TriState);
59 const FileTree = new Class({
60 root: null,
61 nodeMap: {},
63 setRoot: function(root) {
64 this.root = root;
65 this.generateNodeMap(root);
67 if (this.root.isFolder)
68 this.root.calculateSize();
71 getRoot: function() {
72 return this.root;
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);
82 });
85 getNode: function(rowId) {
86 return (this.nodeMap[rowId] === undefined)
87 ? null
88 : this.nodeMap[rowId];
91 getRowId: function(node) {
92 return node.rowId;
95 /**
96 * Returns the nodes in dfs order
98 toArray: function() {
99 const nodes = [];
100 this.root.children.each((node) => {
101 this._getArrayOfNodes(node, nodes);
103 return nodes;
106 _getArrayOfNodes: function(node, array) {
107 array.push(node);
108 node.children.each((child) => {
109 this._getArrayOfNodes(child, array);
114 const FileNode = new Class({
115 name: "",
116 path: "",
117 rowId: null,
118 size: 0,
119 checked: TriState.Unchecked,
120 remaining: 0,
121 progress: 0,
122 priority: FilePriority.Normal,
123 availability: 0,
124 depth: 0,
125 root: null,
126 data: null,
127 isFolder: false,
128 children: [],
131 const FolderNode = new Class({
132 Extends: FileNode,
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;
143 addChild(node) {
144 this.children.push(node);
148 * Recursively calculate size of node and its children
150 calculateSize: function() {
151 let size = 0;
152 let remaining = 0;
153 let progress = 0;
154 let availability = 0;
155 let checked = TriState.Unchecked;
156 let priority = FilePriority.Normal;
158 let isFirstFile = true;
160 this.children.each((node) => {
161 if (node.isFolder)
162 node.calculateSize();
164 size += node.size;
166 if (isFirstFile) {
167 priority = node.priority;
168 checked = node.checked;
169 isFirstFile = false;
171 else {
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);
179 if (!isIgnored) {
180 remaining += node.remaining;
181 progress += (node.progress * node.size);
182 availability += (node.availability * node.size);
186 this.size = 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);
195 return exports();
196 })();
197 Object.freeze(window.qBittorrent.FileTree);