diff --git a/data/gschema.xml b/data/gschema.xml index 06881376..efb31d76 100755 --- a/data/gschema.xml +++ b/data/gschema.xml @@ -12,9 +12,6 @@ false - - false - false diff --git a/meson.build b/meson.build index f29835e7..508aaae2 100644 --- a/meson.build +++ b/meson.build @@ -36,7 +36,6 @@ executable( 'src/ScreenshotBackend.vala', 'src/ScreenshotProxy.vala', 'src/ScreenshotWindow.vala', - 'src/Widgets/SaveDialog.vala', config_file, dependencies: [ dependency('gdk-pixbuf-2.0'), diff --git a/po/POTFILES b/po/POTFILES index c1ae5dca..90f7bdb9 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,4 +1,3 @@ src/Application.vala src/ScreenshotBackend.vala src/ScreenshotWindow.vala -src/Widgets/SaveDialog.vala diff --git a/src/Application.vala b/src/Application.vala index a4878aed..27ada9ac 100755 --- a/src/Application.vala +++ b/src/Application.vala @@ -105,6 +105,19 @@ public class Screenshot.Application : Gtk.Application { } }); + var open_action = new SimpleAction ("open", VariantType.STRING); + open_action.activate.connect ((parameter) => { + var context = Gdk.Display.get_default ().get_app_launch_context (); + context.set_timestamp (Gdk.CURRENT_TIME); + + try { + AppInfo.launch_default_for_uri ("file:///" + parameter.get_string (), context); + } catch (Error e) { + critical (e.message); + } + }); + + add_action (open_action); add_action (quit_action); set_accels_for_action ("app.quit", {"q", "Escape"}); } diff --git a/src/ScreenshotWindow.vala b/src/ScreenshotWindow.vala index 86f1438b..672f5161 100755 --- a/src/ScreenshotWindow.vala +++ b/src/ScreenshotWindow.vala @@ -19,7 +19,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { public bool to_clipboard { get; construct; } - public bool close_on_save { get; set; } public bool mouse_pointer { get; set; } public bool redact { get; set; } @@ -46,7 +45,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { to_clipboard: clipboard ); - close_on_save = true; from_command = true; mouse_pointer = grab_pointer; this.delay = int.max (0, delay); @@ -95,12 +93,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { pointer_switch = new Gtk.Switch (); pointer_switch.halign = Gtk.Align.START; - var close_label = new Gtk.Label (_("Close after saving:")); - close_label.halign = Gtk.Align.END; - - var close_switch = new Gtk.Switch (); - close_switch.halign = Gtk.Align.START; - var redact_label = new Gtk.Label (_("Conceal text:")); redact_label.halign = Gtk.Align.END; @@ -139,8 +131,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { }; option_grid.attach (pointer_label, 0, 0); option_grid.attach (pointer_switch, 1, 0); - option_grid.attach (close_label, 0, 1); - option_grid.attach (close_switch, 1, 1); option_grid.attach (redact_label, 0, 2); option_grid.attach (redact_switch, 1, 2); option_grid.attach (delay_label, 0, 3); @@ -170,8 +160,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { settings = new Settings ("io.elementary.screenshot"); settings.bind ("mouse-pointer", pointer_switch, "active", GLib.SettingsBindFlags.DEFAULT); settings.bind ("mouse-pointer", this, "mouse-pointer", GLib.SettingsBindFlags.DEFAULT); - settings.bind ("close-on-save", close_switch, "active", GLib.SettingsBindFlags.DEFAULT); - settings.bind ("close-on-save", this, "close-on-save", GLib.SettingsBindFlags.DEFAULT); settings.bind ("delay", delay_spin, "value", GLib.SettingsBindFlags.DEFAULT); settings.bind ("redact", redact_switch, "active", GLib.SettingsBindFlags.DEFAULT); settings.bind ("redact", this, "redact", GLib.SettingsBindFlags.DEFAULT); @@ -242,23 +230,30 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { pointer_switch.sensitive = sensitive; } - private void save_file (string file_name, string format, owned string folder_dir, Gdk.Pixbuf screenshot) throws GLib.Error { + private void save_file (Gdk.Pixbuf screenshot) throws GLib.Error { + var date_time = new DateTime.now_local ().format ("%Y-%m-%d %H.%M.%S"); + + /// TRANSLATORS: %s represents a timestamp here + string file_name = _("Screenshot from %s").printf (date_time); + + if (scale_factor > 1) { + file_name += "@%ix".printf (scale_factor); + } + string full_file_name = ""; - string folder_from_settings = ""; + var folder_dir = settings.get_string ("folder-dir"); if (folder_dir == "") { - folder_from_settings = settings.get_string ("folder-dir"); - if (folder_from_settings != "") { - folder_dir = folder_from_settings; - } else { - folder_dir = GLib.Environment.get_user_special_dir (GLib.UserDirectory.PICTURES) - + "%c".printf (GLib.Path.DIR_SEPARATOR) + Application.SAVE_FOLDER; - } - Application.create_dir_if_missing (folder_dir); + folder_dir = Environment.get_user_special_dir (GLib.UserDirectory.PICTURES) + + "%c".printf (Path.DIR_SEPARATOR) + Application.SAVE_FOLDER; } + Application.create_dir_if_missing (folder_dir); + int attempt = 0; + string format = settings.get_string ("format"); + do { if (attempt == 0) { full_file_name = Path.build_filename (folder_dir, "%s.%s".printf (file_name, format)); @@ -270,57 +265,36 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { } while (File.new_for_path (full_file_name).query_exists ()); screenshot.save (full_file_name, format); + + var file_icon = new FileIcon (File.new_for_path (full_file_name)); + + var readable_path = folder_dir.replace (Environment.get_home_dir () + "%c".printf (Path.DIR_SEPARATOR), ""); + + var notification = new Notification (_("Screenshot saved")); + notification.add_button ( + _("Open"), + Action.print_detailed_name ("app.open", new Variant ("s", full_file_name)) + ); + notification.set_body (_("Saved to “%s”").printf (readable_path)); + notification.set_icon (file_icon); + notification.set_priority (NotificationPriority.LOW); + + GLib.Application.get_default ().send_notification (null, notification); } private void save_pixbuf (Gdk.Pixbuf screenshot) { - if (from_command == false) { - var save_dialog = new Screenshot.SaveDialog (screenshot, settings, this); - save_dialog.save_response.connect ((response, folder_dir, output_name, format) => { - save_dialog.destroy (); - - if (response) { - string[] formats = {".png", ".jpg", ".jpeg", ".bmp", ".tiff"}; - string output = output_name; - - foreach (string type in formats) { - output = output.replace (type, ""); - } - - try { - save_file (output, format, folder_dir, screenshot); - - if (close_on_save) { - this.destroy (); - } - } catch (GLib.Error e) { - show_error_dialog (e.message); - } - } - }); - - save_dialog.close.connect (() => { - if (close_on_save) { - this.destroy (); - } - }); - - save_dialog.show_all (); + if (to_clipboard) { + Gtk.Clipboard.get_default (this.get_display ()).set_image (screenshot); } else { - if (to_clipboard) { - Gtk.Clipboard.get_default (this.get_display ()).set_image (screenshot); - } else { - var date_time = new GLib.DateTime.now_local ().format ("%Y-%m-%d %H.%M.%S"); - - /// TRANSLATORS: %s represents a timestamp here - string file_name = _("Screenshot from %s").printf (date_time); - string format = settings.get_string ("format"); - try { - save_file (file_name, format, "", screenshot); - } catch (GLib.Error e) { - show_error_dialog (e.message); - } + try { + save_file (screenshot); + } catch (GLib.Error e) { + show_error_dialog (e.message); } - this.destroy (); + } + + if (from_command) { + destroy (); } } @@ -335,11 +309,6 @@ public class Screenshot.ScreenshotWindow : Hdy.ApplicationWindow { Gdk.Pixbuf? pixbuf = null; try { pixbuf = backend.capture.end (res); - } catch (GLib.IOError.CANCELLED e) { - if (close_on_save) { - this.destroy (); - return; - } } catch (Error e) { show_error_dialog (e.message); } diff --git a/src/Widgets/SaveDialog.vala b/src/Widgets/SaveDialog.vala deleted file mode 100644 index fe390942..00000000 --- a/src/Widgets/SaveDialog.vala +++ /dev/null @@ -1,270 +0,0 @@ -/* -* Copyright (c) 2014–2016 Fabio Zaramella -* 2017–2022 elementary, Inc. (https://elementary.io) -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License version 3 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Artem Anufrij -* Fabio Zaramella -*/ - -public class Screenshot.SaveDialog : Granite.Dialog { - public Gdk.Pixbuf pixbuf { get; construct; } - public Settings settings { get; construct; } - - public signal void save_response (bool response, string folder_dir, string output_name, string format); - - private Gtk.Label folder_name; - private Gtk.Image folder_image; - - public SaveDialog (Gdk.Pixbuf pixbuf, Settings settings, Gtk.Window parent) { - Object ( - deletable: false, - modal: true, - pixbuf: pixbuf, - settings: settings, - title: _("Screenshot"), - transient_for: parent - ); - } - - construct { - set_keep_above (true); - var folder_dir = Environment.get_user_special_dir (UserDirectory.PICTURES) - + "%c".printf (GLib.Path.DIR_SEPARATOR) + Application.SAVE_FOLDER; - - var folder_from_settings = settings.get_string ("folder-dir"); - - if (folder_from_settings != folder_dir && folder_from_settings != "") { - folder_dir = folder_from_settings; - } - - Application.create_dir_if_missing (folder_dir); - - int width = pixbuf.get_width () / 4; - int height = pixbuf.get_height () / 4; - if (pixbuf.get_width () > Gdk.Screen.width () / 2 || pixbuf.get_height () > Gdk.Screen.height () / 2) { - width /= 2; - height /= 2; - } - - var scale = get_style_context ().get_scale (); - - var preview = new Gtk.Image () { - gicon = pixbuf.scale_simple (width * scale, height * scale, Gdk.InterpType.BILINEAR) - }; - preview.get_style_context ().set_scale (1); - - var preview_event_box = new Gtk.EventBox (); - preview_event_box.add (preview); - - Gtk.drag_source_set (preview_event_box, Gdk.ModifierType.BUTTON1_MASK, null, Gdk.DragAction.COPY); - Gtk.drag_source_add_image_targets (preview_event_box); - Gtk.drag_source_set_icon_gicon (preview_event_box, new ThemedIcon ("image-x-generic")); - preview_event_box.drag_data_get.connect ((widget, context, selection_data, info, time_) => { - selection_data.set_pixbuf (pixbuf); - }); - - var preview_box = new Gtk.Grid () { - margin_top = 18, - margin_bottom = 18, - halign = Gtk.Align.CENTER - }; - preview_box.add (preview_event_box); - - unowned Gtk.StyleContext preview_box_context = preview_box.get_style_context (); - preview_box_context.add_class (Granite.STYLE_CLASS_CARD); - preview_box_context.add_class (Granite.STYLE_CLASS_CHECKERBOARD); - - var dialog_label = new Granite.HeaderLabel (_("Save Image as…")); - - var date_time = new GLib.DateTime.now_local ().format ("%Y-%m-%d %H.%M.%S"); - - /// TRANSLATORS: %s represents a timestamp here - var file_name = _("Screenshot from %s").printf (date_time); - - if (this.scale_factor > 1) { - file_name += "@%ix".printf (this.scale_factor); - } - - var name_label = new Granite.HeaderLabel (_("Name")); - - var name_entry = new Granite.ValidatedEntry () { - activates_default = true, - hexpand = true, - text = file_name - }; - name_entry.grab_focus (); - - var validation_label = new Gtk.Label ("") { - halign = Gtk.Align.END, - justify = Gtk.Justification.RIGHT, - max_width_chars = 55, - wrap = true, - xalign = 1 - }; - validation_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL); - validation_label.get_style_context ().add_class (Gtk.STYLE_CLASS_ERROR); - - var name_message_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - margin_top = 3 - }; - name_message_revealer.add (validation_label); - - var format_label = new Granite.HeaderLabel (_("File Type")); - - var format_cmb = new Gtk.ComboBoxText (); - format_cmb.append_text ("png"); - format_cmb.append_text ("jpeg"); - format_cmb.append_text ("bmp"); - format_cmb.append_text ("tiff"); - - switch (settings.get_string ("format")) { - case "png": - format_cmb.active = 0; - break; - case "jpeg": - format_cmb.active = 1; - break; - case "bmp": - format_cmb.active = 2; - break; - case "tiff": - format_cmb.active = 3; - break; - } - - var location_label = new Granite.HeaderLabel (_("Folder")) { - margin_top = 18 - }; - - folder_name = new Gtk.Label ("") { - halign = Gtk.Align.START, - hexpand = true - }; - - folder_image = new Gtk.Image (); - - update_location_button (folder_dir); - - var arrow = new Gtk.Image.from_icon_name ("view-more-horizontal-symbolic", BUTTON); - - var location_button_indicator = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3); - location_button_indicator.add (folder_image); - location_button_indicator.add (folder_name); - location_button_indicator.add (arrow); - - var location_button = new Gtk.Button () { - child = location_button_indicator - }; - - var location_dialog = new Gtk.FileChooserNative ( - _("Select Screenshots Folder…"), - this, - Gtk.FileChooserAction.SELECT_FOLDER, - _("Select"), - null - ); - location_dialog.set_current_folder (folder_dir); - - var content = this.get_content_area () as Gtk.Box; - content.valign = Gtk.Align.START; - content.vexpand = true; - content.margin_end = 12; - content.margin_bottom = 12; - content.margin_start = 12; - content.add (dialog_label); - content.add (preview_box); - content.add (name_label); - content.add (name_entry); - content.add (name_message_revealer); - content.add (format_label); - content.add (format_cmb); - content.add (location_label); - content.add (location_button); - - var clipboard_btn = (Gtk.Button) add_button (_("Copy to Clipboard"), 0); - - var retry_btn = (Gtk.Button) add_button (_("Cancel"), Gtk.ResponseType.CANCEL); - - var save_btn = (Gtk.Button) add_button (_("Save"), Gtk.ResponseType.APPLY); - save_btn.has_default = true; - save_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); - - name_entry.changed.connect (() => { - if (name_entry.text.length == 0) { - validation_label.label = _("Filename can't be blank"); - name_entry.is_valid = false; - } else if (name_entry.text.contains ("/")) { - validation_label.label = _("Filename can't contain “/”"); - name_entry.is_valid = false; - } else { - name_entry.is_valid = true; - } - - name_message_revealer.reveal_child = !name_entry.is_valid; - save_btn.sensitive = name_entry.is_valid; - }); - - save_btn.clicked.connect (() => { - save_response (true, folder_dir, name_entry.get_text (), format_cmb.get_active_text ()); - }); - - clipboard_btn.clicked.connect (() => { - Gtk.Clipboard.get_default (this.get_display ()).set_image (pixbuf); - this.close (); - }); - - retry_btn.clicked.connect (() => { - save_response (false, folder_dir, file_name, format_cmb.get_active_text ()); - }); - - format_cmb.changed.connect (() => { - settings.set_string ("format", format_cmb.get_active_text ()); - }); - - location_button.clicked.connect (() => { - location_dialog.run (); - }); - - location_dialog.response.connect ((response) => { - if (response == Gtk.ResponseType.ACCEPT) { - SList uris = location_dialog.get_uris (); - foreach (unowned string uri in uris) { - settings.set_string ("folder-dir", Uri.unescape_string (uri.substring (7, -1))); - folder_dir = settings.get_string ("folder-dir"); - } - - update_location_button (folder_dir); - } - }); - } - - private void update_location_button (string folder_dir) { - var file = File.new_for_path (folder_dir); - try { - var info = file.query_info ( - FileAttribute.STANDARD_DISPLAY_NAME + "," + FileAttribute.STANDARD_ICON, - FileQueryInfoFlags.NONE - ); - folder_name.label = info.get_display_name (); - folder_image.gicon = info.get_icon (); - } catch (Error e) { - folder_name.label = folder_dir; - folder_image.gicon = new ThemedIcon ("folder"); - } - } -}