mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-23 09:49:52 +00:00
WebUI: fix 'rename files' dialog cannot be opened more than once
Some checks failed
CI - File health / Check (push) Has been cancelled
CI - macOS / Build (1.2.19, GUI=OFF, 6.7.0) (push) Has been cancelled
CI - macOS / Build (1.2.19, GUI=ON, 6.7.0) (push) Has been cancelled
CI - macOS / Build (2.0.10, GUI=OFF, 6.7.0) (push) Has been cancelled
CI - macOS / Build (2.0.10, GUI=ON, 6.7.0) (push) Has been cancelled
CI - Python / Check (push) Has been cancelled
CI - Ubuntu / Build (1.2.19, GUI=OFF, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (1.2.19, GUI=ON, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (2.0.10, GUI=OFF, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (2.0.10, GUI=ON, 6.5.2) (push) Has been cancelled
CI - WebUI / Check (push) Has been cancelled
CI - Windows / Build (1.2.19) (push) Has been cancelled
CI - Windows / Build (2.0.10) (push) Has been cancelled
Some checks failed
CI - File health / Check (push) Has been cancelled
CI - macOS / Build (1.2.19, GUI=OFF, 6.7.0) (push) Has been cancelled
CI - macOS / Build (1.2.19, GUI=ON, 6.7.0) (push) Has been cancelled
CI - macOS / Build (2.0.10, GUI=OFF, 6.7.0) (push) Has been cancelled
CI - macOS / Build (2.0.10, GUI=ON, 6.7.0) (push) Has been cancelled
CI - Python / Check (push) Has been cancelled
CI - Ubuntu / Build (1.2.19, GUI=OFF, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (1.2.19, GUI=ON, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (2.0.10, GUI=OFF, 6.5.2) (push) Has been cancelled
CI - Ubuntu / Build (2.0.10, GUI=ON, 6.5.2) (push) Has been cancelled
CI - WebUI / Check (push) Has been cancelled
CI - Windows / Build (1.2.19) (push) Has been cancelled
CI - Windows / Build (2.0.10) (push) Has been cancelled
Added an IIFE around the whole script to suppress variable redeclaration errors. Closes #21614. Original PR #21620. PR #21621.
This commit is contained in:
parent
84372de675
commit
49f57b1049
@ -14,15 +14,13 @@
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
if (window.parent.qBittorrent !== undefined)
|
||||
(() => {
|
||||
if (window.parent.qBittorrent !== undefined)
|
||||
window.qBittorrent = window.parent.qBittorrent;
|
||||
window.qBittorrent = window.parent.qBittorrent;
|
||||
window.qBittorrent = window.parent.qBittorrent;
|
||||
|
||||
const TriState = window.qBittorrent.FileTree.TriState;
|
||||
const data = window.MUI.Windows.instances["multiRenamePage"].options.data;
|
||||
let bulkRenameFilesContextMenu;
|
||||
if (!bulkRenameFilesContextMenu) {
|
||||
bulkRenameFilesContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
|
||||
const data = window.MUI.Windows.instances["multiRenamePage"].options.data;
|
||||
const bulkRenameFilesContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
|
||||
targets: "#bulkRenameFilesTableDiv tr",
|
||||
menu: "multiRenameFilesMenu",
|
||||
actions: {
|
||||
@ -40,36 +38,30 @@
|
||||
y: 2
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Setup the dynamic table for bulk renaming
|
||||
const bulkRenameFilesTable = new window.qBittorrent.DynamicTable.BulkRenameTorrentFilesTable();
|
||||
bulkRenameFilesTable.setup("bulkRenameFilesTableDiv", "bulkRenameFilesTableFixedHeaderDiv", bulkRenameFilesContextMenu);
|
||||
// Setup the dynamic table for bulk renaming
|
||||
const bulkRenameFilesTable = new window.qBittorrent.DynamicTable.BulkRenameTorrentFilesTable();
|
||||
bulkRenameFilesTable.setup("bulkRenameFilesTableDiv", "bulkRenameFilesTableFixedHeaderDiv", bulkRenameFilesContextMenu);
|
||||
|
||||
// Inject checkbox into the first column of the table header
|
||||
const tableHeaders = $$("#bulkRenameFilesTableFixedHeaderDiv .dynamicTableHeader th");
|
||||
let checkboxHeader;
|
||||
if (tableHeaders.length > 0) {
|
||||
if (checkboxHeader)
|
||||
checkboxHeader.remove();
|
||||
checkboxHeader = new Element("input");
|
||||
checkboxHeader.set("type", "checkbox");
|
||||
checkboxHeader.set("id", "rootMultiRename_cb");
|
||||
checkboxHeader.addEvent("click", (e) => {
|
||||
bulkRenameFilesTable.toggleGlobalCheckbox();
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
});
|
||||
// Inject checkbox into the first column of the table header
|
||||
const tableHeaders = $$("#bulkRenameFilesTableFixedHeaderDiv .dynamicTableHeader th");
|
||||
if (tableHeaders.length > 0) {
|
||||
const checkboxHeader = new Element("input");
|
||||
checkboxHeader.set("type", "checkbox");
|
||||
checkboxHeader.set("id", "rootMultiRename_cb");
|
||||
checkboxHeader.addEvent("click", (e) => {
|
||||
bulkRenameFilesTable.toggleGlobalCheckbox();
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
});
|
||||
|
||||
const checkboxTH = tableHeaders[0];
|
||||
checkboxHeader.injectInside(checkboxTH);
|
||||
}
|
||||
const checkboxTH = tableHeaders[0];
|
||||
checkboxHeader.injectInside(checkboxTH);
|
||||
}
|
||||
|
||||
// Register keyboard events to modal window
|
||||
// https://github.com/qbittorrent/qBittorrent/pull/18687#discussion_r1135045726
|
||||
let keyboard;
|
||||
if (!keyboard) {
|
||||
keyboard = new Keyboard({
|
||||
// Register keyboard events to modal window
|
||||
// https://github.com/qbittorrent/qBittorrent/pull/18687#discussion_r1135045726
|
||||
const keyboard = new Keyboard({
|
||||
defaultEventType: "keydown",
|
||||
events: {
|
||||
"Escape": function(event) {
|
||||
@ -83,326 +75,326 @@
|
||||
}
|
||||
});
|
||||
keyboard.activate();
|
||||
}
|
||||
|
||||
const fileRenamer = new window.qBittorrent.MultiRename.RenameFiles();
|
||||
fileRenamer.hash = data.hash;
|
||||
const fileRenamer = new window.qBittorrent.MultiRename.RenameFiles();
|
||||
fileRenamer.hash = data.hash;
|
||||
|
||||
// Load Multi Rename Preferences
|
||||
const multiRenamePrefChecked = LocalPreferences.get("multirename_rememberPreferences", "true") === "true";
|
||||
$("multirename_rememberprefs_checkbox").setProperty("checked", multiRenamePrefChecked);
|
||||
// Load Multi Rename Preferences
|
||||
const multiRenamePrefChecked = LocalPreferences.get("multirename_rememberPreferences", "true") === "true";
|
||||
$("multirename_rememberprefs_checkbox").setProperty("checked", multiRenamePrefChecked);
|
||||
|
||||
if (multiRenamePrefChecked) {
|
||||
const multirename_search = LocalPreferences.get("multirename_search", "");
|
||||
fileRenamer.setSearch(multirename_search);
|
||||
$("multiRenameSearch").set("value", multirename_search);
|
||||
if (multiRenamePrefChecked) {
|
||||
const multirename_search = LocalPreferences.get("multirename_search", "");
|
||||
fileRenamer.setSearch(multirename_search);
|
||||
$("multiRenameSearch").set("value", multirename_search);
|
||||
|
||||
const multirename_useRegex = LocalPreferences.get("multirename_useRegex", false);
|
||||
fileRenamer.useRegex = multirename_useRegex === "true";
|
||||
$("use_regex_search").checked = fileRenamer.useRegex;
|
||||
const multirename_useRegex = LocalPreferences.get("multirename_useRegex", false);
|
||||
fileRenamer.useRegex = multirename_useRegex === "true";
|
||||
$("use_regex_search").checked = fileRenamer.useRegex;
|
||||
|
||||
const multirename_matchAllOccurrences = LocalPreferences.get("multirename_matchAllOccurrences", false);
|
||||
fileRenamer.matchAllOccurrences = multirename_matchAllOccurrences === "true";
|
||||
$("match_all_occurrences").checked = fileRenamer.matchAllOccurrences;
|
||||
const multirename_matchAllOccurrences = LocalPreferences.get("multirename_matchAllOccurrences", false);
|
||||
fileRenamer.matchAllOccurrences = multirename_matchAllOccurrences === "true";
|
||||
$("match_all_occurrences").checked = fileRenamer.matchAllOccurrences;
|
||||
|
||||
const multirename_caseSensitive = LocalPreferences.get("multirename_caseSensitive", false);
|
||||
fileRenamer.caseSensitive = multirename_caseSensitive === "true";
|
||||
$("case_sensitive").checked = fileRenamer.caseSensitive;
|
||||
const multirename_caseSensitive = LocalPreferences.get("multirename_caseSensitive", false);
|
||||
fileRenamer.caseSensitive = multirename_caseSensitive === "true";
|
||||
$("case_sensitive").checked = fileRenamer.caseSensitive;
|
||||
|
||||
const multirename_replace = LocalPreferences.get("multirename_replace", "");
|
||||
fileRenamer.setReplacement(multirename_replace);
|
||||
$("multiRenameReplace").set("value", multirename_replace);
|
||||
const multirename_replace = LocalPreferences.get("multirename_replace", "");
|
||||
fileRenamer.setReplacement(multirename_replace);
|
||||
$("multiRenameReplace").set("value", multirename_replace);
|
||||
|
||||
const multirename_appliesTo = LocalPreferences.get("multirename_appliesTo", window.qBittorrent.MultiRename.AppliesTo.FilenameExtension);
|
||||
fileRenamer.appliesTo = window.qBittorrent.MultiRename.AppliesTo[multirename_appliesTo];
|
||||
$("applies_to_option").set("value", fileRenamer.appliesTo);
|
||||
const multirename_appliesTo = LocalPreferences.get("multirename_appliesTo", window.qBittorrent.MultiRename.AppliesTo.FilenameExtension);
|
||||
fileRenamer.appliesTo = window.qBittorrent.MultiRename.AppliesTo[multirename_appliesTo];
|
||||
$("applies_to_option").set("value", fileRenamer.appliesTo);
|
||||
|
||||
const multirename_includeFiles = LocalPreferences.get("multirename_includeFiles", true);
|
||||
fileRenamer.includeFiles = multirename_includeFiles === "true";
|
||||
$("include_files").checked = fileRenamer.includeFiles;
|
||||
const multirename_includeFiles = LocalPreferences.get("multirename_includeFiles", true);
|
||||
fileRenamer.includeFiles = multirename_includeFiles === "true";
|
||||
$("include_files").checked = fileRenamer.includeFiles;
|
||||
|
||||
const multirename_includeFolders = LocalPreferences.get("multirename_includeFolders", false);
|
||||
fileRenamer.includeFolders = multirename_includeFolders === "true";
|
||||
$("include_folders").checked = fileRenamer.includeFolders;
|
||||
const multirename_includeFolders = LocalPreferences.get("multirename_includeFolders", false);
|
||||
fileRenamer.includeFolders = multirename_includeFolders === "true";
|
||||
$("include_folders").checked = fileRenamer.includeFolders;
|
||||
|
||||
const multirename_fileEnumerationStart = LocalPreferences.get("multirename_fileEnumerationStart", 0);
|
||||
fileRenamer.fileEnumerationStart = parseInt(multirename_fileEnumerationStart, 10);
|
||||
$("file_counter").set("value", fileRenamer.fileEnumerationStart);
|
||||
|
||||
const multirename_replaceAll = LocalPreferences.get("multirename_replaceAll", false);
|
||||
fileRenamer.replaceAll = multirename_replaceAll === "true";
|
||||
const renameButtonValue = fileRenamer.replaceAll ? "Replace All" : "Replace";
|
||||
$("renameOptions").set("value", renameButtonValue);
|
||||
$("renameButton").set("value", renameButtonValue);
|
||||
}
|
||||
|
||||
// Fires every time a row's selection changes
|
||||
bulkRenameFilesTable.onRowSelectionChange = function(row) {
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
};
|
||||
|
||||
// Setup Search Events that control renaming
|
||||
$("multiRenameSearch").addEvent("input", (e) => {
|
||||
const sanitized = e.target.value.replace(/\n/g, "");
|
||||
$("multiRenameSearch").set("value", sanitized);
|
||||
|
||||
// Search input has changed
|
||||
$("multiRenameSearch").style["border-color"] = "";
|
||||
LocalPreferences.set("multirename_search", sanitized);
|
||||
fileRenamer.setSearch(sanitized);
|
||||
});
|
||||
$("use_regex_search").addEvent("change", (e) => {
|
||||
fileRenamer.useRegex = e.target.checked;
|
||||
LocalPreferences.set("multirename_useRegex", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("match_all_occurrences").addEvent("change", (e) => {
|
||||
fileRenamer.matchAllOccurrences = e.target.checked;
|
||||
LocalPreferences.set("multirename_matchAllOccurrences", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("case_sensitive").addEvent("change", (e) => {
|
||||
fileRenamer.caseSensitive = e.target.checked;
|
||||
LocalPreferences.set("multirename_caseSensitive", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
|
||||
/**
|
||||
* Fires every time the filerenamer gets changed, it will update all the rows in the table
|
||||
*/
|
||||
fileRenamer.onChanged = function(matchedRows) {
|
||||
// Clear renamed column
|
||||
document
|
||||
.querySelectorAll("span[id^='filesTablefileRenamed']")
|
||||
.forEach((span) => {
|
||||
span.set("text", "");
|
||||
});
|
||||
|
||||
// Update renamed column for matched rows
|
||||
for (let i = 0; i < matchedRows.length; ++i) {
|
||||
const row = matchedRows[i];
|
||||
$("filesTablefileRenamed" + row.rowId).set("text", row.renamed);
|
||||
}
|
||||
};
|
||||
fileRenamer.onInvalidRegex = function(err) {
|
||||
$("multiRenameSearch").style["border-color"] = "#CC0033";
|
||||
};
|
||||
|
||||
// Setup Replace Events that control renaming
|
||||
$("multiRenameReplace").addEvent("input", (e) => {
|
||||
const sanitized = e.target.value.replace(/\n/g, "");
|
||||
$("multiRenameReplace").set("value", sanitized);
|
||||
|
||||
// Replace input has changed
|
||||
$("multiRenameReplace").style["border-color"] = "";
|
||||
LocalPreferences.set("multirename_replace", sanitized);
|
||||
fileRenamer.setReplacement(sanitized);
|
||||
});
|
||||
$("applies_to_option").addEvent("change", (e) => {
|
||||
fileRenamer.appliesTo = e.target.value;
|
||||
LocalPreferences.set("multirename_appliesTo", e.target.value);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("include_files").addEvent("change", (e) => {
|
||||
fileRenamer.includeFiles = e.target.checked;
|
||||
LocalPreferences.set("multirename_includeFiles", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("include_folders").addEvent("change", (e) => {
|
||||
fileRenamer.includeFolders = e.target.checked;
|
||||
LocalPreferences.set("multirename_includeFolders", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("file_counter").addEvent("input", (e) => {
|
||||
let value = e.target.valueAsNumber;
|
||||
if (!value)
|
||||
value = 0;
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > 99999999)
|
||||
value = 99999999;
|
||||
fileRenamer.fileEnumerationStart = value;
|
||||
$("file_counter").set("value", value);
|
||||
LocalPreferences.set("multirename_fileEnumerationStart", value);
|
||||
fileRenamer.update();
|
||||
});
|
||||
|
||||
// Setup Rename Operation Events
|
||||
$("renameButton").addEvent("click", (e) => {
|
||||
// Disable Search Options
|
||||
$("multiRenameSearch").disabled = true;
|
||||
$("use_regex_search").disabled = true;
|
||||
$("match_all_occurrences").disabled = true;
|
||||
$("case_sensitive").disabled = true;
|
||||
// Disable Replace Options
|
||||
$("multiRenameReplace").disabled = true;
|
||||
$("applies_to_option").disabled = true;
|
||||
$("include_files").disabled = true;
|
||||
$("include_folders").disabled = true;
|
||||
$("file_counter").disabled = true;
|
||||
// Disable Rename Buttons
|
||||
$("renameButton").disabled = true;
|
||||
$("renameOptions").disabled = true;
|
||||
// Clear error text
|
||||
$("rename_error").set("text", "");
|
||||
fileRenamer.rename();
|
||||
});
|
||||
fileRenamer.onRenamed = function(rows) {
|
||||
// Disable Search Options
|
||||
$("multiRenameSearch").disabled = false;
|
||||
$("use_regex_search").disabled = false;
|
||||
$("match_all_occurrences").disabled = false;
|
||||
$("case_sensitive").disabled = false;
|
||||
// Disable Replace Options
|
||||
$("multiRenameReplace").disabled = false;
|
||||
$("applies_to_option").disabled = false;
|
||||
$("include_files").disabled = false;
|
||||
$("include_folders").disabled = false;
|
||||
$("file_counter").disabled = false;
|
||||
// Disable Rename Buttons
|
||||
$("renameButton").disabled = false;
|
||||
$("renameOptions").disabled = false;
|
||||
|
||||
// Recreate table
|
||||
let selectedRows = bulkRenameFilesTable.getSelectedRows().map(row => row.rowId.toString());
|
||||
for (const renamedRow of rows)
|
||||
selectedRows = selectedRows.filter(selectedRow => selectedRow !== renamedRow.rowId.toString());
|
||||
bulkRenameFilesTable.clear();
|
||||
|
||||
// Adjust file enumeration count by 1 when replacing single files to prevent naming conflicts
|
||||
if (!fileRenamer.replaceAll) {
|
||||
fileRenamer.fileEnumerationStart++;
|
||||
const multirename_fileEnumerationStart = LocalPreferences.get("multirename_fileEnumerationStart", 0);
|
||||
fileRenamer.fileEnumerationStart = parseInt(multirename_fileEnumerationStart, 10);
|
||||
$("file_counter").set("value", fileRenamer.fileEnumerationStart);
|
||||
|
||||
const multirename_replaceAll = LocalPreferences.get("multirename_replaceAll", false);
|
||||
fileRenamer.replaceAll = multirename_replaceAll === "true";
|
||||
const renameButtonValue = fileRenamer.replaceAll ? "Replace All" : "Replace";
|
||||
$("renameOptions").set("value", renameButtonValue);
|
||||
$("renameButton").set("value", renameButtonValue);
|
||||
}
|
||||
setupTable(selectedRows);
|
||||
};
|
||||
fileRenamer.onRenameError = function(err, row) {
|
||||
if (err.xhr.status === 409)
|
||||
$("rename_error").set("text", `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``);
|
||||
};
|
||||
$("renameOptions").addEvent("change", (e) => {
|
||||
const combobox = e.target;
|
||||
const replaceOperation = combobox.value;
|
||||
if (replaceOperation === "Replace")
|
||||
fileRenamer.replaceAll = false;
|
||||
else if (replaceOperation === "Replace All")
|
||||
fileRenamer.replaceAll = true;
|
||||
else
|
||||
fileRenamer.replaceAll = false;
|
||||
LocalPreferences.set("multirename_replaceAll", fileRenamer.replaceAll);
|
||||
$("renameButton").set("value", replaceOperation);
|
||||
});
|
||||
$("closeButton").addEvent("click", () => {
|
||||
window.parent.qBittorrent.Client.closeWindows();
|
||||
event.preventDefault();
|
||||
});
|
||||
// synchronize header scrolling to table body
|
||||
$("bulkRenameFilesTableDiv").onscroll = function() {
|
||||
const length = $(this).scrollLeft;
|
||||
$("bulkRenameFilesTableFixedHeaderDiv").scrollLeft = length;
|
||||
};
|
||||
|
||||
const handleTorrentFiles = function(files, selectedRows) {
|
||||
const rows = files.map((file, index) => {
|
||||
// Fires every time a row's selection changes
|
||||
bulkRenameFilesTable.onRowSelectionChange = function(row) {
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
};
|
||||
|
||||
const row = {
|
||||
fileId: index,
|
||||
checked: 1, // unchecked
|
||||
path: file.name,
|
||||
original: window.qBittorrent.Filesystem.fileName(file.name),
|
||||
renamed: "",
|
||||
size: file.size
|
||||
};
|
||||
// Setup Search Events that control renaming
|
||||
$("multiRenameSearch").addEvent("input", (e) => {
|
||||
const sanitized = e.target.value.replace(/\n/g, "");
|
||||
$("multiRenameSearch").set("value", sanitized);
|
||||
|
||||
return row;
|
||||
// Search input has changed
|
||||
$("multiRenameSearch").style["border-color"] = "";
|
||||
LocalPreferences.set("multirename_search", sanitized);
|
||||
fileRenamer.setSearch(sanitized);
|
||||
});
|
||||
$("use_regex_search").addEvent("change", (e) => {
|
||||
fileRenamer.useRegex = e.target.checked;
|
||||
LocalPreferences.set("multirename_useRegex", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("match_all_occurrences").addEvent("change", (e) => {
|
||||
fileRenamer.matchAllOccurrences = e.target.checked;
|
||||
LocalPreferences.set("multirename_matchAllOccurrences", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("case_sensitive").addEvent("change", (e) => {
|
||||
fileRenamer.caseSensitive = e.target.checked;
|
||||
LocalPreferences.set("multirename_caseSensitive", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
|
||||
addRowsToTable(rows, selectedRows);
|
||||
};
|
||||
/**
|
||||
* Fires every time the filerenamer gets changed, it will update all the rows in the table
|
||||
*/
|
||||
fileRenamer.onChanged = function(matchedRows) {
|
||||
// Clear renamed column
|
||||
document
|
||||
.querySelectorAll("span[id^='filesTablefileRenamed']")
|
||||
.forEach((span) => {
|
||||
span.set("text", "");
|
||||
});
|
||||
|
||||
const addRowsToTable = function(rows, selectedRows) {
|
||||
let rowId = 0;
|
||||
const rootNode = new window.qBittorrent.FileTree.FolderNode();
|
||||
rootNode.autoCheckFolders = false;
|
||||
// Update renamed column for matched rows
|
||||
for (let i = 0; i < matchedRows.length; ++i) {
|
||||
const row = matchedRows[i];
|
||||
$("filesTablefileRenamed" + row.rowId).set("text", row.renamed);
|
||||
}
|
||||
};
|
||||
fileRenamer.onInvalidRegex = function(err) {
|
||||
$("multiRenameSearch").style["border-color"] = "#CC0033";
|
||||
};
|
||||
|
||||
rows.forEach((row) => {
|
||||
const pathItems = row.path.split(window.qBittorrent.Filesystem.PathSeparator);
|
||||
// Setup Replace Events that control renaming
|
||||
$("multiRenameReplace").addEvent("input", (e) => {
|
||||
const sanitized = e.target.value.replace(/\n/g, "");
|
||||
$("multiRenameReplace").set("value", sanitized);
|
||||
|
||||
pathItems.pop(); // remove last item (i.e. file name)
|
||||
let parent = rootNode;
|
||||
pathItems.forEach((folderName) => {
|
||||
if (folderName === ".unwanted")
|
||||
return;
|
||||
// Replace input has changed
|
||||
$("multiRenameReplace").style["border-color"] = "";
|
||||
LocalPreferences.set("multirename_replace", sanitized);
|
||||
fileRenamer.setReplacement(sanitized);
|
||||
});
|
||||
$("applies_to_option").addEvent("change", (e) => {
|
||||
fileRenamer.appliesTo = e.target.value;
|
||||
LocalPreferences.set("multirename_appliesTo", e.target.value);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("include_files").addEvent("change", (e) => {
|
||||
fileRenamer.includeFiles = e.target.checked;
|
||||
LocalPreferences.set("multirename_includeFiles", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("include_folders").addEvent("change", (e) => {
|
||||
fileRenamer.includeFolders = e.target.checked;
|
||||
LocalPreferences.set("multirename_includeFolders", e.target.checked);
|
||||
fileRenamer.update();
|
||||
});
|
||||
$("file_counter").addEvent("input", (e) => {
|
||||
let value = e.target.valueAsNumber;
|
||||
if (!value)
|
||||
value = 0;
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > 99999999)
|
||||
value = 99999999;
|
||||
fileRenamer.fileEnumerationStart = value;
|
||||
$("file_counter").set("value", value);
|
||||
LocalPreferences.set("multirename_fileEnumerationStart", value);
|
||||
fileRenamer.update();
|
||||
});
|
||||
|
||||
let folderNode = null;
|
||||
if (parent.children !== null) {
|
||||
for (let i = 0; i < parent.children.length; ++i) {
|
||||
const childFolder = parent.children[i];
|
||||
if (childFolder.original === folderName) {
|
||||
folderNode = childFolder;
|
||||
break;
|
||||
// Setup Rename Operation Events
|
||||
$("renameButton").addEvent("click", (e) => {
|
||||
// Disable Search Options
|
||||
$("multiRenameSearch").disabled = true;
|
||||
$("use_regex_search").disabled = true;
|
||||
$("match_all_occurrences").disabled = true;
|
||||
$("case_sensitive").disabled = true;
|
||||
// Disable Replace Options
|
||||
$("multiRenameReplace").disabled = true;
|
||||
$("applies_to_option").disabled = true;
|
||||
$("include_files").disabled = true;
|
||||
$("include_folders").disabled = true;
|
||||
$("file_counter").disabled = true;
|
||||
// Disable Rename Buttons
|
||||
$("renameButton").disabled = true;
|
||||
$("renameOptions").disabled = true;
|
||||
// Clear error text
|
||||
$("rename_error").set("text", "");
|
||||
fileRenamer.rename();
|
||||
});
|
||||
fileRenamer.onRenamed = function(rows) {
|
||||
// Disable Search Options
|
||||
$("multiRenameSearch").disabled = false;
|
||||
$("use_regex_search").disabled = false;
|
||||
$("match_all_occurrences").disabled = false;
|
||||
$("case_sensitive").disabled = false;
|
||||
// Disable Replace Options
|
||||
$("multiRenameReplace").disabled = false;
|
||||
$("applies_to_option").disabled = false;
|
||||
$("include_files").disabled = false;
|
||||
$("include_folders").disabled = false;
|
||||
$("file_counter").disabled = false;
|
||||
// Disable Rename Buttons
|
||||
$("renameButton").disabled = false;
|
||||
$("renameOptions").disabled = false;
|
||||
|
||||
// Recreate table
|
||||
let selectedRows = bulkRenameFilesTable.getSelectedRows().map(row => row.rowId.toString());
|
||||
for (const renamedRow of rows)
|
||||
selectedRows = selectedRows.filter(selectedRow => selectedRow !== renamedRow.rowId.toString());
|
||||
bulkRenameFilesTable.clear();
|
||||
|
||||
// Adjust file enumeration count by 1 when replacing single files to prevent naming conflicts
|
||||
if (!fileRenamer.replaceAll) {
|
||||
fileRenamer.fileEnumerationStart++;
|
||||
$("file_counter").set("value", fileRenamer.fileEnumerationStart);
|
||||
}
|
||||
setupTable(selectedRows);
|
||||
};
|
||||
fileRenamer.onRenameError = function(err, row) {
|
||||
if (err.xhr.status === 409)
|
||||
$("rename_error").set("text", `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``);
|
||||
};
|
||||
$("renameOptions").addEvent("change", (e) => {
|
||||
const combobox = e.target;
|
||||
const replaceOperation = combobox.value;
|
||||
if (replaceOperation === "Replace")
|
||||
fileRenamer.replaceAll = false;
|
||||
else if (replaceOperation === "Replace All")
|
||||
fileRenamer.replaceAll = true;
|
||||
else
|
||||
fileRenamer.replaceAll = false;
|
||||
LocalPreferences.set("multirename_replaceAll", fileRenamer.replaceAll);
|
||||
$("renameButton").set("value", replaceOperation);
|
||||
});
|
||||
$("closeButton").addEvent("click", () => {
|
||||
window.parent.qBittorrent.Client.closeWindows();
|
||||
event.preventDefault();
|
||||
});
|
||||
// synchronize header scrolling to table body
|
||||
$("bulkRenameFilesTableDiv").onscroll = function() {
|
||||
const length = $(this).scrollLeft;
|
||||
$("bulkRenameFilesTableFixedHeaderDiv").scrollLeft = length;
|
||||
};
|
||||
|
||||
const handleTorrentFiles = function(files, selectedRows) {
|
||||
const rows = files.map((file, index) => {
|
||||
|
||||
const row = {
|
||||
fileId: index,
|
||||
checked: 1, // unchecked
|
||||
path: file.name,
|
||||
original: window.qBittorrent.Filesystem.fileName(file.name),
|
||||
renamed: "",
|
||||
size: file.size
|
||||
};
|
||||
|
||||
return row;
|
||||
});
|
||||
|
||||
addRowsToTable(rows, selectedRows);
|
||||
};
|
||||
|
||||
const addRowsToTable = function(rows, selectedRows) {
|
||||
let rowId = 0;
|
||||
const rootNode = new window.qBittorrent.FileTree.FolderNode();
|
||||
rootNode.autoCheckFolders = false;
|
||||
|
||||
rows.forEach((row) => {
|
||||
const pathItems = row.path.split(window.qBittorrent.Filesystem.PathSeparator);
|
||||
|
||||
pathItems.pop(); // remove last item (i.e. file name)
|
||||
let parent = rootNode;
|
||||
pathItems.forEach((folderName) => {
|
||||
if (folderName === ".unwanted")
|
||||
return;
|
||||
|
||||
let folderNode = null;
|
||||
if (parent.children !== null) {
|
||||
for (let i = 0; i < parent.children.length; ++i) {
|
||||
const childFolder = parent.children[i];
|
||||
if (childFolder.original === folderName) {
|
||||
folderNode = childFolder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (folderNode === null) {
|
||||
folderNode = new window.qBittorrent.FileTree.FolderNode();
|
||||
folderNode.autoCheckFolders = false;
|
||||
folderNode.rowId = rowId;
|
||||
folderNode.path = (parent.path === "")
|
||||
? folderName
|
||||
: [parent.path, folderName].join(window.qBittorrent.Filesystem.PathSeparator);
|
||||
folderNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
|
||||
folderNode.original = folderName;
|
||||
folderNode.renamed = "";
|
||||
folderNode.root = parent;
|
||||
parent.addChild(folderNode);
|
||||
if (folderNode === null) {
|
||||
folderNode = new window.qBittorrent.FileTree.FolderNode();
|
||||
folderNode.autoCheckFolders = false;
|
||||
folderNode.rowId = rowId;
|
||||
folderNode.path = (parent.path === "")
|
||||
? folderName
|
||||
: [parent.path, folderName].join(window.qBittorrent.Filesystem.PathSeparator);
|
||||
folderNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
|
||||
folderNode.original = folderName;
|
||||
folderNode.renamed = "";
|
||||
folderNode.root = parent;
|
||||
parent.addChild(folderNode);
|
||||
|
||||
++rowId;
|
||||
}
|
||||
++rowId;
|
||||
}
|
||||
|
||||
parent = folderNode;
|
||||
parent = folderNode;
|
||||
});
|
||||
|
||||
const childNode = new window.qBittorrent.FileTree.FileNode();
|
||||
childNode.rowId = rowId;
|
||||
childNode.path = row.path;
|
||||
childNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
|
||||
childNode.original = row.original;
|
||||
childNode.renamed = "";
|
||||
childNode.root = parent;
|
||||
childNode.data = row;
|
||||
parent.addChild(childNode);
|
||||
|
||||
++rowId;
|
||||
});
|
||||
|
||||
const childNode = new window.qBittorrent.FileTree.FileNode();
|
||||
childNode.rowId = rowId;
|
||||
childNode.path = row.path;
|
||||
childNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
|
||||
childNode.original = row.original;
|
||||
childNode.renamed = "";
|
||||
childNode.root = parent;
|
||||
childNode.data = row;
|
||||
parent.addChild(childNode);
|
||||
bulkRenameFilesTable.populateTable(rootNode);
|
||||
bulkRenameFilesTable.updateTable(false);
|
||||
bulkRenameFilesTable.altRow();
|
||||
|
||||
++rowId;
|
||||
});
|
||||
if (selectedRows !== undefined)
|
||||
bulkRenameFilesTable.reselectRows(selectedRows);
|
||||
|
||||
bulkRenameFilesTable.populateTable(rootNode);
|
||||
bulkRenameFilesTable.updateTable(false);
|
||||
bulkRenameFilesTable.altRow();
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
};
|
||||
|
||||
if (selectedRows !== undefined)
|
||||
bulkRenameFilesTable.reselectRows(selectedRows);
|
||||
|
||||
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
|
||||
fileRenamer.update();
|
||||
};
|
||||
|
||||
const setupTable = function(selectedRows) {
|
||||
new Request.JSON({
|
||||
url: new URI("api/v2/torrents/files?hash=" + data.hash),
|
||||
noCache: true,
|
||||
method: "get",
|
||||
onSuccess: function(files) {
|
||||
if (files.length === 0)
|
||||
bulkRenameFilesTable.clear();
|
||||
else
|
||||
handleTorrentFiles(files, selectedRows);
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
setupTable(data.selectedRows);
|
||||
const setupTable = function(selectedRows) {
|
||||
new Request.JSON({
|
||||
url: new URI("api/v2/torrents/files?hash=" + data.hash),
|
||||
noCache: true,
|
||||
method: "get",
|
||||
onSuccess: function(files) {
|
||||
if (files.length === 0)
|
||||
bulkRenameFilesTable.clear();
|
||||
else
|
||||
handleTorrentFiles(files, selectedRows);
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
setupTable(data.selectedRows);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user