image_page: Specific error for file loading
Give a specific error message if loading the source file fails. Closes #487
This commit is contained in:
parent
b9668c7262
commit
7151cf5d1d
8 changed files with 123 additions and 122 deletions
|
|
@ -54,6 +54,7 @@ use glib::subclass::Signal;
|
|||
use glib::{Properties, SignalGroup};
|
||||
use gufo_common::orientation::Orientation;
|
||||
|
||||
use crate::decoder::tiling::SharedFrameBuffer;
|
||||
use crate::decoder::{self, Decoder, DecoderUpdate, tiling};
|
||||
use crate::deps::*;
|
||||
use crate::metadata::Metadata;
|
||||
|
|
@ -137,13 +138,11 @@ pub enum FitMode {
|
|||
ExactVolatile,
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use decoder::DecoderError;
|
||||
use glycin::Operations;
|
||||
use decoder::DecoderError;
|
||||
use glycin::Operations;
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
use crate::decoder::tiling::SharedFrameBuffer;
|
||||
use crate::editing;
|
||||
|
||||
#[derive(Debug, Default, Properties)]
|
||||
#[properties(wrapper_type = super::LpImage)]
|
||||
|
|
@ -155,9 +154,9 @@ mod imp {
|
|||
#[property(get)]
|
||||
pub(super) is_deleted: Cell<bool>,
|
||||
/// Set if an error has occurred, shown on error_page
|
||||
pub(super) specific_error: RefCell<DecoderError>,
|
||||
pub(super) specific_error: RefCell<Option<DecoderError>>,
|
||||
#[property(get=Self::is_error)]
|
||||
pub(super) is_error: Cell<bool>,
|
||||
pub(super) is_error: PhantomData<bool>,
|
||||
/// Set to true when image is ready for displaying
|
||||
#[property(get)]
|
||||
pub(super) is_loaded: Cell<bool>,
|
||||
|
|
@ -257,7 +256,7 @@ mod imp {
|
|||
pub(super) nth_snapshot: Cell<u8>,
|
||||
|
||||
/// Editing queue
|
||||
pub(super) editing_queue: editing::Queue,
|
||||
pub(super) editing_queue: crate::editing::Queue,
|
||||
pub(super) operations: RefCell<Option<Arc<Operations>>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ impl imp::LpImage {
|
|||
}
|
||||
|
||||
pub(super) fn is_error(&self) -> bool {
|
||||
self.specific_error.borrow().is_err()
|
||||
self.specific_error.borrow().is_some()
|
||||
}
|
||||
|
||||
fn set_loaded(&self, is_loaded: bool) {
|
||||
|
|
@ -279,7 +279,7 @@ impl imp::LpImage {
|
|||
obj.notify_is_loaded();
|
||||
|
||||
if is_loaded {
|
||||
obj.set_specific_error(DecoderError::None);
|
||||
obj.set_specific_error(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -357,26 +357,24 @@ impl LpImage {
|
|||
imp.decoder.replace(Some(Arc::new(decoder)));
|
||||
}
|
||||
|
||||
pub fn specific_error(&self) -> DecoderError {
|
||||
pub fn specific_error(&self) -> Option<DecoderError> {
|
||||
self.imp().specific_error.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn set_specific_error(&self, error: DecoderError) {
|
||||
pub fn set_specific_error(&self, error: Option<DecoderError>) {
|
||||
let imp = self.imp();
|
||||
|
||||
// Keeping first error instead of replacing with new error
|
||||
if error.is_err() && self.is_error() {
|
||||
// Keeping first error instead of replacing with new error or return
|
||||
if error.is_some() == self.is_error() {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.specific_error() != error {
|
||||
let is_err = error.is_err();
|
||||
imp.specific_error.replace(error);
|
||||
self.notify_is_error();
|
||||
let is_err = error.is_some();
|
||||
imp.specific_error.replace(error);
|
||||
self.notify_is_error();
|
||||
|
||||
if is_err {
|
||||
imp.set_loaded(false);
|
||||
}
|
||||
if is_err {
|
||||
imp.set_loaded(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,72 +214,79 @@ impl LpImagePage {
|
|||
let imp = self.imp();
|
||||
let image = self.image();
|
||||
|
||||
match 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)],
|
||||
);
|
||||
if let Some(error) = image.specific_error() {
|
||||
let details;
|
||||
let description;
|
||||
|
||||
imp.error_page.set_description(Some(&message));
|
||||
imp.stack.set_visible_child(&*imp.error_page);
|
||||
imp.error_more_info.set_visible(false);
|
||||
}
|
||||
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();
|
||||
match error {
|
||||
DecoderError::NoLoadersConfigured(err) => {
|
||||
// Translators: {} is replaced with a version number
|
||||
description = gettext_f(
|
||||
"No image loaders available. Maybe the “glycin-loaders” package with compatibility version “{}” is not installed.",
|
||||
[format!("{}+", glycin::COMPAT_VERSION)],
|
||||
);
|
||||
|
||||
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],
|
||||
)
|
||||
};
|
||||
|
||||
imp.error_more_info.connect_clicked(glib::clone!(
|
||||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
move |_| {
|
||||
LpErrorDetails::new(&obj.root().unwrap(), &err, ErrorType::Loader);
|
||||
}
|
||||
));
|
||||
|
||||
imp.error_page.set_description(Some(&message));
|
||||
imp.stack.set_visible_child(&*imp.error_page);
|
||||
}
|
||||
DecoderError::Generic(err) => {
|
||||
imp.error_more_info.connect_clicked(glib::clone!(
|
||||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
move |_| {
|
||||
LpErrorDetails::new(&obj.root().unwrap(), &err, ErrorType::Loader);
|
||||
}
|
||||
));
|
||||
|
||||
if matches!(image.specific_error(), DecoderError::OutOfMemory) {
|
||||
imp.error_page.set_description(Some(&gettext(
|
||||
"There is not enough free memory available to load this image.",
|
||||
)));
|
||||
} else {
|
||||
imp.error_page.set_description(Some(&gettext(
|
||||
"Either the image file is corrupted or it contains unsupported elements.",
|
||||
)));
|
||||
details = err.to_string();
|
||||
}
|
||||
DecoderError::UnsupportedFormat(mime_type, err) => {
|
||||
let content_type =
|
||||
gio::content_type_from_mime_type(&mime_type).unwrap_or_default();
|
||||
let mime_type_description =
|
||||
gio::content_type_get_description(&content_type).to_string();
|
||||
|
||||
imp.error_more_info.set_visible(true);
|
||||
imp.stack.set_visible_child(&*imp.error_page);
|
||||
description =
|
||||
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.",
|
||||
[&mime_type_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 “{} ({}).”",
|
||||
[&mime_type_description, &mime_type],
|
||||
)
|
||||
};
|
||||
|
||||
details = err.to_string();
|
||||
}
|
||||
DecoderError::OutOfMemory(err) => {
|
||||
description =
|
||||
gettext("There is not enough free memory available to load this image.");
|
||||
details = err.to_string();
|
||||
}
|
||||
DecoderError::ImageSource(glib_err, err) => {
|
||||
// Translators: The first occurance of {} is replace with a
|
||||
// translated, more detailled error message.
|
||||
description =
|
||||
gettext_f("Failed to load image file: {}", [&glib_err.to_string()]);
|
||||
details = err.to_string();
|
||||
}
|
||||
DecoderError::Generic(err) => {
|
||||
description = gettext(
|
||||
"Either the image file is corrupted or it contains unsupported elements.",
|
||||
);
|
||||
details = err.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
imp.error_more_info.connect_clicked(glib::clone!(
|
||||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
move |_| {
|
||||
LpErrorDetails::new(&obj.root().unwrap(), &details, ErrorType::Loader);
|
||||
}
|
||||
));
|
||||
|
||||
imp.error_page.set_description(Some(&description));
|
||||
|
||||
imp.error_more_info.set_visible(true);
|
||||
imp.stack.set_visible_child(&*imp.error_page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,7 +650,10 @@ impl LpImageView {
|
|||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
move |image| {
|
||||
if matches!(image.specific_error(), DecoderError::UnsupportedFormat) {
|
||||
if matches!(
|
||||
image.specific_error(),
|
||||
Some(DecoderError::UnsupportedFormat(_, _))
|
||||
) {
|
||||
if obj.current_image().as_ref() == Some(image) {
|
||||
tracing::debug!(
|
||||
"Image format unsupported but not removing since current image"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue