edit: Use filename with (Edited) suffix for "Save As"
This commit is contained in:
parent
e2785d9154
commit
9fbe091f1a
5 changed files with 59 additions and 8 deletions
|
|
@ -15,21 +15,28 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
pub use gettextrs::gettext;
|
pub use gettextrs::gettext;
|
||||||
|
|
||||||
fn freplace(mut s: String, args: impl IntoIterator<Item = impl AsRef<str>>) -> String {
|
fn freplace(mut s: String, args: impl IntoIterator<Item = impl Display>) -> String {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
s = s.replacen("{}", arg.as_ref(), 1);
|
s = s.replacen("{}", &arg.to_string(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gettext_f(format: &str, args: impl IntoIterator<Item = impl AsRef<str>>) -> String {
|
pub fn gettext_f(format: &str, args: impl IntoIterator<Item = impl Display>) -> String {
|
||||||
let s = ugettext(format);
|
let s = ugettext(format);
|
||||||
freplace(s, args)
|
freplace(s, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ngettext(format: &str, format_plural: &str, n: u32) -> String {
|
||||||
|
let s = gettextrs::ngettext(format, format_plural, n);
|
||||||
|
freplace(apply_unicode_escapes(&s).unwrap_or(s), [n])
|
||||||
|
}
|
||||||
|
|
||||||
/// Same as `gettext` but evaluates unicode escape sequences
|
/// Same as `gettext` but evaluates unicode escape sequences
|
||||||
pub fn ugettext(msgid: &str) -> String {
|
pub fn ugettext(msgid: &str) -> String {
|
||||||
let msg = gettext(msgid);
|
let msg = gettext(msgid);
|
||||||
|
|
|
||||||
|
|
@ -152,9 +152,8 @@ trait RectExt: Into<graphene::Rect> {
|
||||||
impl RectExt for graphene::Rect {}
|
impl RectExt for graphene::Rect {}
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::widgets::LpImage;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::widgets::LpImage;
|
||||||
|
|
||||||
#[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)]
|
#[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)]
|
||||||
#[properties(wrapper_type = super::LpEditCropSelection)]
|
#[properties(wrapper_type = super::LpEditCropSelection)]
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,53 @@ mod imp {
|
||||||
if let Some(current_file) = obj.original_image().file() {
|
if let Some(current_file) = obj.original_image().file() {
|
||||||
let file_dialog = gtk::FileDialog::new();
|
let file_dialog = gtk::FileDialog::new();
|
||||||
|
|
||||||
file_dialog.set_initial_file(Some(¤t_file));
|
let suggested_file = if let Some(path) = current_file.path() {
|
||||||
|
if let Some(basename) = path.file_stem() {
|
||||||
|
let mut suggested_file = None;
|
||||||
|
for i in 1..20 {
|
||||||
|
let mut new_path = path.clone();
|
||||||
|
let mut new_filename = basename.to_os_string();
|
||||||
|
|
||||||
|
if i == 1 {
|
||||||
|
// Translators: Filename suffix
|
||||||
|
new_filename.push(gettext(" (Edited)"));
|
||||||
|
} else {
|
||||||
|
// Translators: Filename suffix, {} is replaced by a number
|
||||||
|
new_filename.push(ngettext(" (Edited)", " (Edited {})", i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ext) = path.extension() {
|
||||||
|
new_filename.push(".");
|
||||||
|
new_filename.push(ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_path.set_file_name(new_filename);
|
||||||
|
|
||||||
|
let file = gio::File::for_path(&new_path);
|
||||||
|
let file_exists = file
|
||||||
|
.query_info_future(
|
||||||
|
gio::FILE_ATTRIBUTE_STANDARD_NAME,
|
||||||
|
gio::FileQueryInfoFlags::NONE,
|
||||||
|
glib::Priority::DEFAULT,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.is_ok();
|
||||||
|
|
||||||
|
if !file_exists {
|
||||||
|
suggested_file = Some(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suggested_file.unwrap_or_else(|| current_file.clone())
|
||||||
|
} else {
|
||||||
|
current_file.clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current_file.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
file_dialog.set_initial_file(Some(&suggested_file));
|
||||||
|
|
||||||
match file_dialog.save_future(Some(&obj.window())).await {
|
match file_dialog.save_future(Some(&obj.window())).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2024 Sophie Herold
|
// Copyright (c) 2024 Sophie Herold
|
||||||
|
// Copyright (c) 2025 Rafael Fontenelle
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
|
|
@ -692,8 +692,6 @@ impl LpImageView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(file_event);
|
|
||||||
|
|
||||||
let Some(current_file) = self.current_file() else {
|
let Some(current_file) = self.current_file() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue