summaryrefslogtreecommitdiff
path: root/src/app-window.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/app-window.vala')
-rw-r--r--src/app-window.vala178
1 files changed, 131 insertions, 47 deletions
diff --git a/src/app-window.vala b/src/app-window.vala
index 30adac9..67f10a8 100644
--- a/src/app-window.vala
+++ b/src/app-window.vala
@@ -188,6 +188,7 @@ public class AppWindow : Gtk.ApplicationWindow
public signal void start_scan (string? device, ScanOptions options);
public signal void stop_scan ();
+ public signal void redetect ();
public AppWindow ()
{
@@ -224,7 +225,7 @@ public class AppWindow : Gtk.ApplicationWindow
Gtk.ButtonsType.NONE,
"%s", error_title);
dialog.add_button (_("_Close"), 0);
- dialog.format_secondary_text ("%s", error_text);
+ dialog.format_secondary_markup ("%s", error_text);
dialog.run ();
dialog.destroy ();
}
@@ -245,7 +246,7 @@ public class AppWindow : Gtk.ApplicationWindow
private void update_scan_status ()
{
- scan_button.set_sensitive(false);
+ scan_button.sensitive = false;
if (!have_devices)
{
status_primary_label.set_text (/* Label shown when searching for scanners */
@@ -255,12 +256,13 @@ public class AppWindow : Gtk.ApplicationWindow
}
else if (get_selected_device () != null)
{
- scan_button.set_sensitive(true);
+ scan_button.sensitive = true;
status_primary_label.set_text (/* Label shown when detected a scanner */
_("Ready to Scan"));
status_secondary_label.set_text (get_selected_device_label ());
status_secondary_label.visible = false;
device_combo.visible = true;
+ device_combo.sensitive = true;
}
else if (this.missing_driver != null)
{
@@ -449,7 +451,7 @@ public class AppWindow : Gtk.ApplicationWindow
directory = settings.get_string ("save-directory");
if (directory == null || directory == "")
- directory = Environment.get_user_special_dir (UserDirectory.DOCUMENTS);
+ directory = GLib.Filename.to_uri(Environment.get_user_special_dir (UserDirectory.DOCUMENTS));
var save_dialog = new Gtk.FileChooserNative (/* Save dialog: Dialog title */
_("Save As…"),
@@ -458,12 +460,15 @@ public class AppWindow : Gtk.ApplicationWindow
_("_Save"),
_("_Cancel"));
save_dialog.local_only = false;
+
+ var save_format = settings.get_string ("save-format");
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"));
+ save_dialog.set_current_folder_uri (directory);
+ /* Default filename to use when saving document. */
+ /* To that filename the extension will be added, eg. "Scanned Document.pdf" */
+ save_dialog.set_current_name (_("Scanned Document") + "." + mime_type_to_extension (save_format));
}
/* Filter to only show images by default */
@@ -489,31 +494,32 @@ public class AppWindow : Gtk.ApplicationWindow
file_type_store.set (iter,
/* Save dialog: Label for saving in PDF format */
0, _("PDF (multi-page document)"),
- 1, ".pdf",
+ 1, "application/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, "image/jpeg",
-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, "image/png",
-1);
#if HAVE_WEBP
file_type_store.append (out iter);
file_type_store.set (iter,
/* Save dialog: Label for sabing in WEBP format */
0, _("WebP (compressed)"),
- 1, ".webp",
+ 1, "image/webp",
-1);
#endif
var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
box.visible = true;
+ box.spacing = 10;
save_dialog.set_extra_widget (box);
/* Label in save dialog beside combo box to choose file format (PDF, JPEG, PNG, WEBP) */
@@ -528,29 +534,47 @@ public class AppWindow : Gtk.ApplicationWindow
file_type_combo.add_attribute (renderer, "text", 0);
box.add (file_type_combo);
+ if (file_type_store.get_iter_first (out iter))
+ {
+ do
+ {
+ string mime_type;
+ file_type_store.get (iter, 1, out mime_type, -1);
+ if (mime_type == save_format)
+ file_type_combo.set_active_iter (iter);
+ } while (file_type_store.iter_next (ref iter));
+ }
+
/* Label in save dialog beside compression slider */
var quality_label = new Gtk.Label (_("Compression:"));
box.add (quality_label);
var quality_adjustment = new Gtk.Adjustment (75, 0, 100, 1, 10, 0);
var quality_scale = new Gtk.Scale (Gtk.Orientation.HORIZONTAL, quality_adjustment);
- quality_scale.width_request = 200;
+ quality_scale.width_request = 250;
quality_scale.draw_value = false;
- quality_scale.add_mark (0, Gtk.PositionType.BOTTOM, null);
+ var minimum_size_label = "<small>%s</small>".printf (_("Minimum size"));
+ quality_scale.add_mark (quality_adjustment.lower, Gtk.PositionType.BOTTOM, minimum_size_label);
quality_scale.add_mark (75, Gtk.PositionType.BOTTOM, null);
quality_scale.add_mark (90, Gtk.PositionType.BOTTOM, null);
- quality_scale.add_mark (100, Gtk.PositionType.BOTTOM, null);
+ var full_detail_label = "<small>%s</small>".printf (_("Full detail"));
+ quality_scale.add_mark (quality_adjustment.upper, Gtk.PositionType.BOTTOM, full_detail_label);
quality_adjustment.value = settings.get_int ("jpeg-quality");
quality_adjustment.value_changed.connect (() => { settings.set_int ("jpeg-quality", (int) quality_adjustment.value); });
box.add (quality_scale);
- file_type_combo.set_active (0);
+ /* Quality not applicable to PNG */
+ quality_scale.visible = quality_label.visible = (save_format != "image/png");
+
file_type_combo.changed.connect (() =>
{
- var extension = "";
+ var mime_type = "";
Gtk.TreeIter i;
if (file_type_combo.get_active_iter (out i))
- file_type_store.get (i, 1, out extension, -1);
+ {
+ file_type_store.get (i, 1, out mime_type, -1);
+ settings.set_string ("save-format", mime_type);
+ }
var filename = save_dialog.get_current_name ();
@@ -558,11 +582,11 @@ public class AppWindow : Gtk.ApplicationWindow
var extension_index = filename.last_index_of_char ('.');
if (extension_index >= 0)
filename = filename.slice (0, extension_index);
- filename = filename + extension;
+ filename = filename + "." + mime_type_to_extension (mime_type);
save_dialog.set_current_name (filename);
/* Quality not applicable to PNG */
- quality_scale.visible = quality_label.visible = (extension != ".png");
+ quality_scale.visible = quality_label.visible = (mime_type != "image/png");
});
while (true)
@@ -574,25 +598,20 @@ public class AppWindow : Gtk.ApplicationWindow
return null;
}
- var extension = "";
+ var mime_type = "";
Gtk.TreeIter i;
if (file_type_combo.get_active_iter (out i))
- file_type_store.get (i, 1, out extension, -1);
+ file_type_store.get (i, 1, out mime_type, -1);
var uri = save_dialog.get_uri ();
var extension_index = uri.last_index_of_char ('.');
if (extension_index < 0)
- uri += extension;
+ uri += "." + mime_type_to_extension (mime_type);
/* Check the file(s) don't already exist */
var files = new List<File> ();
- var format = uri_to_format (uri);
-#if HAVE_WEBP
- if (format == "jpeg" || format == "png" || format == "webp")
-#else
- if (format == "jpeg" || format == "png")
-#endif
+ if (mime_type == "image/jpeg" || mime_type == "image/png" || mime_type == "image/webp")
{
for (var j = 0; j < book.n_pages; j++)
files.append (make_indexed_file (uri, j, book.n_pages));
@@ -602,7 +621,8 @@ public class AppWindow : Gtk.ApplicationWindow
if (check_overwrite (save_dialog.transient_for, files))
{
- settings.set_string ("save-directory", save_dialog.get_current_folder ());
+ var directory_uri = uri.substring (0, uri.last_index_of ("/") + 1);
+ settings.set_string ("save-directory", directory_uri);
save_dialog.destroy ();
return uri;
}
@@ -633,19 +653,47 @@ public class AppWindow : Gtk.ApplicationWindow
return true;
}
- private string uri_to_format (string uri)
+ private string? mime_type_to_extension (string mime_type)
{
- var uri_lower = uri.down ();
- if (uri_lower.has_suffix (".pdf"))
+ if (mime_type == "application/pdf")
return "pdf";
- else if (uri_lower.has_suffix (".png"))
+ else if (mime_type == "image/jpeg")
+ return "jpg";
+ else if (mime_type == "image/png")
return "png";
-#if HAVE_WEBP
- else if (uri_lower.has_suffix (".webp"))
+ else if (mime_type == "image/webp")
return "webp";
-#endif
else
- return "jpeg";
+ return null;
+ }
+
+ private string? extension_to_mime_type (string extension)
+ {
+ var extension_lower = extension.down ();
+ if (extension_lower == "pdf")
+ return "application/pdf";
+ else if (extension_lower == "jpg")
+ return "image/jpeg";
+ else if (extension_lower == "png")
+ return "image/png";
+ else if (extension_lower == "webp")
+ return "image/webp";
+ else
+ return null;
+ }
+
+ private string uri_to_mime_type (string uri)
+ {
+ var extension_index = uri.last_index_of_char ('.');
+ if (extension_index < 0)
+ return "image/jpeg";
+ var extension = uri.substring (extension_index + 1);
+
+ var mime_type = extension_to_mime_type (extension);
+ if (mime_type == null)
+ return "image/jpeg";
+
+ return mime_type;
}
private async bool save_document_async ()
@@ -658,7 +706,7 @@ public class AppWindow : Gtk.ApplicationWindow
debug ("Saving to '%s'", uri);
- var format = uri_to_format (uri);
+ var mime_type = uri_to_mime_type (uri);
var cancellable = new Cancellable ();
var progress_bar = new CancellableProgressBar (_("Saving"), cancellable);
@@ -667,7 +715,7 @@ public class AppWindow : Gtk.ApplicationWindow
save_button.sensitive = false;
try
{
- yield book.save_async (format, settings.get_int ("jpeg-quality"), file, (fraction) =>
+ yield book.save_async (mime_type, settings.get_int ("jpeg-quality"), file, (fraction) =>
{
progress_bar.set_fraction (fraction);
}, cancellable);
@@ -748,6 +796,9 @@ public class AppWindow : Gtk.ApplicationWindow
if (scanning)
stop_scan ();
+ have_devices = false;
+ /* Refresh list of devices to detect network scanners, and fix issues with disconnected scanners */
+ redetect ();
clear_document ();
});
}
@@ -773,6 +824,7 @@ public class AppWindow : Gtk.ApplicationWindow
{
status_primary_label.set_text (/* Label shown when scan started */
_("Contacting scanner…"));
+ device_combo.sensitive = false;
start_scan (get_selected_device (), options);
}
@@ -1428,11 +1480,21 @@ public class AppWindow : Gtk.ApplicationWindow
try
{
var dir = DirUtils.make_tmp ("simple-scan-XXXXXX");
- var type = document_hint == "text" ? "pdf" : "jpeg";
- var file = File.new_for_path (Path.build_filename (dir, "scan." + type));
- yield book.save_async (type, settings.get_int ("jpeg-quality"), file, null, null);
+ string mime_type, filename;
+ if (document_hint == "text")
+ {
+ mime_type = "application/pdf";
+ filename = "scan.pdf";
+ }
+ else
+ {
+ mime_type = "image/jpeg";
+ filename = "scan.jpg";
+ }
+ var file = File.new_for_path (Path.build_filename (dir, filename));
+ yield book.save_async (mime_type, settings.get_int ("jpeg-quality"), file, null, null);
var command_line = "xdg-email";
- if (type == "pdf")
+ if (mime_type == "application/pdf")
command_line += " --attach %s".printf (file.get_path ());
else
{
@@ -1574,16 +1636,31 @@ public class AppWindow : Gtk.ApplicationWindow
/* 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 "pixma":
+ /* Message to indicate a Canon Pixma scanner has been detected */
+ message = _("You appear to have a Canon scanner, which is supported by the <a href=\"http://www.sane-project.org/man/sane-pixma.5.html\">Pixma SANE backend</a>.");
+ /* Instructions on how to resolve issue with SANE scanner drivers */
+ instructions = _("Please check if your <a href=\"http://www.sane-project.org/sane-supported-devices.html\">scanner is supported by SANE</a>, otherwise report the issue to the <a href=\"https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/sane-devel\">SANE mailing list</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>.");
+ /* Instructions on how to install Samsung scanner drivers.
+ Because HP acquired Samsung's global printing business in 2017, the support is made on HP site. */
+ instructions = _("Drivers for this are available on the <a href=\"https://support.hp.com\">HP website</a> (HP acquired Samsung's printing business).");
break;
case "hpaio":
+ case "smfp":
/* Message to indicate a HP scanner has been detected */
message = _("You appear to have an HP scanner.");
- packages_to_install = { "libsane-hpaio" };
+ if (missing_driver == "hpaio")
+ packages_to_install = { "libsane-hpaio" };
+ else
+ /* Instructions on how to install HP scanner drivers.
+ smfp is rebranded and slightly modified Samsung devices,
+ for example: HP Laser MFP 135a is rebranded Samsung Xpress SL-M2070.
+ It require custom drivers, not available in hpaio package */
+ instructions = _("Drivers for this are available on the <a href=\"https://support.hp.com\">HP website</a>.");
break;
case "epkowa":
/* Message to indicate an Epson scanner has been detected */
@@ -1591,6 +1668,12 @@ public class AppWindow : Gtk.ApplicationWindow
/* 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;
+ case "lexmark_nscan":
+ /* Message to indicate an Lexmark scanner has been detected */
+ message = _("You appear to have an Lexmark scanner.");
+ /* Instructions on how to install Lexmark scanner drivers */
+ instructions = _("Drivers for this are available on the <a href=\"http://support.lexmark.com\">Lexmark 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);
@@ -1601,6 +1684,7 @@ public class AppWindow : Gtk.ApplicationWindow
label.visible = true;
label.xalign = 0f;
label.vexpand = true;
+ label.use_markup = true;
dialog.get_content_area ().add (label);
var instructions_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
@@ -1780,7 +1864,7 @@ public class AppWindow : Gtk.ApplicationWindow
app.set_accels_for_action ("app.print", { "<Ctrl>P" });
app.set_accels_for_action ("app.help", { "F1" });
app.set_accels_for_action ("app.quit", { "<Ctrl>Q" });
- app.set_accels_for_action ("win.show-help-overlay", { "<Ctrl>F1" });
+ app.set_accels_for_action ("win.show-help-overlay", { "<Ctrl>question" });
var gear_menu = new Menu ();
var section = new Menu ();