From 8eb2b297d6e03975afc17e1d468aa8913639e1a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= <debian@jff.email>
Date: Sun, 22 Mar 2020 17:05:56 +0100
Subject: New upstream version 3.36.0

---
 src/app-window.ui           | 697 +++++++++++++++++++++++++++++++-------------
 src/app-window.vala         | 257 ++++++++++++++--
 src/autosave-manager.vala   |   8 +-
 src/book-view.vala          |   2 +-
 src/help-overlay.ui         |  27 ++
 src/meson.build             |   1 +
 src/page-icon.vala          |  76 +++++
 src/page-view.vala          |  35 +--
 src/page.vala               |   4 +-
 src/preferences-dialog.ui   |  73 ++---
 src/preferences-dialog.vala | 229 +--------------
 src/sane-backends.vapi      |  10 +-
 src/scanner.vala            | 114 ++++++--
 src/simple-scan.vala        |  12 +-
 14 files changed, 974 insertions(+), 571 deletions(-)
 create mode 100644 src/page-icon.vala

(limited to 'src')

diff --git a/src/app-window.ui b/src/app-window.ui
index b34c07e..e0e16c0 100644
--- a/src/app-window.ui
+++ b/src/app-window.ui
@@ -1,12 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.20.0 -->
+<!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <object class="GtkMenu" id="page_menu">
     <property name="visible">True</property>
+    <property name="can_focus">False</property>
     <child>
       <object class="GtkMenuItem" id="rotate_left_menuitem">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="label" translatable="yes" comments="Menu item to rotate page to left (anti-clockwise)">Rotate _Left</property>
         <property name="use_underline">True</property>
         <signal name="activate" handler="rotate_left_button_clicked_cb" swapped="no"/>
@@ -16,6 +18,7 @@
     <child>
       <object class="GtkMenuItem" id="rotate_right_menuitem">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="label" translatable="yes" comments="Menu item to rotate page to right (clockwise)">Rotate _Right</property>
         <property name="use_underline">True</property>
         <signal name="activate" handler="rotate_right_button_clicked_cb" swapped="no"/>
@@ -25,14 +28,17 @@
     <child>
       <object class="GtkMenuItem" id="crop_menuitem">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="label" translatable="yes" comments="Label for page crop submenu">_Crop</property>
         <property name="use_underline">True</property>
         <child type="submenu">
           <object class="GtkMenu" id="crop_menu">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <child>
               <object class="GtkRadioMenuItem" id="no_crop_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for no crop">_None</property>
                 <property name="use_underline">True</property>
                 <property name="active">True</property>
@@ -43,6 +49,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="a4_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to A4 size">A_4</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -53,6 +60,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="a5_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to A5 size">A_5</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -63,6 +71,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="a6_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to A6 size">A_6</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -73,6 +82,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="letter_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to US letter size">_Letter</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -83,6 +93,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="legal_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping to page to US legal size">Le_gal</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -93,6 +104,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="four_by_six_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to 4x6 inch">4×6</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -103,6 +115,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="a3_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping page to A3">A_3</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -113,6 +126,7 @@
             <child>
               <object class="GtkRadioMenuItem" id="custom_crop_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Radio button for cropping to custom page size">_Custom</property>
                 <property name="use_underline">True</property>
                 <property name="draw_as_radio">True</property>
@@ -123,12 +137,14 @@
             <child>
               <object class="GtkSeparatorMenuItem" id="crop_sep_menuitem">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
               </object>
             </child>
             <child>
               <object class="GtkMenuItem" id="crop_rotate_menuitem">
                 <property name="visible">True</property>
                 <property name="sensitive">False</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes" comments="Menu item to rotate the crop area">_Rotate Crop</property>
                 <property name="use_underline">True</property>
                 <signal name="activate" handler="crop_rotate_menuitem_activate_cb" swapped="no"/>
@@ -141,6 +157,7 @@
     <child>
       <object class="GtkMenuItem" id="page_move_left_menuitem">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="label" translatable="yes" comments="Menu item to move the selected page to the left">Move Left</property>
         <signal name="activate" handler="page_move_left_menuitem_activate_cb" swapped="no"/>
         <accelerator key="less" signal="activate"/>
@@ -149,6 +166,7 @@
     <child>
       <object class="GtkMenuItem" id="page_move_right_menuitem">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="label" translatable="yes" comments="Menu item to move the selected page to the right">Move Right</property>
         <property name="use_underline">True</property>
         <signal name="activate" handler="page_move_right_menuitem_activate_cb" swapped="no"/>
@@ -160,6 +178,7 @@
         <property name="label">gtk-copy</property>
         <property name="visible">True</property>
         <property name="sensitive">False</property>
+        <property name="can_focus">False</property>
         <property name="use_underline">True</property>
         <property name="use_stock">True</property>
         <signal name="activate" handler="copy_to_clipboard_button_clicked_cb" swapped="no"/>
@@ -170,6 +189,7 @@
       <object class="GtkImageMenuItem" id="page_delete_menuitem">
         <property name="label">gtk-delete</property>
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="use_underline">True</property>
         <property name="use_stock">True</property>
         <signal name="activate" handler="page_delete_menuitem_activate_cb" swapped="no"/>
@@ -177,147 +197,467 @@
       </object>
     </child>
   </object>
-  <template class="AppWindow" parent="GtkApplicationWindow">
-    <property name="title" translatable="yes" comments="Title of scan window">Document Scanner</property>
-    <property name="icon_name">org.gnome.SimpleScan</property>
-    <signal name="delete-event" handler="window_delete_event_cb" swapped="no"/>
+  <object class="GtkListStore" id="device_model">
+    <columns>
+      <!-- column-name device_name -->
+      <column type="gchararray"/>
+      <!-- column-name label -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkPopover" id="scan_options_popover">
+    <property name="can_focus">False</property>
     <child>
       <object class="GtkBox">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">12</property>
+        <property name="margin_right">12</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
         <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
         <child>
-          <object class="GtkStack" id="stack">
+          <object class="GtkRadioButton" id="scan_single_radio">
             <property name="visible">True</property>
-            <property name="vexpand">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">False</property>
+            <property name="draw_indicator">False</property>
+            <signal name="toggled" handler="scan_single_radio_toggled_cb" swapped="no"/>
             <child>
-              <object class="GtkAlignment">
+              <object class="GtkBox">
                 <property name="visible">True</property>
-                <property name="xscale">0</property>
-                <property name="yscale">0</property>
+                <property name="can_focus">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="spacing">12</property>
                 <child>
-                  <object class="GtkBox">
+                  <object class="GtkImage">
                     <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">10</property>
-                    <child>
-                      <object class="GtkImage">
-                        <property name="visible">True</property>
-                        <property name="opacity">0.5</property>
-                        <property name="pixel_size">120</property>
-                        <property name="icon_name">org.gnome.SimpleScan-symbolic</property>
-                        <property name="icon_size">6</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="status_primary_label">
-                        <property name="visible">True</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                          <attribute name="scale" value="1.5"/>
-                        </attributes>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="status_secondary_label">
-                        <property name="visible">False</property>
-                        <property name="track_visited_links">False</property>
-                        <signal name="activate_link" handler="status_label_activate_link_cb" swapped="no"/>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                    </child>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">scanner-symbolic</property>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">_Single Page</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="name">startup</property>
-              </packing>
             </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkRadioButton" id="scan_adf_radio">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">False</property>
+            <property name="draw_indicator">False</property>
+            <property name="group">scan_single_radio</property>
+            <signal name="toggled" handler="scan_adf_radio_toggled_cb" swapped="no"/>
             <child>
-              <object class="GtkBox" id="main_vbox">
+              <object class="GtkBox">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
+                <property name="can_focus">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="spacing">12</property>
                 <child>
-                  <object class="GtkActionBar" id="action_bar">
+                  <object class="GtkImage">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">scan-type-adf-symbolic</property>
                   </object>
                   <packing>
-                    <property name="pack_type">end</property>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">All Pages From _Feeder</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </object>
-              <packing>
-                <property name="name">document</property>
-              </packing>
             </child>
           </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkRadioButton" id="scan_batch_radio">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">False</property>
+            <property name="draw_indicator">False</property>
+            <property name="group">scan_single_radio</property>
+            <signal name="toggled" handler="scan_batch_radio_toggled_cb" swapped="no"/>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">scan-type-batch-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">_Multiple Pages From Flatbed</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkRadioButton" id="text_radio">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">False</property>
+            <property name="margin_top">12</property>
+            <property name="draw_indicator">False</property>
+            <signal name="toggled" handler="text_radio_toggled_cb" swapped="no"/>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">x-office-document-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">_Text</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkRadioButton" id="photo_radio">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="receives_default">False</property>
+            <property name="draw_indicator">False</property>
+            <property name="group">text_radio</property>
+            <signal name="toggled" handler="photo_radio_toggled_cb" swapped="no"/>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_start">12</property>
+                <property name="margin_end">12</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">image-x-generic-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">_Image</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="preferences_button">
+            <property name="label" translatable="yes">_Preferences</property>
+            <property name="height_request">40</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="margin_top">12</property>
+            <property name="use_underline">True</property>
+            <signal name="clicked" handler="preferences_button_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">5</property>
+          </packing>
         </child>
       </object>
     </child>
+  </object>
+  <template class="AppWindow" parent="GtkApplicationWindow">
+    <property name="width_request">320</property>
+    <property name="height_request">480</property>
+    <property name="can_focus">False</property>
+    <property name="title" translatable="yes" comments="Title of scan window">Document Scanner</property>
+    <property name="icon_name">org.gnome.SimpleScan</property>
+    <signal name="delete-event" handler="window_delete_event_cb" swapped="no"/>
     <child type="titlebar">
       <object class="GtkHeaderBar" id="header_bar">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="vexpand">True</property>
         <property name="show_close_button">True</property>
         <child>
           <object class="GtkBox" id="open_box">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="valign">center</property>
             <child>
               <object class="GtkButton" id="stop_button">
-                <property name="label" translatable="yes">Stop</property>
+                <property name="can_focus">False</property>
                 <property name="receives_default">False</property>
                 <property name="tooltip_text" translatable="yes" comments="Tooltip for stop button">Stop the current scan</property>
                 <property name="use_underline">True</property>
                 <signal name="clicked" handler="stop_scan_button_clicked_cb" swapped="no"/>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkSpinner" id="stop_button_spinner">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="active">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">S_top</property>
+                        <property name="use_underline">True</property>
+                        <property name="width_chars">6</property>
+                        <property name="xalign">0.33</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
                 <style>
                   <class name="text-button"/>
                   <class name="destructive-action"/>
                 </style>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
             </child>
             <child>
               <object class="GtkButton" id="scan_button">
-                <property name="label" translatable="yes" comments="Label on scan toolbar item">Scan</property>
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="receives_default">False</property>
                 <property name="tooltip_text" translatable="yes" comments="Tooltip for scan toolbar button">Scan a single page from the scanner</property>
                 <property name="use_underline">True</property>
                 <signal name="clicked" handler="scan_button_clicked_cb" swapped="no"/>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkImage" id="scan_options_image">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">scanner-symbolic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="margin_right">1</property>
+                        <property name="label" translatable="yes">_Scan</property>
+                        <property name="use_underline">True</property>
+                        <property name="width_chars">6</property>
+                        <property name="xalign">0.33</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
                 <style>
                   <class name="text-button"/>
                   <class name="suggested-action"/>
                 </style>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
             </child>
             <child>
               <object class="GtkMenuButton">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="receives_default">False</property>
                 <property name="popover">scan_options_popover</property>
                 <child>
                   <object class="GtkBox">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkImage" id="scan_options_image">
+                      <object class="GtkImage" id="scan_hint_image">
                         <property name="visible">True</property>
-                        <property name="icon_name">scanner-symbolic</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">x-office-document-symbolic</property>
                       </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
                     </child>
                     <child>
                       <object class="GtkImage">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="icon_name">pan-down-symbolic</property>
                       </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
                     </child>
                   </object>
                 </child>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
             </child>
             <style>
               <class name="linked"/>
@@ -327,11 +667,13 @@
         <child>
           <object class="GtkMenuButton" id="menu_button">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="receives_default">False</property>
             <property name="use_underline">True</property>
             <child>
               <object class="GtkImage">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="icon_name">open-menu-symbolic</property>
                 <property name="icon_size">1</property>
               </object>
@@ -342,12 +684,14 @@
           </object>
           <packing>
             <property name="pack_type">end</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
           <object class="GtkButton" id="save_button">
             <property name="visible">True</property>
             <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
             <property name="receives_default">False</property>
             <property name="tooltip_text" translatable="yes" comments="Tooltip for save toolbar button">Save document to a file</property>
             <property name="use_underline">True</property>
@@ -355,6 +699,7 @@
             <child>
               <object class="GtkImage" id="save_image">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="icon_name">document-save-symbolic</property>
                 <property name="icon_size">1</property>
               </object>
@@ -365,6 +710,7 @@
           </object>
           <packing>
             <property name="pack_type">end</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <style>
@@ -372,170 +718,125 @@
         </style>
       </object>
     </child>
-  </template>
-  <object class="GtkPopover" id="scan_options_popover">
     <child>
       <object class="GtkBox">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="margin">12</property>
-        <property name="spacing">6</property>
-        <child>
-          <object class="GtkRadioButton" id="scan_single_radio">
-            <property name="visible">True</property>
-            <property name="draw_indicator">False</property>
-            <signal name="toggled" handler="scan_single_radio_toggled_cb" swapped="no"/>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="icon_name">scanner-symbolic</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Single Page</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkRadioButton" id="scan_adf_radio">
-            <property name="visible">True</property>
-            <property name="draw_indicator">False</property>
-            <property name="group">scan_single_radio</property>
-            <signal name="toggled" handler="scan_adf_radio_toggled_cb" swapped="no"/>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="icon_name">scan-type-adf-symbolic</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">All Pages From _Feeder</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkRadioButton" id="scan_batch_radio">
-            <property name="visible">True</property>
-            <property name="draw_indicator">False</property>
-            <property name="group">scan_single_radio</property>
-            <signal name="toggled" handler="scan_batch_radio_toggled_cb" swapped="no"/>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="icon_name">scan-type-batch-symbolic</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Multiple Pages From Flatbed</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
         <child>
-          <object class="GtkRadioButton" id="text_radio">
+          <object class="GtkStack" id="stack">
             <property name="visible">True</property>
-            <property name="draw_indicator">False</property>
-            <property name="margin_top">12</property>
-            <signal name="toggled" handler="text_radio_toggled_cb" swapped="no"/>
+            <property name="can_focus">False</property>
+            <property name="vexpand">True</property>
             <child>
-              <object class="GtkBox">
+              <object class="GtkAlignment">
                 <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="icon_name">text-x-generic-symbolic</property>
-                  </object>
-                </child>
+                <property name="can_focus">False</property>
+                <property name="xscale">0</property>
+                <property name="yscale">0</property>
                 <child>
-                  <object class="GtkLabel">
+                  <object class="GtkBox">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Text</property>
-                    <property name="use_underline">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">10</property>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="has_focus">True</property>
+                        <property name="is_focus">True</property>
+                        <property name="can_default">True</property>
+                        <property name="has_default">True</property>
+                        <property name="opacity">0.5</property>
+                        <property name="pixel_size">120</property>
+                        <property name="icon_name">org.gnome.SimpleScan-symbolic</property>
+                        <property name="icon_size">6</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="status_primary_label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                          <attribute name="scale" value="1.5"/>
+                        </attributes>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="status_secondary_label">
+                        <property name="can_focus">False</property>
+                        <property name="track_visited_links">False</property>
+                        <signal name="activate-link" handler="status_label_activate_link_cb" swapped="no"/>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="device_combo">
+                        <property name="visible">False</property>
+                        <property name="model">device_model</property>
+                        <signal name="changed" handler="device_combo_changed_cb" swapped="no"/>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
+              <packing>
+                <property name="name">startup</property>
+              </packing>
             </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkRadioButton" id="photo_radio">
-            <property name="visible">True</property>
-            <property name="draw_indicator">False</property>
-            <property name="group">text_radio</property>
-            <signal name="toggled" handler="photo_radio_toggled_cb" swapped="no"/>
             <child>
-              <object class="GtkBox">
+              <object class="GtkBox" id="main_vbox">
                 <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="icon_name">image-x-generic-symbolic</property>
-                  </object>
-                </child>
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkLabel">
+                  <object class="GtkActionBar" id="action_bar">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Image</property>
-                    <property name="use_underline">True</property>
+                    <property name="can_focus">False</property>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="pack_type">end</property>
+                    <property name="position">0</property>
+                  </packing>
                 </child>
               </object>
+              <packing>
+                <property name="name">document</property>
+                <property name="position">1</property>
+              </packing>
             </child>
           </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
         </child>
       </object>
     </child>
-  </object>
+  </template>
 </interface>
-
diff --git a/src/app-window.vala b/src/app-window.vala
index 02f2072..6f2d353 100644
--- a/src/app-window.vala
+++ b/src/app-window.vala
@@ -44,6 +44,9 @@ public class AppWindow : Gtk.ApplicationWindow
 
     private PreferencesDialog preferences_dialog;
 
+    private bool setting_devices;
+    private bool user_selected_device;
+
     [GtkChild]
     private Gtk.HeaderBar header_bar;
     [GtkChild]
@@ -53,6 +56,10 @@ public class AppWindow : Gtk.ApplicationWindow
     [GtkChild]
     private Gtk.Label status_primary_label;
     [GtkChild]
+    private Gtk.ListStore device_model;
+    [GtkChild]
+    private Gtk.ComboBox device_combo;
+    [GtkChild]
     private Gtk.Label status_secondary_label;
     [GtkChild]
     private Gtk.Box main_vbox;
@@ -98,6 +105,8 @@ public class AppWindow : Gtk.ApplicationWindow
     [GtkChild]
     private Gtk.Image scan_options_image;
     [GtkChild]
+    private Gtk.Image scan_hint_image;
+    [GtkChild]
     private Gtk.RadioButton scan_single_radio;
     [GtkChild]
     private Gtk.RadioButton scan_adf_radio;
@@ -177,12 +186,6 @@ public class AppWindow : Gtk.ApplicationWindow
         set { preferences_dialog.set_page_delay (value); }
     }
 
-    public string? selected_device
-    {
-        owned get { return preferences_dialog.get_selected_device (); }
-        set { preferences_dialog.set_selected_device (value); }
-    }
-
     public signal void start_scan (string? device, ScanOptions options);
     public signal void stop_scan ();
 
@@ -190,6 +193,11 @@ public class AppWindow : Gtk.ApplicationWindow
     {
         settings = new Settings ("org.gnome.SimpleScan");
 
+        var renderer = new Gtk.CellRendererText ();
+        renderer.set_property ("xalign", 0.5);
+        device_combo.pack_start (renderer, true);
+        device_combo.add_attribute (renderer, "text", 1);
+
         book = new Book ();
         book.page_added.connect (page_added_cb);
         book.reordered.connect (reordered_cb);
@@ -199,19 +207,6 @@ public class AppWindow : Gtk.ApplicationWindow
         load ();
 
         clear_document ();
-        autosave_manager = new AutosaveManager ();
-        autosave_manager.book = book;
-        autosave_manager.load ();
-
-        if (book.n_pages == 0)
-            book_needs_saving = false;
-        else
-        {
-            stack.set_visible_child_name ("document");
-            book_view.selected_page = book.get_page (0);
-            book_needs_saving = true;
-            book_changed_cb (book);
-        }
     }
 
     ~AppWindow ()
@@ -255,13 +250,15 @@ public class AppWindow : Gtk.ApplicationWindow
             status_primary_label.set_text (/* Label shown when searching for scanners */
                                            _("Searching for Scanners…"));
             status_secondary_label.visible = false;
+            device_combo.visible = false;
         }
-        else if (selected_device != null)
+        else if (get_selected_device () != null)
         {
             status_primary_label.set_text (/* Label shown when detected a scanner */
                                            _("Ready to Scan"));
-            status_secondary_label.set_text (preferences_dialog.get_selected_device_label ());
-            status_secondary_label.visible = true;
+            status_secondary_label.set_text (get_selected_device_label ());
+            status_secondary_label.visible = false;
+            device_combo.visible = true;
         }
         else if (this.missing_driver != null)
         {
@@ -270,6 +267,7 @@ public class AppWindow : Gtk.ApplicationWindow
             /* Instructions to install driver software */
             status_secondary_label.set_markup (_("You need to <a href=\"install-firmware\">install driver software</a> for your scanner."));
             status_secondary_label.visible = true;
+            device_combo.visible = false;
         }
         else
         {
@@ -278,6 +276,7 @@ public class AppWindow : Gtk.ApplicationWindow
             /* Hint to user on why there are no scanners detected */
             status_secondary_label.set_text (_("Please check your scanner is connected and powered on"));
             status_secondary_label.visible = true;
+            device_combo.visible = false;
         }
     }
 
@@ -285,10 +284,162 @@ public class AppWindow : Gtk.ApplicationWindow
     {
         have_devices = true;
         this.missing_driver = missing_driver;
-        preferences_dialog.set_scan_devices (devices);
+
+        setting_devices = true;
+
+        /* If the user hasn't chosen a scanner choose the best available one */
+        var have_selection = false;
+        if (user_selected_device)
+            have_selection = device_combo.active >= 0;
+
+        /* Add new devices */
+        int index = 0;
+        Gtk.TreeIter iter;
+        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);
+#if VALA_0_36
+                    device_model.remove (ref iter);
+#else
+                    device_model.remove (iter);
+#endif
+                }
+            }
+            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))
+#if VALA_0_36
+            device_model.remove (ref iter);
+#else
+            device_model.remove (iter);
+#endif
+
+        /* 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_scan_status ();
     }
 
+    private bool prompt_to_load_autosaved_book ()
+    {
+        var dialog = new Gtk.MessageDialog (this,
+                                            Gtk.DialogFlags.MODAL,
+                                            Gtk.MessageType.QUESTION,
+                                            Gtk.ButtonsType.YES_NO,
+                                            /* Contents of dialog that shows if autosaved book should be loaded. */
+                                            _("An autosaved book exists. Do you want to open it?"));
+        dialog.set_default_response(Gtk.ResponseType.YES);
+        var response = dialog.run ();
+        dialog.destroy ();
+        return response == Gtk.ResponseType.YES;
+    }
+
+    private string? get_selected_device ()
+    {
+        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;
+    }
+
+    private string? get_selected_device_label ()
+    {
+        Gtk.TreeIter iter;
+
+        if (device_combo.get_active_iter (out iter))
+        {
+            string label;
+            device_model.get (iter, 1, out label, -1);
+            return label;
+        }
+
+        return null;
+    }
+
+    public void set_selected_device (string device)
+    {
+        user_selected_device = true;
+
+        Gtk.TreeIter iter;
+        if (!find_scan_device (device, out iter))
+            return;
+
+        device_combo.set_active_iter (iter);
+    }
+
+    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 string? choose_file_location ()
     {
         /* Get directory to save to */
@@ -543,7 +694,7 @@ public class AppWindow : Gtk.ApplicationWindow
 
     private async bool prompt_to_save_async (string title, string discard_label)
     {
-        if (!book_needs_saving)
+        if (!book_needs_saving || (book.n_pages == 0))
             return true;
 
         var dialog = new Gtk.MessageDialog (this,
@@ -624,7 +775,7 @@ public class AppWindow : Gtk.ApplicationWindow
     {
         status_primary_label.set_text (/* Label shown when scan started */
                                        _("Contacting scanner…"));
-        start_scan (selected_device, options);
+        start_scan (get_selected_device (), options);
     }
 
     private void scan_single_cb ()
@@ -733,10 +884,12 @@ public class AppWindow : Gtk.ApplicationWindow
         if (document_hint == "text")
         {
             text_radio.active = true;
+            scan_hint_image.icon_name = "x-office-document-symbolic";
         }
         else if (document_hint == "photo")
         {
             photo_radio.active = true;
+            scan_hint_image.icon_name = "image-x-generic-symbolic";
         }
 
         if (save)
@@ -757,6 +910,12 @@ public class AppWindow : Gtk.ApplicationWindow
             set_document_hint ("photo", true);
     }
 
+    [GtkCallback]
+    private void preferences_button_clicked_cb (Gtk.Button button)
+    {
+        preferences_dialog.present ();
+    }
+
     private ScanOptions make_scan_options ()
     {
         var options = new ScanOptions ();
@@ -780,9 +939,21 @@ public class AppWindow : Gtk.ApplicationWindow
         return options;
     }
 
+    [GtkCallback]
+    private void device_combo_changed_cb (Gtk.Widget widget)
+    {
+        if (setting_devices)
+            return;
+        user_selected_device = true;
+        if (get_selected_device () != null)
+            settings.set_string ("selected-device", get_selected_device ());
+    }
+
     [GtkCallback]
     private void scan_button_clicked_cb (Gtk.Widget widget)
     {
+        scan_button.visible = false;
+        stop_button.visible = true;
         var options = make_scan_options ();
         options.type = scan_type;
         if (options.type == ScanType.ADF_BOTH)
@@ -793,6 +964,8 @@ public class AppWindow : Gtk.ApplicationWindow
     [GtkCallback]
     private void stop_scan_button_clicked_cb (Gtk.Widget widget)
     {
+        scan_button.visible = true;
+        stop_button.visible = false;
         stop_scan ();
     }
 
@@ -1609,15 +1782,17 @@ 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" });
 
         var gear_menu = new Menu ();
         var section = new Menu ();
         gear_menu.append_section (null, section);
         section.append (_("Email"), "app.email");
+        section.append (_("Print"), "app.print");
         section.append (C_("menu", "Reorder Pages"), "app.reorder");
+        section.append (_("Preferences"), "app.preferences");
         section = new Menu ();
         gear_menu.append_section (null, section);
-        section.append (_("Preferences"), "app.preferences");
         section.append (_("Keyboard Shortcuts"), "win.show-help-overlay");
         section.append (_("Help"), "app.help");
         section.append (_("About Document Scanner"), "app.about");
@@ -1750,6 +1925,20 @@ public class AppWindow : Gtk.ApplicationWindow
             window_height = 400;
         window_is_maximized = state_get_boolean (f, "window", "is-maximized");
         window_is_fullscreen = state_get_boolean (f, "window", "is-fullscreen");
+        scan_type = Scanner.type_from_string(state_get_string (f, "scanner", "scan-type", "single"));
+        set_scan_type (scan_type);
+    }
+
+    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 int state_get_integer (KeyFile f, string group_name, string key, int default = 0)
@@ -1798,6 +1987,7 @@ public class AppWindow : Gtk.ApplicationWindow
         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_string ("scanner", "scan-type", Scanner.type_to_string(scan_type));
         try
         {
             FileUtils.set_contents (state_filename, f.to_data ());
@@ -1811,6 +2001,21 @@ public class AppWindow : Gtk.ApplicationWindow
     public void start ()
     {
         visible = true;
+        autosave_manager = new AutosaveManager ();
+        autosave_manager.book = book;
+
+        if (autosave_manager.exists () && prompt_to_load_autosaved_book ())
+            autosave_manager.load ();
+
+        if (book.n_pages == 0)
+            book_needs_saving = false;
+        else
+        {
+            stack.set_visible_child_name ("document");
+            book_view.selected_page = book.get_page (0);
+            book_needs_saving = true;
+            book_changed_cb (book);
+        }
     }
 }
 
diff --git a/src/autosave-manager.vala b/src/autosave-manager.vala
index 84a1e00..c5eb65e 100644
--- a/src/autosave-manager.vala
+++ b/src/autosave-manager.vala
@@ -59,6 +59,12 @@ public class AutosaveManager
         page_filenames = new HashTable<Page, string> (direct_hash, direct_equal);
     }
 
+    public bool exists ()
+    {
+        var file = File.new_for_path (AUTOSAVE_PATH);
+        return file.query_exists ();
+    }
+
     public void load ()
     {
         debug ("Loading autosave information");
@@ -328,7 +334,7 @@ public class AutosaveManager
             file.set_integer (page_name, "crop-height", page.crop_height);
         }
         file.set_value ("simple-scan", "pages", page_names);
- 
+
         try
         {
             DirUtils.create_with_parents (AUTOSAVE_DIR, 0777);
diff --git a/src/book-view.vala b/src/book-view.vala
index 782a011..12da06f 100644
--- a/src/book-view.vala
+++ b/src/book-view.vala
@@ -34,7 +34,7 @@ public class BookView : Gtk.Box
             else
                 return null;
         }
-        set 
+        set
         {
             if (selected_page == value)
                 return;
diff --git a/src/help-overlay.ui b/src/help-overlay.ui
index dabec9f..b1a0127 100644
--- a/src/help-overlay.ui
+++ b/src/help-overlay.ui
@@ -122,6 +122,33 @@
             </child>
           </object>
         </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes" context="shortcut window">General</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">F1</property>
+                <property name="title" translatable="yes" context="shortcut window">Show help</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;F1</property>
+                <property name="title" translatable="yes" context="shortcut window">Keyboard shortcuts</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;q</property>
+                <property name="title" translatable="yes" context="shortcut window">Quit</property>
+              </object>
+            </child>
+          </object>
+        </child>
       </object>
     </child>
   </object>
diff --git a/src/meson.build b/src/meson.build
index 7d535c8..419ed06 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -24,6 +24,7 @@ simple_scan = executable ('simple-scan',
                             'book.vala',
                             'book-view.vala',
                             'page.vala',
+                            'page-icon.vala',
                             'page-view.vala',
                             'preferences-dialog.vala',
                             'simple-scan.vala',
diff --git a/src/page-icon.vala b/src/page-icon.vala
new file mode 100644
index 0000000..793ca5b
--- /dev/null
+++ b/src/page-icon.vala
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009-2017 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.
+ */
+
+public 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;
+    }
+}
diff --git a/src/page-view.vala b/src/page-view.vala
index abe5e69..91a2c82 100644
--- a/src/page-view.vala
+++ b/src/page-view.vala
@@ -36,7 +36,7 @@ public class PageView : Object
     public bool selected
     {
         get { return selected_; }
-        set    
+        set
         {
             if ((this.selected && selected) || (!this.selected && !selected))
                 return;
@@ -845,39 +845,6 @@ public class PageView : Object
         Gdk.cairo_set_source_pixbuf (context, image, 0, 0);
         context.paint ();
 
-        /* Draw throbber */
-        if (page.is_scanning && !page.has_data)
-        {
-            double outer_radius;
-            if (w > h)
-                outer_radius = 0.15 * w;
-            else
-                outer_radius = 0.15 * h;
-            var arc = Math.PI / animate_n_segments;
-
-            /* Space circles */
-            var x = outer_radius * Math.sin (arc);
-            var y = outer_radius * (Math.cos (arc) - 1.0);
-            var inner_radius = 0.6 * Math.sqrt (x*x + y*y);
-
-            double offset = 0.0;
-            for (var i = 0; i < animate_n_segments; i++, offset += arc * 2)
-            {
-                x = w / 2 + outer_radius * Math.sin (offset);
-                y = h / 2 - outer_radius * Math.cos (offset);
-                context.arc (x, y, inner_radius, 0, 2 * Math.PI);
-
-                if (i == animate_segment)
-                {
-                    context.set_source_rgb (0.75, 0.75, 0.75);
-                    context.fill_preserve ();
-                }
-
-                context.set_source_rgb (0.5, 0.5, 0.5);
-                context.stroke ();
-            }
-        }
-
         /* Draw scan line */
         if (page.is_scanning && page.scan_line > 0)
         {
diff --git a/src/page.vala b/src/page.vala
index 026fdcc..c6b532e 100644
--- a/src/page.vala
+++ b/src/page.vala
@@ -90,7 +90,7 @@ public class Page : Object
     public ScanDirection scan_direction
     {
         get { return scan_direction_; }
-        
+
         set
         {
             if (scan_direction_ == value)
@@ -371,7 +371,7 @@ public class Page : Object
     {
         return_if_fail (width >= 1);
         return_if_fail (height >= 1);
-        
+
         if (crop_name == null && has_crop && crop_width == width && crop_height == height)
             return;
         crop_name = null;
diff --git a/src/preferences-dialog.ui b/src/preferences-dialog.ui
index 75d8a4c..63d06e0 100644
--- a/src/preferences-dialog.ui
+++ b/src/preferences-dialog.ui
@@ -14,14 +14,6 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkListStore" id="device_model">
-    <columns>
-      <!-- column-name device_name -->
-      <column type="gchararray"/>
-      <!-- column-name label -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
   <object class="GtkListStore" id="paper_size_model">
     <columns>
       <!-- column-name width -->
@@ -74,40 +66,12 @@
                     <property name="visible">True</property>
                     <property name="row_spacing">15</property>
                     <property name="column_spacing">10</property>
-                    <child>
-                      <object class="GtkLabel" id="source_label">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside scan source combo box">_Scanner</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">device_combo</property>
-                        <property name="xalign">1</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="device_combo">
-                        <property name="visible">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="model">device_model</property>
-                        <signal name="changed" handler="device_combo_changed_cb" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                      </packing>
-                    </child>
                     <child>
                       <object class="GtkLabel" id="page_side_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside scan side combo box">Scan Sides</property>
+                        <property name="label" translatable="yes" comments="Label beside scan side combo box">Scan _Sides</property>
                         <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">scan_side_box</property>
+                        <property name="mnemonic_widget">front_side_button</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -115,14 +79,15 @@
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
+                        <property name="top_attach">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="paper_size_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside page size combo box">Page Size</property>
+                        <property name="label" translatable="yes" comments="Label beside page size combo box">_Page Size</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">paper_size_combo</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -130,7 +95,7 @@
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">2</property>
+                        <property name="top_attach">1</property>
                       </packing>
                     </child>
                     <child>
@@ -141,7 +106,7 @@
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
-                        <property name="top_attach">2</property>
+                        <property name="top_attach">1</property>
                       </packing>
                     </child>
                     <child>
@@ -184,7 +149,7 @@
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
-                        <property name="top_attach">1</property>
+                        <property name="top_attach">0</property>
                       </packing>
                     </child>
                   </object>
@@ -197,8 +162,9 @@
                     <child>
                       <object class="GtkLabel" id="page_delay_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside page delay scale">Delay</property>
+                        <property name="label" translatable="yes" comments="Label beside page delay scale">_Delay</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">page_delay_3s_button</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -316,7 +282,8 @@
             <child type="tab">
               <object class="GtkLabel">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes" comments="Preferences Dialog: Tab label for scanning settings">Scanning</property>
+                <property name="label" translatable="yes" comments="Preferences Dialog: Tab label for scanning settings">_Scanning</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="tab_fill">False</property>
@@ -336,8 +303,9 @@
                     <child>
                       <object class="GtkLabel" id="text_dpi_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside scan source combo box">_Text Resolution</property>
+                        <property name="label" translatable="yes" comments="Label beside scan resolution combo box">_Text Resolution</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">text_dpi_combo</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -351,8 +319,9 @@
                     <child>
                       <object class="GtkLabel" id="photo_dpi_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside scan source combo box">_Photo Resolution</property>
+                        <property name="label" translatable="yes" comments="Label beside scan resolution combo box">_Image Resolution</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">photo_dpi_combo</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -395,8 +364,9 @@
                     <child>
                       <object class="GtkLabel" id="brightness_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside brightness scale">Brightness</property>
+                        <property name="label" translatable="yes" comments="Label beside brightness scale">_Brightness</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">brightness_scale</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -410,8 +380,9 @@
                     <child>
                       <object class="GtkLabel" id="contrast_label">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes" comments="Label beside contrast scale">Contrast</property>
+                        <property name="label" translatable="yes" comments="Label beside contrast scale">_Contrast</property>
                         <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">contrast_scale</property>
                         <property name="xalign">1</property>
                         <style>
                           <class name="dim-label"/>
@@ -458,7 +429,8 @@
             <child type="tab">
               <object class="GtkLabel">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes" comments="Preferences Dialog: Tab for quality settings">Quality</property>
+                <property name="label" translatable="yes" comments="Preferences Dialog: Tab for quality settings">_Quality</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="tab_fill">False</property>
@@ -471,7 +443,6 @@
   </template>
   <object class="GtkSizeGroup" id="label_size_group">
     <widgets>
-      <widget name="source_label"/>
       <widget name="page_side_label"/>
       <widget name="paper_size_label"/>
       <widget name="page_delay_label"/>
diff --git a/src/preferences-dialog.vala b/src/preferences-dialog.vala
index 1533541..06dca75 100644
--- a/src/preferences-dialog.vala
+++ b/src/preferences-dialog.vala
@@ -15,11 +15,6 @@ private class PreferencesDialog : Gtk.Dialog
 {
     private Settings settings;
 
-    private bool setting_devices;
-    private bool user_selected_device;
-
-    [GtkChild]
-    private Gtk.ComboBox device_combo;
     [GtkChild]
     private Gtk.ComboBox text_dpi_combo;
     [GtkChild]
@@ -31,8 +26,6 @@ private class PreferencesDialog : Gtk.Dialog
     [GtkChild]
     private Gtk.Scale contrast_scale;
     [GtkChild]
-    private Gtk.ListStore device_model;
-    [GtkChild]
     private Gtk.RadioButton page_delay_3s_button;
     [GtkChild]
     private Gtk.RadioButton page_delay_5s_button;
@@ -85,10 +78,6 @@ private class PreferencesDialog : Gtk.Dialog
         paper_size_model.append (out iter);
         paper_size_model.set (iter, 0, 1016, 1, 1524, 2, "4×6", -1);
 
-        var renderer = new Gtk.CellRendererText ();
-        device_combo.pack_start (renderer, true);
-        device_combo.add_attribute (renderer, "text", 1);
-
         var dpi = settings.get_int ("text-dpi");
         if (dpi <= 0)
             dpi = DEFAULT_TEXT_DPI;
@@ -105,7 +94,7 @@ private class PreferencesDialog : Gtk.Dialog
         back_side_button.toggled.connect ((button) => { if (button.active) settings.set_enum ("page-side", ScanType.ADF_BACK); });
         both_side_button.toggled.connect ((button) => { if (button.active) settings.set_enum ("page-side", ScanType.ADF_BOTH); });
 
-        renderer = new Gtk.CellRendererText ();
+        var renderer = new Gtk.CellRendererText ();
         paper_size_combo.pack_start (renderer, true);
         paper_size_combo.add_attribute (renderer, "text", 2);
 
@@ -148,147 +137,6 @@ private class PreferencesDialog : Gtk.Dialog
         page_delay_15s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 15000); });
     }
 
-    public void set_scan_devices (List<ScanDevice> devices)
-    {
-        setting_devices = true;
-
-        /* If the user hasn't chosen a scanner choose the best available one */
-        var have_selection = false;
-        if (user_selected_device)
-            have_selection = device_combo.active >= 0;
-
-        /* Add new devices */
-        int index = 0;
-        Gtk.TreeIter iter;
-        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);
-#if VALA_0_36
-                    device_model.remove (ref iter);
-#else
-                    device_model.remove (iter);
-#endif
-                }
-            }
-            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))
-#if VALA_0_36
-            device_model.remove (ref iter);
-#else
-            device_model.remove (iter);
-#endif
-
-        /* 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;
-    }
-
-    public string? get_selected_device ()
-    {
-        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;
-    }
-
-    public string? get_selected_device_label ()
-    {
-        Gtk.TreeIter iter;
-
-        if (device_combo.get_active_iter (out iter))
-        {
-            string label;
-            device_model.get (iter, 1, out label, -1);
-            return label;
-        }
-
-        return null;
-    }
-
-    public void set_selected_device (string device)
-    {
-        user_selected_device = true;
-
-        Gtk.TreeIter iter;
-        if (!find_scan_device (device, out iter))
-            return;
-
-        device_combo.set_active_iter (iter);
-    }
-
-    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 set_page_side (ScanType page_side)
     {
         switch (page_side)
@@ -453,79 +301,4 @@ private class PreferencesDialog : Gtk.Dialog
                 combo.set_active_iter (iter);
         }
     }
-
-    [GtkCallback]
-    private void device_combo_changed_cb (Gtk.Widget widget)
-    {
-        if (setting_devices)
-            return;
-        user_selected_device = true;
-        if (get_selected_device () != null)
-            settings.set_string ("selected-device", get_selected_device ());
-    }
-}
-
-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;
-    }
 }
diff --git a/src/sane-backends.vapi b/src/sane-backends.vapi
index f636dac..b32c1a4 100644
--- a/src/sane-backends.vapi
+++ b/src/sane-backends.vapi
@@ -48,7 +48,7 @@ namespace Sane {
         NO_MEM,
         ACCESS_DENIED
     }
-     
+
     public static string status_to_string (Status status)
     {
         switch (status)
@@ -88,7 +88,7 @@ namespace Sane {
         SET_VALUE,
         SET_AUTO
     }
-    
+
     public enum Frame
     {
         GRAY,
@@ -154,7 +154,7 @@ namespace Sane {
         PERCENT,
         MICROSECOND
     }
-    
+
     [CCode (cname = "SANE_Constraint_Type", cprefix = "SANE_CONSTRAINT_")]
     public enum ConstraintType
     {
@@ -163,7 +163,7 @@ namespace Sane {
         WORD_LIST,
         STRING_LIST
     }
-    
+
     public class Range
     {
         public Word min;
@@ -225,7 +225,7 @@ namespace Sane {
     public int VERSION_MINOR (Int code);
     [CCode (cname = "SANE_VERSION_BUILD")]
     public int VERSION_BUILD (Int code);
-    
+
     [CCode (cname = "SANE_FIX")]
     public Fixed FIX (double d);
     [CCode (cname = "SANE_UNFIX")]
diff --git a/src/scanner.vala b/src/scanner.vala
index 8bc587f..caf740b 100644
--- a/src/scanner.vala
+++ b/src/scanner.vala
@@ -385,6 +385,24 @@ public class Scanner : Object
         notify_event (new NotifyUpdateDevices ((owned) devices));
     }
 
+    private double scale_fixed (int source_min, int source_max, Sane.OptionDescriptor option, int value)
+    {
+        var v = (double) value;
+
+        return_val_if_fail (option.type == Sane.ValueType.FIXED, value);
+        if (option.constraint_type == Sane.ConstraintType.RANGE && option.range.max != option.range.min)
+        {
+            v -= (double) source_min;
+            v *= Sane.UNFIX (option.range.max) - Sane.UNFIX (option.range.min);
+            v /= (double) (source_max - source_min);
+            v += Sane.UNFIX (option.range.min);
+            debug ("scale_fixed: scaling %d [min: %d, max: %d] to %f [min: %f, max: %f]",
+                   value, source_min, source_max, v, Sane.UNFIX (option.range.min), Sane.UNFIX (option.range.max));
+        }
+
+        return v;
+    }
+
     private int scale_int (int source_min, int source_max, Sane.OptionDescriptor option, int value)
     {
         var v = value;
@@ -530,7 +548,11 @@ public class Scanner : Object
             return;
 
         var status = Sane.control_option (handle, option_index, Sane.Action.SET_VALUE, &option.range.max, null);
-        debug ("sane_control_option (%d, SANE_ACTION_SET_VALUE, option.range.max) -> (%s)", (int) option_index, Sane.status_to_string (status));
+
+        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));
+        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));
     }
 
     private bool set_string_option (Sane.Handle handle, Sane.OptionDescriptor option, Sane.Int option_index, string value, out string result)
@@ -980,6 +1002,7 @@ public class Scanner : Object
                 {
                     Sane.VALUE_SCAN_MODE_COLOR,
                     "Color",
+                    "24bit Color[Fast]", /* brother4 driver, Brother DCP-1622WE, #134 */
                     "24bit Color", /* Seen in the proprietary brother3 driver */
                     "Color - 16 Million Colors" /* Samsung unified driver. LP: 892915 */
                 };
@@ -1131,8 +1154,18 @@ public class Scanner : Object
             {
                 if (job.brightness != 0)
                 {
-                    var brightness = scale_int (-100, 100, option, job.brightness);
-                    set_int_option (handle, option, index, brightness, null);
+                    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");
                 }
             }
             option = get_option_by_name (handle, Sane.NAME_CONTRAST, out index);
@@ -1140,8 +1173,18 @@ public class Scanner : Object
             {
                 if (job.contrast != 0)
                 {
-                    var contrast = scale_int (-100, 100, option, job.contrast);
-                    set_int_option (handle, option, index, contrast, null);
+                    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");
                 }
             }
 
@@ -1175,10 +1218,6 @@ public class Scanner : Object
         if (option.type == Sane.ValueType.GROUP)
             return;
 
-        /* Option disabled */
-        if ((option.cap & Sane.Capability.INACTIVE) != 0)
-            return;
-
         /* Some options are unnamed (e.g. Option 0) */
         if (option.name == null)
             return;
@@ -1205,7 +1244,18 @@ public class Scanner : Object
         if (index == 0)
             return null;
 
-        return Sane.get_option_descriptor (handle, index);
+        var option_descriptor = Sane.get_option_descriptor (handle, index);
+        /*
+        The Sane.Capability.INACTIVE capability indicates that
+        the option is not currently active (e.g., because it's meaningful
+        only if another option is set to some other value).
+        */
+        if ((option_descriptor.cap & Sane.Capability.INACTIVE) != 0)
+        {
+            warning ("The option %s (%d) is inactive and can't be set, please file a bug", name, index);
+            return null;
+        }
+        return option_descriptor;
     }
 
     private void do_complete_document ()
@@ -1242,7 +1292,13 @@ public class Scanner : Object
         if (status == Sane.Status.GOOD)
             state = ScanState.GET_PARAMETERS;
         else if (status == Sane.Status.NO_DOCS)
+        {
             do_complete_document ();
+            if (page_number == 0)
+                fail_scan (status,
+                    /* Error displayed when no documents at the start of scanning */
+                    _("Document feeder empty"));
+        }
         else
         {
             warning ("Unable to start device: %s", Sane.strstatus (status));
@@ -1576,30 +1632,50 @@ public class Scanner : Object
         }
     }
 
-    private string get_scan_type_string (ScanType type)
+    public static string type_to_string (ScanType type)
     {
         switch (type)
         {
         case ScanType.SINGLE:
-            return "ScanType.SINGLE";
+            return "single";
+        case ScanType.BATCH:
+            return "batch";
         case ScanType.ADF_FRONT:
-            return "ScanType.ADF_FRONT";
+            return "adf-front";
         case ScanType.ADF_BACK:
-            return "ScanType.ADF_BACK";
+            return "adf-back";
         case ScanType.ADF_BOTH:
-            return "ScanType.ADF_BOTH";
-        case ScanType.BATCH:
-            return "ScanType.BATCH";
+            return "adf-both";
         default:
             return "%d".printf (type);
         }
     }
 
+    public static ScanType type_from_string (string type)
+    {
+        switch (type)
+        {
+        case "single":
+            return ScanType.SINGLE;
+        case "batch":
+            return ScanType.BATCH;
+        case "adf-front":
+            return ScanType.ADF_FRONT;
+        case "adf-back":
+            return ScanType.ADF_BACK;
+        case "adf-both":
+            return ScanType.ADF_BOTH;
+        default:
+            warning ("Unknown ScanType: %s. Please report this error.", type);
+            return ScanType.SINGLE;
+        }
+    }
+
     public void scan (string? device, ScanOptions options)
     {
         debug ("Scanner.scan (\"%s\", dpi=%d, scan_mode=%s, depth=%d, type=%s, paper_width=%d, paper_height=%d, brightness=%d, contrast=%d, delay=%dms)",
                device != null ? device : "(null)", options.dpi, get_scan_mode_string (options.scan_mode), options.depth,
-               get_scan_type_string (options.type), options.paper_width, options.paper_height,
+               type_to_string (options.type), options.paper_width, options.paper_height,
                options.brightness, options.contrast, options.page_delay);
         var request = new RequestStartScan ();
         request.job = new ScanJob ();
@@ -1634,7 +1710,7 @@ public class Scanner : Object
             thread.join ();
             thread = null;
         }
-        
+
         Sane.exit ();
         debug ("sane_exit ()");
     }
diff --git a/src/simple-scan.vala b/src/simple-scan.vala
index 6175a8e..f41ba93 100644
--- a/src/simple-scan.vala
+++ b/src/simple-scan.vala
@@ -83,7 +83,7 @@ public class SimpleScan : Gtk.Application
 
             device_list.append (default_device);
             app.set_scan_devices (device_list);
-            app.selected_device = default_device.name;
+            app.set_selected_device (default_device.name);
         }
     }
 
@@ -133,7 +133,7 @@ public class SimpleScan : Gtk.Application
 
         app.set_scan_devices (devices_copy, missing_driver);
     }
-    
+
     /* Taken from /usr/local/Brother/sane/Brsane.ini from brscan driver */
     private const uint32 brscan_devices[] = { 0x04f90110, 0x04f90111, 0x04f90112, 0x04f9011d, 0x04f9011e, 0x04f9011f, 0x04f9012b, 0x04f90124, 0x04f90153, 0x04f90125, 0x04f90113, 0x04f90114, 0x04f90115, 0x04f90116, 0x04f90119, 0x04f9011a, 0x04f9011b, 0x04f9011c, 0x04f9012e, 0x04f9012f, 0x04f90130, 0x04f90128, 0x04f90127, 0x04f90142, 0x04f90143, 0x04f90140, 0x04f90141, 0x04f9014e, 0x04f9014f, 0x04f90150, 0x04f90151, 0x04f9010e, 0x04f9013a, 0x04f90120, 0x04f9010f, 0x04f90121, 0x04f90122, 0x04f90132, 0x04f9013d, 0x04f9013c, 0x04f90136, 0x04f90135, 0x04f9013e, 0x04f9013f, 0x04f90144, 0x04f90146, 0x04f90148, 0x04f9014a, 0x04f9014b, 0x04f9014c, 0x04f90157, 0x04f90158, 0x04f9015d, 0x04f9015e, 0x04f9015f, 0x04f90160 };
 
@@ -144,7 +144,7 @@ public class SimpleScan : Gtk.Application
     private const uint32 brscan3_devices[] = { 0x04f90222, 0x04f90223, 0x04f90224, 0x04f90225, 0x04f90229, 0x04f9022a, 0x04f9022c, 0x04f90228, 0x04f90236, 0x04f90227, 0x04f9022b, 0x04f9022d, 0x04f9022e, 0x04f9022f, 0x04f90230, 0x04f9021b, 0x04f9021a, 0x04f90219, 0x04f9023f, 0x04f90216, 0x04f9021d, 0x04f9021c, 0x04f90220, 0x04f9021e, 0x04f9023e, 0x04f90235, 0x04f9023a, 0x04f901c9, 0x04f901ca, 0x04f901cb, 0x04f901cc, 0x04f901ec, 0x04f9020d, 0x04f9020c, 0x04f90257, 0x04f9025d, 0x04f90254, 0x04f9025b, 0x04f9026b, 0x04f90258, 0x04f9025e, 0x04f90256, 0x04f90240, 0x04f9025f, 0x04f90260, 0x04f90261, 0x04f90278, 0x04f9026f, 0x04f9026e, 0x04f9026d, 0x04f90234, 0x04f90239, 0x04f90253, 0x04f90255, 0x04f90259, 0x04f9025a, 0x04f9025c, 0x04f90276 };
 
     /* Taken from /opt/brother/scanner/brscan4/models4/*.ini from brscan4 driver */
-    private const uint32 brscan4_devices[] = { 0x04f90314, 0x04f90313, 0x04f90312, 0x04f90311, 0x04f90310, 0x04f9030f, 0x04f90366, 0x04f90365, 0x04f90364, 0x04f90350, 0x04f9034f, 0x04f9034e, 0x04f9034b, 0x04f90349, 0x04f90347, 0x04f90346, 0x04f90343, 0x04f90342, 0x04f90341, 0x04f90340, 0x04f9033d, 0x04f9033c, 0x04f9033a, 0x04f90339, 0x04f90392, 0x04f90373, 0x04f9036e, 0x04f9036d, 0x04f9036c, 0x04f9036b, 0x04f9036a, 0x04f90369, 0x04f90368, 0x04f90367, 0x04f90338, 0x04f90337, 0x04f90335, 0x04f90331, 0x04f90330, 0x04f90329, 0x04f90328, 0x04f90326, 0x04f90324, 0x04f90322, 0x04f90321, 0x04f90320, 0x04f90372, 0x04f90371, 0x04f90370, 0x04f9036f, 0x04f90361, 0x04f90360, 0x04f9035e, 0x04f9035d, 0x04f9035c, 0x04f9035b, 0x04f90379, 0x04f90378, 0x04f90376, 0x04f9037a, 0x04f9037b, 0x04f90377, 0x04f9037f, 0x04f9037e, 0x04f9037d, 0x04f9037c, 0x04f9035a, 0x04f90359, 0x04f90358, 0x04f90357, 0x04f90356, 0x04f90355, 0x04f90354, 0x04f90353, 0x04f90351, 0x04f90390, 0x04f903b3, 0x04f90396, 0x04f90395, 0x04f90394, 0x04f90393, 0x04f90380, 0x04f90381, 0x04f903bd, 0x04f90383, 0x04f90397, 0x04f90386, 0x04f90384, 0x04f90385, 0x04f90388, 0x04f90389, 0x04f9038b, 0x04f9038a, 0x04f9038c, 0x04f9038e, 0x04f9038f, 0x04f9038d, 0x04f903bc, 0x04f903bb, 0x04f903b6, 0x04f903b5, 0x04f903b4, 0x04f90290, 0x04f9028f, 0x04f9028d, 0x04f9028a, 0x04f90284, 0x04f90283, 0x04f90282, 0x04f90281, 0x04f9027e, 0x04f9027d, 0x04f9027c, 0x04f9027b, 0x04f90280, 0x04f9027a, 0x04f90279, 0x04f9027f, 0x04f90285, 0x04f9029a, 0x04f9029f, 0x04f9029e, 0x04f90289, 0x04f90288, 0x04f960a0, 0x04f960a1, 0x04f90293, 0x04f902b7, 0x04f90294, 0x04f90296, 0x04f90298, 0x04f902ba, 0x04f90299, 0x04f902bb, 0x04f902d4, 0x04f90291, 0x04f902ac, 0x04f902b5, 0x04f90292, 0x04f902b6, 0x04f90295, 0x04f902b8, 0x04f9029c, 0x04f902cb, 0x04f902ca, 0x04f902a6, 0x04f902a7, 0x04f902ab, 0x04f902a5, 0x04f902a8, 0x04f902a0, 0x04f902c1, 0x04f902c0, 0x04f902bf, 0x04f902be, 0x04f902bd, 0x04f902bc, 0x04f902b2, 0x04f90287, 0x04f902cf, 0x04f902ce, 0x04f902cd, 0x04f902c7, 0x04f902c6, 0x04f902c5, 0x04f902c4, 0x04f902b4, 0x04f902b3, 0x04f902c2, 0x04f960a4, 0x04f960a5, 0x04f902cc, 0x04f902c8, 0x04f902c3, 0x04f902d3, 0x04f902b1, 0x04f902b0, 0x04f902af, 0x04f902ae, 0x04f902ad, 0x04f902d1, 0x04f902d0, 0x04f902fb, 0x04f902f1, 0x04f902f0, 0x04f902ef, 0x04f902ed, 0x04f902ec, 0x04f902ee, 0x04f902eb, 0x04f902e9, 0x04f902e8, 0x04f902fa, 0x04f902ea, 0x04f902e6, 0x04f902e5, 0x04f902e4, 0x04f902e3, 0x04f902e2, 0x04f902f9, 0x04f902de, 0x04f902e0, 0x04f902df, 0x04f902e1, 0x04f902e7, 0x04f902fc, 0x04f902fd, 0x04f902fe, 0x04f902dd, 0x04f902c9, 0x04f902ff, 0x04f90300, 0x04f902f2, 0x04f902f3, 0x04f902f4, 0x04f902f8, 0x04f902f5, 0x04f902f6, 0x04f902f7, 0x04f90318, 0x04f960a6, 0x04f960a7, 0x04f960a8, 0x04f960a9 }; 
+    private const uint32 brscan4_devices[] = { 0x04f90314, 0x04f90313, 0x04f90312, 0x04f90311, 0x04f90310, 0x04f9030f, 0x04f90366, 0x04f90365, 0x04f90364, 0x04f90350, 0x04f9034f, 0x04f9034e, 0x04f9034b, 0x04f90349, 0x04f90347, 0x04f90346, 0x04f90343, 0x04f90342, 0x04f90341, 0x04f90340, 0x04f9033d, 0x04f9033c, 0x04f9033a, 0x04f90339, 0x04f90392, 0x04f90373, 0x04f9036e, 0x04f9036d, 0x04f9036c, 0x04f9036b, 0x04f9036a, 0x04f90369, 0x04f90368, 0x04f90367, 0x04f90338, 0x04f90337, 0x04f90335, 0x04f90331, 0x04f90330, 0x04f90329, 0x04f90328, 0x04f90326, 0x04f90324, 0x04f90322, 0x04f90321, 0x04f90320, 0x04f90372, 0x04f90371, 0x04f90370, 0x04f9036f, 0x04f90361, 0x04f90360, 0x04f9035e, 0x04f9035d, 0x04f9035c, 0x04f9035b, 0x04f90379, 0x04f90378, 0x04f90376, 0x04f9037a, 0x04f9037b, 0x04f90377, 0x04f9037f, 0x04f9037e, 0x04f9037d, 0x04f9037c, 0x04f9035a, 0x04f90359, 0x04f90358, 0x04f90357, 0x04f90356, 0x04f90355, 0x04f90354, 0x04f90353, 0x04f90351, 0x04f90390, 0x04f903b3, 0x04f90396, 0x04f90395, 0x04f90394, 0x04f90393, 0x04f90380, 0x04f90381, 0x04f903bd, 0x04f90383, 0x04f90397, 0x04f90386, 0x04f90384, 0x04f90385, 0x04f90388, 0x04f90389, 0x04f9038b, 0x04f9038a, 0x04f9038c, 0x04f9038e, 0x04f9038f, 0x04f9038d, 0x04f903bc, 0x04f903bb, 0x04f903b6, 0x04f903b5, 0x04f903b4, 0x04f90290, 0x04f9028f, 0x04f9028d, 0x04f9028a, 0x04f90284, 0x04f90283, 0x04f90282, 0x04f90281, 0x04f9027e, 0x04f9027d, 0x04f9027c, 0x04f9027b, 0x04f90280, 0x04f9027a, 0x04f90279, 0x04f9027f, 0x04f90285, 0x04f9029a, 0x04f9029f, 0x04f9029e, 0x04f90289, 0x04f90288, 0x04f960a0, 0x04f960a1, 0x04f90293, 0x04f902b7, 0x04f90294, 0x04f90296, 0x04f90298, 0x04f902ba, 0x04f90299, 0x04f902bb, 0x04f902d4, 0x04f90291, 0x04f902ac, 0x04f902b5, 0x04f90292, 0x04f902b6, 0x04f90295, 0x04f902b8, 0x04f9029c, 0x04f902cb, 0x04f902ca, 0x04f902a6, 0x04f902a7, 0x04f902ab, 0x04f902a5, 0x04f902a8, 0x04f902a0, 0x04f902c1, 0x04f902c0, 0x04f902bf, 0x04f902be, 0x04f902bd, 0x04f902bc, 0x04f902b2, 0x04f90287, 0x04f902cf, 0x04f902ce, 0x04f902cd, 0x04f902c7, 0x04f902c6, 0x04f902c5, 0x04f902c4, 0x04f902b4, 0x04f902b3, 0x04f902c2, 0x04f960a4, 0x04f960a5, 0x04f902cc, 0x04f902c8, 0x04f902c3, 0x04f902d3, 0x04f902b1, 0x04f902b0, 0x04f902af, 0x04f902ae, 0x04f902ad, 0x04f902d1, 0x04f902d0, 0x04f902fb, 0x04f902f1, 0x04f902f0, 0x04f902ef, 0x04f902ed, 0x04f902ec, 0x04f902ee, 0x04f902eb, 0x04f902e9, 0x04f902e8, 0x04f902fa, 0x04f902ea, 0x04f902e6, 0x04f902e5, 0x04f902e4, 0x04f902e3, 0x04f902e2, 0x04f902f9, 0x04f902de, 0x04f902e0, 0x04f902df, 0x04f902e1, 0x04f902e7, 0x04f902fc, 0x04f902fd, 0x04f902fe, 0x04f902dd, 0x04f902c9, 0x04f902ff, 0x04f90300, 0x04f902f2, 0x04f902f3, 0x04f902f4, 0x04f902f8, 0x04f902f5, 0x04f902f6, 0x04f902f7, 0x04f90318, 0x04f960a6, 0x04f960a7, 0x04f960a8, 0x04f960a9 };
 
     /* 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, 0x04e83446, 0x04e8341a, 0x04e83437, 0x04e83442, 0x04e83466, 0x04e8340d, 0x04e8341d, 0x04e83420, 0x04e83429, 0x04e83443, 0x04e83438, 0x04e8344c, 0x04e8345d, 0x04e83463, 0x04e83465, 0x04e83450, 0x04e83468, 0x04e83469, 0x04e83471 };
@@ -156,7 +156,7 @@ public class SimpleScan : Gtk.Application
     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 };
 
     /* Brother IDs extracted using the following Python
-     * import sys   
+     * import sys
      * ids = []
      * for f in sys.argv:
      *   for l in file (f).readlines ():
@@ -194,7 +194,7 @@ public class SimpleScan : Gtk.Application
         add_devices (driver_map, brscan4_devices, "brscan4");
         add_devices (driver_map, samsung_devices, "samsung");
         add_devices (driver_map, hpaio_devices, "hpaio");
-        add_devices (driver_map, epkowa_devices, "epkowa");        
+        add_devices (driver_map, epkowa_devices, "epkowa");
         var devices = usb_context.get_devices ();
         for (var i = 0; i < devices.length; i++)
         {
@@ -211,7 +211,7 @@ public class SimpleScan : Gtk.Application
     {
         for (var i = 0; i < devices.length; i++)
             map.insert (devices[i], driver);
-    }   
+    }
 
     private void authorize_cb (Scanner scanner, string resource)
     {
-- 
cgit v1.2.3