diff options
Diffstat (limited to 'src/ui.vala')
-rw-r--r-- | src/ui.vala | 663 |
1 files changed, 441 insertions, 222 deletions
diff --git a/src/ui.vala b/src/ui.vala index 075c97d..31ec151 100644 --- a/src/ui.vala +++ b/src/ui.vala @@ -14,12 +14,27 @@ public class UserInterface private const int DEFAULT_TEXT_DPI = 150; private const int DEFAULT_PHOTO_DPI = 300; + private const GLib.ActionEntry[] action_entries = + { + { "new_document", new_document_activate_cb }, + { "save", save_document_activate_cb }, + { "save_as", save_as_document_activate_cb }, + { "email", email_document_activate_cb }, + { "print", print_document_activate_cb }, + { "preferences", preferences_activate_cb }, + { "help", help_contents_activate_cb }, + { "about", about_activate_cb }, + { "quit", quit_activate_cb } + }; + private Settings settings; private Gtk.Builder builder; - private Gtk.Window window; - private Gtk.VBox main_vbox; + private Gtk.ApplicationWindow window; + private GLib.MenuModel app_menu; + private Gtk.MenuBar menubar; + private Gtk.Box main_vbox; private Gtk.InfoBar info_bar; private Gtk.Image info_bar_image; private Gtk.Label info_bar_label; @@ -74,10 +89,22 @@ public class UserInterface private string error_text; private bool error_change_scanner_hint; - private Book book; + public Book book { get; private set; } private string? book_uri = null; - private AutosaveManager? autosave_manager; + public Page selected_page + { + get + { + return book_view.selected_page; + } + set + { + book_view.selected_page = value; + } + } + + private AutosaveManager autosave_manager; private BookView book_view; private bool updating_page_menu; @@ -88,13 +115,71 @@ public class UserInterface private string document_hint = "photo"; - private string default_file_name = _("Scanned Document.pdf"); - private bool scanning = false; + public string default_file_name { get; set; default = _("Scanned Document.pdf"); } + private bool scanning_ = false; + public bool scanning + { + get { return scanning_; } + set + { + scanning_ = value; + page_delete_menuitem.set_sensitive (!value); + stop_menuitem.set_sensitive (value); + stop_toolbutton.set_sensitive (value); + } + } private int window_width; private int window_height; private bool window_is_maximized; + private uint save_state_timeout; + + public int brightness + { + get { return (int) brightness_adjustment.get_value (); } + set { brightness_adjustment.set_value (value); } + } + + public int contrast + { + get { return (int) contrast_adjustment.get_value (); } + set { contrast_adjustment.set_value (value); } + } + + public int quality + { + get { return (int) quality_adjustment.get_value (); } + set { quality_adjustment.set_value (value); } + } + + public string? selected_device + { + owned get + { + Gtk.TreeIter iter; + + if (device_combo.get_active_iter (out iter)) + { + string device; + device_model.get (iter, 0, out device, -1); + return device; + } + + return null; + } + + set + { + Gtk.TreeIter iter; + if (!find_scan_device (value, out iter)) + return; + + device_combo.set_active_iter (iter); + user_selected_device = true; + } + } + public signal void start_scan (string? device, ScanOptions options); public signal void stop_scan (); public signal void email (string profile, int quality); @@ -109,7 +194,18 @@ public class UserInterface load (); - autosave_manager = AutosaveManager.create (ref book); + autosave_manager = new AutosaveManager (); + autosave_manager.book = book; + autosave_manager.load (); + + if (book.n_pages == 0) + { + add_default_page (); + book.needs_saving = false; + } + else + book_view.selected_page = book.get_page (0); + book.needs_saving_changed.connect (needs_saving_cb); } ~UserInterface () @@ -143,16 +239,11 @@ public class UserInterface Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, "%s", error_title); - dialog.add_button (Gtk.Stock.CLOSE, 0); + dialog.add_button (_("_Close"), 0); dialog.format_secondary_text ("%s", error_text); dialog.destroy (); } - public void set_default_file_name (string default_file_name) - { - this.default_file_name = default_file_name; - } - public void authorize (string resource, out string username, out string password) { /* Label in authorization dialog. '%s' is replaced with the name of the resource requesting authorization */ @@ -176,6 +267,8 @@ public class UserInterface if (setting_devices) return; user_selected_device = true; + if (selected_device != null) + settings.set_string ("selected-device", selected_device); } private void update_info_bar () @@ -188,7 +281,7 @@ public class UserInterface if (have_error) { type = Gtk.MessageType.ERROR; - image_id = Gtk.Stock.DIALOG_ERROR; + image_id = "dialog-error"; title = error_title; text = error_text; show_close_button = true; @@ -197,7 +290,7 @@ public class UserInterface else if (device_model.iter_n_children (null) == 0) { type = Gtk.MessageType.WARNING; - image_id = Gtk.Stock.DIALOG_WARNING; + image_id = "dialog-warning"; /* Warning displayed when no scanners are detected */ title = _("No scanners detected"); /* Hint to user on why there are no scanners detected */ @@ -210,7 +303,7 @@ public class UserInterface } info_bar.set_message_type (type); - info_bar_image.set_from_stock (image_id, Gtk.IconSize.DIALOG); + info_bar_image.set_from_icon_name (image_id, Gtk.IconSize.DIALOG); var message = "<big><b>%s</b></big>\n\n%s".printf (title, text); info_bar_label.set_markup (message); info_bar_close_button.set_visible (show_close_button); @@ -292,37 +385,14 @@ public class UserInterface update_info_bar (); } - private string? get_selected_device () - { - Gtk.TreeIter iter; - - if (device_combo.get_active_iter (out iter)) - { - string device; - device_model.get (iter, 0, out device, -1); - return device; - } - - return null; - } - - public void set_selected_device (string device) - { - Gtk.TreeIter iter; - if (!find_scan_device (device, out iter)) - return; - - device_combo.set_active_iter (iter); - user_selected_device = true; - } - private void add_default_page () { - var page = book.append_page (default_page_width, - default_page_height, - default_page_dpi, - default_page_scan_direction); - book_view.select_page (page); + var page = new Page (default_page_width, + default_page_height, + default_page_dpi, + default_page_scan_direction); + book.append_page (page); + book_view.selected_page = page; } private void on_file_type_changed (Gtk.TreeSelection selection) @@ -363,8 +433,8 @@ public class UserInterface _("Save As..."), window, Gtk.FileChooserAction.SAVE, - Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, - Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT, + _("_Cancel"), Gtk.ResponseType.CANCEL, + _("_Save"), Gtk.ResponseType.ACCEPT, null); save_dialog.set_do_overwrite_confirmation (true); save_dialog.set_local_only (false); @@ -493,7 +563,7 @@ public class UserInterface show_progress_dialog (); try { - book.save (format, get_quality (), file); + book.save (format, quality, file); } catch (Error e) { @@ -507,13 +577,13 @@ public class UserInterface } book_uri = uri; - book.set_needs_saving (false); + book.needs_saving = false; return true; } private bool prompt_to_save (string title, string discard_label) { - if (!book.get_needs_saving ()) + if (!book.needs_saving) return true; var dialog = new Gtk.MessageDialog (window, @@ -525,8 +595,8 @@ public class UserInterface /* Text in dialog warning when a document is about to be lost*/ _("If you don't save, changes will be permanently lost.")); dialog.add_button (discard_label, Gtk.ResponseType.NO); - dialog.add_button (Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL); - dialog.add_button (Gtk.Stock.SAVE, Gtk.ResponseType.YES); + dialog.add_button (_("_Cancel"), Gtk.ResponseType.CANCEL); + dialog.add_button (_("_Save"), Gtk.ResponseType.YES); var response = dialog.run (); dialog.destroy (); @@ -551,13 +621,12 @@ public class UserInterface book.clear (); add_default_page (); book_uri = null; - book.set_needs_saving (false); + book.needs_saving = false; save_as_menuitem.set_sensitive (false); copy_to_clipboard_menuitem.set_sensitive (false); } - [CCode (cname = "G_MODULE_EXPORT new_button_clicked_cb", instance_pos = -1)] - public void new_button_clicked_cb (Gtk.Widget widget) + private void new_document () { if (!prompt_to_save (/* Text in dialog warning when a document is about to be lost */ _("Save current document?"), @@ -570,7 +639,18 @@ public class UserInterface clear_document (); } - private void set_document_hint (string document_hint) + [CCode (cname = "G_MODULE_EXPORT new_button_clicked_cb", instance_pos = -1)] + public void new_button_clicked_cb (Gtk.Widget widget) + { + new_document(); + } + + public void new_document_activate_cb () + { + new_document(); + } + + private void set_document_hint (string document_hint, bool save = false) { this.document_hint = document_hint; @@ -584,20 +664,25 @@ public class UserInterface photo_toolbar_menuitem.set_active (true); photo_menu_menuitem.set_active (true); } + + if (save) + settings.set_string ("document-type", document_hint); } [CCode (cname = "G_MODULE_EXPORT text_menuitem_toggled_cb", instance_pos = -1)] public void text_menuitem_toggled_cb (Gtk.CheckMenuItem widget) { if (widget.get_active ()) - set_document_hint ("text"); + set_document_hint ("text", true); } [CCode (cname = "G_MODULE_EXPORT photo_menuitem_toggled_cb", instance_pos = -1)] public void photo_menuitem_toggled_cb (Gtk.CheckMenuItem widget) { if (widget.get_active ()) - set_document_hint ("photo"); + { + set_document_hint ("photo", true); + } } private void set_page_side (ScanType page_side) @@ -639,21 +724,6 @@ public class UserInterface if (have_iter) paper_size_combo.set_active_iter (iter); } - - private void set_brightness (int brightness) - { - brightness_adjustment.set_value (brightness); - } - - private void set_contrast (int contrast) - { - contrast_adjustment.set_value (contrast); - } - - private void set_quality (int quality) - { - quality_adjustment.set_value (quality); - } private int get_text_dpi () { @@ -702,22 +772,7 @@ public class UserInterface return false; } - private int get_brightness () - { - return (int) brightness_adjustment.get_value (); - } - - private int get_contrast () - { - return (int) contrast_adjustment.get_value (); - } - - private int get_quality () - { - return (int) quality_adjustment.get_value (); - } - - private ScanOptions get_scan_options () + private ScanOptions make_scan_options () { var options = new ScanOptions (); if (document_hint == "text") @@ -733,8 +788,8 @@ public class UserInterface options.depth = 8; } get_paper_size (out options.paper_width, out options.paper_height); - options.brightness = get_brightness (); - options.contrast = get_contrast (); + options.brightness = brightness; + options.contrast = contrast; return options; } @@ -742,9 +797,9 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT scan_button_clicked_cb", instance_pos = -1)] public void scan_button_clicked_cb (Gtk.Widget widget) { - var options = get_scan_options (); + var options = make_scan_options (); options.type = ScanType.SINGLE; - start_scan (get_selected_device (), options); + start_scan (selected_device, options); } [CCode (cname = "G_MODULE_EXPORT stop_scan_button_clicked_cb", instance_pos = -1)] @@ -760,9 +815,9 @@ public class UserInterface stop_scan (); else { - var options = get_scan_options (); + var options = make_scan_options (); options.type = get_page_side (); - start_scan (get_selected_device (), options); + start_scan (selected_device, options); } } @@ -772,6 +827,11 @@ public class UserInterface preferences_dialog.present (); } + public void preferences_activate_cb () + { + preferences_dialog.present (); + } + [CCode (cname = "G_MODULE_EXPORT preferences_dialog_delete_event_cb", instance_pos = -1)] public bool preferences_dialog_delete_event_cb (Gtk.Widget widget) { @@ -786,7 +846,7 @@ public class UserInterface private void update_page_menu () { - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page == null) { page_move_left_menuitem.set_sensitive (false); @@ -796,7 +856,7 @@ public class UserInterface { var index = book.get_page_index (page); page_move_left_menuitem.set_sensitive (index > 0); - page_move_right_menuitem.set_sensitive (index < book.get_n_pages () - 1); + page_move_right_menuitem.set_sensitive (index < book.n_pages - 1); } } @@ -809,11 +869,11 @@ public class UserInterface update_page_menu (); - string? name = null; - if (page.has_crop ()) + var name = "no_crop_menuitem"; + if (page.has_crop) { // FIXME: Make more generic, move into page-size.c and reuse - var crop_name = page.get_named_crop (); + var crop_name = page.crop_name; if (crop_name != null) { if (crop_name == "A4") @@ -832,13 +892,11 @@ public class UserInterface else name = "custom_crop_menuitem"; } - else - name = "no_crop_menuitem"; var menuitem = (Gtk.RadioMenuItem) builder.get_object (name); menuitem.set_active (true); var toolbutton = (Gtk.ToggleToolButton) builder.get_object ("crop_toolbutton"); - toolbutton.set_active (page.has_crop ()); + toolbutton.set_active (page.has_crop); updating_page_menu = false; } @@ -852,7 +910,7 @@ public class UserInterface try { - page.save ("tiff", get_quality (), file); + page.save ("tiff", quality, file); } catch (Error e) { @@ -885,7 +943,7 @@ public class UserInterface { if (updating_page_menu) return; - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page != null) page.rotate_left (); } @@ -895,7 +953,7 @@ public class UserInterface { if (updating_page_menu) return; - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page != null) page.rotate_right (); } @@ -907,19 +965,19 @@ public class UserInterface if (updating_page_menu) return; - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page == null) + { + warning ("Trying to set crop but no selected page"); return; + } if (crop_name == null) - { page.set_no_crop (); - return; - } else if (crop_name == "custom") { - var width = page.get_width (); - var height = page.get_height (); + var width = page.width; + var height = page.height; var crop_width = (int) (width * 0.8 + 0.5); var crop_height = (int) (height * 0.8 + 0.5); page.set_custom_crop (crop_width, crop_height); @@ -1002,7 +1060,7 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT crop_rotate_menuitem_activate_cb", instance_pos = -1)] public void crop_rotate_menuitem_activate_cb (Gtk.Widget widget) { - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page == null) return; page.rotate_crop (); @@ -1011,7 +1069,7 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT page_move_left_menuitem_activate_cb", instance_pos = -1)] public void page_move_left_menuitem_activate_cb (Gtk.Widget widget) { - var page = book_view.get_selected (); + var page = book_view.selected_page; var index = book.get_page_index (page); if (index > 0) book.move_page (page, index - 1); @@ -1022,9 +1080,9 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT page_move_right_menuitem_activate_cb", instance_pos = -1)] public void page_move_right_menuitem_activate_cb (Gtk.Widget widget) { - var page = book_view.get_selected (); + var page = book_view.selected_page; var index = book.get_page_index (page); - if (index < book.get_n_pages () - 1) + if (index < book.n_pages - 1) book.move_page (page, book.get_page_index (page) + 1); update_page_menu (); @@ -1033,7 +1091,7 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT page_delete_menuitem_activate_cb", instance_pos = -1)] public void page_delete_menuitem_activate_cb (Gtk.Widget widget) { - book_view.get_book ().delete_page (book_view.get_selected ()); + book_view.book.delete_page (book_view.selected_page); } [CCode (cname = "G_MODULE_EXPORT save_file_button_clicked_cb", instance_pos = -1)] @@ -1042,10 +1100,15 @@ public class UserInterface save_document (false); } + public void save_document_activate_cb () + { + save_document (false); + } + [CCode (cname = "G_MODULE_EXPORT copy_to_clipboard_button_clicked_cb", instance_pos = -1)] public void copy_to_clipboard_button_clicked_cb (Gtk.Widget widget) { - var page = book_view.get_selected (); + var page = book_view.selected_page; if (page != null) page.copy_to_clipboard (window); } @@ -1056,6 +1119,11 @@ public class UserInterface save_document (true); } + public void save_as_document_activate_cb () + { + save_document (true); + } + private void draw_page (Gtk.PrintOperation operation, Gtk.PrintContext print_context, int page_number) @@ -1067,14 +1135,14 @@ public class UserInterface bool is_landscape = false; if (print_context.get_width () > print_context.get_height ()) is_landscape = true; - if (page.is_landscape () != is_landscape) + if (page.is_landscape != is_landscape) { context.translate (print_context.get_width (), 0); context.rotate (Math.PI_2); } - context.scale (print_context.get_dpi_x () / page.get_dpi (), - print_context.get_dpi_y () / page.get_dpi ()); + context.scale (print_context.get_dpi_x () / page.dpi, + print_context.get_dpi_y () / page.dpi); var image = page.get_image (true); Gdk.cairo_set_source_pixbuf (context, image, 0, 0); @@ -1084,14 +1152,18 @@ public class UserInterface [CCode (cname = "G_MODULE_EXPORT email_button_clicked_cb", instance_pos = -1)] public void email_button_clicked_cb (Gtk.Widget widget) { - email (document_hint, get_quality ()); + email (document_hint, quality); } - [CCode (cname = "G_MODULE_EXPORT print_button_clicked_cb", instance_pos = -1)] - public void print_button_clicked_cb (Gtk.Widget widget) + public void email_document_activate_cb () + { + email (document_hint, quality); + } + + private void print_document () { var print = new Gtk.PrintOperation (); - print.set_n_pages ((int) book.get_n_pages ()); + print.set_n_pages ((int) book.n_pages); print.draw_page.connect (draw_page); try @@ -1106,8 +1178,18 @@ public class UserInterface print.draw_page.disconnect (draw_page); } - [CCode (cname = "G_MODULE_EXPORT help_contents_menuitem_activate_cb", instance_pos = -1)] - public void help_contents_menuitem_activate_cb (Gtk.Widget widget) + [CCode (cname = "G_MODULE_EXPORT print_button_clicked_cb", instance_pos = -1)] + public void print_button_clicked_cb (Gtk.Widget widget) + { + print_document (); + } + + public void print_document_activate_cb () + { + print_document (); + } + + private void show_help () { try { @@ -1121,8 +1203,18 @@ public class UserInterface } } - [CCode (cname = "G_MODULE_EXPORT about_menuitem_activate_cb", instance_pos = -1)] - public void about_menuitem_activate_cb (Gtk.Widget widget) + [CCode (cname = "G_MODULE_EXPORT help_contents_menuitem_activate_cb", instance_pos = -1)] + public void help_contents_menuitem_activate_cb (Gtk.Widget widget) + { + show_help (); + } + + public void help_contents_activate_cb () + { + show_help (); + } + + private void show_about () { string[] authors = { "Robert Ancell <robert.ancell@canonical.com>" }; @@ -1150,6 +1242,17 @@ public class UserInterface null); } + [CCode (cname = "G_MODULE_EXPORT about_menuitem_activate_cb", instance_pos = -1)] + public void about_menuitem_activate_cb (Gtk.Widget widget) + { + show_about (); + } + + public void about_activate_cb () + { + show_about (); + } + private bool on_quit () { if (!prompt_to_save (/* Text in dialog warning when a document is about to be lost */ @@ -1158,33 +1261,12 @@ public class UserInterface _("Quit without Saving"))) return false; - var device = get_selected_device (); - int paper_width = 0, paper_height = 0; - get_paper_size (out paper_width, out paper_height); - - if (device != null) - settings.set_string ("selected-device", device); - settings.set_string ("document-type", document_hint); - settings.set_int ("text-dpi", get_text_dpi ()); - settings.set_int ("photo-dpi", get_photo_dpi ()); - settings.set_enum ("page-side", get_page_side ()); - settings.set_int ("paper-width", paper_width); - settings.set_int ("paper-height", paper_height); - settings.set_int ("brightness", get_brightness ()); - settings.set_int ("contrast", get_contrast ()); - settings.set_int ("jpeg-quality", get_quality ()); - settings.set_int ("window-width", window_width); - settings.set_int ("window-height", window_height); - settings.set_boolean ("window-is-maximized", window_is_maximized); - settings.set_enum ("scan-direction", default_page_scan_direction); - settings.set_int ("page-width", default_page_width); - settings.set_int ("page-height", default_page_height); - settings.set_int ("page-dpi", default_page_dpi); - window.destroy (); - if (autosave_manager != null) - autosave_manager.cleanup (); + if (save_state_timeout != 0) + save_state (true); + + autosave_manager.cleanup (); return true; } @@ -1195,6 +1277,11 @@ public class UserInterface on_quit (); } + public void quit_activate_cb () + { + on_quit (); + } + [CCode (cname = "G_MODULE_EXPORT simple_scan_window_configure_event_cb", instance_pos = -1)] public bool simple_scan_window_configure_event_cb (Gtk.Widget widget, Gdk.EventConfigure event) { @@ -1202,6 +1289,7 @@ public class UserInterface { window_width = event.width; window_height = event.height; + save_state (); } return false; @@ -1227,7 +1315,10 @@ public class UserInterface public bool simple_scan_window_window_state_event_cb (Gtk.Widget widget, Gdk.EventWindowState event) { if ((event.changed_mask & Gdk.WindowState.MAXIMIZED) != 0) + { window_is_maximized = (event.new_window_state & Gdk.WindowState.MAXIMIZED) != 0; + save_state (); + } return false; } @@ -1239,22 +1330,22 @@ public class UserInterface private void page_size_changed_cb (Page page) { - default_page_width = page.get_width (); - default_page_height = page.get_height (); - default_page_dpi = page.get_dpi (); + default_page_width = page.width; + default_page_height = page.height; + default_page_dpi = page.dpi; + save_state (); } private void page_scan_direction_changed_cb (Page page) { - default_page_scan_direction = page.get_scan_direction (); + default_page_scan_direction = page.scan_direction; + save_state (); } private void page_added_cb (Book book, Page page) { - default_page_width = page.get_width (); - default_page_height = page.get_height (); - default_page_dpi = page.get_dpi (); - default_page_scan_direction = page.get_scan_direction (); + page_size_changed_cb (page); + default_page_scan_direction = page.scan_direction; page.size_changed.connect (page_size_changed_cb); page.scan_direction_changed.connect (page_scan_direction_changed_cb); @@ -1267,7 +1358,7 @@ public class UserInterface page.scan_direction_changed.disconnect (page_scan_direction_changed_cb); /* If this is the last page add a new blank one */ - if (book.get_n_pages () == 1) + if (book.n_pages == 1) add_default_page (); update_page_menu (); @@ -1308,23 +1399,43 @@ public class UserInterface private void needs_saving_cb (Book book) { - save_menuitem.set_sensitive (book.get_needs_saving ()); - save_toolbutton.set_sensitive (book.get_needs_saving ()); - if (book.get_needs_saving ()) + save_menuitem.set_sensitive (book.needs_saving); + save_toolbutton.set_sensitive (book.needs_saving); + if (book.needs_saving) save_as_menuitem.set_sensitive (true); copy_to_clipboard_menuitem.set_sensitive (true); } + private bool has_app_menu (Gtk.Application app) + { + /* We have three cases: + * - GNOME 3: show-app-menu true, show-menubar false -> use the app menu + * - Unity, OSX: show-app-menu and show-menubar true -> use the normal menu + * - Other WM, Windows: show-app-menu and show-menubar false -> use the normal menu + */ + var gtk_settings = Gtk.Settings.get_default (); + + bool show_app_menu = false; + bool show_menubar = true; + gtk_settings.get ("gtk-shell-shows-app-menu", &show_app_menu, "gtk-shell-shows-menubar", &show_menubar, null); + + return show_app_menu && !show_menubar; + } + private void load () { Gtk.IconTheme.get_default ().append_search_path (ICON_DIR); Gtk.Window.set_default_icon_name ("scanner"); + var app = Application.get_default () as Gtk.Application; + builder = new Gtk.Builder (); try { builder.add_from_resource ("/org/gnome/SimpleScan/simple-scan.ui"); + if (has_app_menu (app)) + builder.add_from_resource ("/org/gnome/SimpleScan/simple-scan-menu.ui"); } catch (Error e) { @@ -1337,10 +1448,17 @@ public class UserInterface } builder.connect_signals (this); - window = (Gtk.Window) builder.get_object ("simple_scan_window"); - var app = Application.get_default () as Gtk.Application; + window = (Gtk.ApplicationWindow) builder.get_object ("simple_scan_window"); app.add_window (window); - main_vbox = (Gtk.VBox) builder.get_object ("main_vbox"); + menubar = (Gtk.MenuBar) builder.get_object ("menubar"); + if (has_app_menu (app)) + { + app_menu = (GLib.MenuModel) builder.get_object ("appmenu"); + app.add_action_entries (action_entries, this); + app.set_app_menu (app_menu); + menubar.set_visible(false); + } + main_vbox = (Gtk.Box) builder.get_object ("main_vbox"); page_move_left_menuitem = (Gtk.MenuItem) builder.get_object ("page_move_left_menuitem"); page_move_right_menuitem = (Gtk.MenuItem) builder.get_object ("page_move_right_menuitem"); page_delete_menuitem = (Gtk.MenuItem) builder.get_object ("page_delete_menuitem"); @@ -1389,7 +1507,7 @@ public class UserInterface content_area.add (hbox); hbox.show (); - info_bar_image = new Gtk.Image.from_stock (Gtk.Stock.DIALOG_WARNING, Gtk.IconSize.DIALOG); + info_bar_image = new Gtk.Image.from_icon_name ("dialog-warning", Gtk.IconSize.DIALOG); hbox.pack_start (info_bar_image, false, true, 0); info_bar_image.show (); @@ -1398,7 +1516,7 @@ public class UserInterface hbox.pack_start (info_bar_label, true, true, 0); info_bar_label.show (); - info_bar_close_button = (Gtk.Button) info_bar.add_button (Gtk.Stock.CLOSE, Gtk.ResponseType.CLOSE); + info_bar_close_button = (Gtk.Button) info_bar.add_button (_("_Close"), Gtk.ResponseType.CLOSE); info_bar_change_scanner_button = (Gtk.Button) info_bar.add_button (/* Button in error infobar to open preferences dialog and change scanner */ _("Change _Scanner"), 1); @@ -1424,10 +1542,12 @@ public class UserInterface if (dpi <= 0) dpi = DEFAULT_TEXT_DPI; set_dpi_combo (text_dpi_combo, DEFAULT_TEXT_DPI, dpi); + text_dpi_combo.changed.connect (() => { settings.set_int ("text-dpi", get_text_dpi ()); }); dpi = settings.get_int ("photo-dpi"); if (dpi <= 0) dpi = DEFAULT_PHOTO_DPI; set_dpi_combo (photo_dpi_combo, DEFAULT_PHOTO_DPI, dpi); + photo_dpi_combo.changed.connect (() => { settings.set_int ("photo-dpi", get_photo_dpi ()); }); var renderer = new Gtk.CellRendererText (); device_combo.pack_start (renderer, true); @@ -1437,6 +1557,7 @@ public class UserInterface page_side_combo.pack_start (renderer, true); page_side_combo.add_attribute (renderer, "text", 1); set_page_side ((ScanType) settings.get_enum ("page-side")); + page_side_combo.changed.connect (() => { settings.set_enum ("page-side", get_page_side ()); }); renderer = new Gtk.CellRendererText (); paper_size_combo.pack_start (renderer, true); @@ -1444,6 +1565,13 @@ public class UserInterface var paper_width = settings.get_int ("paper-width"); var paper_height = settings.get_int ("paper-height"); set_paper_size (paper_width, paper_height); + paper_size_combo.changed.connect (() => + { + int w, h; + get_paper_size (out w, out h); + settings.set_int ("paper-width", w); + settings.set_int ("paper-height", h); + }); var lower = brightness_adjustment.get_lower (); var darker_label = "<small>%s</small>".printf (_("Darker")); @@ -1452,7 +1580,8 @@ public class UserInterface brightness_scale.add_mark (lower, Gtk.PositionType.BOTTOM, darker_label); brightness_scale.add_mark (0, Gtk.PositionType.BOTTOM, null); brightness_scale.add_mark (upper, Gtk.PositionType.BOTTOM, lighter_label); - set_brightness (settings.get_int ("brightness")); + brightness = settings.get_int ("brightness"); + brightness_adjustment.value_changed.connect (() => { settings.set_int ("brightness", brightness); }); lower = contrast_adjustment.get_lower (); var less_label = "<small>%s</small>".printf (_("Less")); @@ -1461,7 +1590,8 @@ public class UserInterface contrast_scale.add_mark (lower, Gtk.PositionType.BOTTOM, less_label); contrast_scale.add_mark (0, Gtk.PositionType.BOTTOM, null); contrast_scale.add_mark (upper, Gtk.PositionType.BOTTOM, more_label); - set_contrast (settings.get_int ("contrast")); + contrast = settings.get_int ("contrast"); + contrast_adjustment.value_changed.connect (() => { settings.set_int ("contrast", contrast); }); lower = quality_adjustment.get_lower (); var minimum_label = "<small>%s</small>".printf (_("Minimum")); @@ -1470,7 +1600,8 @@ public class UserInterface quality_scale.add_mark (lower, Gtk.PositionType.BOTTOM, minimum_label); quality_scale.add_mark (75, Gtk.PositionType.BOTTOM, null); quality_scale.add_mark (upper, Gtk.PositionType.BOTTOM, maximum_label); - set_quality (settings.get_int ("jpeg-quality")); + quality = settings.get_int ("jpeg-quality"); + quality_adjustment.value_changed.connect (() => { settings.set_int ("jpeg-quality", quality); }); var device = settings.get_string ("selected-device"); if (device != null) @@ -1491,42 +1622,153 @@ public class UserInterface book_view.show_menu.connect (show_page_menu_cb); book_view.show (); - /* Find default page details */ - default_page_scan_direction = (ScanDirection) settings.get_enum ("scan-direction"); - default_page_width = settings.get_int ("page-width"); - if (default_page_width <= 0) - default_page_width = 595; - default_page_height = settings.get_int ("page-height"); - if (default_page_height <= 0) - default_page_height = 842; - default_page_dpi = settings.get_int ("page-dpi"); - if (default_page_dpi <= 0) - default_page_dpi = 72; + /* Load previous state */ + load_state (); /* Restore window size */ - window_width = settings.get_int ("window-width"); - if (window_width <= 0) - window_width = 600; - window_height = settings.get_int ("window-height"); - if (window_height <= 0) - window_height = 400; debug ("Restoring window to %dx%d pixels", window_width, window_height); window.set_default_size (window_width, window_height); - window_is_maximized = settings.get_boolean ("window-is-maximized"); if (window_is_maximized) { debug ("Restoring window to maximized"); window.maximize (); } - if (book.get_n_pages () == 0) - add_default_page (); - book.set_needs_saving (false); - book.needs_saving_changed.connect (needs_saving_cb); - progress_dialog = new ProgressBarDialog (window, _("Saving document...")); book.saving.connect (book_saving_cb); } + + private string state_filename + { + owned get { return Path.build_filename (Environment.get_user_cache_dir (), "simple-scan", "state"); } + } + + private void load_state () + { + debug ("Loading state from %s", state_filename); + + var f = new KeyFile (); + try + { + f.load_from_file (state_filename, KeyFileFlags.NONE); + } + catch (Error e) + { + if (!(e is FileError.NOENT)) + warning ("Failed to load state: %s", e.message); + } + window_width = state_get_integer (f, "window", "width", 600); + if (window_width <= 0) + window_width = 600; + window_height = state_get_integer (f, "window", "height", 400); + if (window_height <= 0) + window_height = 400; + window_is_maximized = state_get_boolean (f, "window", "is-maximized"); + default_page_width = state_get_integer (f, "last-page", "width", 595); + default_page_height = state_get_integer (f, "last-page", "height", 842); + default_page_dpi = state_get_integer (f, "last-page", "dpi", 72); + switch (state_get_string (f, "last-page", "scan-direction", "top-to-bottom")) + { + default: + case "top-to-bottom": + default_page_scan_direction = ScanDirection.TOP_TO_BOTTOM; + break; + case "bottom-to-top": + default_page_scan_direction = ScanDirection.BOTTOM_TO_TOP; + break; + case "left-to-right": + default_page_scan_direction = ScanDirection.LEFT_TO_RIGHT; + break; + case "right-to-left": + default_page_scan_direction = ScanDirection.RIGHT_TO_LEFT; + break; + } + } + + private int state_get_integer (KeyFile f, string group_name, string key, int default = 0) + { + try + { + return f.get_integer (group_name, key); + } + catch + { + return default; + } + } + + private bool state_get_boolean (KeyFile f, string group_name, string key, bool default = false) + { + try + { + return f.get_boolean (group_name, key); + } + catch + { + return default; + } + } + + private string state_get_string (KeyFile f, string group_name, string key, string default = "") + { + try + { + return f.get_string (group_name, key); + } + catch + { + return default; + } + } + + private void save_state (bool force = false) + { + if (!force) + { + if (save_state_timeout != 0) + Source.remove (save_state_timeout); + save_state_timeout = Timeout.add (100, () => + { + save_state (true); + save_state_timeout = 0; + return false; + }); + return; + } + + debug ("Saving state to %s", state_filename); + + var f = new KeyFile (); + f.set_integer ("window", "width", window_width); + f.set_integer ("window", "height", window_height); + f.set_boolean ("window", "is-maximized", window_is_maximized); + f.set_integer ("last-page", "width", default_page_width); + f.set_integer ("last-page", "height", default_page_height); + f.set_integer ("last-page", "dpi", default_page_dpi); + switch (default_page_scan_direction) + { + case ScanDirection.TOP_TO_BOTTOM: + f.set_value ("last-page", "scan-direction", "top-to-bottom"); + break; + case ScanDirection.BOTTOM_TO_TOP: + f.set_value ("last-page", "scan-direction", "bottom-to-top"); + break; + case ScanDirection.LEFT_TO_RIGHT: + f.set_value ("last-page", "scan-direction", "left-to-right"); + break; + case ScanDirection.RIGHT_TO_LEFT: + f.set_value ("last-page", "scan-direction", "right-to-left"); + break; + } + try + { + FileUtils.set_contents (state_filename, f.to_data ()); + } + catch (Error e) + { + warning ("Failed to write state: %s", e.message); + } + } private void book_saving_cb (int page_number) { @@ -1534,7 +1776,7 @@ public class UserInterface while (Gtk.events_pending ()) Gtk.main_iteration (); - var total = (int) book.get_n_pages (); + var total = (int) book.n_pages; var fraction = (page_number + 1.0) / total; var complete = fraction == 1.0; if (complete) @@ -1558,29 +1800,6 @@ public class UserInterface progress_dialog.hide (); } - public Book get_book () - { - return book; - } - - public void set_selected_page (Page page) - { - book_view.select_page (page); - } - - public Page get_selected_page () - { - return book_view.get_selected (); - } - - public void set_scanning (bool scanning) - { - this.scanning = scanning; - page_delete_menuitem.set_sensitive (!scanning); - stop_menuitem.set_sensitive (scanning); - stop_toolbutton.set_sensitive (scanning); - } - public void show_error (string error_title, string error_text, bool change_scanner_hint) { have_error = true; @@ -1600,7 +1819,7 @@ class ProgressBarDialog : Gtk.Window { Gtk.ProgressBar bar; - public ProgressBarDialog (Gtk.Window parent, string title) + public ProgressBarDialog (Gtk.ApplicationWindow parent, string title) { bar = new Gtk.ProgressBar (); var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5); |