Skip to content

Commit

Permalink
Merge pull request #71 from danirod/multiple-requests-in-open
Browse files Browse the repository at this point in the history
Allow to open more than one file at the same time
  • Loading branch information
danirod authored Aug 6, 2024
2 parents 9bf8920 + 0a047e4 commit bf1ea41
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
62 changes: 60 additions & 2 deletions src/widgets/file_dialogs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use gettextrs::gettext;
use glib::types::StaticType;
use glib::{prelude::Cast, types::StaticType};
use gtk::{
gio::{self, ListStore},
prelude::{FileExt, SettingsExtManual},
prelude::{FileExt, ListModelExtManual, SettingsExtManual},
DialogError, FileDialog, FileFilter,
};
use std::path::PathBuf;
Expand All @@ -22,6 +22,8 @@ fn get_cartero_file_filter() -> FileFilter {
filter
}

// Allowing dead_code here because I am going to use this later.
#[allow(dead_code)]
pub async fn open_file(win: &CarteroWindow) -> Result<gio::File, CarteroError> {
let filters = ListStore::with_type(FileFilter::static_type());
let cartero = get_cartero_file_filter();
Expand Down Expand Up @@ -66,6 +68,62 @@ pub async fn open_file(win: &CarteroWindow) -> Result<gio::File, CarteroError> {
Ok(file)
}

pub async fn open_files(win: &CarteroWindow) -> Result<Vec<gio::File>, CarteroError> {
let filters = ListStore::with_type(FileFilter::static_type());
let cartero = get_cartero_file_filter();
filters.append(&cartero);

let dialog = FileDialog::builder()
.accept_label(gettext("Open"))
.title(gettext("Open request"))
.filters(&filters)
.default_filter(&cartero)
.modal(true)
.build();

let app = CarteroApplication::get();
let settings = app.settings();
if let Some(dir) = settings.get::<Option<String>>("last-open-dir") {
let path = PathBuf::from(&dir);
let file = gtk::gio::File::for_path(path);
dialog.set_initial_folder(Some(&file));
}

let files = dialog.open_multiple_future(Some(win)).await.map_err(|e| {
if let Some(file_error) = e.kind::<DialogError>() {
match file_error {
DialogError::Dismissed => CarteroError::NoFilePicked,
_ => CarteroError::FileDialogError,
}
} else {
CarteroError::FileDialogError
}
})?;

let files: Result<Vec<gio::File>, _> = files
.snapshot()
.into_iter()
.map(|obj| obj.downcast::<gio::File>())
.collect::<Result<Vec<gio::File>, _>>();

match files {
Ok(files) => {
let parents = files
.iter()
.filter_map(gio::File::parent)
.collect::<Vec<gio::File>>();
if let Some(location) = parents.first().and_then(gio::File::path) {
let string = location.to_str().ok_or(CarteroError::FileDialogError)?;
settings
.set("last-open-dir", Some(string))
.map_err(|_| CarteroError::FileDialogError)?;
}
Ok(files)
}
Err(_) => Err(CarteroError::FileDialogError),
}
}

pub async fn save_file(win: &CarteroWindow) -> Result<gio::File, CarteroError> {
let filters = ListStore::with_type(FileFilter::static_type());
let cartero = get_cartero_file_filter();
Expand Down
6 changes: 4 additions & 2 deletions src/win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,10 @@ mod imp {
async fn trigger_open(&self) -> Result<(), CarteroError> {
// In order to place the modal, we need a reference to the public type.
let obj = self.obj();
let path = crate::widgets::open_file(&obj).await?;
self.add_endpoint(Some(&path)).await;
let paths = crate::widgets::open_files(&obj).await?;
for path in paths {
self.add_endpoint(Some(&path)).await;
}
self.save_visible_tabs();
Ok(())
}
Expand Down

0 comments on commit bf1ea41

Please sign in to comment.