1
0
Fork 0
mirror of synced 2024-05-17 19:03:08 +12:00

Header row

This commit is contained in:
Rafał Mikrut 2023-10-21 08:36:56 +02:00
parent ac636dfdad
commit 19f0be721f
7 changed files with 196 additions and 119 deletions

91
Cargo.lock generated
View file

@ -959,8 +959,7 @@ dependencies = [
[[package]]
name = "const-field-offset"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6304465f16f463cddc572b737c3df93576edd3a6b53f057bd8beeb29f4ef8dfd"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"const-field-offset-macro",
"field-offset",
@ -969,8 +968,7 @@ dependencies = [
[[package]]
name = "const-field-offset-macro"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57aaaad9185d3bcb3afe63549d8ba60b2fb0ea8dc2da83f62dd56805edf56fd1"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"proc-macro2",
"quote",
@ -1329,6 +1327,8 @@ dependencies = [
name = "czkawka_slint"
version = "6.1.0"
dependencies = [
"chrono",
"czkawka_core",
"rand",
"slint",
"slint-build",
@ -1569,12 +1569,6 @@ dependencies = [
"libc",
]
[[package]]
name = "dunce"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
[[package]]
name = "dwrote"
version = "0.11.0"
@ -2656,9 +2650,8 @@ dependencies = [
[[package]]
name = "i-slint-backend-linuxkms"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e321d0f8d12509ec2ed5b5aba4996922606686ac3d86d70ba126cba1b4e4563"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"calloop 0.11.0",
"drm",
@ -2676,9 +2669,8 @@ dependencies = [
[[package]]
name = "i-slint-backend-qt"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f1ce3687c329341842f79c31c95d7bcf49b6fda7fd19b09e0b5d7fb33b9d6b2"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"const-field-offset",
"cpp",
@ -2696,22 +2688,21 @@ dependencies = [
[[package]]
name = "i-slint-backend-selector"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7382cc01e9c9ef607debe1e4af7e1c6af78720a258fd18d8e32761b8593c5db"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"cfg-if",
"i-slint-backend-linuxkms",
"i-slint-backend-qt",
"i-slint-backend-winit",
"i-slint-common",
"i-slint-core",
]
[[package]]
name = "i-slint-backend-winit"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c0f3f01e2c678d24b81914a38e53d3b660a0ef13831acb59c71bd7c95ed0cb"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"accesskit",
"accesskit_winit",
@ -2748,9 +2739,8 @@ dependencies = [
[[package]]
name = "i-slint-common"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7daf484e68bf27e06b7501767c6e66063c0f85948e57a6de679b53d2d9d2044"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"cfg-if",
"derive_more",
@ -2760,16 +2750,14 @@ dependencies = [
[[package]]
name = "i-slint-compiler"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b99172cc43ca17a78e96e3f8f13699d9fc1c00474d2d87bc57c0f7e816c4a48"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"by_address",
"codemap",
"codemap-diagnostic",
"css-color-parser2",
"derive_more",
"dunce",
"fontdue",
"i-slint-common",
"image",
@ -2791,9 +2779,8 @@ dependencies = [
[[package]]
name = "i-slint-core"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62e590bb3d6009447a52760e9343c25a3bf7a8a7b0ad7ab5a77c5324fcaa957"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"auto_enums",
"bytemuck",
@ -2835,9 +2822,8 @@ dependencies = [
[[package]]
name = "i-slint-core-macros"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62a416f1e9fc42c2bf1f171e5be38a8155850fcd390fce300869bcc9d6c9c117"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"quote",
"syn 2.0.38",
@ -2845,9 +2831,8 @@ dependencies = [
[[package]]
name = "i-slint-renderer-femtovg"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e99a941fca00b96a7756d56e4bc5e2876283f34c693eabc73585c0b91ab84f0"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"cfg-if",
"const-field-offset",
@ -2879,9 +2864,8 @@ dependencies = [
[[package]]
name = "i-slint-renderer-skia"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f617268cfee53e1fa3fcab8f6ab2775deacfce74057386c4ad39ef2647f8db6"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"cfg-if",
"cfg_aliases",
@ -3389,11 +3373,9 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a0adf8d8607a73a5b74cbe4132f57cb349e4bf860103cd089461bbcbc9907e"
dependencies = [
"cc",
"errno",
"libseat-sys",
"log",
"pkg-config",
]
[[package]]
@ -5062,9 +5044,8 @@ dependencies = [
[[package]]
name = "slint"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9a6f76430dde7dc57d374c37aa3103532813cc275a94b515b5907e91dd19334"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"const-field-offset",
"i-slint-backend-selector",
@ -5079,21 +5060,19 @@ dependencies = [
[[package]]
name = "slint-build"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6edc7309a89f14c685086544ea3dbd7668ccdeb03d774f06879f38237e55815"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"i-slint-compiler",
"spin_on",
"thiserror",
"toml_edit 0.19.15",
"toml_edit 0.20.2",
]
[[package]]
name = "slint-macros"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33f96e5ea0574ac69b773b159d43124f7a329107cf60c11516e63d38c2d8c89c"
version = "1.3.0"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"i-slint-compiler",
"proc-macro2",
@ -6226,8 +6205,7 @@ dependencies = [
[[package]]
name = "vtable"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f4c7506238561777a1861d3dc3c0001877c475187e7bc4392ea87ebf631fd9c"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"const-field-offset",
"portable-atomic",
@ -6238,8 +6216,7 @@ dependencies = [
[[package]]
name = "vtable-macro"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b2b8eecdb8e4284adf5546fc518f048f6dc33e7203dbe36fa93a4add39b31f6"
source = "git+https://github.com/slint-ui/slint.git?branch=olivier/fix-3700#c03366792958460a84e4c340a34928643338a963"
dependencies = [
"proc-macro2",
"quote",

View file

@ -14,7 +14,8 @@ build = "build.rs"
#slint = "1.2.2"
slint = { git = "https://github.com/slint-ui/slint.git", branch = "olivier/fix-3700"}
rand = "0.8.5"
#czkawka_core = { version = "6.1.0", path = "../czkawka_core" }
czkawka_core = { version = "6.1.0", path = "../czkawka_core" }
chrono = "0.4.31"
[build-dependencies]
slint-build = { git = "https://github.com/slint-ui/slint.git", branch = "olivier/fix-3700"}

View file

@ -0,0 +1,30 @@
use crate::MainWindow;
use slint::{ComponentHandle, Model, ModelRc, VecModel};
use std::borrow::BorrowMut;
pub fn connect_delete_button(app: &MainWindow) {
let a = app.as_weak();
app.on_deleted(move || {
let app = a.upgrade().unwrap();
let mut r = app.get_empty_folder_model();
let m = r.borrow_mut();
let length_before = m.iter().count();
let (entries_to_delete, entries_left): (Vec<_>, Vec<_>) = m.iter().partition(|(checked, _selected_row, _header_row, _data)| *checked);
let mut s: Vec<_> = m.iter().filter(|(checked, _selected_row, _header_row, _data)| !*checked).collect();
entries_to_delete.into_iter().for_each(|(_checked, _selected_row, _header_row, _data)| {
// TODO delete in parallel items, consider to add progress bar
});
let length_after = s.len();
if length_before != length_after {
dbg!(format!("Items to remove {}", length_before - length_after));
s.iter_mut().for_each(|(_checked, selected_row, _header_row, _data)| {
*selected_row = false;
});
let r = ModelRc::new(VecModel::from(s));
app.set_empty_folder_model(r.into());
}
});
}

View file

@ -0,0 +1,54 @@
use crate::{split_path, CurrentTab, MainWindow};
use chrono::NaiveDateTime;
use czkawka_core::common_tool::CommonData;
use czkawka_core::empty_folder::EmptyFolder;
use slint::{ComponentHandle, ModelRc, SharedString, VecModel};
use std::path::PathBuf;
use std::rc::Rc;
use std::thread;
pub fn connect_scan_button(app: &MainWindow) {
let a = app.as_weak();
app.on_scanned(move |active_tab| {
let app = a.upgrade().unwrap();
app.set_scanning(true);
let a = app.as_weak();
match active_tab {
CurrentTab::EmptyFolders => {
thread::spawn(move || {
let mut ef = EmptyFolder::new();
ef.set_included_directory(vec![PathBuf::from("/home/rafal/Desktop")]);
ef.find_empty_folders(None, None);
ef.get_empty_folder_list();
let mut vector = ef.get_empty_folder_list().keys().cloned().collect::<Vec<PathBuf>>();
vector.sort_unstable_by_key(|e| {
let t = split_path(e.as_path());
(t.0, t.1)
});
a.upgrade_in_event_loop(move |app| {
let mut folder_map = ef.get_empty_folder_list();
let items = Rc::new(VecModel::default());
for path in vector {
let (directory, file) = split_path(&path);
let data_model = VecModel::from_slice(&[
SharedString::from(file),
SharedString::from(directory),
SharedString::from(NaiveDateTime::from_timestamp_opt(folder_map[&path].modified_date as i64, 0).unwrap().to_string()),
]);
items.push((false, false, false, ModelRc::new(data_model)));
}
app.set_empty_folder_model(items.into());
app.set_scanning(false);
})
});
}
_ => panic!(),
}
});
}

View file

@ -1,11 +1,21 @@
use std::rc::Rc;
use slint::{Model, ModelRc, SharedString, VecModel};
slint::include_modules!();
use std::borrow::BorrowMut;
mod connect_delete;
mod connect_scan;
use std::borrow::BorrowMut;
use std::path::Path;
use std::rc::Rc;
use crate::connect_delete::connect_delete_button;
use crate::connect_scan::connect_scan_button;
use czkawka_core::common_tool::CommonData;
use czkawka_core::empty_folder::EmptyFolder;
use slint::{Model, ModelRc, SharedString, VecModel};
slint::include_modules!();
fn main() {
let app = MainWindow::new().unwrap();//.run().unwrap();
let row_data: Rc<VecModel<(bool,bool,ModelRc<SharedString>)>> = Rc::new(VecModel::default());
let app = MainWindow::new().unwrap(); //.run().unwrap();
let row_data: Rc<VecModel<(bool, bool, bool, ModelRc<SharedString>)>> = Rc::new(VecModel::default());
for r in 0..1000 {
let items = VecModel::default();
@ -14,33 +24,20 @@ fn main() {
items.push(slint::format!("Item {r}.{c}").into());
}
row_data.push((r % 2 == 0, r% 3 == 0, ModelRc::new(items)));
row_data.push((r % 4 == 0, r % 3 == 0, r % 2 == 0, ModelRc::new(items)));
}
app.set_empty_folder_model(row_data.into());
// app.set_empty_folder_model(row_data.into());
let a = app.as_weak();
app.on_deleted(move || {
let app = a.upgrade().unwrap();
let mut r = app.get_empty_folder_model();
let m = r.borrow_mut();
let length_before = m.iter().count();
let mut s: Vec<_> = m.iter().filter(|(a,_b,_c)|{
!*a
}).collect();
let length_after = s.len();
if length_before != length_after {
dbg!(format!("Items to remove {}", length_before - length_after));
s.iter_mut().for_each(|(_a, selected_row, _)|{
*selected_row = false;
});
let r = ModelRc::new(VecModel::from(s));
app.set_empty_folder_model(r.into());
}
});
connect_delete_button(&app);
connect_scan_button(&app);
app.run().unwrap();
}
}
pub fn split_path(path: &Path) -> (String, String) {
match (path.parent(), path.file_name()) {
(Some(dir), Some(file)) => (dir.display().to_string(), file.to_string_lossy().into_owned()),
(Some(dir), None) => (dir.display().to_string(), String::new()),
(None, _) => (String::new(), String::new()),
}
}

View file

@ -1,19 +1,24 @@
import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListView, StandardTableView, CheckBox} from "std-widgets.slint";
import {SelectableTableView} from "selectable_tree_view.slint";
import {LeftSidePanel} from "left_side_panel.slint";
import {CurrentTab} from "common.slint";
enum CurrentTab {
EmptyFolders,
SimilarImages,
}
export component MainWindow {
export component MainWindow inherits Window {
callback deleted;
in-out property <CurrentTab> active-tab;
in-out property <[{checked: bool, selected_row: bool, val:[string]}]> empty-folder-model: [
{checked: false, selected_row: false, val: ["kropkarz", "/Xd1", "24.10.2023"]} ,
{checked: false, selected_row: true, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
{checked: true, selected_row: false, val: ["lokkaler", "/Xd1/Vide2", "01.23.1911"]} ,
];
callback scanned(CurrentTab);
in-out property <bool> scanning: false;
in-out property <CurrentTab> active-tab: CurrentTab.EmptyFolders;
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> empty_folder_model: [
{checked: false, selected_row: false, header_row: true, val: ["kropkarz", "/Xd1", "24.10.2023"]} ,
{checked: false, selected_row: true, header_row: false, val: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"]} ,
{checked: true, selected_row: false, header_row: false, val: ["lokkaler", "/Xd1/Vide2", "01.23.1911"]}
];
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> empty_files_model: [];
in-out property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> similar_images_model: [];
title: root.active-tab == CurrentTab.EmptyFiles ? "EmptyFiles" : (root.active-tab == CurrentTab.EmptyFolders ? "EmptyFolders" : "Similar Images");
min-width: 200px;
VerticalBox {
@ -21,32 +26,42 @@ export component MainWindow {
// min-width: 600px;
preferred-height: 300px;
tab_bar := VerticalLayout {
width: 120px;
spacing: 3px;
Button {
text: "Empty Folders";
clicked => { root.active-tab = CurrentTab.EmptyFolders; }
}
Button {
text: "Similar Images";
clicked => { root.active-tab = CurrentTab.SimilarImages; }
}
LeftSidePanel {
scanning: root.scanning;
active-tab <=> root.active-tab;
}
// TODO - using root.active-tab in visible property will not
// TODO - using root.active-tab in visible property will not clear model
if root.active-tab == CurrentTab.EmptyFolders: SelectableTableView {
min-width: 200px;
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
values: empty-folder-model;
}
if root.active-tab == CurrentTab.EmptyFiles: SelectableTableView {
min-width: 200px;
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
values: empty-files-model;
}
if root.active-tab == CurrentTab.SimilarImages: SelectableTableView {
min-width: 200px;
columns: ["Selection", "Folder Name", "Path", "Modification Date"];
values: similar-images-model;
}
}
HorizontalBox {
height: 50px;
scan_button:= Button {
enabled: !scanning;
text: "Scan";
clicked => {
root.scanned(active-tab);
}
}
delete_button:= Button {
enabled: !scanning;
text: "Delete";
clicked => {
root.deleted();
@ -55,4 +70,3 @@ export component MainWindow {
}
}
}

View file

@ -2,7 +2,7 @@ import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListV
export component SelectableTableView inherits Rectangle {
in property <[string]> columns;
in property <[{checked: bool, selected_row: bool, val:[string]}]> values;
in property <[{checked: bool, selected_row: bool, header_row: bool, val:[string]}]> values;
private property <[length]> column_sizes: [30px, 100px, 100px, 100px];
private property <int> column_number: 4;
@ -44,13 +44,16 @@ export component SelectableTableView inherits Rectangle {
}
}
list_view:= ListView {
min-width: 100px;
for r[idx] in root.values : Rectangle {
background: touch-area.has-hover ? (r.selected_row ? #cccccc : #dddddd) : (r.selected_row ? #cccccc: #dddddd);
background: r.header-row ? #888888 : (touch-area.has-hover ? (r.selected_row ? #cccccc : #dddddd) : (r.selected_row ? #cccccc: #dddddd));
// background: touch-area.has-hover ? (selected ? #333333 : #222222) : (selected ? #333333: #222222);
touch_area:= TouchArea {
clicked => {
r.selected_row = !r.selected_row
if (!r.header_row) {
r.selected_row = !r.selected_row
}
}
}
@ -61,7 +64,8 @@ export component SelectableTableView inherits Rectangle {
CheckBox {
//min-width: 200px;
checked: r.checked;
visible: !r.header-row;
checked: r.checked && !r.header-row;
width: root.column-sizes[0];
toggled => {
r.checked = self.checked;