diff options
Diffstat (limited to 'src/Properties.vala')
-rw-r--r-- | src/Properties.vala | 412 |
1 files changed, 185 insertions, 227 deletions
diff --git a/src/Properties.vala b/src/Properties.vala index 3cbd5af..2a07bb0 100644 --- a/src/Properties.vala +++ b/src/Properties.vala @@ -8,53 +8,64 @@ private abstract class Properties : Gtk.Grid { uint line_count = 0; public Properties() { - row_spacing = 0; - column_spacing = 6; + row_spacing = 6; + column_spacing = 12; } - protected void add_line(string label_text, string info_text, bool multi_line = false) { + protected void add_line(string label_text, string info_text, bool multi_line = false, string? href = null) { Gtk.Label label = new Gtk.Label(""); Gtk.Widget info; label.set_justify(Gtk.Justification.RIGHT); + label.get_style_context().add_class("dim-label"); label.set_markup(GLib.Markup.printf_escaped("<span font_weight=\"bold\">%s</span>", label_text)); if (multi_line) { Gtk.ScrolledWindow info_scroll = new Gtk.ScrolledWindow(null, null); - info_scroll.shadow_type = Gtk.ShadowType.ETCHED_IN; + info_scroll.shadow_type = Gtk.ShadowType.NONE; Gtk.TextView view = new Gtk.TextView(); // by default TextView widgets have a white background, which // makes sense during editing. In this instance we only *show* // the content and thus want that the parent's background color // is inherited to the TextView - Gtk.StyleContext context = info_scroll.get_style_context(); - view.override_background_color (Gtk.StateFlags.NORMAL, - context.get_background_color(Gtk.StateFlags.NORMAL)); + view.get_style_context().add_class("shotwell-static"); view.set_wrap_mode(Gtk.WrapMode.WORD); view.set_cursor_visible(false); view.set_editable(false); view.buffer.text = is_string_empty(info_text) ? "" : info_text; + view.hexpand = true; info_scroll.add(view); - label.xalign = 1.0f; - label.yalign = 0.0f; + label.halign = Gtk.Align.END; + label.valign = Gtk.Align.START; info = (Gtk.Widget) info_scroll; } else { Gtk.Label info_label = new Gtk.Label(""); - info_label.set_markup(is_string_empty(info_text) ? "" : info_text); + if (!is_string_empty(info_text)) { + info_label.set_tooltip_markup(info_text); + } + + if (href == null) { + info_label.set_markup(is_string_empty(info_text) ? "" : info_text); + } else { + info_label.set_markup("<a href=\"%s\">%s</a>".printf(href, info_text)); + } info_label.set_ellipsize(Pango.EllipsizeMode.END); - info_label.xalign = 0.0f; - info_label.yalign = 0.5f; + info_label.halign = Gtk.Align.START; + info_label.valign = Gtk.Align.FILL; + info_label.hexpand = false; + info_label.vexpand = false; + info_label.set_justify(Gtk.Justification.LEFT); info_label.set_selectable(true); - label.xalign = 1.0f; - label.yalign = 0.5f; + label.halign = Gtk.Align.END; + label.valign = Gtk.Align.FILL; info = (Gtk.Widget) info_label; } attach(label, 0, (int) line_count, 1, 1); if (multi_line) { - attach(info, 1, (int) line_count, 1, 2); + attach(info, 1, (int) line_count, 1, 3); } else { attach(info, 1, (int) line_count, 1, 1); } @@ -144,13 +155,6 @@ private abstract class Properties : Gtk.Grid { public virtual void internal_update_properties(Page page) { get_properties(page); } - - public void unselect_text() { - foreach (Gtk.Widget child in get_children()) { - if (child is Gtk.Label) - ((Gtk.Label) child).select_region(0, 0); - } - } } private class BasicProperties : Properties { @@ -454,237 +458,191 @@ private class BasicProperties : Properties { } } -private class ExtendedPropertiesWindow : Gtk.Dialog { - private ExtendedProperties properties = null; - - private class ExtendedProperties : Properties { - private const string NO_VALUE = ""; - // Photo stuff - private string file_path; - private uint64 filesize; - private Dimensions? original_dim; - private string camera_make; - private string camera_model; - private string flash; - private string focal_length; - private double gps_lat; - private string gps_lat_ref; - private double gps_long; - private string gps_long_ref; - private double gps_alt; - private string artist; - private string copyright; - private string software; - private string exposure_bias; - private string exposure_date; - private string exposure_time; - private bool is_raw; - private string? development_path; - - // Event stuff - // nothing here which is not already shown in the BasicProperties but - // comments, which are common, see below +private class ExtendedProperties : Properties { + private const string NO_VALUE = ""; + // Photo stuff + private string file_path; + private uint64 filesize; + private Dimensions? original_dim; + private string camera_make; + private string camera_model; + private string flash; + private string focal_length; + private double gps_lat; + private string gps_lat_ref; + private double gps_long; + private string gps_long_ref; + private double gps_alt; + private string artist; + private string copyright; + private string software; + private string exposure_bias; + private string exposure_date; + private string exposure_time; + private bool is_raw; + private string? development_path; + private const string OSM_LINK_TEMPLATE = "https://www.openstreetmap.org/?mlat=%1$f&mlon=%2$f#map=16/%1$f/%2$f"; + + public ExtendedProperties() { + base(); + row_spacing = 6; + } + + // Event stuff + // nothing here which is not already shown in the BasicProperties but + // comments, which are common, see below + + // common stuff + private string comment; - // common stuff - private string comment; - - protected override void clear_properties() { - base.clear_properties(); - - file_path = ""; - development_path = ""; - is_raw = false; - filesize = 0; - original_dim = Dimensions(0, 0); - camera_make = ""; - camera_model = ""; - flash = ""; - focal_length = ""; - gps_lat = -1; - gps_lat_ref = ""; - gps_long = -1; - gps_long_ref = ""; - artist = ""; - copyright = ""; - software = ""; - exposure_bias = ""; - exposure_date = ""; - exposure_time = ""; - comment = ""; - } + protected override void clear_properties() { + base.clear_properties(); + + file_path = ""; + development_path = ""; + is_raw = false; + filesize = 0; + original_dim = Dimensions(0, 0); + camera_make = ""; + camera_model = ""; + flash = ""; + focal_length = ""; + gps_lat = -1; + gps_lat_ref = ""; + gps_long = -1; + gps_long_ref = ""; + artist = ""; + copyright = ""; + software = ""; + exposure_bias = ""; + exposure_date = ""; + exposure_time = ""; + comment = ""; + } + + protected override void get_single_properties(DataView view) { + base.get_single_properties(view); + + DataSource source = view.get_source(); + if (source == null) + return; + + if (source is MediaSource) { + MediaSource media = (MediaSource) source; + file_path = media.get_master_file().get_path(); + development_path = media.get_file().get_path(); + filesize = media.get_master_filesize(); + + // as of right now, all extended properties other than filesize, filepath & comment aren't + // applicable to non-photo media types, so if the current media source isn't a photo, + // just do a short-circuit return + Photo photo = media as Photo; + if (photo == null) + return; - protected override void get_single_properties(DataView view) { - base.get_single_properties(view); + PhotoMetadata? metadata; + + try { + // For some raw files, the developments may not contain metadata (please + // see the comment about cameras generating 'crazy' exif segments in + // Photo.develop_photo() for why), and so we'll want to display what was + // in the original raw file instead. + metadata = photo.get_master_metadata(); + } catch (Error e) { + metadata = photo.get_metadata(); + } - DataSource source = view.get_source(); - if (source == null) + if (metadata == null) return; - if (source is MediaSource) { - MediaSource media = (MediaSource) source; - file_path = media.get_master_file().get_path(); - development_path = media.get_file().get_path(); - filesize = media.get_master_filesize(); - - // as of right now, all extended properties other than filesize, filepath & comment aren't - // applicable to non-photo media types, so if the current media source isn't a photo, - // just do a short-circuit return - Photo photo = media as Photo; - if (photo == null) - return; + // Fix up any timestamp weirdness. + // + // If the exposure date wasn't properly set (the most likely cause of this + // is a raw with a metadataless development), use the one from the photo + // row. + if (metadata.get_exposure_date_time() == null) + metadata.set_exposure_date_time(new MetadataDateTime(photo.get_timestamp())); - PhotoMetadata? metadata; - - try { - // For some raw files, the developments may not contain metadata (please - // see the comment about cameras generating 'crazy' exif segments in - // Photo.develop_photo() for why), and so we'll want to display what was - // in the original raw file instead. - metadata = photo.get_master_metadata(); - } catch (Error e) { - metadata = photo.get_metadata(); - } - - if (metadata == null) - return; - - // Fix up any timestamp weirdness. - // - // If the exposure date wasn't properly set (the most likely cause of this - // is a raw with a metadataless development), use the one from the photo - // row. - if (metadata.get_exposure_date_time() == null) - metadata.set_exposure_date_time(new MetadataDateTime(photo.get_timestamp())); - - is_raw = (photo.get_master_file_format() == PhotoFileFormat.RAW); - original_dim = metadata.get_pixel_dimensions(); - camera_make = metadata.get_camera_make(); - camera_model = metadata.get_camera_model(); - flash = metadata.get_flash_string(); - focal_length = metadata.get_focal_length_string(); - metadata.get_gps(out gps_long, out gps_long_ref, out gps_lat, out gps_lat_ref, out gps_alt); - artist = metadata.get_artist(); - copyright = metadata.get_copyright(); - software = metadata.get_software(); - exposure_bias = metadata.get_exposure_bias(); - time_t exposure_time_obj = metadata.get_exposure_date_time().get_timestamp(); - exposure_date = get_prettyprint_date(Time.local(exposure_time_obj)); - exposure_time = get_prettyprint_time_with_seconds(Time.local(exposure_time_obj)); - comment = media.get_comment(); - } else if (source is EventSource) { - Event event = (Event) source; - comment = event.get_comment(); - } + is_raw = (photo.get_master_file_format() == PhotoFileFormat.RAW); + original_dim = metadata.get_pixel_dimensions(); + camera_make = metadata.get_camera_make(); + camera_model = metadata.get_camera_model(); + flash = metadata.get_flash_string(); + focal_length = metadata.get_focal_length_string(); + metadata.get_gps(out gps_long, out gps_long_ref, out gps_lat, out gps_lat_ref, out gps_alt); + artist = metadata.get_artist(); + copyright = metadata.get_copyright(); + software = metadata.get_software(); + exposure_bias = metadata.get_exposure_bias(); + time_t exposure_time_obj = metadata.get_exposure_date_time().get_timestamp(); + exposure_date = get_prettyprint_date(Time.local(exposure_time_obj)); + exposure_time = get_prettyprint_time_with_seconds(Time.local(exposure_time_obj)); + comment = media.get_comment(); + } else if (source is EventSource) { + Event event = (Event) source; + comment = event.get_comment(); } - - public override void internal_update_properties(Page page) { - base.internal_update_properties(page); + } - if (page is EventsDirectoryPage) { - // nothing special to be done for now for Events - } else { - add_line(_("Location:"), (file_path != "" && file_path != null) ? - file_path.replace("&", "&") : NO_VALUE); + public override void internal_update_properties(Page page) { + base.internal_update_properties(page); - add_line(_("File size:"), (filesize > 0) ? - format_size((int64) filesize) : NO_VALUE); + if (page is EventsDirectoryPage) { + // nothing special to be done for now for Events + } else { + add_line(_("Location:"), (file_path != "" && file_path != null) ? + file_path.replace("&", "&") : NO_VALUE); - if (is_raw) - add_line(_("Current Development:"), development_path); + add_line(_("File size:"), (filesize > 0) ? + format_size((int64) filesize) : NO_VALUE); - add_line(_("Original dimensions:"), (original_dim != null && original_dim.has_area()) ? - "%d × %d".printf(original_dim.width, original_dim.height) : NO_VALUE); + if (is_raw) + add_line(_("Current Development:"), development_path); - add_line(_("Camera make:"), (camera_make != "" && camera_make != null) ? - camera_make : NO_VALUE); + add_line(_("Original dimensions:"), (original_dim != null && original_dim.has_area()) ? + "%d × %d".printf(original_dim.width, original_dim.height) : NO_VALUE); - add_line(_("Camera model:"), (camera_model != "" && camera_model != null) ? - camera_model : NO_VALUE); + add_line(_("Camera make:"), (camera_make != "" && camera_make != null) ? + camera_make : NO_VALUE); - add_line(_("Flash:"), (flash != "" && flash != null) ? flash : NO_VALUE); + add_line(_("Camera model:"), (camera_model != "" && camera_model != null) ? + camera_model : NO_VALUE); - add_line(_("Focal length:"), (focal_length != "" && focal_length != null) ? - focal_length : NO_VALUE); - - add_line(_("Exposure date:"), (exposure_date != "" && exposure_date != null) ? - exposure_date : NO_VALUE); - - add_line(_("Exposure time:"), (exposure_time != "" && exposure_time != null) ? - exposure_time : NO_VALUE); - - add_line(_("Exposure bias:"), (exposure_bias != "" && exposure_bias != null) ? exposure_bias : NO_VALUE); + add_line(_("Flash:"), (flash != "" && flash != null) ? flash : NO_VALUE); + + add_line(_("Focal length:"), (focal_length != "" && focal_length != null) ? + focal_length : NO_VALUE); - add_line(_("GPS latitude:"), (gps_lat != -1 && gps_lat_ref != "" && - gps_lat_ref != null) ? "%f °%s".printf(gps_lat, gps_lat_ref) : NO_VALUE); + add_line(_("Exposure date:"), (exposure_date != "" && exposure_date != null) ? + exposure_date : NO_VALUE); - add_line(_("GPS longitude:"), (gps_long != -1 && gps_long_ref != "" && - gps_long_ref != null) ? "%f °%s".printf(gps_long, gps_long_ref) : NO_VALUE); + add_line(_("Exposure time:"), (exposure_time != "" && exposure_time != null) ? + exposure_time : NO_VALUE); - add_line(_("Artist:"), (artist != "" && artist != null) ? artist : NO_VALUE); + add_line(_("Exposure bias:"), (exposure_bias != "" && exposure_bias != null) ? exposure_bias : NO_VALUE); - add_line(_("Copyright:"), (copyright != "" && copyright != null) ? copyright : NO_VALUE); - - add_line(_("Software:"), (software != "" && software != null) ? software : NO_VALUE); + string? osm_link = null; + if (gps_lat != -1 && gps_lat_ref != "" && gps_long != -1 && gps_long_ref != "") { + var old_locale = Intl.setlocale(LocaleCategory.NUMERIC, "C"); + osm_link = OSM_LINK_TEMPLATE.printf(gps_lat, gps_long); + Intl.setlocale(LocaleCategory.NUMERIC, old_locale); } - bool has_comment = (comment != "" && comment != null); - add_line(_("Comment:"), has_comment ? comment : NO_VALUE, has_comment); - } - } + add_line(_("GPS latitude:"), (gps_lat != -1 && gps_lat_ref != "" && + gps_lat_ref != null) ? "%f °%s".printf(gps_lat, gps_lat_ref) : NO_VALUE, false, osm_link); - public ExtendedPropertiesWindow(Gtk.Window owner) { - Object(use_header_bar: Resources.use_header_bar()); - - add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.KEY_PRESS_MASK); - focus_on_map = true; - set_accept_focus(true); - set_can_focus(true); - set_title(_("Extended Information")); - set_position(Gtk.WindowPosition.CENTER); - set_transient_for(owner); - set_type_hint(Gdk.WindowTypeHint.DIALOG); - - delete_event.connect(hide_on_delete); - - properties = new ExtendedProperties(); - properties.halign = Gtk.Align.FILL; - properties.valign = Gtk.Align.FILL; - properties.hexpand = true; - properties.vexpand = true; - properties.set_margin_top (3); - properties.set_margin_bottom (3); - properties.set_margin_start (3); - properties.set_margin_end (3); - ((Gtk.Box) get_content_area()).add(properties); - } + add_line(_("GPS longitude:"), (gps_long != -1 && gps_long_ref != "" && + gps_long_ref != null) ? "%f °%s".printf(gps_long, gps_long_ref) : NO_VALUE, false, osm_link); - public override bool button_press_event(Gdk.EventButton event) { - // LMB only - if (event.button != 1) - return (base.button_press_event != null) ? base.button_press_event(event) : true; + add_line(_("Artist:"), (artist != "" && artist != null) ? artist : NO_VALUE); - begin_move_drag((int) event.button, (int) event.x_root, (int) event.y_root, event.time); + add_line(_("Copyright:"), (copyright != "" && copyright != null) ? copyright : NO_VALUE); - return true; - } - - public override bool key_press_event(Gdk.EventKey event) { - // hide properties - if (Gdk.keyval_name(event.keyval) == "Escape") { - hide(); - return true; + add_line(_("Software:"), (software != "" && software != null) ? software : NO_VALUE); } - // or send through to AppWindow - return AppWindow.get_instance().key_press_event(event); - } - public void update_properties(Page page) { - properties.update_properties(page); - } - - public override void show_all() { - base.show_all(); - properties.unselect_text(); - grab_focus(); + bool has_comment = (comment != "" && comment != null); + add_line(_("Comment:"), has_comment ? comment : NO_VALUE, has_comment); } + } |