image: Use enum for specific errors

This commit is contained in:
Sophie Herold 2024-07-19 23:19:34 +02:00
parent 134c488dbd
commit e08866a1da
6 changed files with 112 additions and 66 deletions

View file

@ -98,4 +98,3 @@ impl LpErrorDetails {
obj
}
}

View file

@ -132,6 +132,8 @@ pub enum FitMode {
}
mod imp {
use decoder::DecoderError;
use super::*;
use crate::decoder::tiling::SharedFrameBuffer;
use crate::editing;
@ -145,8 +147,8 @@ mod imp {
pub(super) queued_reload: RefCell<Option<gio::File>>,
#[property(get)]
pub(super) is_deleted: Cell<bool>,
#[property(get)]
pub(super) is_unsupported: Cell<bool>,
#[property(get, builder(DecoderError::None))]
pub(super) specific_error: Cell<DecoderError>,
/// Set to true when image is ready for displaying
#[property(get)]
pub(super) is_loaded: Cell<bool>,

View file

@ -16,6 +16,8 @@
//
// SPDX-License-Identifier: GPL-3.0-or-later
use decoder::DecoderError;
use super::*;
impl imp::LpImage {
@ -110,7 +112,7 @@ impl imp::LpImage {
));
}
}
DecoderUpdate::Error(err) => {
DecoderUpdate::GenericError(err) => {
self.set_error(Some(err));
}
DecoderUpdate::Animated => {
@ -128,8 +130,8 @@ impl imp::LpImage {
self.tick_callback.replace(Some(callback_id));
}
}
DecoderUpdate::UnsupportedFormat => {
self.set_unsupported(true);
DecoderUpdate::SpecificError(err) => {
self.set_specific_error(err);
}
}
}
@ -248,13 +250,13 @@ impl imp::LpImage {
}
}
fn set_unsupported(&self, is_unsupported: bool) {
fn set_specific_error(&self, error: DecoderError) {
let obj = self.obj();
if obj.is_unsupported() != is_unsupported {
self.is_unsupported.set(true);
obj.notify_is_unsupported();
if obj.specific_error() != error {
self.specific_error.set(error);
obj.notify_specific_error();
if is_unsupported {
if error.is_err() {
self.set_loaded(false);
}
}
@ -269,7 +271,7 @@ impl imp::LpImage {
if is_loaded {
self.set_error(None);
self.set_unsupported(false);
self.set_specific_error(DecoderError::None);
}
}
}

View file

@ -27,6 +27,7 @@ use gtk::prelude::*;
use gtk::CompositeTemplate;
use super::LpErrorDetails;
use crate::decoder::DecoderError;
use crate::deps::*;
use crate::util::gettext::*;
use crate::widgets::LpImage;
@ -209,37 +210,47 @@ impl LpImagePage {
let imp = self.imp();
let image = self.image();
if image.is_unsupported() {
let message = if glycin::Loader::supported_mime_types().await.is_empty() {
// Translators: {} is replace with a version number
gettext_f(
"No image loaders available. Maybe the “glycin-loaders” package with compatibility version “{}+” is not installed.",
[ format!("{}+", glycin::COMPAT_VERSION)])
} else {
let mime_type = image.metadata().mime_type().unwrap_or_default();
let content_type = gio::content_type_from_mime_type(&mime_type).unwrap_or_default();
let description = gio::content_type_get_description(&content_type).to_string();
if glycin::Loader::DEFAULT_MIME_TYPES.contains(&mime_type.as_str()) {
// Translators: The first occurance of {} is replace with a description of the
// format and the second with an id (mime-type) of the format.
gettext_f(
"The image format “{} ({})” is known but not installed.",
[&description, &mime_type],
)
} else {
// Translators: The first occurance of {} is replace with a description of the
// format and the second with an id (mime-type) of the format.
gettext_f(
"Unknown image format “{} ({}).”",
[&description, &mime_type],
)
}
};
if image.specific_error() == DecoderError::NoLoadersConfigured {
// Translators: {} is replaced with a version number
let message = gettext_f(
"No image loaders available. Maybe the “glycin-loaders” package with compatibility version “{}” is not installed.",
[ format!("{}+", glycin::COMPAT_VERSION)]);
imp.error_page.set_description(Some(&message));
imp.stack.set_visible_child(&*imp.error_page);
imp.error_more_info.set_visible(false);
} else if image.specific_error() == DecoderError::UnsupportedFormat {
let mime_type = image.metadata().mime_type().unwrap_or_default();
let content_type = gio::content_type_from_mime_type(&mime_type).unwrap_or_default();
let description = gio::content_type_get_description(&content_type).to_string();
let message = if glycin::Loader::DEFAULT_MIME_TYPES.contains(&mime_type.as_str()) {
// Translators: The first occurance of {} is replace with a description of the
// format and the second with an id (mime-type) of the format.
gettext_f(
"The image format “{} ({})” is known but not installed.",
[&description, &mime_type],
)
} else {
// Translators: The first occurance of {} is replace with a description of the
// format and the second with an id (mime-type) of the format.
gettext_f(
"Unknown image format “{} ({}).”",
[&description, &mime_type],
)
};
if let Some(err) = image.error() {
imp.error_more_info.connect_clicked(glib::clone!(
#[weak(rename_to = obj)]
self,
move |_| {
LpErrorDetails::new(&obj.root().unwrap(), &err);
}
));
}
imp.error_page.set_description(Some(&message));
imp.stack.set_visible_child(&*imp.error_page);
} else if let Some(err) = image.error() {
imp.error_more_info.connect_clicked(glib::clone!(

View file

@ -41,6 +41,7 @@ use glib::translate::IntoGlib;
use glib::{clone, Properties};
use gtk::CompositeTemplate;
use crate::decoder::DecoderError;
use crate::deps::*;
use crate::file_model::LpFileModel;
use crate::util::gettext::*;
@ -535,31 +536,28 @@ impl LpImageView {
fn new_image_page(&self, file: &gio::File) -> LpImagePage {
let page = LpImagePage::from_file(file);
page.image().connect_notify_local(
Some("is-unsupported"),
glib::clone!(
#[weak(rename_to = obj)]
self,
move |image, _| {
if image.is_unsupported() {
if obj.current_image().as_ref() == Some(image) {
log::debug!(
"Image format unsupported but not removing since current image"
);
return;
}
page.image().connect_specific_error_notify(glib::clone!(
#[weak(rename_to = obj)]
self,
move |image| {
if image.specific_error() == DecoderError::UnsupportedFormat {
if obj.current_image().as_ref() == Some(image) {
log::debug!(
"Image format unsupported but not removing since current image"
);
return;
}
if let Some(file) = image.file() {
log::debug!("Removing image with unsupported format {:?}", file.uri());
obj.model().remove(&file);
if let Some(current_file) = obj.current_file() {
obj.update_sliding_view(&current_file);
}
if let Some(file) = image.file() {
log::debug!("Removing image with unsupported format {:?}", file.uri());
obj.model().remove(&file);
if let Some(current_file) = obj.current_file() {
obj.update_sliding_view(&current_file);
}
}
}
),
);
}
));
page
}