diff options
Diffstat (limited to 'src/ui.vala')
-rw-r--r-- | src/ui.vala | 283 |
1 files changed, 208 insertions, 75 deletions
diff --git a/src/ui.vala b/src/ui.vala index 362c53b..17392bc 100644 --- a/src/ui.vala +++ b/src/ui.vala @@ -45,6 +45,7 @@ public class UserInterface : Gtk.ApplicationWindow 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] @@ -149,6 +150,7 @@ public class UserInterface : Gtk.ApplicationWindow [GtkChild] private Gtk.Adjustment quality_adjustment; private bool setting_devices; + private string? missing_driver = null; private bool user_selected_device; private Gtk.FileChooserDialog? save_dialog; @@ -185,7 +187,6 @@ public class UserInterface : Gtk.ApplicationWindow private string document_hint = "photo"; - public string default_file_name { get; set; default = _("Scanned Document.pdf"); } private bool scanning_ = false; public bool scanning { @@ -315,6 +316,7 @@ public class UserInterface : Gtk.ApplicationWindow "%s", error_title); dialog.add_button (_("_Close"), 0); dialog.format_secondary_text ("%s", error_text); + dialog.run (); dialog.destroy (); } @@ -350,6 +352,7 @@ public class UserInterface : Gtk.ApplicationWindow 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) @@ -365,10 +368,21 @@ public class UserInterface : Gtk.ApplicationWindow { type = Gtk.MessageType.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 */ - text = _("Please check your scanner is connected and powered on"); + 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 { @@ -382,10 +396,11 @@ public class UserInterface : Gtk.ApplicationWindow 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) + public void set_scan_devices (List<ScanDevice> devices, string? missing_driver = null) { bool have_selection = false; int index; @@ -393,6 +408,8 @@ public class UserInterface : Gtk.ApplicationWindow 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; @@ -469,31 +486,6 @@ public class UserInterface : Gtk.ApplicationWindow book_view.selected_page = page; } - private void on_file_type_changed (Gtk.TreeSelection selection) - { - var extension = get_selected_extension (selection); - 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); - } - - private string get_selected_extension (Gtk.TreeSelection selection) - { - Gtk.TreeModel model; - Gtk.TreeIter iter; - string extension = ""; - - if (selection.get_selected (out model, out iter)) - model.get (iter, 1, out extension, -1); - return extension; - } - private string choose_file_location () { /* Get directory to save to */ @@ -513,7 +505,8 @@ public class UserInterface : Gtk.ApplicationWindow save_dialog.do_overwrite_confirmation = true; save_dialog.local_only = false; save_dialog.set_current_folder (directory); - save_dialog.set_current_name (default_file_name); + /* 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 (); @@ -528,16 +521,6 @@ public class UserInterface : Gtk.ApplicationWindow filter.add_pattern ("*"); save_dialog.add_filter (filter); - var expander = new Gtk.Expander.with_mnemonic (/* */ - _("Select File _Type")); - expander.spacing = 5; - save_dialog.set_extra_widget (expander); - - string default_extension = ""; - var index = default_file_name.last_index_of_char ('.'); - if (index >= 0) - default_extension = default_file_name.substring (index); - var file_type_store = new Gtk.ListStore (2, typeof (string), typeof (string)); Gtk.TreeIter iter; file_type_store.append (out iter); @@ -559,40 +542,54 @@ public class UserInterface : Gtk.ApplicationWindow 1, ".png", -1); - var file_type_view = new Gtk.TreeView.with_model (file_type_store); - file_type_view.headers_visible = false; - file_type_view.rules_hint = true; - var column = new Gtk.TreeViewColumn.with_attributes ("", - new Gtk.CellRendererText (), - "text", 0, null); - file_type_view.append_column (column); - expander.add (file_type_view); + 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); - if (file_type_store.get_iter_first (out iter)) + file_type_combo.set_active (0); + file_type_combo.changed.connect (() => { - do - { - string e; - file_type_store.get (iter, 1, out e, -1); - if (default_extension == e) - file_type_view.get_selection ().select_iter (iter); - } while (file_type_store.iter_next (ref iter)); - } - file_type_view.get_selection ().changed.connect (on_file_type_changed); + var extension = ""; + Gtk.TreeIter i; + if (file_type_combo.get_active_iter (out i)) + file_type_store.get (i, 1, out extension, -1); - expander.show_all (); + 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); var response = save_dialog.run (); string? uri = null; if (response == Gtk.ResponseType.ACCEPT) { - var selection = file_type_view.get_selection (); - var extension = get_selected_extension (selection); + 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; @@ -602,7 +599,6 @@ public class UserInterface : Gtk.ApplicationWindow settings.set_string ("save-directory", save_dialog.get_current_folder ()); - file_type_view.get_selection ().changed.disconnect (on_file_type_changed); save_dialog.destroy (); save_dialog = null; @@ -968,7 +964,7 @@ public class UserInterface : Gtk.ApplicationWindow menuitem.active = true; crop_button.active = page.has_crop; crop_toolbutton.active = page.has_crop; - + updating_page_menu = false; } @@ -1082,7 +1078,7 @@ public class UserInterface : Gtk.ApplicationWindow else no_crop_menuitem.active = true; } - + [GtkCallback] private void crop_toolbutton_toggled_cb (Gtk.ToggleToolButton widget) { @@ -1223,7 +1219,7 @@ public class UserInterface : Gtk.ApplicationWindow b = make_reorder_button (_("Reverse"), "C1C2C3C4C5C6-C6C5C4C3C2C1"); b.clicked.connect (() => { - book.reverse (); + book.reverse (); dialog.destroy (); }); b.visible = true; @@ -1255,7 +1251,7 @@ public class UserInterface : Gtk.ApplicationWindow 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); @@ -1406,7 +1402,7 @@ public class UserInterface : Gtk.ApplicationWindow { email (document_hint, quality); } - + private void print_document () { var print = new Gtk.PrintOperation (); @@ -1544,20 +1540,155 @@ public class UserInterface : Gtk.ApplicationWindow private void info_bar_response_cb (Gtk.InfoBar widget, int response_id) { - if (response_id == 1) + switch (response_id) { + /* Change scanner */ + case 1: device_combo.grab_focus (); preferences_dialog.present (); - } - else - { + 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.epsom.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) + { + 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 */ + var error_text = _("Failed to install drivers (error code %d).").printf (e.code); + } + + } + catch (Error e) + { + /* Label shown if failed to install drivers */ + error_text = _("Failed to install drivers."); + warning ("Failed to install drivers: %s", e.message); + } + instructions_label.set_text (result_text); + }); + } + + dialog.run (); + dialog.destroy (); + } + + 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); + } + [GtkCallback] private bool simple_scan_window_window_state_event_cb (Gtk.Widget widget, Gdk.EventWindowState event) { @@ -1735,6 +1866,8 @@ public class UserInterface : Gtk.ApplicationWindow 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); @@ -2050,7 +2183,7 @@ public class UserInterface : Gtk.ApplicationWindow private class ProgressBarDialog : Gtk.Window { private Gtk.ProgressBar bar; - + public double fraction { get { return bar.fraction; } |