Trigger save dialog via close_request
This simplifies the code and fixes that unsaved changes were only saved for the active window and dropped for all others. Part-of: <https://gitlab.gnome.org/GNOME/loupe/-/merge_requests/576>
This commit is contained in:
parent
aa4bdbb114
commit
6b4d057167
3 changed files with 60 additions and 62 deletions
|
|
@ -20,7 +20,6 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use crate::util::gettext::*;
|
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
|
|
||||||
|
|
@ -135,53 +134,9 @@ impl LpApplication {
|
||||||
.build(),
|
.build(),
|
||||||
gio::ActionEntryBuilder::new("quit")
|
gio::ActionEntryBuilder::new("quit")
|
||||||
.activate(|app: &Self, _, _| {
|
.activate(|app: &Self, _, _| {
|
||||||
if let Some(win) = app.active_window() {
|
// Give all windows the chance to handle close-request
|
||||||
if let Some(lp_window) = win.downcast_ref::<LpWindow>() {
|
for win in app.windows() {
|
||||||
if let Some(edit_window) = lp_window.edit_window() {
|
win.close();
|
||||||
if edit_window.has_unsaved_changes() {
|
|
||||||
let dialog = adw::AlertDialog::new(
|
|
||||||
Some(&gettext("Unsaved Changes")),
|
|
||||||
Some(&gettext(
|
|
||||||
"Changes which are not lost will be permanently lost",
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
dialog.add_response("cancel", &gettext("Cancel"));
|
|
||||||
dialog.add_response("discard", &gettext("Discard"));
|
|
||||||
dialog.add_response("save", &gettext("Save"));
|
|
||||||
|
|
||||||
let app_clone = app.clone();
|
|
||||||
let win_clone = win.clone();
|
|
||||||
let edit_window_clone = edit_window.clone();
|
|
||||||
let dialog_clone = dialog.clone();
|
|
||||||
|
|
||||||
dialog.set_response_appearance(
|
|
||||||
"discard",
|
|
||||||
adw::ResponseAppearance::Destructive,
|
|
||||||
);
|
|
||||||
|
|
||||||
glib::MainContext::default().spawn_local(async move {
|
|
||||||
let res =
|
|
||||||
dialog_clone.choose_future(Some(&win_clone)).await;
|
|
||||||
|
|
||||||
match res.as_str() {
|
|
||||||
"cancel" => {}
|
|
||||||
"discard" => {
|
|
||||||
app_clone.quit();
|
|
||||||
}
|
|
||||||
"save" => {
|
|
||||||
edit_window_clone
|
|
||||||
.save_as_and_quit(app_clone.clone());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
app.quit();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build(),
|
.build(),
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ use glycin::Operations;
|
||||||
|
|
||||||
use super::LpImage;
|
use super::LpImage;
|
||||||
use super::edit::LpEditCrop;
|
use super::edit::LpEditCrop;
|
||||||
use crate::LpApplication;
|
|
||||||
use crate::deps::*;
|
use crate::deps::*;
|
||||||
use crate::util::ErrorType;
|
use crate::util::ErrorType;
|
||||||
use crate::util::gettext::*;
|
use crate::util::gettext::*;
|
||||||
|
|
@ -490,19 +489,6 @@ impl LpEditWindow {
|
||||||
self.imp().is_save_sensitive()
|
self.imp().is_save_sensitive()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_as_and_quit(&self, app: LpApplication) {
|
|
||||||
glib::spawn_future_local(glib::clone!(
|
|
||||||
#[weak(rename_to=win)]
|
|
||||||
self,
|
|
||||||
#[strong]
|
|
||||||
app,
|
|
||||||
async move {
|
|
||||||
win.imp().save_overwrite().await;
|
|
||||||
app.quit()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_operation(&self, operation: glycin::Operation) {
|
pub fn add_operation(&self, operation: glycin::Operation) {
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
|
|
||||||
|
|
@ -517,4 +503,40 @@ impl LpEditWindow {
|
||||||
|
|
||||||
self.set_operations(Some(Arc::new(Operations::new(operations))));
|
self.set_operations(Some(Arc::new(Operations::new(operations))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns if the window should proceed with closing
|
||||||
|
pub async fn ensure_saved(&self) -> glib::Propagation {
|
||||||
|
if self.has_unsaved_changes() {
|
||||||
|
let dialog = adw::AlertDialog::new(
|
||||||
|
Some(&gettext("Unsaved Changes")),
|
||||||
|
Some(&gettext(
|
||||||
|
"Changes which are not lost will be permanently lost",
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
dialog.add_response("cancel", &gettext("Cancel"));
|
||||||
|
dialog.add_response("discard", &gettext("Discard"));
|
||||||
|
dialog.add_response("save", &gettext("Save"));
|
||||||
|
|
||||||
|
dialog.set_response_appearance("discard", adw::ResponseAppearance::Destructive);
|
||||||
|
|
||||||
|
let res = dialog.choose_future(Some(self)).await;
|
||||||
|
|
||||||
|
match res.as_str() {
|
||||||
|
"cancel" => glib::Propagation::Stop,
|
||||||
|
"close" => glib::Propagation::Stop,
|
||||||
|
"discard" => glib::Propagation::Proceed,
|
||||||
|
"save" => {
|
||||||
|
self.imp().save_overwrite().await;
|
||||||
|
glib::Propagation::Proceed
|
||||||
|
}
|
||||||
|
res => {
|
||||||
|
tracing::error!("Invalid dialog result: {res}");
|
||||||
|
glib::Propagation::Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glib::Propagation::Proceed
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,11 @@ mod imp {
|
||||||
// and keeps the others usable
|
// and keeps the others usable
|
||||||
gtk::WindowGroup::new().add_window(&*obj);
|
gtk::WindowGroup::new().add_window(&*obj);
|
||||||
|
|
||||||
|
obj.connect_close_request(|win| {
|
||||||
|
win.imp().close_request();
|
||||||
|
glib::Propagation::Stop
|
||||||
|
});
|
||||||
|
|
||||||
glib::timeout_add_local_once(
|
glib::timeout_add_local_once(
|
||||||
std::time::Duration::from_millis(SHOW_WINDOW_AFTER),
|
std::time::Duration::from_millis(SHOW_WINDOW_AFTER),
|
||||||
glib::clone!(
|
glib::clone!(
|
||||||
|
|
@ -151,6 +156,22 @@ mod imp {
|
||||||
impl WindowImpl for LpWindow {}
|
impl WindowImpl for LpWindow {}
|
||||||
impl ApplicationWindowImpl for LpWindow {}
|
impl ApplicationWindowImpl for LpWindow {}
|
||||||
impl AdwApplicationWindowImpl for LpWindow {}
|
impl AdwApplicationWindowImpl for LpWindow {}
|
||||||
|
|
||||||
|
impl LpWindow {
|
||||||
|
pub fn close_request(&self) {
|
||||||
|
let obj = self.obj().to_owned();
|
||||||
|
glib::MainContext::default().spawn_local(async move {
|
||||||
|
if let Some(edit_window) = obj.edit_window() {
|
||||||
|
if matches!(edit_window.ensure_saved().await, glib::Propagation::Proceed) {
|
||||||
|
obj.destroy();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Without editing window, we can always close
|
||||||
|
obj.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue