summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app-window.ui1
-rw-r--r--src/app-window.vala178
-rw-r--r--src/book.vala26
-rw-r--r--src/help-overlay.ui9
-rw-r--r--src/page-view.vala106
-rw-r--r--src/scanner.vala80
-rw-r--r--src/simple-scan.vala294
7 files changed, 579 insertions, 115 deletions
diff --git a/src/app-window.ui b/src/app-window.ui
index e0e16c0..6f42a51 100644
--- a/src/app-window.ui
+++ b/src/app-window.ui
@@ -670,6 +670,7 @@
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
+ <accelerator key="F10" signal="activate"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
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 ();
diff --git a/src/book.vala b/src/book.vala
index 6db2952..798fe98 100644
--- a/src/book.vala
+++ b/src/book.vala
@@ -136,10 +136,10 @@ public class Book : Object
return pages.index (page);
}
- public async void save_async (string t, int q, File f, ProgressionCallback? p, Cancellable? c) throws Error
+ public async void save_async (string mime_type, int quality, File file, ProgressionCallback? progress_cb, Cancellable? cancellable = null) throws Error
{
var book_saver = new BookSaver ();
- yield book_saver.save_async (this, t, q, f, p, c);
+ yield book_saver.save_async (this, mime_type, quality, file, progress_cb, cancellable);
}
}
@@ -160,7 +160,7 @@ private class BookSaver
* distributes all encode tasks to other threads then yield so
* the ui can continue operating. The method then return once saving
* is completed, cancelled, or failed */
- public async void save_async (Book book, string type, int quality, File file, ProgressionCallback? progression_callback, Cancellable? cancellable) throws Error
+ public async void save_async (Book book, string mime_type, int quality, File file, ProgressionCallback? progression_callback, Cancellable? cancellable) throws Error
{
var timer = new Timer ();
@@ -184,20 +184,20 @@ private class BookSaver
/* Configure an encoder */
ThreadPoolFunc<EncodeTask>? encode_delegate = null;
- switch (type)
+ switch (mime_type)
{
- case "jpeg":
+ case "image/jpeg":
encode_delegate = encode_jpeg;
break;
- case "png":
+ case "image/png":
encode_delegate = encode_png;
break;
#if HAVE_WEBP
- case "webp":
+ case "image/webp":
encode_delegate = encode_webp;
break;
#endif
- case "pdf":
+ case "application/pdf":
encode_delegate = encode_pdf;
break;
}
@@ -205,16 +205,16 @@ private class BookSaver
/* Configure a writer */
ThreadFunc<Error?>? write_delegate = null;
- switch (type)
+ switch (mime_type)
{
- case "jpeg":
- case "png":
+ case "image/jpeg":
+ case "image/png":
#if HAVE_WEBP
- case "webp":
+ case "image/webp":
#endif
write_delegate = write_multifile;
break;
- case "pdf":
+ case "application/pdf":
write_delegate = write_pdf;
break;
}
diff --git a/src/help-overlay.ui b/src/help-overlay.ui
index b1a0127..105d876 100644
--- a/src/help-overlay.ui
+++ b/src/help-overlay.ui
@@ -136,7 +136,14 @@
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
- <property name="accelerator">&lt;ctrl&gt;F1</property>
+ <property name="accelerator">F10</property>
+ <property name="title" translatable="yes" context="shortcut window">Open menu</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator">&lt;ctrl&gt;question</property>
<property name="title" translatable="yes" context="shortcut window">Keyboard shortcuts</property>
</object>
</child>
diff --git a/src/page-view.vala b/src/page-view.vala
index 91a2c82..90a8071 100644
--- a/src/page-view.vala
+++ b/src/page-view.vala
@@ -45,7 +45,9 @@ public class PageView : Object
}
}
- private int border_width = 1;
+ private int ruler_width = 8;
+
+ private int border_width = 2;
/* True if image needs to be regenerated */
private bool update_image = true;
@@ -508,12 +510,12 @@ public class PageView : Object
private int get_preview_width ()
{
- return width_ - border_width * 2;
+ return width_ - (border_width + ruler_width) * 2;
}
private int get_preview_height ()
{
- return height_ - border_width * 2;
+ return height_ - (border_width + ruler_width) * 2;
}
private void update_page_view ()
@@ -569,10 +571,10 @@ public class PageView : Object
var cy = page.crop_y;
var cw = page.crop_width;
var ch = page.crop_height;
- var dx = page_to_screen_x (cx);
- var dy = page_to_screen_y (cy);
- var dw = page_to_screen_x (cw);
- var dh = page_to_screen_y (ch);
+ var dx = page_to_screen_x (cx) + border_width + ruler_width;
+ var dy = page_to_screen_y (cy) + border_width + ruler_width;
+ var dw = page_to_screen_x (cw) + border_width + ruler_width;
+ var dh = page_to_screen_y (ch) + border_width + ruler_width;
var ix = x - dx;
var iy = y - dy;
@@ -633,7 +635,7 @@ public class PageView : Object
selected_crop_x = page.crop_x;
selected_crop_y = page.crop_y;
selected_crop_w = page.crop_width;
- selected_crop_h = page.crop_height;;
+ selected_crop_h = page.crop_height;
}
}
@@ -831,19 +833,79 @@ public class PageView : Object
context.set_line_width (1);
context.translate (x_offset, y_offset);
+ /* Draw image */
+ context.translate (border_width + ruler_width, border_width + ruler_width);
+ Gdk.cairo_set_source_pixbuf (context, image, 0, 0);
+ context.paint ();
+
/* Draw page border */
context.set_source_rgb (0, 0, 0);
context.set_line_width (border_width);
- context.rectangle ((double)border_width / 2,
- (double)border_width / 2,
- width_ - border_width,
- height_ - border_width);
+
+ context.rectangle (0,
+ 0.0,
+ w,
+ h);
context.stroke ();
- /* Draw image */
- context.translate (border_width, border_width);
- Gdk.cairo_set_source_pixbuf (context, image, 0, 0);
- context.paint ();
+ /* Draw horizontal ruler */
+ context.set_line_width (1);
+ var ruler_tick = 0;
+ var line = 0.0;
+ var big_ruler_tick = 5;
+
+ while (ruler_tick <= page.width)
+ {
+ line = page_to_screen_x (ruler_tick) + 0.5;
+ if (big_ruler_tick == 5)
+ {
+ context.move_to (line, 0);
+ context.line_to (line, -ruler_width);
+ context.move_to (line, h);
+ context.line_to (line, h + ruler_width);
+ big_ruler_tick = 0;
+ }
+ else
+ {
+ context.move_to (line, -2);
+ context.line_to (line, -5);
+ context.move_to (line, h + 2);
+ context.line_to (line, h + 5);
+ }
+ ruler_tick = ruler_tick + page.dpi/5;
+ big_ruler_tick = big_ruler_tick + 1;
+ }
+ context.stroke ();
+
+ /* Draw vertical ruler */
+ ruler_tick = 0;
+ line = 0.0;
+ big_ruler_tick = 5;
+ while (ruler_tick <= page.height)
+ {
+ line = page_to_screen_y (ruler_tick) + 0.5;
+
+ if (big_ruler_tick == 5)
+ {
+ context.move_to (0, line);
+ context.line_to (-ruler_width, line);
+
+ context.move_to (w, line);
+ context.line_to (w + ruler_width, line);
+ big_ruler_tick = 0;
+ }
+ else
+ {
+ context.move_to (-2, line);
+ context.line_to (-5, line);
+
+ context.move_to (w + 2, line);
+ context.line_to (w + 5, line);
+ }
+ ruler_tick = ruler_tick + page.dpi/5;
+ big_ruler_tick = big_ruler_tick + 1;
+ }
+ context.stroke ();
/* Draw scan line */
if (page.is_scanning && page.scan_line > 0)
@@ -907,9 +969,19 @@ public class PageView : Object
context.fill ();
/* Show new edge */
- context.rectangle (dx - 1.5, dy - 1.5, dw + 3, dh + 3);
context.set_source_rgb (1.0, 1.0, 1.0);
+ context.move_to (-border_width, dy - 1.5);
+ context.line_to (border_width + w, dy - 1.5);
+ context.move_to (-border_width, dy + dh + 1.5);
+ context.line_to (border_width + w, dy + dh + 1.5);
+ context.stroke ();
+
+ context.move_to (dx - 1.5, -border_width);
+ context.line_to (dx - 1.5, border_width + h);
+ context.move_to (dx + dw + 1.5, -border_width);
+ context.line_to (dx + dw + 1.5, border_width + h);
context.stroke ();
+
context.rectangle (dx - 0.5, dy - 0.5, dw + 1, dh + 1);
context.set_source_rgb (0.0, 0.0, 0.0);
context.stroke ();
diff --git a/src/scanner.vala b/src/scanner.vala
index dc58f14..becb9fa 100644
--- a/src/scanner.vala
+++ b/src/scanner.vala
@@ -429,7 +429,7 @@ public class Scanner : Object
return false;
var status = Sane.control_option (handle, option_index, Sane.Action.SET_AUTO, null, null);
- debug ("sane_control_option (%d, SANE_ACTION_SET_AUTO) -> %s", (int) option_index, Sane.status_to_string (status));
+ debug ("sane_control_option (%d, SANE_ACTION_SET_AUTO, %s=auto) -> %s", (int) option_index, option.name, Sane.status_to_string (status));
if (status != Sane.Status.GOOD)
warning ("Error setting default option %s: %s", option.name, Sane.strstatus(status));
@@ -443,7 +443,7 @@ public class Scanner : Object
Sane.Bool v = (Sane.Bool) value;
var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, &v, null);
result = (bool) v;
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s) -> (%s, %s)", (int) option_index, value ? "SANE_TRUE" : "SANE_FALSE", Sane.status_to_string (status), result ? "SANE_TRUE" : "SANE_FALSE");
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=%s) -> (%s, %s)", (int) option_index, option.name, value ? "SANE_TRUE" : "SANE_FALSE", Sane.status_to_string (status), result ? "SANE_TRUE" : "SANE_FALSE");
}
private void set_int_option (Sane.Handle handle, Sane.OptionDescriptor option, Sane.Int option_index, int value, out int result)
@@ -480,7 +480,7 @@ public class Scanner : Object
}
var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, &v, null);
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %d) -> (%s, %d)", (int) option_index, value, Sane.status_to_string (status), (int) v);
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=%d) -> (%s, %d)", (int) option_index, option.name, value, Sane.status_to_string (status), (int) v);
result = (int) v;
}
@@ -520,7 +520,7 @@ public class Scanner : Object
v_fixed = Sane.FIX (v);
var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, &v_fixed, null);
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %f) -> (%s, %f)", (int) option_index, value, Sane.status_to_string (status), Sane.UNFIX (v_fixed));
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=%f) -> (%s, %f)", (int) option_index, option.name, value, Sane.status_to_string (status), Sane.UNFIX (v_fixed));
result = Sane.UNFIX (v_fixed);
}
@@ -550,9 +550,9 @@ public class Scanner : Object
var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, &option.range.max, null);
if (option.type == Sane.ValueType.FIXED)
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, option.range.max=%f) -> (%s)", (int) option_index, Sane.UNFIX (option.range.max), Sane.status_to_string (status));
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=option.range.max=%f) -> (%s)", (int) option_index, option.name, Sane.UNFIX (option.range.max), Sane.status_to_string (status));
else
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, option.range.max=%d) -> (%s)", (int) option_index, (int) option.range.max, Sane.status_to_string (status));
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=option.range.max=%d) -> (%s)", (int) option_index, option.name, (int) option.range.max, Sane.status_to_string (status));
}
private bool set_string_option (Sane.Handle handle, Sane.OptionDescriptor option, Sane.Int option_index, string value, out string result)
@@ -568,7 +568,7 @@ public class Scanner : Object
s[i] = '\0';
var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, s, null);
result = (string) s;
- debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, \"%s\") -> (%s, \"%s\")", (int) option_index, value, Sane.status_to_string (status), result);
+ debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, %s=\"%s\") -> (%s, \"%s\")", (int) option_index, option.name, value, Sane.status_to_string (status), result);
return status == Sane.Status.GOOD;
}
@@ -918,7 +918,6 @@ public class Scanner : Object
option = get_option_by_name (handle, Sane.NAME_SCAN_SOURCE, out index);
if (option == null)
{
- debug ("SCAN_SOURCE not available, trying alternative \"doc-source\"");
option = get_option_by_name (handle, "doc-source", out index); /* Samsung unified driver. LP: #892915 */
}
if (option != null)
@@ -932,7 +931,7 @@ public class Scanner : Object
"FlatBed",
"Normal",
Sane.I18N ("Normal"),
- "Document Table" /* Epson scanners, eg. ET-3760 */
+ "Document Table" /* Epson scanners, eg. ET-3760 */
};
string[] adf_sources =
@@ -1135,7 +1134,12 @@ public class Scanner : Object
else
set_option_to_max (handle, option, index);
}
-
+ if (job.page_width == 0) /* #90 Fix automatic mode for Epson scanners */
+ {
+ option = get_option_by_name (handle, "scan-area", out index);
+ if (option != null)
+ set_string_option (handle, option, index, "Maximum", null);
+ }
/* Set page size */
option = get_option_by_name (handle, Sane.NAME_PAGE_WIDTH, out index);
if (option != null && job.page_width > 0.0)
@@ -1147,40 +1151,34 @@ public class Scanner : Object
option = get_option_by_name (handle, Sane.NAME_BRIGHTNESS, out index);
if (option != null)
{
- if (job.brightness != 0)
+ if (option.type == Sane.ValueType.FIXED)
{
- if (option.type == Sane.ValueType.FIXED)
- {
- var brightness = scale_fixed (-100, 100, option, job.brightness);
- set_fixed_option (handle, option, index, brightness, null);
- }
- else if (option.type == Sane.ValueType.INT)
- {
- var brightness = scale_int (-100, 100, option, job.brightness);
- set_int_option (handle, option, index, brightness, null);
- }
- else
- warning ("Unable to set brightness, please file a bug");
+ var brightness = scale_fixed (-100, 100, option, job.brightness);
+ set_fixed_option (handle, option, index, brightness, null);
}
+ else if (option.type == Sane.ValueType.INT)
+ {
+ var brightness = scale_int (-100, 100, option, job.brightness);
+ set_int_option (handle, option, index, brightness, null);
+ }
+ else
+ warning ("Unable to set brightness, please file a bug");
}
option = get_option_by_name (handle, Sane.NAME_CONTRAST, out index);
if (option != null)
{
- if (job.contrast != 0)
+ if (option.type == Sane.ValueType.FIXED)
{
- if (option.type == Sane.ValueType.FIXED)
- {
- var contrast = scale_fixed (-100, 100, option, job.contrast);
- set_fixed_option (handle, option, index, contrast, null);
- }
- else if (option.type == Sane.ValueType.INT)
- {
- var contrast = scale_int (-100, 100, option, job.contrast);
- set_int_option (handle, option, index, contrast, null);
- }
- else
- warning ("Unable to set contrast, please file a bug");
+ var contrast = scale_fixed (-100, 100, option, job.contrast);
+ set_fixed_option (handle, option, index, contrast, null);
+ }
+ else if (option.type == Sane.ValueType.INT)
+ {
+ var contrast = scale_int (-100, 100, option, job.contrast);
+ set_int_option (handle, option, index, contrast, null);
}
+ else
+ warning ("Unable to set contrast, please file a bug");
}
/* Test scanner options (hoping will not effect other scanners...) */
@@ -1294,6 +1292,16 @@ public class Scanner : Object
/* Error displayed when no documents at the start of scanning */
_("Document feeder empty"));
}
+ else if (status == Sane.Status.NO_MEM)
+ {
+ fail_scan (status,
+ /* Out of memory error message with help instruction.
+ Message written in Pango text markup language,
+ A carriage return makes a line break, <tt> tag makes a monospace font */
+ _("Insufficient memory to perform scan.\n" +
+ "Try to decrease <tt>Resolution</tt> or <tt>Page Size</tt> in <tt>Preferences</tt> menu. " +
+ "For some scanners when scanning in high resolution, the scan size is restricted."));
+ }
else if (status == Sane.Status.DEVICE_BUSY)
{
/* If device is busy don't interrupt, but keep waiting for scanner */
diff --git a/src/simple-scan.vala b/src/simple-scan.vala
index 771dc82..3f495e5 100644
--- a/src/simple-scan.vala
+++ b/src/simple-scan.vala
@@ -54,6 +54,7 @@ public class SimpleScan : Gtk.Application
book = app.book;
app.start_scan.connect (scan_cb);
app.stop_scan.connect (cancel_cb);
+ app.redetect.connect (redetect_cb);
scanner = Scanner.get_instance ();
scanner.update_devices.connect (update_scan_devices_cb);
@@ -542,6 +543,217 @@ public class SimpleScan : Gtk.Application
0x04f960a9, /* ADS-1600W */
};
+ /* Taken from backend/pixma/pixma_mp150.c pixma_mp730.c pixma_mp750.c pixma_mp800.c in the pixma SANE backend repository */
+ /* Canon Pixma IDs extracted using the following Python script
+ import sys
+ for f in sys.argv:
+ for l in open(f, "r").readlines():
+ tokens=l.split ()
+ if len (tokens) >= 3 and tokens[0].startswith("#define") and tokens[1].endswith("_PID") and tokens[2].startswith("0x") and not tokens[2].endswith("ffff"):
+ print ( "0x04a9" + tokens[2][2:] + ", /* " + tokens[1][:-4] + " * /")
+ */
+ private const uint32 pixma_devices[] = {
+ 0x04a91709, /* MP150 */
+ 0x04a9170a, /* MP170 */
+ 0x04a9170b, /* MP450 */
+ 0x04a9170c, /* MP500 */
+ 0x04a91712, /* MP530 */
+ 0x04a91714, /* MP160 */
+ 0x04a91715, /* MP180 */
+ 0x04a91716, /* MP460 */
+ 0x04a91717, /* MP510 */
+ 0x04a91718, /* MP600 */
+ 0x04a91719, /* MP600R */
+ 0x04a9172b, /* MP140 */
+ 0x04a9171c, /* MX7600 */
+ 0x04a91721, /* MP210 */
+ 0x04a91722, /* MP220 */
+ 0x04a91723, /* MP470 */
+ 0x04a91724, /* MP520 */
+ 0x04a91725, /* MP610 */
+ 0x04a91727, /* MX300 */
+ 0x04a91728, /* MX310 */
+ 0x04a91729, /* MX700 */
+ 0x04a9172c, /* MX850 */
+ 0x04a9172e, /* MP630 */
+ 0x04a9172f, /* MP620 */
+ 0x04a91730, /* MP540 */
+ 0x04a91731, /* MP480 */
+ 0x04a91732, /* MP240 */
+ 0x04a91733, /* MP260 */
+ 0x04a91734, /* MP190 */
+ 0x04a91735, /* MX860 */
+ 0x04a91736, /* MX320 */
+ 0x04a91737, /* MX330 */
+ 0x04a9173a, /* MP250 */
+ 0x04a9173b, /* MP270 */
+ 0x04a9173c, /* MP490 */
+ 0x04a9173d, /* MP550 */
+ 0x04a9173e, /* MP560 */
+ 0x04a9173f, /* MP640 */
+ 0x04a91741, /* MX340 */
+ 0x04a91742, /* MX350 */
+ 0x04a91743, /* MX870 */
+ 0x04a91746, /* MP280 */
+ 0x04a91747, /* MP495 */
+ 0x04a91748, /* MG5100 */
+ 0x04a91749, /* MG5200 */
+ 0x04a9174a, /* MG6100 */
+ 0x04a9174d, /* MX360 */
+ 0x04a9174e, /* MX410 */
+ 0x04a9174f, /* MX420 */
+ 0x04a91750, /* MX880 */
+ 0x04a91751, /* MG2100 */
+ 0x04a91752, /* MG3100 */
+ 0x04a91753, /* MG4100 */
+ 0x04a91754, /* MG5300 */
+ 0x04a91755, /* MG6200 */
+ 0x04a91757, /* MP493 */
+ 0x04a91758, /* E500 */
+ 0x04a91759, /* MX370 */
+ 0x04a9175B, /* MX430 */
+ 0x04a9175C, /* MX510 */
+ 0x04a9175D, /* MX710 */
+ 0x04a9175E, /* MX890 */
+ 0x04a9175A, /* E600 */
+ 0x04a91763, /* MG4200 */
+ 0x04a9175F, /* MP230 */
+ 0x04a91765, /* MG6300 */
+ 0x04a91760, /* MG2200 */
+ 0x04a91761, /* E510 */
+ 0x04a91762, /* MG3200 */
+ 0x04a91764, /* MG5400 */
+ 0x04a91766, /* MX390 */
+ 0x04a91767, /* E610 */
+ 0x04a91768, /* MX450 */
+ 0x04a91769, /* MX520 */
+ 0x04a9176a, /* MX720 */
+ 0x04a9176b, /* MX920 */
+ 0x04a9176c, /* MG2400 */
+ 0x04a9176d, /* MG2500 */
+ 0x04a9176e, /* MG3500 */
+ 0x04a9176f, /* MG6500 */
+ 0x04a91770, /* MG6400 */
+ 0x04a91771, /* MG5500 */
+ 0x04a91772, /* MG7100 */
+ 0x04a91774, /* MX470 */
+ 0x04a91775, /* MX530 */
+ 0x04a91776, /* MB5000 */
+ 0x04a91777, /* MB5300 */
+ 0x04a91778, /* MB2000 */
+ 0x04a91779, /* MB2300 */
+ 0x04a9177a, /* E400 */
+ 0x04a9177b, /* E560 */
+ 0x04a9177c, /* MG7500 */
+ 0x04a9177e, /* MG6600 */
+ 0x04a9177f, /* MG5600 */
+ 0x04a91780, /* MG2900 */
+ 0x04a91788, /* E460 */
+ 0x04a91787, /* MX490 */
+ 0x04a91789, /* E480 */
+ 0x04a9178a, /* MG3600 */
+ 0x04a9178b, /* MG7700 */
+ 0x04a9178c, /* MG6900 */
+ 0x04a9178d, /* MG6800 */
+ 0x04a9178e, /* MG5700 */
+ 0x04a91792, /* MB2700 */
+ 0x04a91793, /* MB2100 */
+ 0x04a91794, /* G3000 */
+ 0x04a91795, /* G2000 */
+ 0x04a9179f, /* TS9000 */
+ 0x04a91800, /* TS8000 */
+ 0x04a91801, /* TS6000 */
+ 0x04a91802, /* TS5000 */
+ 0x04a9180b, /* MG3000 */
+ 0x04a9180c, /* E470 */
+ 0x04a9181e, /* E410 */
+ 0x04a9181d, /* G4000 */
+ 0x04a91822, /* TS6100 */
+ 0x04a91825, /* TS5100 */
+ 0x04a91827, /* TS3100 */
+ 0x04a91828, /* E3100 */
+ 0x04a9178f, /* MB5400 */
+ 0x04a91790, /* MB5100 */
+ 0x04a91820, /* TS9100 */
+ 0x04a91823, /* TR8500 */
+ 0x04a91824, /* TR7500 */
+ 0x04a9185c, /* TS9500 */
+ 0x04a91912, /* LIDE400 */
+ 0x04a91913, /* LIDE300 */
+ 0x04a91821, /* TS8100 */
+ 0x04a9183a, /* G2010 */
+ 0x04a9183b, /* G3010 */
+ 0x04a9183d, /* G4010 */
+ 0x04a9183e, /* TS9180 */
+ 0x04a9183f, /* TS8180 */
+ 0x04a91840, /* TS6180 */
+ 0x04a91841, /* TR8580 */
+ 0x04a91842, /* TS8130 */
+ 0x04a91843, /* TS6130 */
+ 0x04a91844, /* TR8530 */
+ 0x04a91845, /* TR7530 */
+ 0x04a91846, /* XK50 */
+ 0x04a91847, /* XK70 */
+ 0x04a91854, /* TR4500 */
+ 0x04a91855, /* E4200 */
+ 0x04a91856, /* TS6200 */
+ 0x04a91857, /* TS6280 */
+ 0x04a91858, /* TS6230 */
+ 0x04a91859, /* TS8200 */
+ 0x04a9185a, /* TS8280 */
+ 0x04a9185b, /* TS8230 */
+ 0x04a9185d, /* TS9580 */
+ 0x04a9185e, /* TR9530 */
+ 0x04a91863, /* G7000 */
+ 0x04a91865, /* G6000 */
+ 0x04a91866, /* G6080 */
+ 0x04a91869, /* GM4000 */
+ 0x04a91873, /* XK80 */
+ 0x04a9188b, /* TS5300 */
+ 0x04a9188c, /* TS5380 */
+ 0x04a9188d, /* TS6300 */
+ 0x04a9188e, /* TS6380 */
+ 0x04a9188f, /* TS7330 */
+ 0x04a91890, /* TS8300 */
+ 0x04a91891, /* TS8380 */
+ 0x04a91892, /* TS8330 */
+ 0x04a91893, /* XK60 */
+ 0x04a91894, /* TS6330 */
+ 0x04a918a2, /* TS3300 */
+ 0x04a918a3, /* E3300 */
+ 0x04a9261f, /* MP10 */
+ 0x04a9262f, /* MP730 */
+ 0x04a92630, /* MP700 */
+ 0x04a92635, /* MP5 */
+ 0x04a9263c, /* MP360 */
+ 0x04a9263d, /* MP370 */
+ 0x04a9263e, /* MP390 */
+ 0x04a9263f, /* MP375R */
+ 0x04a9264c, /* MP740 */
+ 0x04a9264d, /* MP710 */
+ 0x04a9265d, /* MF5730 */
+ 0x04a9265e, /* MF5750 */
+ 0x04a9265f, /* MF5770 */
+ 0x04a92660, /* MF3110 */
+ 0x04a926e6, /* IR1020 */
+ 0x04a91706, /* MP750 */
+ 0x04a91708, /* MP760 */
+ 0x04a91707, /* MP780 */
+ 0x04a9170d, /* MP800 */
+ 0x04a9170e, /* MP800R */
+ 0x04a91713, /* MP830 */
+ 0x04a9171a, /* MP810 */
+ 0x04a9171b, /* MP960 */
+ 0x04a91726, /* MP970 */
+ 0x04a91901, /* CS8800F */
+ 0x04a9172d, /* MP980 */
+ 0x04a91740, /* MP990 */
+ 0x04a91908, /* CS9000F */
+ 0x04a9174b, /* MG8100 */
+ 0x04a91756, /* MG8200 */
+ 0x04a9190d, /* CS9000F_MII */
+ };
+
/* Taken from uld/noarch/oem.conf in the Samsung SANE driver */
private const uint32 samsung_devices[] = { 0x04e83425, 0x04e8341c, 0x04e8342a, 0x04e8343d, 0x04e83456, 0x04e8345a, 0x04e83427, 0x04e8343a, 0x04e83428, 0x04e8343b, 0x04e83455, 0x04e83421, 0x04e83439, 0x04e83444, 0x04e8343f, 0x04e8344e, 0x04e83431, 0x04e8345c, 0x04e8344d, 0x04e83462, 0x04e83464, 0x04e83461, 0x04e83460, 0x04e8340e, 0x04e83435,
0x04e8340f, 0x04e83441, 0x04e8344f, 0x04e83413, 0x04e8341b, 0x04e8342e, 0x04e83426, 0x04e8342b, 0x04e83433, 0x04e83440, 0x04e83434, 0x04e8345b, 0x04e83457, 0x04e8341f, 0x04e83453, 0x04e8344b, 0x04e83409, 0x04e83412, 0x04e83419, 0x04e8342c, 0x04e8343c, 0x04e83432, 0x04e8342d, 0x04e83430, 0x04e8342f,
@@ -549,6 +761,10 @@ public class SimpleScan : Gtk.Application
0x04e8347c, 0x04e8347e, 0x04e83481, 0x04e83482, 0x04e83331, 0x04e83332, 0x04e83483, 0x04e83484, 0x04e83485, 0x04e83478, 0x04e83325, 0x04e83327, 0x04e8346f, 0x04e83477, 0x04e83324, 0x04e83326, 0x04e83486, 0x04e83487, 0x04e83489
};
+ /* Taken from uld/noarch/oem.conf in the HP/Samsung SANE driver
+ These devices are rebranded Samsung Multifunction Printers. */
+ private const uint32 smfp_devices[] = { 0x03F0AA2A, 0x03F0CE2A, 0x03F0C02A, 0x03F0EB2A, 0x03F0F22A };
+
/* Taken from /usr/share/hplip/data/models/models.dat in the HPAIO driver */
private const uint32 hpaio_devices[] = {
0x04f92311, /* HP Officejet d125xi All-in-One Printer */
@@ -1236,6 +1452,68 @@ public class SimpleScan : Gtk.Application
/* Taken from epkowa.desc from iscan-data package for Epson driver */
private const uint32 epkowa_devices[] = { 0x04b80101, 0x04b80102, 0x04b80103, 0x04b80104, 0x04b80105, 0x04b80106, 0x04b80107, 0x04b80108, 0x04b80109, 0x04b8010a, 0x04b8010b, 0x04b8010c, 0x04b8010d, 0x04b8010e, 0x04b8010f, 0x04b80110, 0x04b80112, 0x04b80114, 0x04b80116, 0x04b80118, 0x04b80119, 0x04b8011a, 0x04b8011b, 0x04b8011c, 0x04b8011d, 0x04b8011e, 0x04b8011f, 0x04b80120, 0x04b80121, 0x04b80122, 0x04b80126, 0x04b80128, 0x04b80129, 0x04b8012a, 0x04b8012b, 0x04b8012c, 0x04b8012d, 0x04b8012e, 0x04b8012f, 0x04b80130, 0x04b80131, 0x04b80133, 0x04b80135, 0x04b80136, 0x04b80137, 0x04b80138, 0x04b8013a, 0x04b8013b, 0x04b8013c, 0x04b8013d, 0x04b80142, 0x04b80143, 0x04b80144, 0x04b80147, 0x04b8014a, 0x04b8014b, 0x04b80151, 0x04b80153, 0x04b80801, 0x04b80802, 0x04b80805, 0x04b80806, 0x04b80807, 0x04b80808, 0x04b8080a, 0x04b8080c, 0x04b8080d, 0x04b8080e, 0x04b8080f, 0x04b80810, 0x04b80811, 0x04b80813, 0x04b80814, 0x04b80815, 0x04b80817, 0x04b80818, 0x04b80819, 0x04b8081a, 0x04b8081c, 0x04b8081d, 0x04b8081f, 0x04b80820, 0x04b80821, 0x04b80827, 0x04b80828, 0x04b80829, 0x04b8082a, 0x04b8082b, 0x04b8082e, 0x04b8082f, 0x04b80830, 0x04b80831, 0x04b80833, 0x04b80834, 0x04b80835, 0x04b80836, 0x04b80837, 0x04b80838, 0x04b80839, 0x04b8083a, 0x04b8083c, 0x04b8083f, 0x04b80841, 0x04b80843, 0x04b80844, 0x04b80846, 0x04b80847, 0x04b80848, 0x04b80849, 0x04b8084a, 0x04b8084c, 0x04b8084d, 0x04b8084f, 0x04b80850, 0x04b80851, 0x04b80852, 0x04b80853, 0x04b80854, 0x04b80855, 0x04b80856, 0x04b8085c, 0x04b8085d, 0x04b8085e, 0x04b8085f, 0x04b80860, 0x04b80861, 0x04b80862, 0x04b80863, 0x04b80864, 0x04b80865, 0x04b80866, 0x04b80869, 0x04b8086a, 0x04b80870, 0x04b80871, 0x04b80872, 0x04b80873, 0x04b80878, 0x04b80879, 0x04b8087b, 0x04b8087c, 0x04b8087d, 0x04b8087e, 0x04b8087f, 0x04b80880, 0x04b80881, 0x04b80883, 0x04b80884, 0x04b80885, 0x04b8088f, 0x04b80890, 0x04b80891, 0x04b80892, 0x04b80893, 0x04b80894, 0x04b80895, 0x04b80896, 0x04b80897, 0x04b80898, 0x04b80899, 0x04b8089a, 0x04b8089b, 0x04b8089c, 0x04b8089d, 0x04b8089e, 0x04b8089f, 0x04b808a0, 0x04b808a1, 0x04b808a5, 0x04b808a6, 0x04b808a8, 0x04b808a9, 0x04b808aa, 0x04b808ab, 0x04b808ac, 0x04b808ad, 0x04b808ae, 0x04b808af, 0x04b808b0, 0x04b808b3, 0x04b808b4, 0x04b808b5, 0x04b808b6, 0x04b808b7, 0x04b808b8, 0x04b808b9, 0x04b808bd, 0x04b808be, 0x04b808bf, 0x04b808c0, 0x04b808c1, 0x04b808c3, 0x04b808c4, 0x04b808c5, 0x04b808c6, 0x04b808c7, 0x04b808c8, 0x04b808c9, 0x04b808ca, 0x04b808cd, 0x04b808d0 };
+
+ /* Taken from /usr/local/lexmark/unix_scan_drivers/etc/lexmark_nscan.conf */
+ /* Lexmark IDs extracted using command:
+ * grep -r "usb .* /usr" --no-filename --only-matching | sed 's/usb //' | sed 's/ 0x//' | sed 's/ \/usr/,/'
+ */
+ private const uint32 lexmark_nscan_devices[] = {
+ 0x043d0279,
+ 0x043d027a,
+ 0x043d01D6,
+ 0x043d01D7,
+ 0x043d01D8,
+ 0x043d01DC,
+ 0x043d01DE,
+ 0x043d01E0,
+ 0x043d01FA,
+ 0x043d01FB,
+ 0x043d01FC,
+ 0x043d01FD,
+ 0x043d01FE,
+ 0x043d01FF,
+ 0x043d01F4,
+ 0x043d0120,
+ 0x043d0121,
+ 0x043d0128,
+ 0x043d014F,
+ 0x043d0149,
+ 0x043d0152,
+ 0x043d0168,
+ 0x043d0169,
+ 0x043d016A,
+ 0x043d012D,
+ 0x043d01C4,
+ 0x043d01C5,
+ 0x043d01C6,
+ 0x043d01CF,
+ 0x043d01D0,
+ 0x043d01D1,
+ 0x043d01DB,
+ 0x043d01ED,
+ 0x043d01F1,
+ 0x043d01F5,
+ 0x043d0222,
+ 0x043d0223,
+ 0x043d0227,
+ 0x043d0228,
+ 0x043d022A,
+ 0x043d022B,
+ 0x043d022F,
+ 0x043d0230,
+ 0x043d0231,
+ 0x043d0234,
+ 0x043d0235,
+ 0x043d0244,
+ 0x043d0245,
+ 0x043d0246,
+ 0x043d0247,
+ 0x043d0248,
+ 0x043d024A,
+ 0x043d024E,
+ 0x043d024F
+ };
+
/* Brother IDs extracted using the following Python
*
* import sys
@@ -1273,9 +1551,12 @@ public class SimpleScan : Gtk.Application
add_devices (driver_map, brscan2_devices, "brscan2");
add_devices (driver_map, brscan3_devices, "brscan3");
add_devices (driver_map, brscan4_devices, "brscan4");
+ add_devices (driver_map, pixma_devices, "pixma");
add_devices (driver_map, samsung_devices, "samsung");
+ add_devices (driver_map, smfp_devices, "smfp");
add_devices (driver_map, hpaio_devices, "hpaio");
add_devices (driver_map, epkowa_devices, "epkowa");
+ add_devices (driver_map, lexmark_nscan_devices, "lexmark_nscan");
var devices = usb_context.get_devices ();
for (var i = 0; i < devices.length; i++)
{
@@ -1547,6 +1828,12 @@ public class SimpleScan : Gtk.Application
scanner.cancel ();
}
+ private void redetect_cb (AppWindow ui)
+ {
+ scanner.redetect ();
+ }
+
+
private static void log_cb (string? log_domain, LogLevelFlags log_level, string message)
{
string prefix;
@@ -1695,7 +1982,7 @@ public class SimpleScan : Gtk.Application
}
catch (Error e)
{
- stderr.printf ("Error fixing PDF file: %s", e.message);
+ stderr.printf ("Error fixing PDF file: %s\n", e.message);
return Posix.EXIT_FAILURE;
}
return Posix.EXIT_SUCCESS;
@@ -1715,6 +2002,11 @@ public class SimpleScan : Gtk.Application
DirUtils.create_with_parents (path, 0700);
path = Path.build_filename (Environment.get_user_cache_dir (), "simple-scan", "simple-scan.log", null);
log_file = FileStream.open (path, "w");
+ if (log_file == null )
+ {
+ stderr.printf ("Error: Unable to open %s file for writing\n", path);
+ return Posix.EXIT_FAILURE;
+ }
Log.set_default_handler (log_cb);
debug ("Starting %s %s, PID=%i", args[0], VERSION, Posix.getpid ());