Fixes random things (#1160)
* AB * More simple * Optimize even more code * Delete info * Common * Randoms * Included * ProfData * Upgrade
This commit is contained in:
parent
bf78fc8b57
commit
0defcbd253
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -17,4 +17,5 @@ ci_tester/target
|
|||
ci_tester/Cargo.lock
|
||||
krokiet/Cargo.lock
|
||||
krokiet/target
|
||||
*.json
|
||||
*.json
|
||||
*.mm_profdata
|
847
Cargo.lock
generated
847
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,8 @@
|
|||
## Version 7.0.0 - ?
|
||||
### BREAKING CHANGES
|
||||
- Reducing size of cache files, made old cache files incompatible with new version
|
||||
- `-C` in CLI now saves as compact json
|
||||
|
||||
### GTK GUI
|
||||
- Added drag&drop support for included/excluded folders - [#1106](https://github.com/qarmin/czkawka/pull/1106)
|
||||
- Added information where are saved scan results - [#1102](https://github.com/qarmin/czkawka/pull/1102)
|
||||
|
@ -23,6 +27,7 @@
|
|||
- Fixed recognizing not accessible folders as non-empty - [#1152](https://github.com/qarmin/czkawka/pull/1152)
|
||||
- Unifying code for collecting files to scan - [#1159](https://github.com/qarmin/czkawka/pull/1159)
|
||||
- Decrease memory usage when collecting files by removing unused fields in custom file entries structs - [#1159](https://github.com/qarmin/czkawka/pull/1159)
|
||||
- Decrease a little size of cache by few percents and improve loading/saving speed - [#1159](https://github.com/qarmin/czkawka/pull/1159)
|
||||
|
||||
## Version 6.1.0 - 15.10.2023r
|
||||
- BREAKING CHANGE - Changed cache saving method, deduplicated, optimized and simplified procedure(all files needs to be hashed again) - [#1072](https://github.com/qarmin/czkawka/pull/1072), [#1086](https://github.com/qarmin/czkawka/pull/1086)
|
||||
|
@ -171,7 +176,7 @@
|
|||
## Version 3.2.0 - 07.08.2021r
|
||||
- Use checkbox instead selection to select files [#392](https://github.com/qarmin/czkawka/pull/392)
|
||||
- Re-enable hardlink on windows - [#410](https://github.com/qarmin/czkawka/pull/410)
|
||||
- Fix symlink and harlink creating - [#409](https://github.com/qarmin/czkawka/pull/409)
|
||||
- Fix symlink and hardlink creating - [#409](https://github.com/qarmin/czkawka/pull/409)
|
||||
- Add image preview to duplicate finder [#408](https://github.com/qarmin/czkawka/pull/408)
|
||||
- Add setting maximum file size [#407](https://github.com/qarmin/czkawka/pull/407)
|
||||
- Add new grouping algorithm to similar images [#405](https://github.com/qarmin/czkawka/pull/405)
|
||||
|
|
|
@ -26,7 +26,7 @@ hamming = "0.1"
|
|||
|
||||
# Needed by same music
|
||||
bitflags = "2.4"
|
||||
lofty = "0.17"
|
||||
lofty = "0.18"
|
||||
|
||||
# Needed by broken files
|
||||
zip = { version = "0.6", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
|
||||
|
@ -42,7 +42,7 @@ blake3 = "1.5"
|
|||
crc32fast = "1.3"
|
||||
xxhash-rust = { version = "0.8", features = ["xxh3"] }
|
||||
|
||||
tempfile = "3.8"
|
||||
tempfile = "3.9"
|
||||
|
||||
# Video Duplicates
|
||||
vid_dup_finder_lib = "0.1"
|
||||
|
@ -56,7 +56,7 @@ serde_json = "1.0"
|
|||
# Language
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
rust-embed = { version = "8.2", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
# Raw image files
|
||||
|
|
|
@ -331,40 +331,21 @@ pub fn split_path(path: &Path) -> (String, String) {
|
|||
}
|
||||
|
||||
pub fn split_path_compare(path_a: &Path, path_b: &Path) -> Ordering {
|
||||
let parent_dir_a = path_a.parent();
|
||||
let parent_dir_b = path_b.parent();
|
||||
if parent_dir_a.is_none() || parent_dir_b.is_none() {
|
||||
let file_name_a = path_a.file_name();
|
||||
let file_name_b = path_b.file_name();
|
||||
if file_name_a.is_none() || file_name_b.is_none() {
|
||||
return Ordering::Equal;
|
||||
}
|
||||
|
||||
return if file_name_a > file_name_b { Ordering::Greater } else { Ordering::Less };
|
||||
}
|
||||
if parent_dir_a > parent_dir_b {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Less
|
||||
match path_a.parent().cmp(&path_b.parent()) {
|
||||
Ordering::Equal => path_a.file_name().cmp(&path_b.file_name()),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_crash_message(library_name: &str, file_path: &str, home_library_url: &str) -> String {
|
||||
format!("{library_name} library crashed when opening \"{file_path}\", please check if this is fixed with the latest version of {library_name} (e.g. with https://github.com/qarmin/crates_tester) and if it is not fixed, please report bug here - {home_library_url}")
|
||||
format!("{library_name} library crashed when opening \"{file_path}\", please check if this is fixed with the latest version of {library_name} and if it is not fixed, please report bug here - {home_library_url}")
|
||||
}
|
||||
|
||||
pub fn regex_check(expression_item: &SingleExcludedItem, directory: impl AsRef<Path>) -> bool {
|
||||
if expression_item.expression == "*" {
|
||||
pub fn regex_check(expression_item: &SingleExcludedItem, directory_name: &str) -> bool {
|
||||
if expression_item.expression_splits.is_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if expression_item.expression_splits.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get rid of non unicode characters
|
||||
let directory_name = directory.as_ref().to_string_lossy();
|
||||
|
||||
// Early checking if directory contains all parts needed by expression
|
||||
for split in &expression_item.unique_extensions_splits {
|
||||
if !directory_name.contains(split) {
|
||||
|
@ -481,7 +462,7 @@ where
|
|||
infos.push(format!(
|
||||
"dry_run - would create hardlink from {:?} to {:?}",
|
||||
original_file.get_path(),
|
||||
original_file.get_path()
|
||||
file_entry.get_path()
|
||||
));
|
||||
} else {
|
||||
if dry_run {
|
||||
|
@ -519,7 +500,7 @@ where
|
|||
if dry_run {
|
||||
infos.push(format!("dry_run - would delete file: {:?}", i.get_path()));
|
||||
} else {
|
||||
if let Err(e) = std::fs::remove_file(i.get_path()) {
|
||||
if let Err(e) = fs::remove_file(i.get_path()) {
|
||||
errors.push(format!("Cannot delete file: {:?} - {e}", i.get_path()));
|
||||
failed_to_remove_files += 1;
|
||||
} else {
|
||||
|
@ -661,6 +642,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_regex() {
|
||||
assert!(regex_check(&new_excluded_item("*"), "/home/rafal"));
|
||||
assert!(regex_check(&new_excluded_item("*home*"), "/home/rafal"));
|
||||
assert!(regex_check(&new_excluded_item("*home"), "/home"));
|
||||
assert!(regex_check(&new_excluded_item("*home/"), "/home/"));
|
||||
|
|
|
@ -12,33 +12,34 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::BTreeMap;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
const CACHE_VERSION: &str = "70";
|
||||
|
||||
pub fn get_broken_files_cache_file() -> String {
|
||||
"cache_broken_files_61.bin".to_string()
|
||||
format!("cache_broken_files_{CACHE_VERSION}.bin")
|
||||
}
|
||||
|
||||
pub fn get_similar_images_cache_file(hash_size: &u8, hash_alg: &HashAlg, image_filter: &FilterType) -> String {
|
||||
format!(
|
||||
"cache_similar_images_{}_{}_{}_61.bin",
|
||||
hash_size,
|
||||
"cache_similar_images_{hash_size}_{}_{}_{CACHE_VERSION}.bin",
|
||||
convert_algorithm_to_string(hash_alg),
|
||||
convert_filters_to_string(image_filter),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_similar_videos_cache_file() -> String {
|
||||
"cache_similar_videos_61.bin".to_string()
|
||||
format!("cache_similar_videos_{CACHE_VERSION}.bin")
|
||||
}
|
||||
pub fn get_similar_music_cache_file(checking_tags: bool) -> &'static str {
|
||||
pub fn get_similar_music_cache_file(checking_tags: bool) -> String {
|
||||
if checking_tags {
|
||||
"cache_same_music_tags_61.bin"
|
||||
format!("cache_same_music_tags_{CACHE_VERSION}.bin")
|
||||
} else {
|
||||
"cache_same_music_fingerprints_61.bin"
|
||||
format!("cache_same_music_fingerprints_{CACHE_VERSION}.bin")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_duplicate_cache_file(type_of_hash: &HashType, is_prehash: bool) -> String {
|
||||
let prehash_str = if is_prehash { "_prehash" } else { "" };
|
||||
format!("cache_duplicates_{type_of_hash:?}{prehash_str}_61.bin")
|
||||
format!("cache_duplicates_{type_of_hash:?}{prehash_str}_{CACHE_VERSION}.bin")
|
||||
}
|
||||
|
||||
#[fun_time(message = "save_cache_to_file_generalized", level = "debug")]
|
||||
|
|
|
@ -305,8 +305,7 @@ impl Directories {
|
|||
self.reference_directories.iter().any(|e| path.starts_with(e))
|
||||
}
|
||||
|
||||
pub fn is_excluded(&self, path: impl AsRef<Path>) -> bool {
|
||||
let path = path.as_ref();
|
||||
pub fn is_excluded(&self, path: &Path) -> bool {
|
||||
#[cfg(target_family = "windows")]
|
||||
let path = normalize_windows_path(path);
|
||||
// We're assuming that `excluded_directories` are already normalized
|
||||
|
|
|
@ -85,15 +85,17 @@ impl ExcludedItems {
|
|||
pub fn get_excluded_items(&self) -> &Vec<String> {
|
||||
&self.expressions
|
||||
}
|
||||
pub fn is_excluded(&self, path: impl AsRef<Path>) -> bool {
|
||||
pub fn is_excluded(&self, path: &Path) -> bool {
|
||||
if self.connected_expressions.is_empty() {
|
||||
return false;
|
||||
}
|
||||
#[cfg(target_family = "windows")]
|
||||
let path = normalize_windows_path(path);
|
||||
|
||||
let path_str = path.to_string_lossy();
|
||||
|
||||
for expression in &self.connected_expressions {
|
||||
if regex_check(expression, &path) {
|
||||
if regex_check(expression, &path_str) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +109,7 @@ pub fn new_excluded_item(expression: &str) -> SingleExcludedItem {
|
|||
let mut unique_extensions_splits = expression_splits.clone();
|
||||
unique_extensions_splits.sort();
|
||||
unique_extensions_splits.dedup();
|
||||
unique_extensions_splits.sort_by_key(|b| std::cmp::Reverse(b.len()));
|
||||
SingleExcludedItem {
|
||||
expression,
|
||||
expression_splits,
|
||||
|
|
|
@ -222,7 +222,7 @@ impl SameMusic {
|
|||
|
||||
if self.common_data.use_cache {
|
||||
let (messages, loaded_items) =
|
||||
load_cache_from_file_generalized_by_path::<MusicEntry>(get_similar_music_cache_file(checking_tags), self.get_delete_outdated_cache(), &self.music_to_check);
|
||||
load_cache_from_file_generalized_by_path::<MusicEntry>(&get_similar_music_cache_file(checking_tags), self.get_delete_outdated_cache(), &self.music_to_check);
|
||||
self.get_text_messages_mut().extend_with_another_messages(messages);
|
||||
loaded_hash_map = loaded_items.unwrap_or_default();
|
||||
|
||||
|
@ -260,7 +260,7 @@ impl SameMusic {
|
|||
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
|
||||
}
|
||||
|
||||
let messages = save_cache_to_file_generalized(get_similar_music_cache_file(checking_tags), &all_results, self.common_data.save_also_as_json, 0);
|
||||
let messages = save_cache_to_file_generalized(&get_similar_music_cache_file(checking_tags), &all_results, self.common_data.save_also_as_json, 0);
|
||||
self.get_text_messages_mut().extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ regex = "1.10"
|
|||
image_hasher = "1.2"
|
||||
|
||||
# Move files to trash
|
||||
trash = "3.1"
|
||||
trash = "3.2"
|
||||
|
||||
# For moving files(why std::fs doesn't have such features?)
|
||||
fs_extra = "1.3"
|
||||
|
@ -44,7 +44,7 @@ fs_extra = "1.3"
|
|||
# Language
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
rust-embed = { version = "8.2", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
log = "0.4.20"
|
||||
|
|
|
@ -450,7 +450,7 @@ fn popover_custom_select_unselect(
|
|||
need_to_change_thing = true;
|
||||
}
|
||||
} else {
|
||||
if regex_check(&name_wildcard_lowercase_excluded, name.to_lowercase()) {
|
||||
if regex_check(&name_wildcard_lowercase_excluded, &name.to_lowercase()) {
|
||||
need_to_change_thing = true;
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ fn popover_custom_select_unselect(
|
|||
need_to_change_thing = true;
|
||||
}
|
||||
} else {
|
||||
if regex_check(&path_wildcard_lowercase_excluded, path.to_lowercase()) {
|
||||
if regex_check(&path_wildcard_lowercase_excluded, &path.to_lowercase()) {
|
||||
need_to_change_thing = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,15 +11,6 @@ repository = "https://github.com/qarmin/czkawka"
|
|||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
# Try to use only needed features from https://github.com/slint-ui/slint/blob/master/api/rs/slint/Cargo.toml#L23-L31
|
||||
#slint = { path = "/home/rafal/test/slint/api/rs/slint/", default-features = false, features = ["std",
|
||||
#slint = { git = "https://github.com/slint-ui/slint.git", default-features = false, features = [
|
||||
slint = { version = "1.3", default-features = false, features = [
|
||||
"std",
|
||||
"backend-winit",
|
||||
"compat-1-2"
|
||||
] }
|
||||
|
||||
rand = "0.8"
|
||||
czkawka_core = { version = "6.1.0", path = "../czkawka_core" }
|
||||
chrono = "0.4.31"
|
||||
|
@ -40,13 +31,21 @@ rayon = "1.8.0"
|
|||
# Translations
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
rust-embed = { version = "8.2", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
# Try to use only needed features from https://github.com/slint-ui/slint/blob/master/api/rs/slint/Cargo.toml#L23-L31
|
||||
#slint = { path = "/home/rafal/test/slint/api/rs/slint/", default-features = false, features = ["std",
|
||||
slint = { git = "https://github.com/slint-ui/slint.git", default-features = false, features = [
|
||||
# slint = { version = "1.3", default-features = false, features = [
|
||||
"std",
|
||||
"backend-winit",
|
||||
"compat-1-2"
|
||||
] }
|
||||
[build-dependencies]
|
||||
slint-build = "1.3"
|
||||
#slint-build = { git = "https://github.com/slint-ui/slint.git" }
|
||||
#slint-build = { path = "/home/rafal/test/slint/api/rs/build/"}
|
||||
slint-build = { git = "https://github.com/slint-ui/slint.git" }
|
||||
# slint-build = "1.3"
|
||||
|
||||
[features]
|
||||
default = ["winit_femtovg", "winit_software"]
|
||||
|
|
|
@ -3,7 +3,6 @@ use slint::{ComponentHandle, Model, ModelRc, VecModel};
|
|||
use crate::common::{get_is_header_mode, get_name_idx, get_path_idx};
|
||||
use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow};
|
||||
use czkawka_core::common::{remove_folder_if_contains_only_empty_folders, CHARACTER};
|
||||
use log::info;
|
||||
use rayon::prelude::*;
|
||||
|
||||
pub fn connect_delete_button(app: &MainWindow) {
|
||||
|
@ -64,7 +63,6 @@ fn remove_selected_items(items: Vec<MainListModel>, active_tab: CurrentTab) {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
info!("Removing items: {:?} {:?}", items_to_remove, active_tab);
|
||||
// Iterate over empty folders and not delete them if they are not empty
|
||||
if active_tab == CurrentTab::EmptyFolders {
|
||||
items_to_remove.into_par_iter().for_each(|item| {
|
||||
|
|
|
@ -259,7 +259,7 @@ pub fn save_base_settings_to_file(app: &MainWindow) {
|
|||
|
||||
pub fn save_custom_settings_to_file(app: &MainWindow) {
|
||||
let current_item = app.global::<Settings>().get_settings_preset_idx();
|
||||
let result = save_data_to_file(get_config_file(current_item), &collect_settings(app));
|
||||
let result = save_data_to_file(get_config_file(current_item + 1), &collect_settings(app));
|
||||
|
||||
if let Err(e) = result {
|
||||
error!("{e}");
|
||||
|
@ -279,14 +279,18 @@ where
|
|||
}
|
||||
|
||||
let result = match std::fs::read_to_string(&config_file) {
|
||||
Ok(serialized) => match serde_json::from_str(&serialized) {
|
||||
Ok(custom_settings) => Ok(custom_settings),
|
||||
Err(e) => Err(format!("Cannot deserialize settings: {e}")),
|
||||
},
|
||||
Ok(serialized) => {
|
||||
debug!("Loading data from file {:?} took {:?}", config_file, current_time.elapsed());
|
||||
|
||||
match serde_json::from_str(&serialized) {
|
||||
Ok(custom_settings) => Ok(custom_settings),
|
||||
Err(e) => Err(format!("Cannot deserialize settings: {e}")),
|
||||
}
|
||||
}
|
||||
Err(e) => Err(format!("Cannot read config file: {e}")),
|
||||
};
|
||||
|
||||
debug!("Loading data from file {:?} took {:?}", config_file, current_time.elapsed());
|
||||
debug!("Loading and converting data from file {:?} took {:?}", config_file, current_time.elapsed());
|
||||
|
||||
result
|
||||
}
|
||||
|
|
101
krokiet/ui/included_directories.slint
Normal file
101
krokiet/ui/included_directories.slint
Normal file
|
@ -0,0 +1,101 @@
|
|||
|
||||
import {Button, StandardListView, VerticalBox, ListView, ScrollView, TextEdit, CheckBox} from "std-widgets.slint";
|
||||
import {Callabler} from "callabler.slint";
|
||||
|
||||
export struct IncludedDirectoriesModel {
|
||||
path: string,
|
||||
referended_folder: bool,
|
||||
}
|
||||
|
||||
export component InlcudedDirectories {
|
||||
in-out property <[IncludedDirectoriesModel]> model: [{path: "/home/path", referended_folder: false}];
|
||||
in-out property <int> current_index: -1;
|
||||
|
||||
in-out property <length> size_referenced_folder: 40px;
|
||||
|
||||
min-width: 50px;
|
||||
VerticalLayout {
|
||||
HorizontalLayout {
|
||||
spacing: 5px;
|
||||
Text {
|
||||
text: "Referenced folder";
|
||||
width: size_referenced_folder;
|
||||
}
|
||||
Text{
|
||||
horizontal-stretch: 1.0;
|
||||
text: "Path";
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
for data in model : Rectangle {
|
||||
height: 30px;
|
||||
border_radius: 5px;
|
||||
width: parent.width;
|
||||
HorizontalLayout {
|
||||
spacing: 5px;
|
||||
width: parent.width;
|
||||
|
||||
CheckBox {
|
||||
checked: data.referended_folder;
|
||||
width: size_referenced_folder;
|
||||
}
|
||||
Text {
|
||||
horizontal-stretch: 1.0;
|
||||
text: data.path;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export component ExcludeDirectories {
|
||||
in-out property <[string]> model: ["/home/path"];
|
||||
in-out property <int> current_index: -1;
|
||||
private property <PointerEvent> event;
|
||||
|
||||
min-width: 50px;
|
||||
VerticalLayout {
|
||||
HorizontalLayout {
|
||||
spacing: 5px;
|
||||
Text {
|
||||
text: "Path";
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
for data[idx] in model : Rectangle {
|
||||
height: 30px;
|
||||
border_radius: 5px;
|
||||
width: parent.width;
|
||||
|
||||
touch_area := TouchArea {
|
||||
clicked => {
|
||||
if (current_index == -1) {
|
||||
|
||||
}
|
||||
}
|
||||
double-clicked => {
|
||||
if (event.button == PointerEventButton.middle && event.kind == PointerEventKind.up) {
|
||||
Callabler.item_opened(data)
|
||||
}
|
||||
}
|
||||
pointer-event(event) => {
|
||||
root.event = event;
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 5px;
|
||||
width: parent.width;
|
||||
|
||||
Text {
|
||||
horizontal-stretch: 1.0;
|
||||
text: data;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,7 +108,7 @@ export component LeftSidePanel {
|
|||
HorizontalLayout {
|
||||
alignment: start;
|
||||
Button {
|
||||
enabled: GuiState.active_tab != CurrentTab.Settings && GuiState.available_subsettings;
|
||||
visible: GuiState.active_tab != CurrentTab.Settings && GuiState.available_subsettings;
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
max-height: self.width;
|
||||
|
@ -122,7 +122,7 @@ export component LeftSidePanel {
|
|||
HorizontalLayout {
|
||||
alignment: end;
|
||||
Button {
|
||||
enabled: GuiState.active_tab != CurrentTab.Settings;
|
||||
visible: GuiState.active_tab != CurrentTab.Settings;
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
max-height: self.width;
|
||||
|
|
|
@ -75,17 +75,16 @@ export component SelectableTableView inherits Rectangle {
|
|||
height: 20px;
|
||||
background: r.header-row ? ColorPalette.list_view_normal_header_color : (touch-area.has-hover ? (r.selected_row ? ColorPalette.list-view-normal-selected-header : ColorPalette.list_view_normal_color) : (r.selected_row ? ColorPalette.list-view-normal-selected-header : ColorPalette.list_view_normal_color));
|
||||
touch_area := TouchArea {
|
||||
clicked => {
|
||||
function clicked_manual() {
|
||||
if (!r.header_row) {
|
||||
r.selected_row = !r.selected_row;
|
||||
if (root.selected-item == -1) {
|
||||
r.selected_row = !r.selected_row;
|
||||
root.selected-item = idx;
|
||||
} else {
|
||||
if (r.selected_row == true) {
|
||||
if (!r.selected_row && root.selected-item != idx) {
|
||||
r.selected_row = !r.selected_row;
|
||||
root.values[root.selected-item].selected_row = false;
|
||||
root.selected-item = idx;
|
||||
} else {
|
||||
root.selected-item = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,13 +95,19 @@ export component SelectableTableView inherits Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
double-clicked => {
|
||||
Callabler.item_opened(r.val[root.parentPathIdx - 1] + "/" + r.val[root.fileNameIdx - 1])
|
||||
}
|
||||
pointer-event(event) => {
|
||||
// TODO this should be clicked by double-click
|
||||
// TODO this should be clicked by double-click - https://github.com/slint-ui/slint/issues/4235
|
||||
if (event.button == PointerEventButton.right && event.kind == PointerEventKind.up) {
|
||||
Callabler.item_opened(r.val[root.parentPathIdx - 1])
|
||||
} else if (event.button == PointerEventButton.middle && event.kind == PointerEventKind.up) {
|
||||
Callabler.item_opened(r.val[root.parentPathIdx - 1] + "/" + r.val[root.fileNameIdx - 1])
|
||||
} else if (event.button == PointerEventButton.left && event.kind == PointerEventKind.up) {
|
||||
clicked_manual();
|
||||
}
|
||||
//else if (event.button == PointerEventButton.middle && event.kind == PointerEventKind.up) {
|
||||
// Callabler.item_opened(r.val[root.parentPathIdx - 1] + "/" + r.val[root.fileNameIdx - 1])
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { Preview } from "preview.slint";
|
|||
import {PopupNewDirectories} from "popup_new_directories.slint";
|
||||
import { PopupSelect } from "popup_select.slint";
|
||||
|
||||
component ComboBoxWrapper inherits HorizontalLayout {
|
||||
component ComboBoxWrapper inherits HorizontalLayout {
|
||||
in-out property <string> text;
|
||||
in-out property <[string]> model;
|
||||
in-out property <int> current_index;
|
||||
|
|
Loading…
Reference in a new issue