Add option to turn off cache (#263)

This commit is contained in:
Rafał Mikrut 2021-03-04 12:09:53 +01:00 committed by GitHub
parent 1d904a858e
commit 17f97bd958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 200 additions and 107 deletions

View File

@ -2,7 +2,7 @@ use std::fs::{File, Metadata, OpenOptions};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{fs, thread};
use std::{fs, mem, thread};
use crate::common::Common;
use crate::common_directory::Directories;
@ -78,6 +78,7 @@ pub struct BrokenFiles {
recursive_search: bool,
delete_method: DeleteMethod,
stopped_search: bool,
use_cache: bool,
}
impl BrokenFiles {
@ -93,6 +94,7 @@ impl BrokenFiles {
delete_method: DeleteMethod::None,
stopped_search: false,
broken_files: Default::default(),
use_cache: true,
}
}
@ -130,6 +132,10 @@ impl BrokenFiles {
self.delete_method = delete_method;
}
pub fn set_use_cache(&mut self, use_cache: bool) {
self.use_cache = use_cache;
}
pub fn set_recursive_search(&mut self, recursive_search: bool) {
self.recursive_search = recursive_search;
}
@ -297,27 +303,35 @@ impl BrokenFiles {
fn look_for_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::Sender<ProgressData>>) -> bool {
let system_time = SystemTime::now();
let loaded_hash_map = match load_cache_from_file(&mut self.text_messages) {
Some(t) => t,
None => Default::default(),
};
let loaded_hash_map;
let mut records_already_cached: HashMap<String, FileEntry> = Default::default();
let mut non_cached_files_to_check: HashMap<String, FileEntry> = Default::default();
for (name, file_entry) in &self.files_to_check {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(name) {
// If loaded data doesn't contains current image info
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
if file_entry.size != loaded_hash_map.get(name).unwrap().size || file_entry.modified_date != loaded_hash_map.get(name).unwrap().modified_date {
// When size or modification date of image changed, then it is clear that is different image
if self.use_cache {
loaded_hash_map = match load_cache_from_file(&mut self.text_messages) {
Some(t) => t,
None => Default::default(),
};
for (name, file_entry) in &self.files_to_check {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(name) {
// If loaded data doesn't contains current image info
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
// Checking may be omitted when already there is entry with same size and modification date
records_already_cached.insert(name.clone(), loaded_hash_map.get(name).unwrap().clone());
if file_entry.size != loaded_hash_map.get(name).unwrap().size || file_entry.modified_date != loaded_hash_map.get(name).unwrap().modified_date {
// When size or modification date of image changed, then it is clear that is different image
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
// Checking may be omitted when already there is entry with same size and modification date
records_already_cached.insert(name.clone(), loaded_hash_map.get(name).unwrap().clone());
}
}
}
} else {
loaded_hash_map = Default::default();
mem::swap(&mut self.files_to_check, &mut non_cached_files_to_check);
}
let check_was_breaked = AtomicBool::new(false); // Used for breaking from GUI and ending check thread
@ -430,16 +444,18 @@ impl BrokenFiles {
self.broken_files = vec_file_entry.iter().filter_map(|f| if f.error_string.is_empty() { None } else { Some(f.clone()) }).collect();
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = self.files_to_check.clone();
if self.use_cache {
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = self.files_to_check.clone();
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
for (_name, file_entry) in loaded_hash_map {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
save_cache_to_file(&all_results, &mut self.text_messages);
}
for (_name, file_entry) in loaded_hash_map {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
save_cache_to_file(&all_results, &mut self.text_messages);
self.information.number_of_broken_files = self.broken_files.len();

View File

@ -10,7 +10,7 @@ use std::io::{self, Error, ErrorKind};
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{fs, thread};
use std::{fs, mem, thread};
use crate::common::Common;
use crate::common_directory::Directories;
@ -151,6 +151,7 @@ pub struct DuplicateFinder {
ignore_hard_links: bool,
dryrun: bool,
stopped_search: bool,
use_cache: bool,
}
impl DuplicateFinder {
@ -172,6 +173,7 @@ impl DuplicateFinder {
ignore_hard_links: true,
hash_type: HashType::Blake3,
dryrun: false,
use_cache: true,
}
}
@ -221,6 +223,10 @@ impl DuplicateFinder {
&self.files_with_identical_names
}
pub fn set_use_cache(&mut self, use_cache: bool) {
self.use_cache = use_cache;
}
pub const fn get_files_sorted_by_size(&self) -> &BTreeMap<u64, Vec<FileEntry>> {
&self.files_with_identical_size
}
@ -795,38 +801,46 @@ impl DuplicateFinder {
.collect();
}
CheckingMethod::Hash => {
let loaded_hash_map = match load_hashes_from_file(&mut self.text_messages, &self.hash_type) {
Some(t) => t,
None => Default::default(),
};
let loaded_hash_map;
let mut records_already_cached: HashMap<u64, Vec<FileEntry>> = Default::default();
let mut non_cached_files_to_check: HashMap<u64, Vec<FileEntry>> = Default::default();
for (size, vec_file_entry) in pre_checked_map {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(&size) {
// If loaded data doesn't contains current info
non_cached_files_to_check.insert(size, vec_file_entry);
} else {
let loaded_vec_file_entry = loaded_hash_map.get(&size).unwrap();
let mut records_already_cached: BTreeMap<u64, Vec<FileEntry>> = Default::default();
let mut non_cached_files_to_check: BTreeMap<u64, Vec<FileEntry>> = Default::default();
for file_entry in vec_file_entry {
let mut found: bool = false;
for loaded_file_entry in loaded_vec_file_entry {
if file_entry.path == loaded_file_entry.path && file_entry.modified_date == loaded_file_entry.modified_date {
records_already_cached.entry(file_entry.size).or_insert_with(Vec::new);
records_already_cached.get_mut(&file_entry.size).unwrap().push(loaded_file_entry.clone());
found = true;
break;
if self.use_cache {
loaded_hash_map = match load_hashes_from_file(&mut self.text_messages, &self.hash_type) {
Some(t) => t,
None => Default::default(),
};
for (size, vec_file_entry) in pre_checked_map {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(&size) {
// If loaded data doesn't contains current info
non_cached_files_to_check.insert(size, vec_file_entry);
} else {
let loaded_vec_file_entry = loaded_hash_map.get(&size).unwrap();
for file_entry in vec_file_entry {
let mut found: bool = false;
for loaded_file_entry in loaded_vec_file_entry {
if file_entry.path == loaded_file_entry.path && file_entry.modified_date == loaded_file_entry.modified_date {
records_already_cached.entry(file_entry.size).or_insert_with(Vec::new);
records_already_cached.get_mut(&file_entry.size).unwrap().push(loaded_file_entry.clone());
found = true;
break;
}
}
}
if !found {
non_cached_files_to_check.entry(file_entry.size).or_insert_with(Vec::new);
non_cached_files_to_check.get_mut(&file_entry.size).unwrap().push(file_entry);
if !found {
non_cached_files_to_check.entry(file_entry.size).or_insert_with(Vec::new);
non_cached_files_to_check.get_mut(&file_entry.size).unwrap().push(file_entry);
}
}
}
}
} else {
loaded_hash_map = Default::default();
mem::swap(&mut pre_checked_map, &mut non_cached_files_to_check);
}
full_hash_results = non_cached_files_to_check
@ -860,43 +874,43 @@ impl DuplicateFinder {
.while_some()
.collect();
// Size, Vec
'main: for (size, vec_file_entry) in records_already_cached {
// Check if size already exists, if exists we must to change it outside because cannot have mut and non mut reference to full_hash_results
for (full_size, full_hashmap, _errors, _bytes_read) in &mut full_hash_results {
if size == *full_size {
for file_entry in vec_file_entry {
full_hashmap.entry(file_entry.hash.clone()).or_insert_with(Vec::new);
full_hashmap.get_mut(&file_entry.hash).unwrap().push(file_entry);
if self.use_cache {
'main: for (size, vec_file_entry) in records_already_cached {
// Check if size already exists, if exists we must to change it outside because cannot have mut and non mut reference to full_hash_results
for (full_size, full_hashmap, _errors, _bytes_read) in &mut full_hash_results {
if size == *full_size {
for file_entry in vec_file_entry {
full_hashmap.entry(file_entry.hash.clone()).or_insert_with(Vec::new);
full_hashmap.get_mut(&file_entry.hash).unwrap().push(file_entry);
}
continue 'main;
}
continue 'main;
}
}
// Size doesn't exists add results to files
let mut temp_hashmap: HashMap<String, Vec<FileEntry>> = Default::default();
for file_entry in vec_file_entry {
temp_hashmap.entry(file_entry.hash.clone()).or_insert_with(Vec::new);
temp_hashmap.get_mut(&file_entry.hash).unwrap().push(file_entry);
}
full_hash_results.push((size, temp_hashmap, Vec::new(), 0));
}
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = Default::default();
for (_size, vec_file_entry) in loaded_hash_map {
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
}
for (_size, hashmap, _errors, _bytes_read) in &full_hash_results {
for vec_file_entry in hashmap.values() {
// Size doesn't exists add results to files
let mut temp_hashmap: HashMap<String, Vec<FileEntry>> = Default::default();
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry.clone());
temp_hashmap.entry(file_entry.hash.clone()).or_insert_with(Vec::new);
temp_hashmap.get_mut(&file_entry.hash).unwrap().push(file_entry);
}
full_hash_results.push((size, temp_hashmap, Vec::new(), 0));
}
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = Default::default();
for (_size, vec_file_entry) in loaded_hash_map {
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
}
for (_size, hashmap, _errors, _bytes_read) in &full_hash_results {
for vec_file_entry in hashmap.values() {
for file_entry in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry.clone());
}
}
}
save_hashes_to_file(&all_results, &mut self.text_messages, &self.hash_type);
}
save_hashes_to_file(&all_results, &mut self.text_messages, &self.hash_type);
}
_ => panic!("What"),
}

View File

@ -20,7 +20,7 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread::sleep;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{fs, thread};
use std::{fs, mem, thread};
/// Type to store for each entry in the similarity BK-tree.
type Node = [u8; 8];
@ -79,6 +79,7 @@ pub struct SimilarImages {
stopped_search: bool,
similarity: Similarity,
images_to_check: HashMap<String, FileEntry>,
use_cache: bool,
}
/// Info struck with helpful information's about results
@ -111,6 +112,7 @@ impl SimilarImages {
stopped_search: false,
similarity: Similarity::High,
images_to_check: Default::default(),
use_cache: true,
}
}
@ -130,6 +132,10 @@ impl SimilarImages {
&self.information
}
pub fn set_use_cache(&mut self, use_cache: bool) {
self.use_cache = use_cache;
}
pub fn set_recursive_search(&mut self, recursive_search: bool) {
self.recursive_search = recursive_search;
}
@ -321,27 +327,35 @@ impl SimilarImages {
fn sort_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::Sender<ProgressData>>) -> bool {
let hash_map_modification = SystemTime::now();
let loaded_hash_map = match load_hashes_from_file(&mut self.text_messages) {
Some(t) => t,
None => Default::default(),
};
let loaded_hash_map;
let mut records_already_cached: HashMap<String, FileEntry> = Default::default();
let mut non_cached_files_to_check: HashMap<String, FileEntry> = Default::default();
for (name, file_entry) in &self.images_to_check {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(name) {
// If loaded data doesn't contains current image info
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
if file_entry.size != loaded_hash_map.get(name).unwrap().size || file_entry.modified_date != loaded_hash_map.get(name).unwrap().modified_date {
// When size or modification date of image changed, then it is clear that is different image
if self.use_cache {
loaded_hash_map = match load_hashes_from_file(&mut self.text_messages) {
Some(t) => t,
None => Default::default(),
};
for (name, file_entry) in &self.images_to_check {
#[allow(clippy::collapsible_if)]
if !loaded_hash_map.contains_key(name) {
// If loaded data doesn't contains current image info
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
// Checking may be omitted when already there is entry with same size and modification date
records_already_cached.insert(name.clone(), loaded_hash_map.get(name).unwrap().clone());
if file_entry.size != loaded_hash_map.get(name).unwrap().size || file_entry.modified_date != loaded_hash_map.get(name).unwrap().modified_date {
// When size or modification date of image changed, then it is clear that is different image
non_cached_files_to_check.insert(name.clone(), file_entry.clone());
} else {
// Checking may be omitted when already there is entry with same size and modification date
records_already_cached.insert(name.clone(), loaded_hash_map.get(name).unwrap().clone());
}
}
}
} else {
loaded_hash_map = Default::default();
mem::swap(&mut self.images_to_check, &mut non_cached_files_to_check);
}
Common::print_time(hash_map_modification, SystemTime::now(), "sort_images - reading data from cache and preparing them".to_string());
@ -426,12 +440,14 @@ impl SimilarImages {
self.image_hashes.get_mut(buf).unwrap().push(file_entry.clone());
}
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = loaded_hash_map;
for (file_entry, _hash) in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
if self.use_cache {
// Must save all results to file, old loaded from file with all currently counted results
let mut all_results: HashMap<String, FileEntry> = loaded_hash_map;
for (file_entry, _hash) in vec_file_entry {
all_results.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
save_hashes_to_file(&all_results, &mut self.text_messages);
}
save_hashes_to_file(&all_results, &mut self.text_messages);
Common::print_time(hash_map_modification, SystemTime::now(), "sort_images - saving data to files".to_string());
let hash_map_modification = SystemTime::now();

View File

@ -2485,6 +2485,21 @@ This program is free to use and will always be.
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_save_at_exit">
<property name="label" translatable="yes">Save configuration at exit</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_confirm_deletion">
<property name="label" translatable="yes">Show confirm dialog when deleting</property>
@ -2497,7 +2512,7 @@ This program is free to use and will always be.
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="position">2</property>
</packing>
</child>
<child>
@ -2512,12 +2527,12 @@ This program is free to use and will always be.
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_save_at_exit">
<property name="label" translatable="yes">Save configuration at exit</property>
<object class="GtkCheckButton" id="check_button_settings_use_cache">
<property name="label" translatable="yes">Use cache</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>

View File

@ -91,6 +91,7 @@ pub fn connect_button_search(
let radio_button_hash_type_crc32 = gui_data.main_notebook.radio_button_hash_type_crc32.clone();
let radio_button_hash_type_xxh3 = gui_data.main_notebook.radio_button_hash_type_xxh3.clone();
let check_button_settings_hide_hard_links = gui_data.settings.check_button_settings_hide_hard_links.clone();
let check_button_settings_use_cache = gui_data.settings.check_button_settings_use_cache.clone();
buttons_search_clone.connect_clicked(move |_| {
let included_directories = get_path_buf_from_vector_of_strings(get_string_from_list_store(&tree_view_included_directories));
@ -99,6 +100,7 @@ pub fn connect_button_search(
let excluded_items = entry_excluded_items.get_text().as_str().to_string().split(',').map(|e| e.to_string()).collect::<Vec<String>>();
let allowed_extensions = entry_allowed_extensions.get_text().as_str().to_string();
let hide_hard_links = check_button_settings_hide_hard_links.get_active();
let use_cache = check_button_settings_use_cache.get_active();
let show_dialog = Arc::new(AtomicBool::new(true));
@ -167,6 +169,7 @@ pub fn connect_button_search(
df.set_check_method(check_method);
df.set_hash_type(hash_type);
df.set_ignore_hard_links(hide_hard_links);
df.set_use_cache(use_cache);
df.find_duplicates(Some(&stop_receiver), Some(&futures_sender_duplicate_files));
let _ = glib_stop_sender.send(Message::Duplicates(df));
});
@ -292,6 +295,7 @@ pub fn connect_button_search(
sf.set_excluded_items(excluded_items);
sf.set_minimal_file_size(minimal_file_size);
sf.set_similarity(similarity);
sf.set_use_cache(use_cache);
sf.find_similar_images(Some(&stop_receiver), Some(&futures_sender_similar_images));
let _ = glib_stop_sender.send(Message::SimilarImages(sf));
});
@ -402,6 +406,7 @@ pub fn connect_button_search(
br.set_excluded_directory(excluded_directories);
br.set_recursive_search(recursive_search);
br.set_excluded_items(excluded_items);
br.set_use_cache(use_cache);
br.find_broken_files(Some(&stop_receiver), Some(&futures_sender_broken_files));
let _ = glib_stop_sender.send(Message::BrokenFiles(br));
});

View File

@ -9,6 +9,7 @@ pub struct GUISettings {
pub check_button_settings_load_at_start: gtk::CheckButton,
pub check_button_settings_confirm_deletion: gtk::CheckButton,
pub check_button_settings_show_text_view: gtk::CheckButton,
pub check_button_settings_use_cache: gtk::CheckButton,
// Duplicates
pub check_button_settings_hide_hard_links: gtk::CheckButton,
@ -31,6 +32,7 @@ impl GUISettings {
let check_button_settings_load_at_start: gtk::CheckButton = builder.get_object("check_button_settings_load_at_start").unwrap();
let check_button_settings_confirm_deletion: gtk::CheckButton = builder.get_object("check_button_settings_confirm_deletion").unwrap();
let check_button_settings_show_text_view: gtk::CheckButton = builder.get_object("check_button_settings_show_text_view").unwrap();
let check_button_settings_use_cache: gtk::CheckButton = builder.get_object("check_button_settings_use_cache").unwrap();
// Duplicates
let check_button_settings_hide_hard_links: gtk::CheckButton = builder.get_object("check_button_settings_hide_hard_links").unwrap();
@ -54,6 +56,7 @@ impl GUISettings {
button_settings_reset_configuration,
check_button_settings_show_preview_similar_images,
check_button_settings_hide_hard_links,
check_button_settings_use_cache,
}
}
}

View File

@ -112,10 +112,15 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
let check_button_settings_show_text_view = gui_data.settings.check_button_settings_show_text_view.clone();
data_to_save.push(check_button_settings_show_text_view.get_active().to_string());
//// Show bottom text panel with errors
//// Hide/Show hard linked files, with same inodes
data_to_save.push("--hide_hard_links:".to_string());
let check_button_settings_hide_hard_links = gui_data.settings.check_button_settings_hide_hard_links.clone();
data_to_save.push(check_button_settings_hide_hard_links.get_active().to_string());
//// Use cache system
data_to_save.push("--use_cache:".to_string());
let check_button_settings_use_cache = gui_data.settings.check_button_settings_use_cache.clone();
data_to_save.push(check_button_settings_use_cache.get_active().to_string());
}
// Creating/Opening config file
@ -143,9 +148,9 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
}
}
if data_saved {
add_text_to_text_view(&text_view_errors, format!("Saved configuration to file {}", config_dir.display()).as_str());
add_text_to_text_view(&text_view_errors, format!("Saved configuration to file {}", config_file.display()).as_str());
} else {
add_text_to_text_view(&text_view_errors, format!("Failed to save configuration data to file {}", config_dir.display()).as_str());
add_text_to_text_view(&text_view_errors, format!("Failed to save configuration data to file {}", config_file.display()).as_str());
}
} else {
add_text_to_text_view(&text_view_errors, "Failed to get home directory, so can't save file.");
@ -164,6 +169,7 @@ enum TypeOfLoadedData {
ShowPreviews,
BottomTextPanel,
HideHardLinks,
UseCache,
}
pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
@ -207,6 +213,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
let mut show_previews: bool = true;
let mut bottom_text_panel: bool = true;
let mut hide_hard_links: bool = true;
let mut use_cache: bool = true;
let mut current_type = TypeOfLoadedData::None;
for (line_number, line) in loaded_data.replace("\r\n", "\n").split('\n').enumerate() {
@ -234,6 +241,8 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
current_type = TypeOfLoadedData::BottomTextPanel;
} else if line.starts_with("--hide_hard_links") {
current_type = TypeOfLoadedData::HideHardLinks;
} else if line.starts_with("--use_cache") {
current_type = TypeOfLoadedData::UseCache;
} else if line.starts_with("--") {
current_type = TypeOfLoadedData::None;
add_text_to_text_view(
@ -338,6 +347,19 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
);
}
}
TypeOfLoadedData::UseCache => {
let line = line.to_lowercase();
if line == "1" || line == "true" {
use_cache = true;
} else if line == "0" || line == "false" {
use_cache = false;
} else {
add_text_to_text_view(
&text_view_errors,
format!("Found invalid data in line {} \"{}\" isn't proper value(0/1/true/false) when loading file {:?}", line_number, line, config_file).as_str(),
);
}
}
}
}
}
@ -389,6 +411,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
gui_data.scrolled_window_errors.show();
}
gui_data.settings.check_button_settings_hide_hard_links.set_active(hide_hard_links);
gui_data.settings.check_button_settings_use_cache.set_active(use_cache);
} else {
gui_data.settings.check_button_settings_load_at_start.set_active(false);
}
@ -469,6 +492,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
gui_data.settings.check_button_settings_show_preview_similar_images.set_active(true);
gui_data.settings.check_button_settings_show_text_view.set_active(true);
gui_data.settings.check_button_settings_hide_hard_links.set_active(true);
gui_data.settings.check_button_settings_use_cache.set_active(true);
}
if manual_clearing {
add_text_to_text_view(&text_view_errors, "Current configuration was cleared.");