Subsettings
This commit is contained in:
parent
2cc8b97035
commit
062785c008
|
@ -32,11 +32,20 @@ const TEMP_EXTENSIONS: &[&str] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Debug)]
|
#[derive(Clone, Serialize, Debug)]
|
||||||
pub struct FileEntry {
|
pub struct TemporaryFileEntry {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub modified_date: u64,
|
pub modified_date: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TemporaryFileEntry {
|
||||||
|
pub fn get_path(&self) -> &PathBuf {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
pub fn get_modified_date(&self) -> u64 {
|
||||||
|
self.modified_date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Info {
|
pub struct Info {
|
||||||
pub number_of_temporary_files: usize,
|
pub number_of_temporary_files: usize,
|
||||||
|
@ -45,7 +54,7 @@ pub struct Info {
|
||||||
pub struct Temporary {
|
pub struct Temporary {
|
||||||
common_data: CommonToolData,
|
common_data: CommonToolData,
|
||||||
information: Info,
|
information: Info,
|
||||||
temporary_files: Vec<FileEntry>,
|
temporary_files: Vec<TemporaryFileEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Temporary {
|
impl Temporary {
|
||||||
|
@ -138,7 +147,7 @@ impl Temporary {
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
pub fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>) -> Option<FileEntry> {
|
pub fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>) -> Option<TemporaryFileEntry> {
|
||||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
let current_file_name = entry_data.path();
|
let current_file_name = entry_data.path();
|
||||||
|
@ -158,7 +167,7 @@ impl Temporary {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Creating new file entry
|
// Creating new file entry
|
||||||
Some(FileEntry {
|
Some(TemporaryFileEntry {
|
||||||
modified_date: get_modified_time(&metadata, warnings, ¤t_file_name, false),
|
modified_date: get_modified_time(&metadata, warnings, ¤t_file_name, false),
|
||||||
path: current_file_name,
|
path: current_file_name,
|
||||||
})
|
})
|
||||||
|
@ -234,7 +243,7 @@ impl CommonData for Temporary {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Temporary {
|
impl Temporary {
|
||||||
pub const fn get_temporary_files(&self) -> &Vec<FileEntry> {
|
pub const fn get_temporary_files(&self) -> &Vec<TemporaryFileEntry> {
|
||||||
&self.temporary_files
|
&self.temporary_files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,9 @@ pub enum StrDataEmptyFiles {
|
||||||
pub enum IntDataTemporaryFiles {
|
pub enum IntDataTemporaryFiles {
|
||||||
ModificationDatePart1,
|
ModificationDatePart1,
|
||||||
ModificationDatePart2,
|
ModificationDatePart2,
|
||||||
SizePart1,
|
|
||||||
SizePart2,
|
|
||||||
}
|
}
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum StrDataTemporaryFiles {
|
pub enum StrDataTemporaryFiles {
|
||||||
Size,
|
|
||||||
Name,
|
Name,
|
||||||
Path,
|
Path,
|
||||||
ModificationDate,
|
ModificationDate,
|
||||||
|
@ -253,13 +250,12 @@ pub fn get_int_size_idx(active_tab: CurrentTab) -> usize {
|
||||||
CurrentTab::SimilarImages => IntDataSimilarImages::SizePart1 as usize,
|
CurrentTab::SimilarImages => IntDataSimilarImages::SizePart1 as usize,
|
||||||
CurrentTab::DuplicateFiles => IntDataDuplicateFiles::SizePart1 as usize,
|
CurrentTab::DuplicateFiles => IntDataDuplicateFiles::SizePart1 as usize,
|
||||||
CurrentTab::BigFiles => IntDataBigFiles::SizePart1 as usize,
|
CurrentTab::BigFiles => IntDataBigFiles::SizePart1 as usize,
|
||||||
CurrentTab::TemporaryFiles => IntDataTemporaryFiles::SizePart1 as usize,
|
|
||||||
CurrentTab::SimilarVideos => IntDataSimilarVideos::SizePart1 as usize,
|
CurrentTab::SimilarVideos => IntDataSimilarVideos::SizePart1 as usize,
|
||||||
CurrentTab::SimilarMusic => IntDataSimilarMusic::SizePart1 as usize,
|
CurrentTab::SimilarMusic => IntDataSimilarMusic::SizePart1 as usize,
|
||||||
CurrentTab::BrokenFiles => IntDataBrokenFiles::SizePart1 as usize,
|
CurrentTab::BrokenFiles => IntDataBrokenFiles::SizePart1 as usize,
|
||||||
CurrentTab::BadExtensions => IntDataBadExtensions::SizePart1 as usize,
|
CurrentTab::BadExtensions => IntDataBadExtensions::SizePart1 as usize,
|
||||||
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
|
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
|
||||||
CurrentTab::EmptyFolders | CurrentTab::InvalidSymlinks => panic!("Unable to get size from this tab"),
|
CurrentTab::EmptyFolders | CurrentTab::InvalidSymlinks | CurrentTab::TemporaryFiles => panic!("Unable to get size from this tab"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ use czkawka_core::same_music::{MusicEntry, SameMusic};
|
||||||
use czkawka_core::similar_images;
|
use czkawka_core::similar_images;
|
||||||
use czkawka_core::similar_images::{ImagesEntry, SimilarImages};
|
use czkawka_core::similar_images::{ImagesEntry, SimilarImages};
|
||||||
use czkawka_core::similar_videos::{SimilarVideos, VideosEntry};
|
use czkawka_core::similar_videos::{SimilarVideos, VideosEntry};
|
||||||
|
use czkawka_core::temporary::{Temporary, TemporaryFileEntry};
|
||||||
|
|
||||||
use crate::common::split_u64_into_i32s;
|
use crate::common::split_u64_into_i32s;
|
||||||
use crate::settings::{collect_settings, SettingsCustom, ALLOWED_HASH_TYPE_VALUES, ALLOWED_RESIZE_ALGORITHM_VALUES};
|
use crate::settings::{collect_settings, SettingsCustom, ALLOWED_HASH_TYPE_VALUES, ALLOWED_RESIZE_ALGORITHM_VALUES};
|
||||||
|
@ -74,8 +75,10 @@ pub fn connect_scan_button(app: &MainWindow, progress_sender: Sender<ProgressDat
|
||||||
CurrentTab::BrokenFiles => {
|
CurrentTab::BrokenFiles => {
|
||||||
scan_broken_files(a, progress_sender, stop_receiver, custom_settings);
|
scan_broken_files(a, progress_sender, stop_receiver, custom_settings);
|
||||||
}
|
}
|
||||||
|
CurrentTab::TemporaryFiles => {
|
||||||
|
scan_temporary_files(a, progress_sender, stop_receiver, custom_settings);
|
||||||
|
}
|
||||||
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
|
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -168,7 +171,7 @@ fn write_duplicate_results(app: &MainWindow, vector: Vec<(Option<DuplicateEntry>
|
||||||
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.set_similar_images_model(items.into());
|
app.set_duplicate_files_model(items.into());
|
||||||
app.invoke_scan_ended(format!("Found {items_found} similar duplicates files").into());
|
app.invoke_scan_ended(format!("Found {items_found} similar duplicates files").into());
|
||||||
app.global::<GuiState>().set_info_text(messages.into());
|
app.global::<GuiState>().set_info_text(messages.into());
|
||||||
}
|
}
|
||||||
|
@ -257,7 +260,7 @@ fn write_big_files_results(app: &MainWindow, vector: Vec<FileEntry>, messages: S
|
||||||
let (data_model_str, data_model_int) = prepare_data_model_big_files(&fe);
|
let (data_model_str, data_model_int) = prepare_data_model_big_files(&fe);
|
||||||
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
||||||
}
|
}
|
||||||
app.set_empty_folder_model(items.into());
|
app.set_big_files_model(items.into());
|
||||||
app.invoke_scan_ended(format!("Found {items_found} files").into());
|
app.invoke_scan_ended(format!("Found {items_found} files").into());
|
||||||
app.global::<GuiState>().set_info_text(messages.into());
|
app.global::<GuiState>().set_info_text(messages.into());
|
||||||
}
|
}
|
||||||
|
@ -592,6 +595,48 @@ fn prepare_data_model_invalid_symlinks(fe: &SymlinksFileEntry) -> (ModelRc<Share
|
||||||
let modification_split = split_u64_into_i32s(fe.get_modified_date());
|
let modification_split = split_u64_into_i32s(fe.get_modified_date());
|
||||||
let data_model_int = VecModel::from_slice(&[modification_split.0, modification_split.1]);
|
let data_model_int = VecModel::from_slice(&[modification_split.0, modification_split.1]);
|
||||||
(data_model_str, data_model_int)
|
(data_model_str, data_model_int)
|
||||||
|
} ////////////////////////////////////////// Temporary Files
|
||||||
|
fn scan_temporary_files(a: Weak<MainWindow>, progress_sender: Sender<ProgressData>, stop_receiver: Receiver<()>, custom_settings: SettingsCustom) {
|
||||||
|
thread::Builder::new()
|
||||||
|
.stack_size(DEFAULT_THREAD_SIZE)
|
||||||
|
.spawn(move || {
|
||||||
|
let mut finder = Temporary::new();
|
||||||
|
set_common_settings(&mut finder, &custom_settings);
|
||||||
|
finder.find_temporary_files(Some(&stop_receiver), Some(&progress_sender));
|
||||||
|
|
||||||
|
let mut vector = finder.get_temporary_files().clone();
|
||||||
|
let messages = finder.get_text_messages().create_messages_text();
|
||||||
|
|
||||||
|
vector.par_sort_unstable_by(|a, b| split_path_compare(a.path.as_path(), b.path.as_path()));
|
||||||
|
|
||||||
|
a.upgrade_in_event_loop(move |app| {
|
||||||
|
crate::connect_scan::write_temporary_files_results(&app, vector, messages);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
fn write_temporary_files_results(app: &MainWindow, vector: Vec<TemporaryFileEntry>, messages: String) {
|
||||||
|
let items_found = vector.len();
|
||||||
|
let items = Rc::new(VecModel::default());
|
||||||
|
for fe in vector {
|
||||||
|
let (data_model_str, data_model_int) = crate::connect_scan::prepare_data_model_temporary_files(&fe);
|
||||||
|
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
||||||
|
}
|
||||||
|
app.set_temporary_files_model(items.into());
|
||||||
|
app.invoke_scan_ended(format!("Found {items_found} files").into());
|
||||||
|
app.global::<GuiState>().set_info_text(messages.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_data_model_temporary_files(fe: &TemporaryFileEntry) -> (ModelRc<SharedString>, ModelRc<i32>) {
|
||||||
|
let (directory, file) = split_path(&fe.path);
|
||||||
|
let data_model_str = VecModel::from_slice(&[
|
||||||
|
file.into(),
|
||||||
|
directory.into(),
|
||||||
|
NaiveDateTime::from_timestamp_opt(fe.modified_date as i64, 0).unwrap().to_string().into(),
|
||||||
|
]);
|
||||||
|
let modification_split = split_u64_into_i32s(fe.get_modified_date());
|
||||||
|
let data_model_int = VecModel::from_slice(&[modification_split.0, modification_split.1]);
|
||||||
|
(data_model_str, data_model_int)
|
||||||
}
|
}
|
||||||
////////////////////////////////////////// Broken Files
|
////////////////////////////////////////// Broken Files
|
||||||
fn scan_broken_files(a: Weak<MainWindow>, progress_sender: Sender<ProgressData>, stop_receiver: Receiver<()>, custom_settings: SettingsCustom) {
|
fn scan_broken_files(a: Weak<MainWindow>, progress_sender: Sender<ProgressData>, stop_receiver: Receiver<()>, custom_settings: SettingsCustom) {
|
||||||
|
@ -620,7 +665,7 @@ fn write_broken_files_results(app: &MainWindow, vector: Vec<BrokenEntry>, messag
|
||||||
let (data_model_str, data_model_int) = crate::connect_scan::prepare_data_model_broken_files(&fe);
|
let (data_model_str, data_model_int) = crate::connect_scan::prepare_data_model_broken_files(&fe);
|
||||||
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
||||||
}
|
}
|
||||||
app.set_empty_folder_model(items.into());
|
app.set_broken_files_model(items.into());
|
||||||
app.invoke_scan_ended(format!("Found {items_found} files").into());
|
app.invoke_scan_ended(format!("Found {items_found} files").into());
|
||||||
app.global::<GuiState>().set_info_text(messages.into());
|
app.global::<GuiState>().set_info_text(messages.into());
|
||||||
}
|
}
|
||||||
|
@ -666,7 +711,7 @@ fn write_bad_extensions_results(app: &MainWindow, vector: Vec<BadFileEntry>, mes
|
||||||
let (data_model_str, data_model_int) = prepare_data_model_bad_extensions(&fe);
|
let (data_model_str, data_model_int) = prepare_data_model_bad_extensions(&fe);
|
||||||
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
insert_data_to_model(&items, data_model_str, data_model_int, false);
|
||||||
}
|
}
|
||||||
app.set_empty_folder_model(items.into());
|
app.set_bad_extensions_model(items.into());
|
||||||
app.invoke_scan_ended(format!("Found {items_found} files with bad extensions").into());
|
app.invoke_scan_ended(format!("Found {items_found} files with bad extensions").into());
|
||||||
app.global::<GuiState>().set_info_text(messages.into());
|
app.global::<GuiState>().set_info_text(messages.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,4 +93,12 @@ pub fn zeroing_all_models(app: &MainWindow) {
|
||||||
app.set_empty_folder_model(Rc::new(VecModel::default()).into());
|
app.set_empty_folder_model(Rc::new(VecModel::default()).into());
|
||||||
app.set_empty_files_model(Rc::new(VecModel::default()).into());
|
app.set_empty_files_model(Rc::new(VecModel::default()).into());
|
||||||
app.set_similar_images_model(Rc::new(VecModel::default()).into());
|
app.set_similar_images_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_duplicate_files_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_similar_music_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_big_files_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_bad_extensions_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_broken_files_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_similar_videos_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_invalid_symlinks_model(Rc::new(VecModel::default()).into());
|
||||||
|
app.set_temporary_files_model(Rc::new(VecModel::default()).into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export global GuiState {
|
||||||
in-out property <bool> choosing_include_directories;
|
in-out property <bool> choosing_include_directories;
|
||||||
in-out property <bool> visible_tool_settings;
|
in-out property <bool> visible_tool_settings;
|
||||||
|
|
||||||
in-out property <bool> available_subsettings: active_tab == CurrentTab.SimilarImages;
|
in-out property <bool> available_subsettings: active_tab == CurrentTab.SimilarImages || active_tab == CurrentTab.DuplicateFiles || active_tab == CurrentTab.SimilarVideos || active_tab == CurrentTab.SimilarMusic || active_tab == CurrentTab.BigFiles || active_tab == CurrentTab.BrokenFiles;
|
||||||
in-out property <CurrentTab> active_tab: CurrentTab.DuplicateFiles;
|
in-out property <CurrentTab> active_tab: CurrentTab.DuplicateFiles;
|
||||||
in-out property <bool> is_tool_tab_active: active_tab != CurrentTab.Settings && active_tab != CurrentTab.About;
|
in-out property <bool> is_tool_tab_active: active_tab != CurrentTab.Settings && active_tab != CurrentTab.About;
|
||||||
in-out property <[SelectModel]> select_results_list: [{data: SelectMode.SelectAll, name: "Select All"}, {data: SelectMode.UnselectAll, name: "Deselect All"}, {data: SelectMode.SelectTheSmallestResolution, name: "Select the smallest resolution"}];
|
in-out property <[SelectModel]> select_results_list: [{data: SelectMode.SelectAll, name: "Select All"}, {data: SelectMode.UnselectAll, name: "Deselect All"}, {data: SelectMode.SelectTheSmallestResolution, name: "Select the smallest resolution"}];
|
||||||
|
|
|
@ -68,7 +68,7 @@ export component LeftSidePanel {
|
||||||
callback changed_current_tab();
|
callback changed_current_tab();
|
||||||
width: 120px;
|
width: 120px;
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
spacing: 10px;
|
spacing: 2px;
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: GuiState.active_tab != CurrentTab.About;
|
visible: GuiState.active_tab != CurrentTab.About;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
@ -110,7 +110,6 @@ export component LeftSidePanel {
|
||||||
curr_tab: r.tab;
|
curr_tab: r.tab;
|
||||||
changed_current_tab() => {root.changed_current_tab();}
|
changed_current_tab() => {root.changed_current_tab();}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
@ -88,8 +88,8 @@ export component MainList {
|
||||||
visible: GuiState.active_tab == CurrentTab.TemporaryFiles;
|
visible: GuiState.active_tab == CurrentTab.TemporaryFiles;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
height: parent.height;
|
height: parent.height;
|
||||||
columns: ["Selection", "Size", "File Name", "Path", "Modification Date"];
|
columns: ["Selection", "File Name", "Path", "Modification Date"];
|
||||||
column-sizes: [35px, size_px, name_px, path_px, mod_px];
|
column-sizes: [35px, name_px, path_px, mod_px];
|
||||||
values <=> temporary_files_model;
|
values <=> temporary_files_model;
|
||||||
parentPathIdx: 3;
|
parentPathIdx: 3;
|
||||||
fileNameIdx: 2;
|
fileNameIdx: 2;
|
||||||
|
@ -143,8 +143,8 @@ export component MainList {
|
||||||
visible: GuiState.active_tab == CurrentTab.BrokenFiles;
|
visible: GuiState.active_tab == CurrentTab.BrokenFiles;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
height: parent.height;
|
height: parent.height;
|
||||||
columns: ["Selection", "Size", "File Name", "Type of Error", "Path", "Modification Date"];
|
columns: ["Selection", "File Name", "Path", "Type of Error", "Size", "Modification Date"];
|
||||||
column-sizes: [35px, size_px, name_px, 200px, path_px, mod_px];
|
column-sizes: [35px, name_px, path_px, 200px, size_px, mod_px];
|
||||||
values <=> broken_files_model;
|
values <=> broken_files_model;
|
||||||
parentPathIdx: 4;
|
parentPathIdx: 4;
|
||||||
fileNameIdx: 2;
|
fileNameIdx: 2;
|
||||||
|
|
|
@ -72,14 +72,7 @@ export component PopupNewDirectories inherits Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button {
|
|
||||||
// text:"KKK";
|
|
||||||
// clicked => {
|
|
||||||
// show-popup();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
show_popup() => {
|
show_popup() => {
|
||||||
popup_window.show();
|
popup_window.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ export global Settings {
|
||||||
|
|
||||||
|
|
||||||
// Allowed subsettings
|
// Allowed subsettings
|
||||||
// Duplicate
|
// Similar Images
|
||||||
in-out property <[string]> similar_images_sub_available_hash_size: ["8", "16", "32", "64"];
|
in-out property <[string]> similar_images_sub_available_hash_size: ["8", "16", "32", "64"];
|
||||||
in-out property <int> similar_images_sub_hash_size_index: 0;
|
in-out property <int> similar_images_sub_hash_size_index: 0;
|
||||||
in-out property <[string]> similar_images_sub_available_resize_algorithm: ["Lanczos3", "Nearest", "Triangle", "Gaussian", "CatmullRom"];
|
in-out property <[string]> similar_images_sub_available_resize_algorithm: ["Lanczos3", "Nearest", "Triangle", "Gaussian", "CatmullRom"];
|
||||||
|
@ -50,4 +50,37 @@ export global Settings {
|
||||||
in-out property <float> similar_images_sub_max_similarity: 40;
|
in-out property <float> similar_images_sub_max_similarity: 40;
|
||||||
in-out property <float> similar_images_sub_current_similarity: 20;
|
in-out property <float> similar_images_sub_current_similarity: 20;
|
||||||
in-out property <bool> similar_images_sub_ignore_same_size;
|
in-out property <bool> similar_images_sub_ignore_same_size;
|
||||||
|
|
||||||
|
// Duplicates
|
||||||
|
in-out property <[string]> duplicates_sub_check_method: ["Hash", "Size", "Name", "Size and Name"];
|
||||||
|
in-out property <int> duplicates_sub_check_method_index: 0;
|
||||||
|
in-out property <[string]> duplicates_sub_available_hash_type: ["Blake3", "CRC32", "XXH3"];
|
||||||
|
in-out property <int> duplicates_sub_available_hash_type_index: 0;
|
||||||
|
|
||||||
|
// Big files
|
||||||
|
in-out property <[string]> biggest_files_sub_method: ["The Biggest", "The Smallest"];
|
||||||
|
in-out property <int> biggest_files_sub_method_index: 0;
|
||||||
|
in-out property <string> biggest_files_sub_number_of_files: 50;
|
||||||
|
|
||||||
|
// Similar Videos
|
||||||
|
in-out property <bool> similar_videos_sub_ignore_same_size;
|
||||||
|
in-out property <float> similar_videos_sub_max_similarity: 20;
|
||||||
|
in-out property <float> similar_videos_sub_current_similarity: 15;
|
||||||
|
|
||||||
|
// Same Music
|
||||||
|
in-out property <[string]> similar_music_sub_audio_check_type: ["Tags", "Fingerprint"];
|
||||||
|
in-out property <int> similar_music_sub_audio_check_type_index: 0;
|
||||||
|
in-out property <bool> similar_music_sub_approximate_comparison;
|
||||||
|
in-out property <bool> similar_music_sub_title: true;
|
||||||
|
in-out property <bool> similar_music_sub_artist: true;
|
||||||
|
in-out property <bool> similar_music_sub_year: false;
|
||||||
|
in-out property <bool> similar_music_sub_bitrate: false;
|
||||||
|
in-out property <bool> similar_music_sub_genre: false;
|
||||||
|
in-out property <bool> similar_music_sub_length: false;
|
||||||
|
|
||||||
|
// Broken Files
|
||||||
|
in-out property <bool> broken_files_sub_audio: true;
|
||||||
|
in-out property <bool> broken_files_sub_pdf: false;
|
||||||
|
in-out property <bool> broken_files_sub_archive: false;
|
||||||
|
in-out property <bool> broken_files_sub_image: false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ global SettingsSize {
|
||||||
out property <length> item_height: 30px;
|
out property <length> item_height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
component TextComponent inherits HorizontalLayout {
|
export component TextComponent inherits HorizontalLayout {
|
||||||
in-out property <string> model;
|
in-out property <string> model;
|
||||||
in property <string> name;
|
in property <string> name;
|
||||||
spacing: 5px;
|
spacing: 5px;
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {ColorPalette} from "color_palette.slint";
|
||||||
import {GuiState} from "gui_state.slint";
|
import {GuiState} from "gui_state.slint";
|
||||||
import { Preview } from "preview.slint";
|
import { Preview } from "preview.slint";
|
||||||
import {PopupNewDirectories} from "popup_new_directories.slint";
|
import {PopupNewDirectories} from "popup_new_directories.slint";
|
||||||
|
import {TextComponent} from "settings_list.slint";
|
||||||
|
|
||||||
component ComboBoxWrapper inherits HorizontalLayout {
|
component ComboBoxWrapper inherits HorizontalLayout {
|
||||||
in-out property <string> text;
|
in-out property <string> text;
|
||||||
|
@ -62,7 +63,8 @@ component SliderWrapper inherits HorizontalLayout {
|
||||||
|
|
||||||
export component ToolSettings {
|
export component ToolSettings {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
if GuiState.active_tab == CurrentTab.SimilarImages: VerticalLayout {
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.SimilarImages;
|
||||||
spacing: 5px;
|
spacing: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
SubsettingsHeader { }
|
SubsettingsHeader { }
|
||||||
|
@ -94,5 +96,128 @@ export component ToolSettings {
|
||||||
}
|
}
|
||||||
Rectangle {}
|
Rectangle {}
|
||||||
}
|
}
|
||||||
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.DuplicateFiles;
|
||||||
|
spacing: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
SubsettingsHeader { }
|
||||||
|
ComboBoxWrapper {
|
||||||
|
text: "Check method";
|
||||||
|
model: Settings.duplicates_sub_check_method;
|
||||||
|
current_index <=> Settings.duplicates_sub_check_method_index;
|
||||||
|
}
|
||||||
|
ComboBoxWrapper {
|
||||||
|
text: "Hash type";
|
||||||
|
model: Settings.duplicates_sub_available_hash_type;
|
||||||
|
current_index <=> Settings.duplicates_sub_available_hash_type_index;
|
||||||
|
}
|
||||||
|
Rectangle {}
|
||||||
|
}
|
||||||
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.BigFiles;
|
||||||
|
spacing: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
SubsettingsHeader { }
|
||||||
|
ComboBoxWrapper {
|
||||||
|
text: "Checked files";
|
||||||
|
model: Settings.biggest_files_sub_method;
|
||||||
|
current_index <=> Settings.biggest_files_sub_method_index;
|
||||||
|
}
|
||||||
|
TextComponent {
|
||||||
|
name: "Number of files";
|
||||||
|
model <=> Settings.biggest_files_sub_number_of_files;
|
||||||
|
}
|
||||||
|
Rectangle {}
|
||||||
|
}
|
||||||
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.SimilarVideos;
|
||||||
|
spacing: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
SubsettingsHeader { }
|
||||||
|
SliderWrapper {
|
||||||
|
text: "Max difference";
|
||||||
|
end_text: "(" + round(Settings.similar_videos_sub_current_similarity) + "/" + round(Settings.similar_videos_sub_max_similarity) + ")";
|
||||||
|
end_text_size: 40px;
|
||||||
|
maximum <=> Settings.similar_videos_sub_max_similarity;
|
||||||
|
value <=> Settings.similar_videos_sub_current_similarity;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Ignore same size";
|
||||||
|
checked <=> Settings.similar_images_sub_ignore_same_size;
|
||||||
|
}
|
||||||
|
Rectangle {}
|
||||||
|
}
|
||||||
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.SimilarMusic;
|
||||||
|
spacing: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
SubsettingsHeader { }
|
||||||
|
ComboBoxWrapper {
|
||||||
|
text: "Audio check type";
|
||||||
|
model: Settings.similar_music_sub_audio_check_type;
|
||||||
|
current_index <=> Settings.similar_music_sub_audio_check_type_index;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Approximate Tag Comparison";
|
||||||
|
checked <=> Settings.similar_music_sub_approximate_comparison;
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Compared tags";
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Title";
|
||||||
|
checked <=> Settings.similar_music_sub_title;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Artist";
|
||||||
|
checked <=> Settings.similar_music_sub_artist;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Bitrate";
|
||||||
|
checked <=> Settings.similar_music_sub_bitrate;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Genre";
|
||||||
|
checked <=> Settings.similar_music_sub_genre;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Year";
|
||||||
|
checked <=> Settings.similar_music_sub_year;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Length";
|
||||||
|
checked <=> Settings.similar_music_sub_length;
|
||||||
|
}
|
||||||
|
Rectangle {}
|
||||||
|
}
|
||||||
|
VerticalLayout {
|
||||||
|
visible: GuiState.active_tab == CurrentTab.BrokenFiles;
|
||||||
|
spacing: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
SubsettingsHeader { }
|
||||||
|
Text {
|
||||||
|
text: "Type of files to check";
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Audio";
|
||||||
|
checked <=> Settings.broken_files_sub_audio;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Pdf";
|
||||||
|
checked <=> Settings.broken_files_sub_pdf;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Archive";
|
||||||
|
checked <=> Settings.broken_files_sub_archive;
|
||||||
|
}
|
||||||
|
CheckBoxWrapper {
|
||||||
|
text: "Image";
|
||||||
|
checked <=> Settings.broken_files_sub_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue