1
0
Fork 0
mirror of synced 2024-05-03 03:52:58 +12:00
This commit is contained in:
Rafał Mikrut 2024-02-14 22:44:39 +01:00
parent 1e9b055964
commit 6567bc7d8f
14 changed files with 65 additions and 89 deletions

View file

@ -9,7 +9,7 @@ pub fn get_str_path_idx(active_tab: CurrentTab) -> usize {
CurrentTab::EmptyFolders => 1,
CurrentTab::EmptyFiles => 1,
CurrentTab::SimilarImages => 4,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}
pub fn get_str_name_idx(active_tab: CurrentTab) -> usize {
@ -17,7 +17,7 @@ pub fn get_str_name_idx(active_tab: CurrentTab) -> usize {
CurrentTab::EmptyFolders => 0,
CurrentTab::EmptyFiles => 0,
CurrentTab::SimilarImages => 3,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}
@ -26,14 +26,14 @@ pub fn get_int_modification_date_idx(active_tab: CurrentTab) -> usize {
CurrentTab::EmptyFiles => 0,
CurrentTab::SimilarImages => 0,
CurrentTab::EmptyFolders => 0,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}
pub fn get_int_size_idx(active_tab: CurrentTab) -> usize {
match active_tab {
CurrentTab::EmptyFiles => 2,
CurrentTab::SimilarImages => 2,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
CurrentTab::EmptyFolders => panic!("Unable to get size from this tab"),
}
}
@ -41,14 +41,14 @@ pub fn get_int_size_idx(active_tab: CurrentTab) -> usize {
pub fn get_int_width_idx(active_tab: CurrentTab) -> usize {
match active_tab {
CurrentTab::SimilarImages => 4,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
_ => panic!("Unable to get height from this tab"),
}
}
pub fn get_int_height_idx(active_tab: CurrentTab) -> usize {
match active_tab {
CurrentTab::SimilarImages => 5,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
_ => panic!("Unable to get height from this tab"),
}
}
@ -57,7 +57,7 @@ pub fn get_is_header_mode(active_tab: CurrentTab) -> bool {
match active_tab {
CurrentTab::EmptyFolders | CurrentTab::EmptyFiles => false,
CurrentTab::SimilarImages => true,
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}
@ -66,7 +66,7 @@ pub fn get_tool_model(app: &MainWindow, tab: CurrentTab) -> ModelRc<MainListMode
CurrentTab::EmptyFolders => app.get_empty_folder_model(),
CurrentTab::SimilarImages => app.get_similar_images_model(),
CurrentTab::EmptyFiles => app.get_empty_files_model(),
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}
@ -75,7 +75,7 @@ pub fn set_tool_model(app: &MainWindow, tab: CurrentTab, model: ModelRc<MainList
CurrentTab::EmptyFolders => app.set_empty_folder_model(model),
CurrentTab::SimilarImages => app.set_similar_images_model(model),
CurrentTab::EmptyFiles => app.set_empty_files_model(model),
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
}

View file

@ -6,7 +6,7 @@ use czkawka_core::common_messages::Messages;
use crate::common::{get_is_header_mode, get_tool_model, set_tool_model};
use crate::model_operations::{collect_full_path_from_model, deselect_all_items, filter_out_checked_items};
use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow};
use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow, Settings};
pub fn connect_delete_button(app: &MainWindow) {
let a = app.as_weak();
@ -17,9 +17,9 @@ pub fn connect_delete_button(app: &MainWindow) {
let model = get_tool_model(&app, active_tab);
let remove_to_trash = false;
let settings = app.global::<Settings>();
let (errors, new_model) = handle_delete_items(&model, active_tab, remove_to_trash);
let (errors, new_model) = handle_delete_items(&app, &model, active_tab, settings.get_move_to_trash());
if let Some(new_model) = new_model {
set_tool_model(&app, active_tab, new_model);
@ -31,13 +31,14 @@ pub fn connect_delete_button(app: &MainWindow) {
});
}
fn handle_delete_items(items: &ModelRc<MainListModel>, active_tab: CurrentTab, remove_to_trash: bool) -> (Vec<String>, Option<ModelRc<MainListModel>>) {
fn handle_delete_items(app: &MainWindow, items: &ModelRc<MainListModel>, active_tab: CurrentTab, remove_to_trash: bool) -> (Vec<String>, Option<ModelRc<MainListModel>>) {
let (entries_to_delete, mut entries_left) = filter_out_checked_items(items, get_is_header_mode(active_tab));
if !entries_to_delete.is_empty() {
let vec_items_to_remove = collect_full_path_from_model(&entries_to_delete, active_tab);
let errors = remove_selected_items(vec_items_to_remove, active_tab, remove_to_trash);
deselect_all_items(&mut entries_left);
app.set_text_summary_text(format!("Deleted {} items, failed to remove {} items", entries_to_delete.len() - errors.len(), errors.len()).into());
let r = ModelRc::new(VecModel::from(entries_left)); // TODO here maybe should also stay old model if entries cannot be removed
return (errors, Some(r));
@ -48,7 +49,6 @@ fn handle_delete_items(items: &ModelRc<MainListModel>, active_tab: CurrentTab, r
// TODO delete in parallel items, consider to add progress bar
// For empty folders double check if folders are really empty - this function probably should be run in thread
// and at the end should be send signal to main thread to update model
// TODO handle also situations where cannot delete file/folder
fn remove_selected_items(items_to_remove: Vec<String>, active_tab: CurrentTab, remove_to_trash: bool) -> Vec<String> {
// Iterate over empty folders and not delete them if they are not empty
if active_tab == CurrentTab::EmptyFolders {

View file

@ -37,4 +37,13 @@ pub fn connect_open_items(app: &MainWindow) {
error!("Failed to open cache folder {:?}: {e}", cache_folder);
}
});
app.global::<Callabler>().on_open_link(move |link| {
match open::that(link.as_str()) {
Ok(()) => {}
Err(e) => {
eprintln!("Failed to open link: {e}");
}
};
});
}

View file

@ -46,7 +46,7 @@ pub fn connect_scan_button(app: &MainWindow, progress_sender: Sender<ProgressDat
CurrentTab::SimilarImages => {
scan_similar_images(a, progress_sender, stop_receiver, custom_settings);
}
CurrentTab::Settings => panic!("Button should be disabled"),
CurrentTab::Settings | CurrentTab::About => panic!("Button should be disabled"),
}
});
}
@ -58,12 +58,12 @@ fn scan_similar_images(a: Weak<MainWindow>, progress_sender: Sender<ProgressData
let mut finder = SimilarImages::new();
set_common_settings(&mut finder, &custom_settings);
finder.set_hash_size(custom_settings.similar_images_sub_hash_size);
let resize_algortithm = ALLOWED_RESIZE_ALGORITHM_VALUES
let resize_algorithm = ALLOWED_RESIZE_ALGORITHM_VALUES
.iter()
.find(|(setting_name, _gui_name, _resize_alg)| setting_name == &custom_settings.similar_images_sub_resize_algorithm)
.expect("Resize algorithm not found")
.2;
finder.set_image_filter(resize_algortithm);
finder.set_image_filter(resize_algorithm);
let hash_type = ALLOWED_HASH_TYPE_VALUES
.iter()
.find(|(setting_name, _gui_name, _resize_alg)| setting_name == &custom_settings.similar_images_sub_hash_type)

View file

@ -64,10 +64,6 @@ fn main() {
let (progress_sender, progress_receiver): (Sender<ProgressData>, Receiver<ProgressData>) = unbounded();
let (stop_sender, stop_receiver): (Sender<()>, Receiver<()>) = unbounded();
// to_remove_debug(&app);
// Slint files may already contains data in models, so clear them before starting - todo,
// check if non zeroed models are useful
zeroing_all_models(&app);
set_initial_gui_infos(&app);
@ -98,56 +94,3 @@ pub fn zeroing_all_models(app: &MainWindow) {
app.set_empty_files_model(Rc::new(VecModel::default()).into());
app.set_similar_images_model(Rc::new(VecModel::default()).into());
}
// // TODO remove this after debugging - or leave commented
// pub fn to_remove_debug(app: &MainWindow) {
// app.set_empty_folder_model(to_remove_create_without_header("@@").into());
// app.set_empty_files_model(to_remove_create_without_header("%%").into());
// app.set_similar_images_model(to_remove_create_with_header().into());
// }
// fn to_remove_create_with_header() -> Rc<VecModel<MainListModel>> {
// let header_row_data: Rc<VecModel<MainListModel>> = Rc::new(VecModel::default());
// for r in 0..10_000 {
// let items = VecModel::default();
//
// for c in 0..3 {
// items.push(slint::format!("Item {r}.{c}"));
// }
//
// let is_header = r % 3 == 0;
// let is_checked = (r % 2 == 0) && !is_header;
//
// let item = MainListModel {
// checked: is_checked,
// header_row: is_header,
// selected_row: false,
// val: ModelRc::new(items),
// };
//
// header_row_data.push(item);
// }
// header_row_data
// }
// fn to_remove_create_without_header(s: &str) -> Rc<VecModel<MainListModel>> {
// let non_header_row_data: Rc<VecModel<MainListModel>> = Rc::new(VecModel::default());
// for r in 0..100_000 {
// let items = VecModel::default();
//
// for c in 0..3 {
// items.push(slint::format!("Item {r}.{c}.{s}"));
// }
//
// let is_checked = r % 2 == 0;
//
// let item = MainListModel {
// checked: is_checked,
// header_row: false,
// selected_row: false,
// val: ModelRc::new(items),
// };
//
// non_header_row_data.push(item);
// }
// non_header_row_data
// }

View file

@ -199,7 +199,7 @@ pub fn create_default_settings_files() {
}
}
for i in 1..=10 {
for i in 0..10 {
let config_file = get_config_file(i);
if let Some(config_file) = config_file {
if !config_file.is_file() {

View file

@ -23,10 +23,10 @@ export component ActionButtons inherits HorizontalLayout {
callback show_select_popup(length, length);
callback show_remove_popup();
callback request_folder_to_move();
in-out property <BottomPanelVisibility> bottom_panel_visibility: BottomPanelVisibility.Directories;
in-out property <BottomPanelVisibility> bottom_panel_visibility <=> GuiState.bottom_panel_visibility;
in-out property <bool> stop_requested: false;
in-out property <bool> scanning;
in-out property <bool> lists_enabled: GuiState.active_tab != CurrentTab.Settings;
in-out property <bool> lists_enabled: GuiState.is_tool_tab_active;
out property <int> name;
height: 30px;
spacing: 4px;

View file

@ -32,4 +32,6 @@ export global Callabler {
callback open_config_folder();
callback open_cache_folder();
callback open_link(string);
}

View file

@ -2,7 +2,8 @@ export enum CurrentTab {
EmptyFolders,
EmptyFiles,
SimilarImages,
Settings
Settings,
About
}
export enum TypeOfOpenedItem {

View file

@ -1,5 +1,5 @@
import {CurrentTab} from "common.slint";
import {SelectModel, SelectMode} from "common.slint";
import {SelectModel, SelectMode, BottomPanelVisibility} from "common.slint";
// State Gui state that shows the current state of the GUI
// It extends Settings global state with settings that are not saved to the settings file
@ -19,5 +19,8 @@ export global GuiState {
in-out property <bool> available_subsettings: active_tab == CurrentTab.SimilarImages;
in-out property <CurrentTab> active_tab: CurrentTab.EmptyFiles;
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 <BottomPanelVisibility> bottom_panel_visibility: BottomPanelVisibility.Directories;
}

View file

@ -1,5 +1,5 @@
import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListView, StandardTableView, CheckBox} from "std-widgets.slint";
import {CurrentTab} from "common.slint";
import {CurrentTab, BottomPanelVisibility} from "common.slint";
import {ColorPalette} from "color_palette.slint";
import {GuiState} from "gui_state.slint";
import {Callabler} from "callabler.slint";
@ -70,11 +70,20 @@ export component LeftSidePanel {
VerticalLayout {
spacing: 20px;
Rectangle {
visible: GuiState.active_tab != CurrentTab.About;
height: 100px;
Image {
width: root.width;
source: @image-url("../icons/logo.png");
}
touch_area := TouchArea {
clicked => {
GuiState.active_tab = CurrentTab.About;
Callabler.tab_changed();
root.changed_current_tab();
GuiState.bottom_panel_visibility = BottomPanelVisibility.NotVisible;
}
}
}
VerticalLayout {
@ -110,7 +119,7 @@ export component LeftSidePanel {
HorizontalLayout {
alignment: start;
Button {
visible: GuiState.active_tab != CurrentTab.Settings && GuiState.available_subsettings;
visible: GuiState.available_subsettings;
min-width: 20px;
min-height: 20px;
max-height: self.width;

View file

@ -5,6 +5,7 @@ import {CurrentTab, TypeOfOpenedItem} from "common.slint";
import {MainListModel} from "common.slint";
import {SettingsList} from "settings_list.slint";
import {GuiState} from "gui_state.slint";
import {About} from "about.slint";
export component MainList {
in-out property <[MainListModel]> empty_folder_model: [
@ -55,6 +56,10 @@ export component MainList {
visible: GuiState.active_tab == CurrentTab.Settings;
}
about_app := About {
visible: GuiState.active_tab == CurrentTab.About;
}
focus_item := FocusScope {
width: 0px; // Hack to not steal first click from other components - https://github.com/slint-ui/slint/issues/3503
// Hack not works https://github.com/slint-ui/slint/issues/3503#issuecomment-1817809834 because disables key-released event

View file

@ -83,7 +83,7 @@ export component MainWindow inherits Window {
similar_images_model <=> root.similar_images_model;
}
preview_or_tool_settings := Rectangle {
visible: (GuiState.preview_visible || tool_settings.visible) && GuiState.active_tab != CurrentTab.Settings;
visible: (GuiState.preview_visible || tool_settings.visible) && GuiState.is_tool_tab_active;
height: parent.height;
x: parent.width / 2;
width: self.visible ? parent.width / 2 : 0;
@ -134,9 +134,17 @@ export component MainWindow inherits Window {
}
}
text_summary := LineEdit {
text: text_summary_text;
read-only: true;
HorizontalLayout {
spacing: 5px;
text_summary := LineEdit {
text: text_summary_text;
read-only: true;
}
Text {
text: "Krokiet\n7.0.0";
vertical-alignment: center;
horizontal-alignment: center;
}
}
bottom_panel := BottomPanel {

View file

@ -84,10 +84,6 @@ export component PopupMoveFolders inherits Rectangle {
}
}
init => {
show_popup();
}
show_popup() => {
popup_window.show();
}