editing: Decide editable based on true mime type

Previously it was decided on the early unreliable mime type.

Fixes #449
This commit is contained in:
Sophie Herold 2025-02-19 11:46:32 +01:00
parent e3a58270b1
commit 1d40a28b54
4 changed files with 31 additions and 12 deletions

View file

@ -0,0 +1 @@
Decide if an image has a format that supports editing based on the reliable mime-type. That way a wrong file extension will not impact the detection of the format being editable.

View file

@ -105,17 +105,28 @@ impl Metadata {
}
pub fn mime_type(&self) -> Option<String> {
self.file_info
.as_ref()
.and_then(|x| x.mime_type.as_ref())
.map(|x| x.to_string())
self.mime_type.clone()
}
/// Unreliable mime type
///
/// Before the image is successfully loaded, this mime type might be wrong
/// since it is not yet based on the more complex mime type detection used
/// by glyin.
pub fn unreliable_mime_type(&self) -> Option<String> {
self.mime_type().or_else(|| {
self.file_info
.as_ref()
.and_then(|x| x.mime_type.as_ref())
.map(|x| x.to_string())
})
}
pub fn format_name(&self) -> Option<String> {
self.image_info
.as_ref()
.and_then(|x| x.format_name.clone())
.or_else(|| self.mime_type())
.or_else(|| self.unreliable_mime_type())
}
pub fn alpha_channel(&self) -> Option<bool> {

View file

@ -34,14 +34,14 @@ impl imp::LpImage {
/// Set filename after filename changed
async fn set_file_changed(&self, file: &gio::File) {
let obj = self.obj();
let prev_mime_type = obj.metadata().mime_type();
let prev_mime_type = obj.metadata().unreliable_mime_type();
self.file.replace(Some(file.clone()));
self.reload_file_info().await;
// Reload if mime type changed since other decoding path might be responsible
// now
if obj.metadata().mime_type() != prev_mime_type {
if obj.metadata().unreliable_mime_type() != prev_mime_type {
obj.load(file).await;
return;
}
@ -80,6 +80,11 @@ impl imp::LpImage {
self.emmit_metadata_changed();
obj.reset_rotation();
glib::spawn_future_local(glib::clone!(
#[weak(rename_to=obj)]
self,
async move { obj.check_editable().await },
));
}
DecoderUpdate::Dimensions => {
log::debug!("Received dimensions: {:?}", self.untransformed_dimensions());
@ -360,8 +365,12 @@ impl LpImage {
// Reset background color for reloads
imp.set_background_color(None);
let (decoder, decoder_update) =
Decoder::new(file.clone(), self.metadata().mime_type(), tiles.clone()).await;
let (decoder, decoder_update) = Decoder::new(
file.clone(),
self.metadata().unreliable_mime_type(),
tiles.clone(),
)
.await;
let weak_obj = self.downgrade();
glib::spawn_future_local(async move {
@ -374,7 +383,5 @@ impl LpImage {
});
imp.decoder.replace(Some(Arc::new(decoder)));
imp.check_editable().await;
}
}

View file

@ -231,7 +231,7 @@ impl LpImagePage {
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 mime_type = image.metadata().unreliable_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();