diff --git a/src/metadata/gps.rs b/src/metadata/gps.rs index ea8f3e8..a5d779b 100644 --- a/src/metadata/gps.rs +++ b/src/metadata/gps.rs @@ -47,11 +47,23 @@ impl GPSCoord { let deg = self.deg; if let (Some(min), Some(sec)) = (self.min, self.sec) { - format!("{deg}° {min}′ {sec}″ {reference}") + format!("{deg}° {min}′ {sec:05.2}″ {reference}") } else if let Some(min) = self.min { - format!("{deg}° {min}′ {reference}") + format!("{deg}° {min:06.3}′ {reference}") } else { - format!("{deg}° {reference}") + format!("{deg:08.5}° {reference}") + } + } + + fn machine_readable(&self, reference: &str) -> String { + let deg = self.deg; + + if let (Some(min), Some(sec)) = (self.min, self.sec) { + format!("{reference}{deg}°{min}'{sec:05.2}\"") + } else if let Some(min) = self.min { + format!("{reference}{deg}°{min:06.3}'") + } else { + format!("{reference}{deg:08.5}°") } } @@ -159,6 +171,18 @@ impl GPSLocation { coord.display(&reference) } + pub fn machine_readable(&self) -> String { + let coord = self.latitude; + let reference = if coord.sing { "N" } else { "S" }; + let lat = coord.machine_readable(reference); + + let coord = self.longitude; + let reference = if coord.sing { "E" } else { "W" }; + let lon = coord.machine_readable(reference); + + format!("{lat} {lon}") + } + pub fn longitude_display(&self) -> String { let coord = self.longitude; let reference = if coord.sing { diff --git a/src/widgets/properties_view.rs b/src/widgets/properties_view.rs index 4807697..cf385fe 100644 --- a/src/widgets/properties_view.rs +++ b/src/widgets/properties_view.rs @@ -20,6 +20,7 @@ use std::cell::{OnceCell, RefCell}; use adw::prelude::*; use adw::subclass::prelude::*; +use glib::translate::IntoGlib; use glib::Properties; use gtk::CompositeTemplate; @@ -91,6 +92,10 @@ mod imp { obj.imp().open_directory().await; }); + klass.install_action("properties.copy-location", None, move |obj, _, _| { + obj.imp().copy_location(); + }); + klass.install_action("properties.open-location", None, move |obj, _, _| { obj.imp().open_location(); }); @@ -280,6 +285,26 @@ mod imp { }; } + /// Copy GPS location + fn copy_location(&self) { + let obj = self.obj(); + + if let Some(location) = obj.image().and_then(|x| x.metadata().gps_location()) { + let clipboard = obj.display().clipboard(); + clipboard.set_text(&location.machine_readable()); + let _ = obj.activate_action( + "win.show-toast", + Some( + &( + gettext("Image Coordinates Copied"), + adw::ToastPriority::Normal.into_glib(), + ) + .to_variant(), + ), + ); + } + } + /// Open GPS location in apps like Maps via `geo:` URI fn open_location(&self) { let obj = self.obj(); diff --git a/src/widgets/properties_view.ui b/src/widgets/properties_view.ui index e8feaaf..0f7f57c 100644 --- a/src/widgets/properties_view.ui +++ b/src/widgets/properties_view.ui @@ -104,9 +104,23 @@ Location - location_button + True + - + + center + properties.copy-location + edit-copy-symbolic + Copy Coordinates + + + + + center properties.open-location mark-location-symbolic