propertiesView: Use decoder format
Use the format that we actually used when decoding. The mime type is usually derived from the file extension which might not always be correct. Issue #43 Part-of: <https://gitlab.gnome.org/Incubator/loupe/-/merge_requests/132>
This commit is contained in:
parent
f8e64d9805
commit
a2a9b4134b
6 changed files with 44 additions and 38 deletions
|
|
@ -68,12 +68,12 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow">
|
<object class="AdwActionRow">
|
||||||
<property name="title" translatable="yes">File Type</property>
|
<property name="title" translatable="yes">Image Format</property>
|
||||||
<property name="subtitle-selectable">True</property>
|
<property name="subtitle-selectable">True</property>
|
||||||
<binding name="subtitle">
|
<binding name="subtitle">
|
||||||
<closure type="gchararray" function="file_type">
|
<lookup type="LpImage" name="format-name">
|
||||||
<lookup name="file-info">LpPropertiesView</lookup>
|
<lookup type="LpPropertiesView" name="image"/>
|
||||||
</closure>
|
</lookup>
|
||||||
</binding>
|
</binding>
|
||||||
<style>
|
<style>
|
||||||
<class name="property"/>
|
<class name="property"/>
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,29 @@ pub use image_rs_other::ImageRsOther;
|
||||||
pub use svg::{Svg, RSVG_MAX_SIZE};
|
pub use svg::{Svg, RSVG_MAX_SIZE};
|
||||||
|
|
||||||
use super::{Decoder, UpdateSender};
|
use super::{Decoder, UpdateSender};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum ImageFormat {
|
||||||
|
ImageRs(image_rs::ImageFormat),
|
||||||
|
// TODO: Add details about contained format
|
||||||
|
Heif,
|
||||||
|
Svg,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ImageFormat {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
match self {
|
||||||
|
Self::ImageRs(format) => {
|
||||||
|
let debug = format!("{:?}", format);
|
||||||
|
if debug.len() <= 4 {
|
||||||
|
// uppercase abbreviations
|
||||||
|
write!(f, "{}", debug.to_uppercase())
|
||||||
|
} else {
|
||||||
|
write!(f, "{}", debug)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Heif => write!(f, "HEIF Container"),
|
||||||
|
Self::Svg => write!(f, "SVG"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,7 @@ use gtk::graphene;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub use formats::RSVG_MAX_SIZE;
|
pub use formats::{ImageFormat, RSVG_MAX_SIZE};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum ImageFormat {
|
|
||||||
ImageRs(image_rs::ImageFormat),
|
|
||||||
// TODO: Add details about contained format
|
|
||||||
Heif,
|
|
||||||
Svg,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for ImageFormat {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
|
||||||
match self {
|
|
||||||
Self::ImageRs(format) => write!(f, "{:?}", format),
|
|
||||||
Self::Heif => write!(f, "HEIF"),
|
|
||||||
Self::Svg => write!(f, "SVG"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
/// Renderer requests new tiles
|
/// Renderer requests new tiles
|
||||||
|
|
|
||||||
|
|
@ -165,10 +165,13 @@ mod imp {
|
||||||
glib::ParamSpecBoolean::builder("is-loaded")
|
glib::ParamSpecBoolean::builder("is-loaded")
|
||||||
.read_only()
|
.read_only()
|
||||||
.build(),
|
.build(),
|
||||||
glib::ParamSpecBoolean::builder("error").read_only().build(),
|
glib::ParamSpecString::builder("error").read_only().build(),
|
||||||
glib::ParamSpecObject::builder::<LpImageMetadata>("metadata")
|
glib::ParamSpecObject::builder::<LpImageMetadata>("metadata")
|
||||||
.read_only()
|
.read_only()
|
||||||
.build(),
|
.build(),
|
||||||
|
glib::ParamSpecString::builder("format-name")
|
||||||
|
.read_only()
|
||||||
|
.build(),
|
||||||
glib::ParamSpecDouble::builder("rotation")
|
glib::ParamSpecDouble::builder("rotation")
|
||||||
.explicit_notify()
|
.explicit_notify()
|
||||||
.build(),
|
.build(),
|
||||||
|
|
@ -206,6 +209,7 @@ mod imp {
|
||||||
"is-loaded" => obj.is_loaded().to_value(),
|
"is-loaded" => obj.is_loaded().to_value(),
|
||||||
"error" => obj.error().to_value(),
|
"error" => obj.error().to_value(),
|
||||||
"metadata" => obj.metadata().to_value(),
|
"metadata" => obj.metadata().to_value(),
|
||||||
|
"format-name" => obj.format_name().to_value(),
|
||||||
"rotation" => obj.rotation().to_value(),
|
"rotation" => obj.rotation().to_value(),
|
||||||
"mirrored" => obj.mirrored().to_value(),
|
"mirrored" => obj.mirrored().to_value(),
|
||||||
"zoom" => obj.zoom().to_value(),
|
"zoom" => obj.zoom().to_value(),
|
||||||
|
|
@ -713,6 +717,7 @@ impl LpImage {
|
||||||
}
|
}
|
||||||
DecoderUpdate::Format(format) => {
|
DecoderUpdate::Format(format) => {
|
||||||
imp.format.replace(Some(format));
|
imp.format.replace(Some(format));
|
||||||
|
self.notify("format-name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -964,7 +969,7 @@ impl LpImage {
|
||||||
|
|
||||||
/// Maximal zoom allowed for this image
|
/// Maximal zoom allowed for this image
|
||||||
fn max_zoom(&self) -> f64 {
|
fn max_zoom(&self) -> f64 {
|
||||||
if let Some(decoder::ImageFormat::Svg) = dbg!(self.format()) {
|
if let Some(decoder::ImageFormat::Svg) = self.format() {
|
||||||
let (width, height) = self.original_dimensions();
|
let (width, height) = self.original_dimensions();
|
||||||
// Avoid division by 0
|
// Avoid division by 0
|
||||||
let long_side = f64::max(1., i32::max(width, height) as f64);
|
let long_side = f64::max(1., i32::max(width, height) as f64);
|
||||||
|
|
@ -1435,6 +1440,11 @@ impl LpImage {
|
||||||
*self.imp().format.borrow()
|
*self.imp().format.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Image format displayable name
|
||||||
|
pub fn format_name(&self) -> Option<String> {
|
||||||
|
self.imp().format.borrow().map(|x| x.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns decoding error if one occured
|
/// Returns decoding error if one occured
|
||||||
pub fn error(&self) -> Option<String> {
|
pub fn error(&self) -> Option<String> {
|
||||||
self.imp().error.borrow().clone()
|
self.imp().error.borrow().clone()
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ impl LpImageView {
|
||||||
pub fn set_image_from_path(&self, path: &Path) {
|
pub fn set_image_from_path(&self, path: &Path) {
|
||||||
// Add image to recently used file. Does not work in Flatpaks:
|
// Add image to recently used file. Does not work in Flatpaks:
|
||||||
// <https://github.com/flatpak/xdg-desktop-portal/issues/215>
|
// <https://github.com/flatpak/xdg-desktop-portal/issues/215>
|
||||||
gtk::RecentManager::default().add_item(&dbg!(gio::File::for_path(path).uri()));
|
gtk::RecentManager::default().add_item(&gio::File::for_path(path).uri());
|
||||||
|
|
||||||
if let Err(err) = self.load_path(path) {
|
if let Err(err) = self.load_path(path) {
|
||||||
log::error!("Failed to load path: {err}");
|
log::error!("Failed to load path: {err}");
|
||||||
|
|
|
||||||
|
|
@ -380,18 +380,6 @@ impl LpPropertiesView {
|
||||||
.unwrap_or_else(|| FALLBACK.to_owned()) // and if we get nothing, use `FALLBACK`
|
.unwrap_or_else(|| FALLBACK.to_owned()) // and if we get nothing, use `FALLBACK`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
|
||||||
fn file_type(&self, info: Option<gio::FileInfo>) -> String {
|
|
||||||
info.and_then(|i| i.content_type())
|
|
||||||
.map(|t| t.to_string())
|
|
||||||
.map(|t| {
|
|
||||||
t.rsplit('/').collect::<Vec<&str>>()[0]
|
|
||||||
.to_owned()
|
|
||||||
.to_uppercase()
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| FALLBACK.to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn file_size(&self, info: Option<gio::FileInfo>) -> String {
|
fn file_size(&self, info: Option<gio::FileInfo>) -> String {
|
||||||
info.map(|info| {
|
info.map(|info| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue