1
0
Fork 0
mirror of synced 2024-05-12 00:13:06 +12:00
czkawka/czkawka_gui/src/main.rs

178 lines
7.7 KiB
Rust
Raw Normal View History

// Remove console window in Windows OS
#![windows_subsystem = "windows"]
2021-07-16 16:51:54 +12:00
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::too_many_arguments)]
mod compute_results;
2021-01-25 00:01:02 +13:00
mod connect_about_buttons;
mod connect_button_delete;
2021-02-25 01:53:46 +13:00
mod connect_button_hardlink;
mod connect_button_move;
mod connect_button_save;
mod connect_button_search;
mod connect_button_select;
mod connect_button_stop;
2021-01-25 00:01:02 +13:00
mod connect_header_buttons;
mod connect_hide_text_view_errors;
mod connect_notebook_tabs;
2020-11-09 22:09:22 +13:00
mod connect_popovers;
2020-12-02 22:25:27 +13:00
mod connect_progress_window;
mod connect_selection_of_directories;
mod connect_settings;
mod connect_similar_image_size_change;
mod create_tree_view;
2021-01-25 00:01:02 +13:00
mod gui_about;
mod gui_bottom_buttons;
mod gui_data;
2021-01-25 00:01:02 +13:00
mod gui_header;
mod gui_main_notebook;
mod gui_popovers;
mod gui_progress_dialog;
2021-02-23 21:40:19 +13:00
mod gui_settings;
mod gui_upper_notepad;
mod help_functions;
mod initialize_gui;
2021-01-11 00:06:25 +13:00
mod notebook_enums;
mod opening_selecting_records;
mod saving_loading;
Windows taskbar progress support (#264) * Initial Windows taskbar progress support * Changes to COM (un)init It turns out winapi exposes IIDs through a `uuidof()` function of interfaces, so the copied one can be removed. * Don't return error codes Now the `TaskbarProgress` functions fail silently. The `TaskbarProgress` struct now will always be created (even in case of errors in initialisation), but it won't do anything. * Fix builds for other systems * Formatted code * Fix progress shown after the operation finished A progress update was received after the stop event. Also `as_ref()` was removed in many places (I don't even know why it was there). * Remove redundant call to hide It's already called by the `glib_stop_receiver` receiver. * Release the ITaskbarList3 and call CoUninitialize at exit Because objects moved to closures used as fallbacks in GTK have [static lifetimes](https://gtk-rs.org/docs-src/tutorial/closures#closures), the `TaskbarProgress` will never be dropped. To workaround this problem a `release` function is called when the main window is closed. This function behaves like `drop`, but sets the struct in a valid "empty" state, so that calling `release`/`drop` again won't cause problems. * Don't set the NORMAL state manually Because only NOPROGRESS and INDETERMINATE states are used, there is no need to set the NORMAL state when changing the progress value. Now `set_progress_value` will also change the `TaskbarProgress::current_state` if such situation occurs. > Unless [SetProgressState](https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate) > has set a blocking state (TBPF_ERROR or TBPF_PAUSED) for the window, a call to **SetProgressValue** assumes the TBPF_NORMAL > state even if it is not explicitly set. A call to **SetProgressValue** overrides and clears the TBPF_INDETERMINATE state. See the [SetProgressValue documentation](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressvalue#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group)
2021-02-21 00:24:36 +13:00
mod taskbar_progress;
#[cfg(not(target_os = "windows"))]
mod taskbar_progress_dummy;
#[cfg(target_os = "windows")]
mod taskbar_progress_win;
mod tests;
use czkawka_core::*;
use crate::compute_results::*;
2021-01-25 00:01:02 +13:00
use crate::connect_about_buttons::*;
use crate::connect_button_delete::*;
2021-02-25 01:53:46 +13:00
use crate::connect_button_hardlink::*;
use crate::connect_button_move::*;
use crate::connect_button_save::*;
use crate::connect_button_search::*;
use crate::connect_button_select::*;
use crate::connect_button_stop::*;
2021-01-25 00:01:02 +13:00
use crate::connect_header_buttons::*;
use crate::connect_hide_text_view_errors::*;
use crate::connect_notebook_tabs::*;
2020-11-09 22:09:22 +13:00
use crate::connect_popovers::*;
2020-12-02 22:25:27 +13:00
use crate::connect_progress_window::*;
use crate::connect_selection_of_directories::*;
use crate::connect_settings::*;
use crate::connect_similar_image_size_change::*;
use crate::gui_data::*;
use crate::initialize_gui::*;
use crate::saving_loading::*;
use crate::tests::validate_notebook_data;
use gtk::prelude::*;
use std::{env, process};
fn main() {
let mut exit_program_after_initialization: bool = false;
// Printing version
{
let all_arguments: Vec<String> = env::args().skip(1).collect(); // Not need to check program name
for i in all_arguments {
if i == "-v" || i == "--version" {
2020-10-02 03:54:26 +13:00
println!("Czkawka GUI {}", CZKAWKA_VERSION);
process::exit(0);
}
if i == "-q" || i == "--quit" {
exit_program_after_initialization = true;
}
}
}
2020-09-05 07:12:18 +12:00
gtk::init().expect("Failed to initialize GTK.");
let mut gui_data: GuiData = GuiData::new();
// Used for getting data from thread
2020-12-02 22:25:27 +13:00
let (glib_stop_sender, glib_stop_receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
// Futures progress report
let (futures_sender_duplicate_files, futures_receiver_duplicate_files): (futures::channel::mpsc::UnboundedSender<duplicate::ProgressData>, futures::channel::mpsc::UnboundedReceiver<duplicate::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_empty_files, futures_receiver_empty_files): (futures::channel::mpsc::UnboundedSender<empty_files::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_files::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_empty_folder, futures_receiver_empty_folder): (futures::channel::mpsc::UnboundedSender<empty_folder::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_folder::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_big_file, futures_receiver_big_file): (futures::channel::mpsc::UnboundedSender<big_file::ProgressData>, futures::channel::mpsc::UnboundedReceiver<big_file::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_same_music, futures_receiver_same_music): (futures::channel::mpsc::UnboundedSender<same_music::ProgressData>, futures::channel::mpsc::UnboundedReceiver<same_music::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_similar_images, futures_receiver_similar_images): (futures::channel::mpsc::UnboundedSender<similar_images::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_images::ProgressData>) =
futures::channel::mpsc::unbounded();
let (futures_sender_similar_videos, futures_receiver_similar_videos): (futures::channel::mpsc::UnboundedSender<similar_videos::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_videos::ProgressData>) =
futures::channel::mpsc::unbounded();
let (futures_sender_temporary, futures_receiver_temporary): (futures::channel::mpsc::UnboundedSender<temporary::ProgressData>, futures::channel::mpsc::UnboundedReceiver<temporary::ProgressData>) = futures::channel::mpsc::unbounded();
let (futures_sender_invalid_symlinks, futures_receiver_invalid_symlinks): (futures::channel::mpsc::UnboundedSender<invalid_symlinks::ProgressData>, futures::channel::mpsc::UnboundedReceiver<invalid_symlinks::ProgressData>) =
futures::channel::mpsc::unbounded();
let (futures_sender_broken_files, futures_receiver_broken_files): (futures::channel::mpsc::UnboundedSender<broken_files::ProgressData>, futures::channel::mpsc::UnboundedReceiver<broken_files::ProgressData>) = futures::channel::mpsc::unbounded();
initialize_gui(&mut gui_data);
validate_notebook_data(&gui_data); // Must be run after initialization of gui, to check if everything was properly setup
reset_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Fallback for invalid loading setting project
load_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors, &gui_data.scrolled_window_errors);
connect_button_delete(&gui_data);
connect_button_save(&gui_data);
2020-12-02 22:25:27 +13:00
connect_button_search(
&gui_data,
glib_stop_sender,
futures_sender_duplicate_files,
futures_sender_empty_files,
futures_sender_empty_folder,
futures_sender_big_file,
futures_sender_same_music,
futures_sender_similar_images,
futures_sender_similar_videos,
2020-12-02 22:25:27 +13:00
futures_sender_temporary,
futures_sender_invalid_symlinks,
2021-01-13 08:06:12 +13:00
futures_sender_broken_files,
2020-12-02 22:25:27 +13:00
);
connect_button_select(&gui_data);
connect_button_stop(&gui_data);
connect_button_hardlink_symlink(&gui_data);
connect_button_move(&gui_data);
connect_notebook_tabs(&gui_data);
connect_selection_of_directories(&gui_data);
2020-11-09 22:09:22 +13:00
connect_popovers(&gui_data);
2020-12-02 22:25:27 +13:00
connect_compute_results(&gui_data, glib_stop_receiver);
connect_progress_window(
&gui_data,
futures_receiver_duplicate_files,
futures_receiver_empty_files,
futures_receiver_empty_folder,
futures_receiver_big_file,
futures_receiver_same_music,
futures_receiver_similar_images,
futures_receiver_similar_videos,
2020-12-02 22:25:27 +13:00
futures_receiver_temporary,
futures_receiver_invalid_symlinks,
2021-01-13 08:06:12 +13:00
futures_receiver_broken_files,
2020-12-02 22:25:27 +13:00
);
connect_hide_text_view_errors(&gui_data);
connect_settings(&gui_data);
2021-01-25 00:01:02 +13:00
connect_button_about(&gui_data);
connect_about_buttons(&gui_data);
connect_similar_image_size_change(&gui_data);
// Quit the program when X in main window was clicked
{
let window_main = gui_data.window_main.clone();
Windows taskbar progress support (#264) * Initial Windows taskbar progress support * Changes to COM (un)init It turns out winapi exposes IIDs through a `uuidof()` function of interfaces, so the copied one can be removed. * Don't return error codes Now the `TaskbarProgress` functions fail silently. The `TaskbarProgress` struct now will always be created (even in case of errors in initialisation), but it won't do anything. * Fix builds for other systems * Formatted code * Fix progress shown after the operation finished A progress update was received after the stop event. Also `as_ref()` was removed in many places (I don't even know why it was there). * Remove redundant call to hide It's already called by the `glib_stop_receiver` receiver. * Release the ITaskbarList3 and call CoUninitialize at exit Because objects moved to closures used as fallbacks in GTK have [static lifetimes](https://gtk-rs.org/docs-src/tutorial/closures#closures), the `TaskbarProgress` will never be dropped. To workaround this problem a `release` function is called when the main window is closed. This function behaves like `drop`, but sets the struct in a valid "empty" state, so that calling `release`/`drop` again won't cause problems. * Don't set the NORMAL state manually Because only NOPROGRESS and INDETERMINATE states are used, there is no need to set the NORMAL state when changing the progress value. Now `set_progress_value` will also change the `TaskbarProgress::current_state` if such situation occurs. > Unless [SetProgressState](https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate) > has set a blocking state (TBPF_ERROR or TBPF_PAUSED) for the window, a call to **SetProgressValue** assumes the TBPF_NORMAL > state even if it is not explicitly set. A call to **SetProgressValue** overrides and clears the TBPF_INDETERMINATE state. See the [SetProgressValue documentation](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressvalue#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group)
2021-02-21 00:24:36 +13:00
let taskbar_state = gui_data.taskbar_state.clone();
window_main.connect_delete_event(move |_, _| {
save_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Save configuration at exit
gtk::main_quit();
Windows taskbar progress support (#264) * Initial Windows taskbar progress support * Changes to COM (un)init It turns out winapi exposes IIDs through a `uuidof()` function of interfaces, so the copied one can be removed. * Don't return error codes Now the `TaskbarProgress` functions fail silently. The `TaskbarProgress` struct now will always be created (even in case of errors in initialisation), but it won't do anything. * Fix builds for other systems * Formatted code * Fix progress shown after the operation finished A progress update was received after the stop event. Also `as_ref()` was removed in many places (I don't even know why it was there). * Remove redundant call to hide It's already called by the `glib_stop_receiver` receiver. * Release the ITaskbarList3 and call CoUninitialize at exit Because objects moved to closures used as fallbacks in GTK have [static lifetimes](https://gtk-rs.org/docs-src/tutorial/closures#closures), the `TaskbarProgress` will never be dropped. To workaround this problem a `release` function is called when the main window is closed. This function behaves like `drop`, but sets the struct in a valid "empty" state, so that calling `release`/`drop` again won't cause problems. * Don't set the NORMAL state manually Because only NOPROGRESS and INDETERMINATE states are used, there is no need to set the NORMAL state when changing the progress value. Now `set_progress_value` will also change the `TaskbarProgress::current_state` if such situation occurs. > Unless [SetProgressState](https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate) > has set a blocking state (TBPF_ERROR or TBPF_PAUSED) for the window, a call to **SetProgressValue** assumes the TBPF_NORMAL > state even if it is not explicitly set. A call to **SetProgressValue** overrides and clears the TBPF_INDETERMINATE state. See the [SetProgressValue documentation](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressvalue#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group)
2021-02-21 00:24:36 +13:00
taskbar_state.borrow_mut().release();
Inhibit(false)
});
}
// We start the gtk main loop.
gtk::main();
// Quiting if quit flag was provided
if exit_program_after_initialization {
gtk::main_quit();
}
}