image: Use enum for specific errors
This commit is contained in:
parent
134c488dbd
commit
e08866a1da
6 changed files with 112 additions and 66 deletions
|
|
@ -55,14 +55,42 @@ pub enum DecoderUpdate {
|
|||
Dimensions,
|
||||
/// Metadata available
|
||||
Metadata(Box<Metadata>),
|
||||
/// Image format not supported or unknown
|
||||
UnsupportedFormat,
|
||||
/// New image data available, redraw
|
||||
Redraw,
|
||||
/// Start animation
|
||||
Animated,
|
||||
SpecificError(DecoderError),
|
||||
/// And error occurred during decoding
|
||||
Error(anyhow::Error),
|
||||
GenericError(anyhow::Error),
|
||||
}
|
||||
|
||||
#[derive(glib::Enum, Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[enum_type(name = "LpDecoderError")]
|
||||
//#[enum_dynamic(lazy_registration = true)]
|
||||
#[repr(i32)]
|
||||
pub enum DecoderError {
|
||||
/// Image format not supported or unknown
|
||||
UnsupportedFormat,
|
||||
/// No glycin-loaders installed
|
||||
NoLoadersConfigured,
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
impl DecoderError {
|
||||
pub fn is_err(self) -> bool {
|
||||
matches!(self, Self::None)
|
||||
}
|
||||
|
||||
pub fn is_ok(self) -> bool {
|
||||
!matches!(self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
impl glib::value::ToValueOptional for DecoderError {
|
||||
fn to_value_optional(s: Option<&Self>) -> glib::Value {
|
||||
s.unwrap_or(&Self::None).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl UpdateSender {
|
||||
|
|
@ -87,9 +115,15 @@ impl UpdateSender {
|
|||
|
||||
if let Err(err) = result {
|
||||
if err.unsupported_format().is_some() {
|
||||
update_sender.send(DecoderUpdate::UnsupportedFormat);
|
||||
update_sender.send(DecoderUpdate::SpecificError(
|
||||
DecoderError::UnsupportedFormat,
|
||||
));
|
||||
} else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) {
|
||||
update_sender.send(DecoderUpdate::SpecificError(
|
||||
DecoderError::NoLoadersConfigured,
|
||||
));
|
||||
}
|
||||
update_sender.send(DecoderUpdate::Error(err.into()));
|
||||
update_sender.send(DecoderUpdate::GenericError(err.into()));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -153,7 +187,7 @@ impl Decoder {
|
|||
pub fn request(&self, tile_request: TileRequest) {
|
||||
if let FormatDecoder::Svg(svg) = &self.decoder {
|
||||
if let Err(err) = svg.request(tile_request) {
|
||||
self.update_sender.send(DecoderUpdate::Error(err));
|
||||
self.update_sender.send(DecoderUpdate::GenericError(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,4 +98,3 @@ impl LpErrorDetails {
|
|||
obj
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!(
|
||||
|
|
|
|||
|
|
@ -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(¤t_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(¤t_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
));
|
||||
|
||||
page
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue