image: Show image after error in file resolved

LpImage already reloads the image after an image is
invalid because of unsupported format or decoding error.
This patch makes that the "is-loaded" property is changed
to true again after the problem is resolved by a file change.

This should also hopefully works around problems with apps like GIMP
writing files in a way where an error appears itermittently.

Closes #256
This commit is contained in:
Sophie Herold 2023-11-16 23:50:41 +01:00
parent 831cf953c6
commit a1edf6f882

View file

@ -810,10 +810,7 @@ impl LpImage {
self.request_tiles(); self.request_tiles();
} }
DecoderUpdate::Redraw => { DecoderUpdate::Redraw => {
if !self.is_loaded() { self.set_loaded(true);
imp.is_loaded.set(true);
self.notify("is-loaded");
}
self.queue_draw(); self.queue_draw();
imp.frame_buffer.rcu(|tiles| { imp.frame_buffer.rcu(|tiles| {
@ -832,7 +829,7 @@ impl LpImage {
} }
} }
DecoderUpdate::Error(err) => { DecoderUpdate::Error(err) => {
self.set_error(err); self.set_error(Some(err));
} }
DecoderUpdate::Format(format) => { DecoderUpdate::Format(format) => {
imp.format.replace(Some(format)); imp.format.replace(Some(format));
@ -844,10 +841,7 @@ impl LpImage {
imp.tick_callback.replace(Some(callback_id)); imp.tick_callback.replace(Some(callback_id));
} }
DecoderUpdate::UnsupportedFormat => { DecoderUpdate::UnsupportedFormat => {
if !self.is_unsupported() { self.set_unsupported(true);
imp.is_unsupported.set(true);
self.notify("is-unsupported");
}
} }
} }
} }
@ -974,7 +968,7 @@ impl LpImage {
let file_replace = self.file().map_or(false, |x| x.equal(&file)); let file_replace = self.file().map_or(false, |x| x.equal(&file));
self.set_file(&file); self.set_file(&file);
if file_replace { if file_replace {
log::debug!("Image got replaced"); log::debug!("Image got replaced {}", file.uri());
let obj = self.clone(); let obj = self.clone();
// TODO: error handling is missing // TODO: error handling is missing
spawn(async move { spawn(async move {
@ -986,6 +980,7 @@ impl LpImage {
gio::FileMonitorEvent::ChangesDoneHint => { gio::FileMonitorEvent::ChangesDoneHint => {
let obj = self.clone(); let obj = self.clone();
let file = file_a.clone(); let file = file_a.clone();
log::debug!("Image was edited {}", file.uri());
// TODO: error handling is missing // TODO: error handling is missing
spawn(async move { spawn(async move {
obj.load(&file).await; obj.load(&file).await;
@ -994,6 +989,7 @@ impl LpImage {
gio::FileMonitorEvent::Deleted gio::FileMonitorEvent::Deleted
| gio::FileMonitorEvent::MovedOut | gio::FileMonitorEvent::MovedOut
| gio::FileMonitorEvent::Unmounted => { | gio::FileMonitorEvent::Unmounted => {
log::debug!("File no longer available: {event:?} {}", file_a.uri());
self.imp().is_deleted.set(true); self.imp().is_deleted.set(true);
self.notify("is-deleted"); self.notify("is-deleted");
} }
@ -1714,10 +1710,39 @@ impl LpImage {
self.imp().error.borrow().clone() self.imp().error.borrow().clone()
} }
fn set_error(&self, err: anyhow::Error) { fn set_error(&self, err: Option<anyhow::Error>) {
log::debug!("Decoding error: {err:?}"); log::debug!("Decoding error: {err:?}");
self.imp().error.replace(Some(err.to_string())); self.imp()
.error
.replace(err.as_ref().map(|x| x.to_string()));
self.notify("error"); self.notify("error");
if err.is_some() {
self.set_loaded(false);
}
}
fn set_unsupported(&self, is_unsupported: bool) {
if self.is_unsupported() != is_unsupported {
self.imp().is_unsupported.set(true);
self.notify("is-unsupported");
if is_unsupported {
self.set_loaded(false);
}
}
}
fn set_loaded(&self, is_loaded: bool) {
if self.is_loaded() != is_loaded {
self.imp().is_loaded.set(is_loaded);
self.notify("is-loaded");
if is_loaded {
self.set_error(None);
self.set_unsupported(false);
}
}
} }
/// Returns scaling aware rounded application pixel /// Returns scaling aware rounded application pixel