summaryrefslogtreecommitdiff
path: root/src/ui.vala
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2017-11-11 18:47:31 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2017-11-11 18:47:31 +0100
commitab6556e393162fff0e0e0c80a9fff689b4e2ca05 (patch)
tree74d12800f57397f6123cac49f814e5cabb1df205 /src/ui.vala
parent657d8b8812f16b2c377e5b77ff2ffcc4046a7dce (diff)
New upstream version 3.26.2upstream/3.26.2
Diffstat (limited to 'src/ui.vala')
-rw-r--r--src/ui.vala2398
1 files changed, 0 insertions, 2398 deletions
diff --git a/src/ui.vala b/src/ui.vala
deleted file mode 100644
index 554b161..0000000
--- a/src/ui.vala
+++ /dev/null
@@ -1,2398 +0,0 @@
-/*
- * Copyright (C) 2009-2015 Canonical Ltd.
- * Author: Robert Ancell <robert.ancell@canonical.com>,
- * Eduard Gotwig <g@ox.io>
- *
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later
- * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
- * license.
- */
-
-[GtkTemplate (ui = "/org/gnome/SimpleScan/simple-scan.ui")]
-public class UserInterface : Gtk.ApplicationWindow
-{
- 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 },
- { "reorder", reorder_document_activate_cb },
- { "save", save_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;
-
- [GtkChild]
- private Gtk.MenuBar menubar;
- [GtkChild]
- private Gtk.Toolbar toolbar;
- [GtkChild]
- private Gtk.Menu page_menu;
- [GtkChild]
- private Gtk.Box main_vbox;
- private Gtk.InfoBar info_bar;
- private Gtk.Image info_bar_image;
- private Gtk.Label info_bar_label;
- private Gtk.Button info_bar_close_button;
- private Gtk.Button info_bar_change_scanner_button;
- private Gtk.Button info_bar_install_button;
- [GtkChild]
- private Gtk.RadioMenuItem custom_crop_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem a4_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem a5_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem a6_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem letter_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem legal_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem four_by_six_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem no_crop_menuitem;
- [GtkChild]
- private Gtk.MenuItem page_move_left_menuitem;
- [GtkChild]
- private Gtk.MenuItem page_move_right_menuitem;
- [GtkChild]
- private Gtk.MenuItem page_delete_menuitem;
- [GtkChild]
- private Gtk.MenuItem crop_rotate_menuitem;
- [GtkChild]
- private Gtk.MenuItem save_menuitem;
- [GtkChild]
- private Gtk.MenuItem email_menuitem;
- [GtkChild]
- private Gtk.MenuItem print_menuitem;
- [GtkChild]
- private Gtk.MenuItem copy_to_clipboard_menuitem;
- [GtkChild]
- private Gtk.Button save_button;
- [GtkChild]
- private Gtk.ToolButton save_toolbutton;
- [GtkChild]
- private Gtk.MenuItem stop_scan_menuitem;
- [GtkChild]
- private Gtk.ToolButton stop_toolbutton;
- [GtkChild]
- private Gtk.ToggleButton crop_button;
- [GtkChild]
- private Gtk.ToggleToolButton crop_toolbutton;
- [GtkChild]
- private Gtk.Button stop_button;
- [GtkChild]
- private Gtk.Button scan_button;
-
- [GtkChild]
- private Gtk.RadioMenuItem text_button_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem text_button_hb_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem text_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem photo_button_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem photo_button_hb_menuitem;
- [GtkChild]
- private Gtk.RadioMenuItem photo_menuitem;
-
- [GtkChild]
- private Gtk.Dialog authorize_dialog;
- [GtkChild]
- private Gtk.Label authorize_label;
- [GtkChild]
- private Gtk.Entry username_entry;
- [GtkChild]
- private Gtk.Entry password_entry;
-
- [GtkChild]
- private Gtk.Dialog preferences_dialog;
- [GtkChild]
- private Gtk.ComboBox device_combo;
- [GtkChild]
- private Gtk.ComboBox text_dpi_combo;
- [GtkChild]
- private Gtk.ComboBox photo_dpi_combo;
- [GtkChild]
- private Gtk.ComboBox page_side_combo;
- [GtkChild]
- private Gtk.ComboBox paper_size_combo;
- [GtkChild]
- private Gtk.Scale brightness_scale;
- [GtkChild]
- private Gtk.Scale contrast_scale;
- [GtkChild]
- private Gtk.Scale quality_scale;
- [GtkChild]
- private Gtk.Scale page_delay_scale;
- [GtkChild]
- private Gtk.ListStore device_model;
- [GtkChild]
- private Gtk.ListStore text_dpi_model;
- [GtkChild]
- private Gtk.ListStore photo_dpi_model;
- [GtkChild]
- private Gtk.ListStore page_side_model;
- [GtkChild]
- private Gtk.ListStore paper_size_model;
- [GtkChild]
- private Gtk.Adjustment brightness_adjustment;
- [GtkChild]
- private Gtk.Adjustment contrast_adjustment;
- [GtkChild]
- private Gtk.Adjustment quality_adjustment;
- [GtkChild]
- private Gtk.Adjustment page_delay_adjustment;
- private bool setting_devices;
- private string? missing_driver = null;
- private bool user_selected_device;
-
- private Gtk.FileChooserDialog? save_dialog;
- private ProgressBarDialog progress_dialog;
-
- private bool have_error;
- private string error_title;
- private string error_text;
- private bool error_change_scanner_hint;
-
- public Book book { get; private set; }
- private bool book_needs_saving;
- private string? book_uri = null;
-
- 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;
- private int default_page_width;
- private int default_page_height;
- private int default_page_dpi;
- private ScanDirection default_page_scan_direction;
-
- private string document_hint = "photo";
-
- private bool scanning_ = false;
- public bool scanning
- {
- get { return scanning_; }
- set
- {
- scanning_ = value;
- page_delete_menuitem.sensitive = !value;
- stop_scan_menuitem.sensitive = value;
- stop_toolbutton.sensitive = value;
- scan_button.visible = !value;
- stop_button.visible = value;
- }
- }
-
- private int window_width;
- private int window_height;
- private bool window_is_maximized;
- private bool window_is_fullscreen;
-
- private uint save_state_timeout;
-
- public int brightness
- {
- get { return (int) brightness_adjustment.value; }
- set { brightness_adjustment.value = value; }
- }
-
- public int contrast
- {
- get { return (int) contrast_adjustment.value; }
- set { contrast_adjustment.value = value; }
- }
-
- public int quality
- {
- get { return (int) quality_adjustment.value; }
- set { quality_adjustment.value = value; }
- }
-
- public int page_delay
- {
- get { return (int) page_delay_adjustment.value; }
- set { page_delay_adjustment.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);
-
- public UserInterface ()
- {
- settings = new Settings ("org.gnome.SimpleScan");
-
- book = new Book ();
- book.page_added.connect (page_added_cb);
- book.reordered.connect (reordered_cb);
- book.page_removed.connect (page_removed_cb);
- book.changed.connect (book_changed_cb);
-
- load ();
-
- clear_document ();
- autosave_manager = new AutosaveManager ();
- autosave_manager.book = book;
- autosave_manager.load ();
-
- if (book.n_pages == 0)
- book_needs_saving = false;
- else
- {
- book_view.selected_page = book.get_page (0);
- book_needs_saving = true;
- book_changed_cb (book);
- }
- }
-
- ~UserInterface ()
- {
- book.page_added.disconnect (page_added_cb);
- book.reordered.disconnect (reordered_cb);
- book.page_removed.disconnect (page_removed_cb);
- }
-
- private bool find_scan_device (string device, out Gtk.TreeIter iter)
- {
- bool have_iter = false;
-
- if (device_model.get_iter_first (out iter))
- {
- do
- {
- string d;
- device_model.get (iter, 0, out d, -1);
- if (d == device)
- have_iter = true;
- } while (!have_iter && device_model.iter_next (ref iter));
- }
-
- return have_iter;
- }
-
- private void show_error_dialog (string error_title, string error_text)
- {
- var dialog = new Gtk.MessageDialog (this,
- Gtk.DialogFlags.MODAL,
- Gtk.MessageType.WARNING,
- Gtk.ButtonsType.NONE,
- "%s", error_title);
- dialog.add_button (_("_Close"), 0);
- dialog.format_secondary_text ("%s", error_text);
- dialog.run ();
- dialog.destroy ();
- }
-
- 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 */
- var description = _("Username and password required to access '%s'").printf (resource);
-
- username_entry.text = "";
- password_entry.text = "";
- authorize_label.set_text (description);
-
- authorize_dialog.visible = true;
- authorize_dialog.run ();
- authorize_dialog.visible = false;
-
- username = username_entry.text;
- password = password_entry.text;
- }
-
- [GtkCallback]
- private void device_combo_changed_cb (Gtk.Widget widget)
- {
- if (setting_devices)
- return;
- user_selected_device = true;
- if (selected_device != null)
- settings.set_string ("selected-device", selected_device);
- }
-
- private void update_info_bar ()
- {
- Gtk.MessageType type;
- string title, text, image_id;
- bool show_close_button = false;
- bool show_install_button = false;
- bool show_change_scanner_button = false;
-
- if (have_error)
- {
- type = Gtk.MessageType.ERROR;
- image_id = "dialog-error";
- title = error_title;
- text = error_text;
- show_close_button = true;
- show_change_scanner_button = error_change_scanner_hint;
- }
- else if (device_model.iter_n_children (null) == 0)
- {
- type = Gtk.MessageType.WARNING;
- image_id = "dialog-warning";
- if (missing_driver == null)
- {
- /* Warning displayed when no scanners are detected */
- title = _("No scanners detected");
- /* Hint to user on why there are no scanners detected */
- text = _("Please check your scanner is connected and powered on");
- }
- else
- {
- /* Warning displayed when no drivers are installed but a compatible scanner is detected */
- title = _("Additional software needed");
- /* Instructions to install driver software */
- text = _("You need to install driver software for your scanner.");
- show_install_button = true;
- }
- }
- else
- {
- info_bar.visible = false;
- return;
- }
-
- info_bar.message_type = type;
- 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.visible = show_close_button;
- info_bar_change_scanner_button.visible = show_change_scanner_button;
- info_bar_install_button.visible = show_install_button;
- info_bar.visible = true;
- }
-
- public void set_scan_devices (List<ScanDevice> devices, string? missing_driver = null)
- {
- bool have_selection = false;
- int index;
- Gtk.TreeIter iter;
-
- setting_devices = true;
-
- this.missing_driver = missing_driver;
-
- /* If the user hasn't chosen a scanner choose the best available one */
- if (user_selected_device)
- have_selection = device_combo.active >= 0;
-
- /* Add new devices */
- index = 0;
- foreach (var device in devices)
- {
- int n_delete = -1;
-
- /* Find if already exists */
- if (device_model.iter_nth_child (out iter, null, index))
- {
- int i = 0;
- do
- {
- string name;
- bool matched;
-
- device_model.get (iter, 0, out name, -1);
- matched = name == device.name;
-
- if (matched)
- {
- n_delete = i;
- break;
- }
- i++;
- } while (device_model.iter_next (ref iter));
- }
-
- /* If exists, remove elements up to this one */
- if (n_delete >= 0)
- {
- int i;
-
- /* Update label */
- device_model.set (iter, 1, device.label, -1);
-
- for (i = 0; i < n_delete; i++)
- {
- device_model.iter_nth_child (out iter, null, index);
- device_model.remove (iter);
- }
- }
- else
- {
- device_model.insert (out iter, index);
- device_model.set (iter, 0, device.name, 1, device.label, -1);
- }
- index++;
- }
-
- /* Remove any remaining devices */
- while (device_model.iter_nth_child (out iter, null, index))
- device_model.remove (iter);
-
- /* Select the previously selected device or the first available device */
- if (!have_selection)
- {
- var device = settings.get_string ("selected-device");
- if (device != null && find_scan_device (device, out iter))
- device_combo.set_active_iter (iter);
- else
- device_combo.set_active (0);
- }
-
- setting_devices = false;
-
- update_info_bar ();
- }
-
- private string choose_file_location ()
- {
- /* Get directory to save to */
- string? directory = null;
- directory = settings.get_string ("save-directory");
-
- if (directory == null || directory == "")
- directory = Environment.get_user_special_dir (UserDirectory.DOCUMENTS);
-
- save_dialog = new Gtk.FileChooserDialog (/* Save dialog: Dialog title */
- _("Save As..."),
- this,
- Gtk.FileChooserAction.SAVE,
- _("_Cancel"), Gtk.ResponseType.CANCEL,
- _("_Save"), Gtk.ResponseType.ACCEPT,
- null);
- save_dialog.local_only = false;
- if (book_uri != null)
- save_dialog.set_uri (book_uri);
- else {
- save_dialog.set_current_folder (directory);
- /* Default filename to use when saving document */
- save_dialog.set_current_name (_("Scanned Document.pdf"));
- }
-
- /* Filter to only show images by default */
- var filter = new Gtk.FileFilter ();
- filter.set_filter_name (/* Save dialog: Filter name to show only image files */
- _("Image Files"));
- filter.add_pixbuf_formats ();
- filter.add_mime_type ("application/pdf");
- save_dialog.add_filter (filter);
- filter = new Gtk.FileFilter ();
- filter.set_filter_name (/* Save dialog: Filter name to show all files */
- _("All Files"));
- filter.add_pattern ("*");
- save_dialog.add_filter (filter);
-
- var file_type_store = new Gtk.ListStore (2, typeof (string), typeof (string));
- Gtk.TreeIter iter;
- file_type_store.append (out iter);
- file_type_store.set (iter,
- /* Save dialog: Label for saving in PDF format */
- 0, _("PDF (multi-page document)"),
- 1, ".pdf",
- -1);
- file_type_store.append (out iter);
- file_type_store.set (iter,
- /* Save dialog: Label for saving in JPEG format */
- 0, _("JPEG (compressed)"),
- 1, ".jpg",
- -1);
- file_type_store.append (out iter);
- file_type_store.set (iter,
- /* Save dialog: Label for saving in PNG format */
- 0, _("PNG (lossless)"),
- 1, ".png",
- -1);
-
- var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
- box.visible = true;
- save_dialog.set_extra_widget (box);
-
- /* Label in save dialog beside combo box to choose file format (PDF, JPEG, PNG) */
- var label = new Gtk.Label (_("File format:"));
- label.visible = true;
- box.pack_start (label, false, false, 0);
-
- var file_type_combo = new Gtk.ComboBox.with_model (file_type_store);
- file_type_combo.visible = true;
- var renderer = new Gtk.CellRendererText ();
- file_type_combo.pack_start (renderer, true);
- file_type_combo.add_attribute (renderer, "text", 0);
-
- file_type_combo.set_active (0);
- file_type_combo.changed.connect (() =>
- {
- var extension = "";
- Gtk.TreeIter i;
- if (file_type_combo.get_active_iter (out i))
- file_type_store.get (i, 1, out extension, -1);
-
- var path = save_dialog.get_filename ();
- var filename = Path.get_basename (path);
-
- /* Replace extension */
- var extension_index = filename.last_index_of_char ('.');
- if (extension_index >= 0)
- filename = filename.slice (0, extension_index);
- filename = filename + extension;
- save_dialog.set_current_name (filename);
- });
- box.pack_start (file_type_combo, false, false, 0);
-
- string? uri = null;
- while (true)
- {
- var response = save_dialog.run ();
- if (response != Gtk.ResponseType.ACCEPT)
- break;
-
- var extension = "";
- Gtk.TreeIter i;
- if (file_type_combo.get_active_iter (out i))
- file_type_store.get (i, 1, out extension, -1);
-
- var path = save_dialog.get_filename ();
- var filename = Path.get_basename (path);
-
- var extension_index = filename.last_index_of_char ('.');
- if (extension_index < 0)
- path += extension;
-
- uri = File.new_for_path (path).get_uri ();
-
- /* Check the file(s) don't already exist */
- var files = new List<File> ();
- var format = uri_to_format (uri);
- if (format == "jpeg" || format == "png")
- {
- for (var j = 0; j < book.n_pages; j++)
- files.append (book.make_indexed_file (uri, j));
- }
- else
- files.append (File.new_for_uri (uri));
-
- if (check_overwrite (save_dialog, files))
- break;
- }
-
- settings.set_string ("save-directory", save_dialog.get_current_folder ());
-
- save_dialog.destroy ();
- save_dialog = null;
-
- return uri;
- }
-
- private bool check_overwrite (Gtk.Window parent, List<File> files)
- {
- foreach (var file in files)
- {
- if (!file.query_exists ())
- continue;
-
- var dialog = new Gtk.MessageDialog (parent, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE,
- /* Contents of dialog that shows if saving would overwrite and existing file. %s is replaced with the name of the file. */
- _("A file named “%s” already exists. Do you want to replace it?"), file.get_basename ());
- dialog.add_button (_("_Cancel"), Gtk.ResponseType.CANCEL);
- dialog.add_button (/* Button in dialog that shows if saving would overwrite and existing file. Clicking the button allows simple-scan to overwrite the file. */
- _("_Replace"), Gtk.ResponseType.ACCEPT);
- var response = dialog.run ();
- dialog.destroy ();
-
- if (response != Gtk.ResponseType.ACCEPT)
- return false;
- }
-
- return true;
- }
-
- private string uri_to_format (string uri)
- {
- var uri_lower = uri.down ();
- if (uri_lower.has_suffix (".pdf"))
- return "pdf";
- else if (uri_lower.has_suffix (".png"))
- return "png";
- else
- return "jpeg";
- }
-
- private bool save_document ()
- {
- var uri = choose_file_location ();
- if (uri == null)
- return false;
-
- var file = File.new_for_uri (uri);
-
- debug ("Saving to '%s'", uri);
-
- var format = uri_to_format (uri);
-
- show_progress_dialog ();
- try
- {
- book.save (format, quality, file);
- }
- catch (Error e)
- {
- hide_progress_dialog ();
- warning ("Error saving file: %s", e.message);
- show_error (/* Title of error dialog when save failed */
- _("Failed to save file"),
- e.message,
- false);
- return false;
- }
-
- book_needs_saving = false;
- book_uri = uri;
- return true;
- }
-
- private bool prompt_to_save (string title, string discard_label)
- {
- if (!book_needs_saving)
- return true;
-
- var dialog = new Gtk.MessageDialog (this,
- Gtk.DialogFlags.MODAL,
- Gtk.MessageType.WARNING,
- Gtk.ButtonsType.NONE,
- "%s", title);
- dialog.format_secondary_text ("%s",
- /* 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 (_("_Cancel"), Gtk.ResponseType.CANCEL);
- dialog.add_button (_("_Save"), Gtk.ResponseType.YES);
-
- var response = dialog.run ();
- dialog.destroy ();
-
- switch (response)
- {
- case Gtk.ResponseType.YES:
- if (save_document ())
- return true;
- else
- return false;
- case Gtk.ResponseType.NO:
- return true;
- default:
- return false;
- }
- }
-
- private void clear_document ()
- {
- book_view.default_page = new Page (default_page_width,
- default_page_height,
- default_page_dpi,
- default_page_scan_direction);
- book.clear ();
- book_needs_saving = false;
- book_uri = null;
- save_menuitem.sensitive = false;
- email_menuitem.sensitive = false;
- print_menuitem.sensitive = false;
- save_button.sensitive = false;
- save_toolbutton.sensitive = false;
- copy_to_clipboard_menuitem.sensitive = false;
- }
-
- private void new_document ()
- {
- if (!prompt_to_save (/* Text in dialog warning when a document is about to be lost */
- _("Save current document?"),
- /* Button in dialog to create new document and discard unsaved document */
- _("Discard Changes")))
- return;
-
- if (scanning)
- stop_scan ();
- clear_document ();
- }
-
- [GtkCallback]
- private 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;
-
- if (document_hint == "text")
- {
- text_button_menuitem.active = true;
- text_button_hb_menuitem.active = true;
- text_menuitem.active = true;
- }
- else if (document_hint == "photo")
- {
- photo_button_menuitem.active = true;
- photo_button_hb_menuitem.active = true;
- photo_menuitem.active = true;
- }
-
- if (save)
- settings.set_string ("document-type", document_hint);
- }
-
- [GtkCallback]
- private void text_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_document_hint ("text", true);
- }
-
- [GtkCallback]
- private void photo_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_document_hint ("photo", true);
- }
-
- private void set_page_side (ScanType page_side)
- {
- Gtk.TreeIter iter;
-
- if (page_side_model.get_iter_first (out iter))
- {
- do
- {
- int s;
- page_side_model.get (iter, 0, out s, -1);
- if (s == page_side)
- {
- page_side_combo.set_active_iter (iter);
- return;
- }
- } while (page_side_model.iter_next (ref iter));
- }
- }
-
- private void set_paper_size (int width, int height)
- {
- Gtk.TreeIter iter;
- bool have_iter;
-
- for (have_iter = paper_size_model.get_iter_first (out iter);
- have_iter;
- have_iter = paper_size_model.iter_next (ref iter))
- {
- int w, h;
- paper_size_model.get (iter, 0, out w, 1, out h, -1);
- if (w == width && h == height)
- break;
- }
-
- if (!have_iter)
- have_iter = paper_size_model.get_iter_first (out iter);
- if (have_iter)
- paper_size_combo.set_active_iter (iter);
- }
-
- private int get_text_dpi ()
- {
- Gtk.TreeIter iter;
- int dpi = DEFAULT_TEXT_DPI;
-
- if (text_dpi_combo.get_active_iter (out iter))
- text_dpi_model.get (iter, 0, out dpi, -1);
-
- return dpi;
- }
-
- private int get_photo_dpi ()
- {
- Gtk.TreeIter iter;
- int dpi = DEFAULT_PHOTO_DPI;
-
- if (photo_dpi_combo.get_active_iter (out iter))
- photo_dpi_model.get (iter, 0, out dpi, -1);
-
- return dpi;
- }
-
- private ScanType get_page_side ()
- {
- Gtk.TreeIter iter;
- int page_side = ScanType.ADF_BOTH;
-
- if (page_side_combo.get_active_iter (out iter))
- page_side_model.get (iter, 0, out page_side, -1);
-
- return (ScanType) page_side;
- }
-
- private bool get_paper_size (out int width, out int height)
- {
- Gtk.TreeIter iter;
-
- width = height = 0;
- if (paper_size_combo.get_active_iter (out iter))
- {
- paper_size_model.get (iter, 0, ref width, 1, ref height, -1);
- return true;
- }
-
- return false;
- }
-
- private ScanOptions make_scan_options ()
- {
- var options = new ScanOptions ();
- if (document_hint == "text")
- {
- options.scan_mode = ScanMode.GRAY;
- options.dpi = get_text_dpi ();
- options.depth = 2;
- }
- else
- {
- options.scan_mode = ScanMode.COLOR;
- options.dpi = get_photo_dpi ();
- options.depth = 8;
- }
- get_paper_size (out options.paper_width, out options.paper_height);
- options.brightness = brightness;
- options.contrast = contrast;
- options.page_delay = page_delay;
-
- return options;
- }
-
- [GtkCallback]
- private void scan_button_clicked_cb (Gtk.Widget widget)
- {
- var options = make_scan_options ();
- options.type = ScanType.SINGLE;
- start_scan (selected_device, options);
- }
-
- [GtkCallback]
- private void stop_scan_button_clicked_cb (Gtk.Widget widget)
- {
- stop_scan ();
- }
-
- [GtkCallback]
- private void continuous_scan_button_clicked_cb (Gtk.Widget widget)
- {
- if (scanning)
- stop_scan ();
- else
- {
- var options = make_scan_options ();
- options.type = get_page_side ();
- start_scan (selected_device, options);
- }
- }
-
- [GtkCallback]
- private void batch_button_clicked_cb (Gtk.Widget widget)
- {
- var options = make_scan_options ();
- options.type = ScanType.BATCH;
- start_scan (selected_device, options);
- }
-
- [GtkCallback]
- private void preferences_button_clicked_cb (Gtk.Widget widget)
- {
- preferences_dialog.present ();
- }
-
- public void preferences_activate_cb ()
- {
- preferences_dialog.present ();
- }
-
- [GtkCallback]
- private bool preferences_dialog_delete_event_cb (Gtk.Widget widget, Gdk.EventAny event)
- {
- return true;
- }
-
- [GtkCallback]
- private void preferences_dialog_response_cb (Gtk.Widget widget, int response_id)
- {
- preferences_dialog.visible = false;
- }
-
- private void update_page_menu ()
- {
- var page = book_view.selected_page;
- if (page == null)
- {
- page_move_left_menuitem.sensitive = false;
- page_move_right_menuitem.sensitive = false;
- }
- else
- {
- var index = book.get_page_index (page);
- page_move_left_menuitem.sensitive = index > 0;
- page_move_right_menuitem.sensitive = index < book.n_pages - 1;
- }
- }
-
- private void page_selected_cb (BookView view, Page? page)
- {
- if (page == null)
- return;
-
- updating_page_menu = true;
-
- update_page_menu ();
-
- var menuitem = no_crop_menuitem;
- if (page.has_crop)
- {
- var crop_name = page.crop_name;
- if (crop_name != null)
- {
- if (crop_name == "A4")
- menuitem = a4_menuitem;
- else if (crop_name == "A5")
- menuitem = a5_menuitem;
- else if (crop_name == "A6")
- menuitem = a6_menuitem;
- else if (crop_name == "letter")
- menuitem = letter_menuitem;
- else if (crop_name == "legal")
- menuitem = legal_menuitem;
- else if (crop_name == "4x6")
- menuitem = four_by_six_menuitem;
- }
- else
- menuitem = custom_crop_menuitem;
- }
-
- menuitem.active = true;
- crop_button.active = page.has_crop;
- crop_toolbutton.active = page.has_crop;
-
- updating_page_menu = false;
- }
-
- private void show_page_cb (BookView view, Page page)
- {
- var path = get_temporary_filename ("scanned-page", "png");
- if (path == null)
- return;
- var file = File.new_for_path (path);
-
- try
- {
- page.save ("png", quality, file);
- }
- catch (Error e)
- {
- show_error_dialog (/* Error message display when unable to save image for preview */
- _("Unable to save image for preview"),
- e.message);
- return;
- }
-
- try
- {
- Gtk.show_uri (screen, file.get_uri (), Gtk.get_current_event_time ());
- }
- catch (Error e)
- {
- show_error_dialog (/* Error message display when unable to preview image */
- _("Unable to open image preview application"),
- e.message);
- }
- }
-
- private void show_page_menu_cb (BookView view)
- {
- page_menu.popup (null, null, null, 3, Gtk.get_current_event_time ());
- }
-
- [GtkCallback]
- private void rotate_left_button_clicked_cb (Gtk.Widget widget)
- {
- if (updating_page_menu)
- return;
- var page = book_view.selected_page;
- if (page != null)
- page.rotate_left ();
- }
-
- [GtkCallback]
- private void rotate_right_button_clicked_cb (Gtk.Widget widget)
- {
- if (updating_page_menu)
- return;
- var page = book_view.selected_page;
- if (page != null)
- page.rotate_right ();
- }
-
- private void set_crop (string? crop_name)
- {
- crop_rotate_menuitem.sensitive = crop_name != null;
-
- if (updating_page_menu)
- return;
-
- 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 ();
- else if (crop_name == "custom")
- {
- 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);
- page.move_crop ((width - crop_width) / 2, (height - crop_height) / 2);
- }
- else
- page.set_named_crop (crop_name);
- }
-
- [GtkCallback]
- private void no_crop_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop (null);
- }
-
- [GtkCallback]
- private void custom_crop_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("custom");
- }
-
- [GtkCallback]
- private void crop_button_toggled_cb (Gtk.ToggleButton widget)
- {
- if (updating_page_menu)
- return;
-
- if (widget.active)
- custom_crop_menuitem.active = true;
- else
- no_crop_menuitem.active = true;
- }
-
- [GtkCallback]
- private void crop_toolbutton_toggled_cb (Gtk.ToggleToolButton widget)
- {
- if (updating_page_menu)
- return;
-
- if (widget.active)
- custom_crop_menuitem.active = true;
- else
- no_crop_menuitem.active = true;
- }
-
- [GtkCallback]
- private void four_by_six_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("4x6");
- }
-
- [GtkCallback]
- private void legal_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("legal");
- }
-
- [GtkCallback]
- private void letter_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("letter");
- }
-
- [GtkCallback]
- private void a6_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("A6");
- }
-
- [GtkCallback]
- private void a5_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("A5");
- }
-
- [GtkCallback]
- private void a4_menuitem_toggled_cb (Gtk.CheckMenuItem widget)
- {
- if (widget.active)
- set_crop ("A4");
- }
-
- [GtkCallback]
- private void crop_rotate_menuitem_activate_cb (Gtk.Widget widget)
- {
- var page = book_view.selected_page;
- if (page == null)
- return;
- page.rotate_crop ();
- }
-
- [GtkCallback]
- private void page_move_left_menuitem_activate_cb (Gtk.Widget widget)
- {
- var page = book_view.selected_page;
- var index = book.get_page_index (page);
- if (index > 0)
- book.move_page (page, index - 1);
- }
-
- [GtkCallback]
- private void page_move_right_menuitem_activate_cb (Gtk.Widget widget)
- {
- var page = book_view.selected_page;
- var index = book.get_page_index (page);
- if (index < book.n_pages - 1)
- book.move_page (page, book.get_page_index (page) + 1);
- }
-
- [GtkCallback]
- private void page_delete_menuitem_activate_cb (Gtk.Widget widget)
- {
- book_view.book.delete_page (book_view.selected_page);
- }
-
- private void reorder_document ()
- {
- var dialog = new Gtk.Window ();
- dialog.type_hint = Gdk.WindowTypeHint.DIALOG;
- dialog.modal = true;
- dialog.border_width = 12;
- /* Title of dialog to reorder pages */
- dialog.title = _("Reorder Pages");
- dialog.set_transient_for (this);
- dialog.key_press_event.connect ((e) =>
- {
- if (e.state == 0 && e.keyval == Gdk.Key.Escape)
- {
- dialog.destroy ();
- return true;
- }
-
- return false;
- });
- dialog.visible = true;
-
- var g = new Gtk.Grid ();
- g.row_homogeneous = true;
- g.row_spacing = 6;
- g.column_homogeneous = true;
- g.column_spacing = 6;
- g.visible = true;
- dialog.add (g);
-
- /* Label on button for combining sides in reordering dialog */
- var b = make_reorder_button (_("Combine sides"), "F1F2F3B1B2B3-F1B1F2B2F3B3");
- b.clicked.connect (() =>
- {
- book.combine_sides ();
- dialog.destroy ();
- });
- b.visible = true;
- g.attach (b, 0, 0, 1, 1);
-
- /* Label on button for combining sides in reverse order in reordering dialog */
- b = make_reorder_button (_("Combine sides (reverse)"), "F1F2F3B3B2B1-F1B1F2B2F3B3");
- b.clicked.connect (() =>
- {
- book.combine_sides_reverse ();
- dialog.destroy ();
- });
- b.visible = true;
- g.attach (b, 1, 0, 1, 1);
-
- /* Label on button for reversing in reordering dialog */
- b = make_reorder_button (_("Reverse"), "C1C2C3C4C5C6-C6C5C4C3C2C1");
- b.clicked.connect (() =>
- {
- book.reverse ();
- dialog.destroy ();
- });
- b.visible = true;
- g.attach (b, 0, 2, 1, 1);
-
- /* Label on button for cancelling page reordering dialog */
- b = make_reorder_button (_("Keep unchanged"), "C1C2C3C4C5C6-C1C2C3C4C5C6");
- b.clicked.connect (() =>
- {
- dialog.destroy ();
- });
- b.visible = true;
- g.attach (b, 1, 2, 1, 1);
-
- dialog.present ();
- }
-
- public void reorder_document_activate_cb ()
- {
- reorder_document ();
- }
-
- [GtkCallback]
- private void reorder_menuitem_activate_cb (Gtk.Widget widget)
- {
- reorder_document ();
- }
-
- private Gtk.Button make_reorder_button (string text, string items)
- {
- var b = new Gtk.Button ();
-
- var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
- vbox.visible = true;
- b.add (vbox);
-
- var label = new Gtk.Label (text);
- label.visible = true;
- vbox.pack_start (label, true, true, 0);
-
- var rb = make_reorder_box (items);
- rb.visible = true;
- vbox.pack_start (rb, true, true, 0);
-
- return b;
- }
-
- private Gtk.Box make_reorder_box (string items)
- {
- var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
- box.visible = true;
-
- Gtk.Box? page_box = null;
- for (var i = 0; items[i] != '\0'; i++)
- {
- if (items[i] == '-')
- {
- var a = new Gtk.Arrow (Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE);
- a.visible = true;
- box.pack_start (a, false, false, 0);
- page_box = null;
- continue;
- }
-
- /* First character describes side */
- var side = items[i];
- i++;
- if (items[i] == '\0')
- break;
-
- if (page_box == null)
- {
- page_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3);
- page_box.visible = true;
- box.pack_start (page_box, false, false, 0);
- }
-
- /* Get colours for each page (from Tango palette) */
- var r = 1.0;
- var g = 1.0;
- var b = 1.0;
- switch (side)
- {
- case 'F':
- /* Plum */
- r = 0x75 / 255.0;
- g = 0x50 / 255.0;
- b = 0x7B / 255.0;
- break;
- case 'B':
- /* Orange */
- r = 0xF5 / 255.0;
- g = 0x79 / 255.0;
- b = 0.0;
- break;
- case 'C':
- /* Butter to Scarlet Red */
- var p = (items[i] - '1') / 5.0;
- r = (0xED / 255.0) * (1 - p) + 0xCC * p;
- g = (0xD4 / 255.0) * (1 - p);
- b = 0;
- break;
- }
-
- /* Mix with white to look more paper like */
- r = r + (1.0 - r) * 0.7;
- g = g + (1.0 - g) * 0.7;
- b = b + (1.0 - b) * 0.7;
-
- var icon = new PageIcon ("%c".printf (items[i]), r, g, b);
- icon.visible = true;
- page_box.pack_start (icon, false, false, 0);
- }
-
- return box;
- }
-
- [GtkCallback]
- private void save_file_button_clicked_cb (Gtk.Widget widget)
- {
- save_document ();
- }
-
- public void save_document_activate_cb ()
- {
- save_document ();
- }
-
- [GtkCallback]
- private void copy_to_clipboard_button_clicked_cb (Gtk.Widget widget)
- {
- var page = book_view.selected_page;
- if (page != null)
- page.copy_to_clipboard (this);
- }
-
- private void draw_page (Gtk.PrintOperation operation,
- Gtk.PrintContext print_context,
- int page_number)
- {
- var context = print_context.get_cairo_context ();
- var page = book.get_page (page_number);
-
- /* Rotate to same aspect */
- bool is_landscape = false;
- if (print_context.get_width () > print_context.get_height ())
- is_landscape = true;
- 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.dpi,
- print_context.get_dpi_y () / page.dpi);
-
- var image = page.get_image (true);
- Gdk.cairo_set_source_pixbuf (context, image, 0, 0);
- context.paint ();
- }
-
- [GtkCallback]
- private void email_button_clicked_cb (Gtk.Widget widget)
- {
- email (document_hint, quality);
- }
-
- public void email_document_activate_cb ()
- {
- email (document_hint, quality);
- }
-
- private void print_document ()
- {
- var print = new Gtk.PrintOperation ();
- print.n_pages = (int) book.n_pages;
- print.draw_page.connect (draw_page);
-
- try
- {
- print.run (Gtk.PrintOperationAction.PRINT_DIALOG, this);
- }
- catch (Error e)
- {
- warning ("Error printing: %s", e.message);
- }
-
- print.draw_page.disconnect (draw_page);
- }
-
- [GtkCallback]
- private void print_button_clicked_cb (Gtk.Widget widget)
- {
- print_document ();
- }
-
- public void print_document_activate_cb ()
- {
- print_document ();
- }
-
- private void launch_help ()
- {
- try
- {
- Gtk.show_uri (screen, "help:simple-scan", Gtk.get_current_event_time ());
- }
- catch (Error e)
- {
- show_error_dialog (/* Error message displayed when unable to launch help browser */
- _("Unable to open help file"),
- e.message);
- }
- }
-
- [GtkCallback]
- private void help_contents_menuitem_activate_cb (Gtk.Widget widget)
- {
- launch_help ();
- }
-
- public void help_contents_activate_cb ()
- {
- launch_help ();
- }
-
- private void show_about ()
- {
- string[] authors = { "Robert Ancell <robert.ancell@canonical.com>" };
-
- /* The license this software is under (GPL3+) */
- string license = _("This program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <http://www.gnu.org/licenses/>.");
-
- /* Title of about dialog */
- string title = _("About Simple Scan");
-
- /* Description of program */
- string description = _("Simple document scanning tool");
-
- Gtk.show_about_dialog (this,
- "title", title,
- "program-name", "Simple Scan",
- "version", VERSION,
- "comments", description,
- "logo-icon-name", "scanner",
- "authors", authors,
- "translator-credits", _("translator-credits"),
- "website", "https://launchpad.net/simple-scan",
- "copyright", "Copyright © 2009-2015 Canonical Ltd.",
- "license", license,
- "wrap-license", true,
- null);
- }
-
- [GtkCallback]
- private 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 */
- _("Save document before quitting?"),
- /* Button in dialog to quit and discard unsaved document */
- _("Quit without Saving")))
- return false;
-
- destroy ();
-
- if (save_state_timeout != 0)
- save_state (true);
-
- autosave_manager.cleanup ();
-
- return true;
- }
-
- [GtkCallback]
- private void quit_menuitem_activate_cb (Gtk.Widget widget)
- {
- on_quit ();
- }
-
- public void quit_activate_cb ()
- {
- on_quit ();
- }
-
- public override void size_allocate (Gtk.Allocation allocation)
- {
- base.size_allocate (allocation);
-
- if (!window_is_maximized && !window_is_fullscreen)
- {
- get_size (out window_width, out window_height);
- save_state ();
- }
- }
-
- private void info_bar_response_cb (Gtk.InfoBar widget, int response_id)
- {
- switch (response_id)
- {
- /* Change scanner */
- case 1:
- device_combo.grab_focus ();
- preferences_dialog.present ();
- break;
- /* Install drivers */
- case 2:
- install_drivers ();
- break;
- default:
- have_error = false;
- error_title = null;
- error_text = null;
- update_info_bar ();
- break;
- }
- }
-
- private void install_drivers ()
- {
- var message = "", instructions = "";
- string[] packages_to_install = {};
- switch (missing_driver)
- {
- case "brscan":
- case "brscan2":
- case "brscan3":
- case "brscan4":
- /* Message to indicate a Brother scanner has been detected */
- message = _("You appear to have a Brother scanner.");
- /* Instructions on how to install Brother scanner drivers */
- instructions = _("Drivers for this are available on the <a href=\"http://support.brother.com\">Brother website</a>.");
- break;
- case "samsung":
- /* Message to indicate a Samsung scanner has been detected */
- message = _("You appear to have a Samsung scanner.");
- /* Instructions on how to install Samsung scanner drivers */
- instructions = _("Drivers for this are available on the <a href=\"http://samsung.com/support\">Samsung website</a>.");
- break;
- case "hpaio":
- /* Message to indicate a HP scanner has been detected */
- message = _("You appear to have an HP scanner.");
- packages_to_install = { "libsane-hpaio" };
- break;
- case "epkowa":
- /* Message to indicate an Epson scanner has been detected */
- message = _("You appear to have an Epson scanner.");
- /* Instructions on how to install Epson scanner drivers */
- instructions = _("Drivers for this are available on the <a href=\"http://support.epson.com\">Epson website</a>.");
- break;
- }
- var dialog = new Gtk.Dialog.with_buttons (/* Title of dialog giving instructions on how to install drivers */
- _("Install drivers"), this, Gtk.DialogFlags.MODAL, _("_Close"), Gtk.ResponseType.CLOSE);
- dialog.get_content_area ().border_width = 12;
- dialog.get_content_area ().spacing = 6;
-
- var label = new Gtk.Label (message);
- label.visible = true;
- label.xalign = 0f;
- dialog.get_content_area ().pack_start (label, true, true, 0);
-
- var instructions_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
- instructions_box.visible = true;
- dialog.get_content_area ().pack_start (instructions_box, true, true, 0);
-
- var stack = new Gtk.Stack ();
- instructions_box.pack_start (stack, false, false, 0);
-
- var spinner = new Gtk.Spinner ();
- spinner.visible = true;
- stack.add (spinner);
-
- var status_label = new Gtk.Label ("");
- status_label.visible = true;
- stack.add (status_label);
-
- var instructions_label = new Gtk.Label (instructions);
- instructions_label.visible = true;
- instructions_label.xalign = 0f;
- instructions_label.use_markup = true;
- instructions_box.pack_start (instructions_label, false, false, 0);
-
- label = new Gtk.Label (/* Message in driver install dialog */
- _("Once installed you will need to restart Simple Scan."));
- label.visible = true;
- label.xalign = 0f;
- dialog.get_content_area ().border_width = 12;
- dialog.get_content_area ().pack_start (label, true, true, 0);
-
- if (packages_to_install.length > 0)
- {
-#if HAVE_PACKAGEKIT
- stack.visible = true;
- spinner.active = true;
- instructions_label.set_text (/* Label shown while installing drivers */
- _("Installing drivers..."));
- install_packages.begin (packages_to_install, () => {}, (object, result) =>
- {
- status_label.visible = true;
- spinner.active = false;
- status_label.set_text ("☒");
- stack.visible_child = status_label;
- /* Label shown once drivers successfully installed */
- var result_text = _("Drivers installed successfully!");
- try
- {
- var results = install_packages.end (result);
- if (results.get_error_code () == null)
- status_label.set_text ("☑");
- else
- {
- var e = results.get_error_code ();
- /* Label shown if failed to install drivers */
- result_text = _("Failed to install drivers (error code %d).").printf (e.code);
- }
- }
- catch (Error e)
- {
- /* Label shown if failed to install drivers */
- result_text = _("Failed to install drivers.");
- warning ("Failed to install drivers: %s", e.message);
- }
- instructions_label.set_text (result_text);
- });
-#else
- instructions_label.set_text (/* Label shown to prompt user to install packages (when PackageKit not available) */
- _("You need to install the %s package(s).").printf (string.joinv (", ", packages_to_install)));
-#endif
- }
-
- dialog.run ();
- dialog.destroy ();
- }
-
-#if HAVE_PACKAGEKIT
- private async Pk.Results? install_packages (string[] packages, Pk.ProgressCallback progress_callback) throws GLib.Error
- {
- var task = new Pk.Task ();
- Pk.Results results;
- results = yield task.resolve_async (Pk.Filter.NOT_INSTALLED, packages, null, progress_callback);
- if (results == null || results.get_error_code () != null)
- return results;
-
- var package_array = results.get_package_array ();
- var package_ids = new string[package_array.length + 1];
- package_ids[package_array.length] = null;
- for (var i = 0; i < package_array.length; i++)
- package_ids[i] = package_array.data[i].get_id ();
-
- return yield task.install_packages_async (package_ids, null, progress_callback);
- }
-#endif
-
- public override bool window_state_event (Gdk.EventWindowState event)
- {
- var result = Gdk.EVENT_PROPAGATE;
-
- if (base.window_state_event != null)
- result = base.window_state_event (event);
-
- if ((event.changed_mask & Gdk.WindowState.MAXIMIZED) != 0)
- {
- window_is_maximized = (event.new_window_state & Gdk.WindowState.MAXIMIZED) != 0;
- save_state ();
- }
- if ((event.changed_mask & Gdk.WindowState.FULLSCREEN) != 0)
- {
- window_is_fullscreen = (event.new_window_state & Gdk.WindowState.FULLSCREEN) != 0;
- save_state ();
- }
-
- return result;
- }
-
- [GtkCallback]
- private bool window_delete_event_cb (Gtk.Widget widget, Gdk.EventAny event)
- {
- return !on_quit ();
- }
-
- private void page_size_changed_cb (Page page)
- {
- 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.scan_direction;
- save_state ();
- }
-
- private void page_added_cb (Book book, Page page)
- {
- 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);
-
- update_page_menu ();
- }
-
- private void reordered_cb (Book book)
- {
- update_page_menu ();
- }
-
- private void page_removed_cb (Book book, Page page)
- {
- page.size_changed.disconnect (page_size_changed_cb);
- page.scan_direction_changed.disconnect (page_scan_direction_changed_cb);
-
- update_page_menu ();
- }
-
- private void set_dpi_combo (Gtk.ComboBox combo, int default_dpi, int current_dpi)
- {
- var renderer = new Gtk.CellRendererText ();
- combo.pack_start (renderer, true);
- combo.add_attribute (renderer, "text", 1);
-
- var model = combo.model as Gtk.ListStore;
- int[] scan_resolutions = {75, 150, 300, 600, 1200, 2400};
- foreach (var dpi in scan_resolutions)
- {
- string label;
- if (dpi == default_dpi)
- /* Preferences dialog: Label for default resolution in resolution list */
- label = _("%d dpi (default)").printf (dpi);
- else if (dpi == 75)
- /* Preferences dialog: Label for minimum resolution in resolution list */
- label = _("%d dpi (draft)").printf (dpi);
- else if (dpi == 1200)
- /* Preferences dialog: Label for maximum resolution in resolution list */
- label = _("%d dpi (high resolution)").printf (dpi);
- else
- /* Preferences dialog: Label for resolution value in resolution list (dpi = dots per inch) */
- label = _("%d dpi").printf (dpi);
-
- Gtk.TreeIter iter;
- model.append (out iter);
- model.set (iter, 0, dpi, 1, label, -1);
-
- if (dpi == current_dpi)
- combo.set_active_iter (iter);
- }
- }
-
- private void book_changed_cb (Book book)
- {
- save_menuitem.sensitive = true;
- email_menuitem.sensitive = true;
- print_menuitem.sensitive = true;
- save_button.sensitive = true;
- save_toolbutton.sensitive = true;
- book_needs_saving = true;
- copy_to_clipboard_menuitem.sensitive = true;
- }
-
- 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;
-
- if (is_traditional_desktop ())
- {
- set_titlebar (null);
- menubar.visible = true;
- toolbar.visible = true;
- }
- else
- {
- app.add_action_entries (action_entries, this);
-
- var appmenu = new Menu ();
- var section = new Menu ();
- appmenu.append_section (null, section);
- section.append (_("New Document"), "app.new_document");
-
- section = new Menu ();
- appmenu.append_section (null, section);
- var menu = new Menu ();
- section.append_submenu (_("Document"), menu);
- menu.append (_("Reorder Pages"), "app.reorder");
- menu.append (_("Save"), "app.save");
- menu.append (_("Email..."), "app.email");
- menu.append (_("Print..."), "app.print");
-
- section = new Menu ();
- appmenu.append_section (null, section);
- section.append (_("Preferences"), "app.preferences");
-
- section = new Menu ();
- appmenu.append_section (null, section);
- section.append (_("Help"), "app.help");
- section.append (_("About"), "app.about");
- section.append (_("Quit"), "app.quit");
-
- app.app_menu = appmenu;
-
- app.add_accelerator ("<Ctrl>N", "app.new_document", null);
- app.add_accelerator ("<Ctrl>S", "app.save", null);
- app.add_accelerator ("<Ctrl>E", "app.email", null);
- app.add_accelerator ("<Ctrl>P", "app.print", null);
- app.add_accelerator ("F1", "app.help", null);
- app.add_accelerator ("<Ctrl>Q", "app.quit", null);
- }
- app.add_window (this);
-
- /* Add InfoBar (not supported in Glade) */
- info_bar = new Gtk.InfoBar ();
- info_bar.response.connect (info_bar_response_cb);
- main_vbox.pack_start (info_bar, false, true, 0);
- var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12);
- var content_area = info_bar.get_content_area () as Gtk.Container;
- content_area.add (hbox);
- hbox.visible = true;
-
- 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.visible = true;
-
- info_bar_label = new Gtk.Label (null);
- info_bar_label.set_alignment (0.0f, 0.5f);
- hbox.pack_start (info_bar_label, true, true, 0);
- info_bar_label.visible = true;
-
- info_bar_close_button = info_bar.add_button (_("_Close"), Gtk.ResponseType.CLOSE) as Gtk.Button;
- info_bar_change_scanner_button = info_bar.add_button (/* Button in error infobar to open preferences dialog and change scanner */
- _("Change _Scanner"), 1) as Gtk.Button;
- info_bar_install_button = info_bar.add_button (/* Button in error infobar to prompt user to install drivers */
- _("_Install Drivers"), 2) as Gtk.Button;
-
- Gtk.TreeIter iter;
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 0, 1, 0, 2,
- /* Combo box value for automatic paper size */
- _("Automatic"), -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 1050, 1, 1480, 2, "A6", -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 1480, 1, 2100, 2, "A5", -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 2100, 1, 2970, 2, "A4", -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 2159, 1, 2794, 2, "Letter", -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 2159, 1, 3556, 2, "Legal", -1);
- paper_size_model.append (out iter);
- paper_size_model.set (iter, 0, 1016, 1, 1524, 2, "4×6", -1);
-
- var dpi = settings.get_int ("text-dpi");
- 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);
- device_combo.add_attribute (renderer, "text", 1);
-
- renderer = new Gtk.CellRendererText ();
- 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);
- paper_size_combo.add_attribute (renderer, "text", 2);
- 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.lower;
- var darker_label = "<small>%s</small>".printf (_("Darker"));
- var upper = brightness_adjustment.upper;
- var lighter_label = "<small>%s</small>".printf (_("Lighter"));
- 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);
- brightness = settings.get_int ("brightness");
- brightness_adjustment.value_changed.connect (() => { settings.set_int ("brightness", brightness); });
-
- lower = contrast_adjustment.lower;
- var less_label = "<small>%s</small>".printf (_("Less"));
- upper = contrast_adjustment.upper;
- var more_label = "<small>%s</small>".printf (_("More"));
- 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);
- contrast = settings.get_int ("contrast");
- contrast_adjustment.value_changed.connect (() => { settings.set_int ("contrast", contrast); });
-
- lower = quality_adjustment.lower;
- var minimum_label = "<small>%s</small>".printf (_("Minimum"));
- upper = quality_adjustment.upper;
- var maximum_label = "<small>%s</small>".printf (_("Maximum"));
- 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);
- quality = settings.get_int ("jpeg-quality");
- quality_adjustment.value_changed.connect (() => { settings.set_int ("jpeg-quality", quality); });
-
- page_delay_scale.add_mark (0, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (500, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (1000, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (2000, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (4000, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (6000, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (8000, Gtk.PositionType.BOTTOM, null);
- page_delay_scale.add_mark (10000, Gtk.PositionType.BOTTOM, null);
- page_delay = settings.get_int ("page-delay");
- page_delay_scale.format_value.connect ((value) => { return "%.1fs".printf (value / 1000.0); });
- page_delay_adjustment.value_changed.connect (() => { settings.set_int ("page-delay", page_delay); });
-
- var document_type = settings.get_string ("document-type");
- if (document_type != null)
- set_document_hint (document_type);
-
- book_view = new BookView (book);
- book_view.border_width = 18;
- main_vbox.pack_end (book_view, true, true, 0);
- book_view.page_selected.connect (page_selected_cb);
- book_view.show_page.connect (show_page_cb);
- book_view.show_menu.connect (show_page_menu_cb);
- book_view.visible = true;
-
- authorize_dialog.transient_for = this;
- preferences_dialog.transient_for = this;
-
- /* Load previous state */
- load_state ();
-
- /* Restore window size */
- debug ("Restoring window to %dx%d pixels", window_width, window_height);
- set_default_size (window_width, window_height);
- if (window_is_maximized)
- {
- debug ("Restoring window to maximized");
- maximize ();
- }
- if (window_is_fullscreen)
- {
- debug ("Restoring window to fullscreen");
- fullscreen ();
- }
-
- progress_dialog = new ProgressBarDialog (this, _("Saving document..."));
- book.saving.connect (book_saving_cb);
- }
-
- private bool is_desktop (string name)
- {
- var desktop_name_list = Environment.get_variable ("XDG_CURRENT_DESKTOP");
- if (desktop_name_list == null)
- return false;
-
- foreach (var n in desktop_name_list.split (":"))
- if (n == name)
- return true;
-
- return false;
- }
-
- private bool is_traditional_desktop ()
- {
- const string[] traditional_desktops = { "Unity", "XFCE", "MATE", "LXDE", "Cinnamon", "X-Cinnamon" };
- foreach (var name in traditional_desktops)
- if (is_desktop (name))
- return true;
- return false;
- }
-
- 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");
- window_is_fullscreen = state_get_boolean (f, "window", "is-fullscreen");
- 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_boolean ("window", "is-fullscreen", window_is_fullscreen);
- 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)
- {
- /* Prevent GUI from freezing */
- while (Gtk.events_pending ())
- Gtk.main_iteration ();
-
- var total = (int) book.n_pages;
- var fraction = (page_number + 1.0) / total;
- var complete = fraction == 1.0;
- if (complete)
- Timeout.add (500, () => {
- progress_dialog.visible = false;
- return false;
- });
- var message = _("Saving page %d out of %d").printf (page_number + 1, total);
-
- progress_dialog.fraction = fraction;
- progress_dialog.message = message;
- }
-
- public void show_progress_dialog ()
- {
- progress_dialog.visible = true;
- }
-
- public void hide_progress_dialog ()
- {
- progress_dialog.visible = false;
- }
-
- public void show_error (string error_title, string error_text, bool change_scanner_hint)
- {
- have_error = true;
- this.error_title = error_title;
- this.error_text = error_text;
- error_change_scanner_hint = change_scanner_hint;
- update_info_bar ();
- }
-
- public void start ()
- {
- visible = true;
- }
-}
-
-private class ProgressBarDialog : Gtk.Window
-{
- private Gtk.ProgressBar bar;
-
- public double fraction
- {
- get { return bar.fraction; }
- set { bar.fraction = value; }
- }
-
- public string message
- {
- get { return bar.text; }
- set { bar.text = value; }
- }
-
- public ProgressBarDialog (Gtk.ApplicationWindow parent, string title)
- {
- bar = new Gtk.ProgressBar ();
- var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5);
- var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
- hbox.hexpand = true;
-
- bar.text = "";
- bar.show_text = true;
- bar.set_size_request (225, 25);
- set_size_request (250, 50);
-
- vbox.pack_start (bar, true, false, 0);
- hbox.pack_start (vbox, true, false, 0);
- add (hbox);
- this.title = title;
-
- transient_for = parent;
- set_position (Gtk.WindowPosition.CENTER_ON_PARENT);
- modal = true;
- resizable = false;
-
- hbox.visible = true;
- vbox.visible = true;
- bar.visible = true;
- }
-}
-
-// FIXME: Duplicated from simple-scan.vala
-private string? get_temporary_filename (string prefix, string extension)
-{
- /* NOTE: I'm not sure if this is a 100% safe strategy to use g_file_open_tmp(), close and
- * use the filename but it appears to work in practise */
-
- var filename = "%sXXXXXX.%s".printf (prefix, extension);
- string path;
- try
- {
- var fd = FileUtils.open_tmp (filename, out path);
- Posix.close (fd);
- }
- catch (Error e)
- {
- warning ("Error saving email attachment: %s", e.message);
- return null;
- }
-
- return path;
-}
-
-private class PageIcon : Gtk.DrawingArea
-{
- private string text;
- private double r;
- private double g;
- private double b;
- private const int MINIMUM_WIDTH = 20;
-
- public PageIcon (string text, double r = 1.0, double g = 1.0, double b = 1.0)
- {
- this.text = text;
- this.r = r;
- this.g = g;
- this.b = b;
- }
-
- public override void get_preferred_width (out int minimum_width, out int natural_width)
- {
- minimum_width = natural_width = MINIMUM_WIDTH;
- }
-
- public override void get_preferred_height (out int minimum_height, out int natural_height)
- {
- minimum_height = natural_height = (int) Math.round (MINIMUM_WIDTH * Math.SQRT2);
- }
-
- public override void get_preferred_height_for_width (int width, out int minimum_height, out int natural_height)
- {
- minimum_height = natural_height = (int) (width * Math.SQRT2);
- }
-
- public override void get_preferred_width_for_height (int height, out int minimum_width, out int natural_width)
- {
- minimum_width = natural_width = (int) (height / Math.SQRT2);
- }
-
- public override bool draw (Cairo.Context c)
- {
- var w = get_allocated_width ();
- var h = get_allocated_height ();
- if (w * Math.SQRT2 > h)
- w = (int) Math.round (h / Math.SQRT2);
- else
- h = (int) Math.round (w * Math.SQRT2);
-
- c.translate ((get_allocated_width () - w) / 2, (get_allocated_height () - h) / 2);
-
- c.rectangle (0.5, 0.5, w - 1, h - 1);
-
- c.set_source_rgb (r, g, b);
- c.fill_preserve ();
-
- c.set_line_width (1.0);
- c.set_source_rgb (0.0, 0.0, 0.0);
- c.stroke ();
-
- Cairo.TextExtents extents;
- c.text_extents (text, out extents);
- c.translate ((w - extents.width) * 0.5 - 0.5, (h + extents.height) * 0.5 - 0.5);
- c.show_text (text);
-
- return true;
- }
-}