|
| 1 | +use gdk4::{DragAction, FileList}; |
| 2 | +use std::collections::HashSet; |
1 | 3 | use std::path::PathBuf;
|
2 | 4 |
|
3 | 5 | use gtk4::prelude::*;
|
4 |
| -use gtk4::{FileChooserNative, Notebook, Orientation, ResponseType, TreeView, Window}; |
| 6 | +use gtk4::{DropTarget, FileChooserNative, Notebook, Orientation, ResponseType, TreeView, Window}; |
5 | 7 |
|
6 | 8 | #[cfg(target_family = "windows")]
|
7 | 9 | use czkawka_core::common::Common;
|
@@ -61,6 +63,11 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
|
61 | 63 | notebook_upper,
|
62 | 64 | );
|
63 | 65 | }
|
| 66 | + // Drag and drop |
| 67 | + { |
| 68 | + configure_directory_drop(&gui_data.upper_notebook.tree_view_included_directories, false); |
| 69 | + configure_directory_drop(&gui_data.upper_notebook.tree_view_excluded_directories, true); |
| 70 | + } |
64 | 71 | // Remove Excluded Folder
|
65 | 72 | {
|
66 | 73 | let buttons_remove_excluded_directory = gui_data.upper_notebook.buttons_remove_excluded_directory.clone();
|
@@ -93,6 +100,32 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
|
93 | 100 | }
|
94 | 101 | }
|
95 | 102 |
|
| 103 | +fn configure_directory_drop(tree_view: &TreeView, excluded_items: bool) { |
| 104 | + let tv = tree_view.clone(); |
| 105 | + let drop_target = DropTarget::builder().name("file-drop-target").actions(DragAction::COPY).build(); |
| 106 | + drop_target.set_types(&[FileList::static_type()]); |
| 107 | + drop_target.connect_drop(move |_, value, _, _| { |
| 108 | + if let Ok(file_list) = value.get::<FileList>() { |
| 109 | + let mut folders: HashSet<PathBuf> = HashSet::new(); |
| 110 | + for f in file_list.files() { |
| 111 | + if let Some(path) = f.path() { |
| 112 | + if path.is_dir() { |
| 113 | + folders.insert(path); |
| 114 | + } else if let Some(parent) = path.parent() { |
| 115 | + if parent.is_dir() { |
| 116 | + folders.insert(parent.to_path_buf()); |
| 117 | + } |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + add_directories(&tv, &folders.into_iter().collect(), excluded_items); |
| 122 | + } |
| 123 | + true |
| 124 | + }); |
| 125 | + |
| 126 | + tree_view.add_controller(drop_target); |
| 127 | +} |
| 128 | + |
96 | 129 | fn connect_file_dialog(file_dialog_include_exclude_folder_selection: &FileChooserNative, include_tree_view: TreeView, exclude_tree_view: TreeView, notebook_upper: Notebook) {
|
97 | 130 | file_dialog_include_exclude_folder_selection.connect_response(move |file_chooser, response_type| {
|
98 | 131 | if response_type == ResponseType::Accept {
|
@@ -121,26 +154,30 @@ fn connect_file_dialog(file_dialog_include_exclude_folder_selection: &FileChoose
|
121 | 154 | }
|
122 | 155 | }
|
123 | 156 |
|
124 |
| - let list_store = get_list_store(tree_view); |
125 |
| - |
126 |
| - if excluded_items { |
127 |
| - for file_entry in &folders { |
128 |
| - let values: [(u32, &dyn ToValue); 1] = [(ColumnsExcludedDirectory::Path as u32, &file_entry.to_string_lossy().to_string())]; |
129 |
| - list_store.set(&list_store.append(), &values); |
130 |
| - } |
131 |
| - } else { |
132 |
| - for file_entry in &folders { |
133 |
| - let values: [(u32, &dyn ToValue); 2] = [ |
134 |
| - (ColumnsIncludedDirectory::Path as u32, &file_entry.to_string_lossy().to_string()), |
135 |
| - (ColumnsIncludedDirectory::ReferenceButton as u32, &false), |
136 |
| - ]; |
137 |
| - list_store.set(&list_store.append(), &values); |
138 |
| - } |
139 |
| - } |
| 157 | + add_directories(tree_view, &folders, excluded_items); |
140 | 158 | }
|
141 | 159 | });
|
142 | 160 | }
|
143 | 161 |
|
| 162 | +fn add_directories(tree_view: &TreeView, folders: &Vec<PathBuf>, excluded_items: bool) { |
| 163 | + let list_store = get_list_store(tree_view); |
| 164 | + |
| 165 | + if excluded_items { |
| 166 | + for file_entry in folders { |
| 167 | + let values: [(u32, &dyn ToValue); 1] = [(ColumnsExcludedDirectory::Path as u32, &file_entry.to_string_lossy().to_string())]; |
| 168 | + list_store.set(&list_store.append(), &values); |
| 169 | + } |
| 170 | + } else { |
| 171 | + for file_entry in folders { |
| 172 | + let values: [(u32, &dyn ToValue); 2] = [ |
| 173 | + (ColumnsIncludedDirectory::Path as u32, &file_entry.to_string_lossy().to_string()), |
| 174 | + (ColumnsIncludedDirectory::ReferenceButton as u32, &false), |
| 175 | + ]; |
| 176 | + list_store.set(&list_store.append(), &values); |
| 177 | + } |
| 178 | + } |
| 179 | +} |
| 180 | + |
144 | 181 | fn add_manually_directories(window_main: &Window, tree_view: &TreeView, excluded_items: bool) {
|
145 | 182 | let dialog = gtk4::Dialog::builder()
|
146 | 183 | .title(flg!("include_manually_directories_dialog_title"))
|
|
0 commit comments