summaryrefslogtreecommitdiff
path: root/src/ui.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui.vala')
-rw-r--r--src/ui.vala283
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; }