summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2020-03-22 17:05:56 +0100
committerJörg Frings-Fürst <debian@jff.email>2020-03-22 17:05:56 +0100
commit8eb2b297d6e03975afc17e1d468aa8913639e1a9 (patch)
tree21d1aaab420f11d16e64dd776c30614fffabd3de /src
parentcf2cbd3850aa6913cb47226bbe95c3bdaf369dec (diff)
New upstream version 3.36.0upstream/3.36.0
Diffstat (limited to 'src')
-rw-r--r--src/app-window.ui697
-rw-r--r--src/app-window.vala257
-rw-r--r--src/autosave-manager.vala8
-rw-r--r--src/book-view.vala2
-rw-r--r--src/help-overlay.ui27
-rw-r--r--src/meson.build1
-rw-r--r--src/page-icon.vala76
-rw-r--r--src/page-view.vala35
-rw-r--r--src/page.vala4
-rw-r--r--src/preferences-dialog.ui73
-rw-r--r--src/preferences-dialog.vala229
-rw-r--r--src/sane-backends.vapi10
-rw-r--r--src/scanner.vala114
-rw-r--r--src/simple-scan.vala12
14 files changed, 974 insertions, 571 deletions
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 ();
@@ -781,8 +940,20 @@ public class AppWindow : Gtk.ApplicationWindow
}
[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 -->
@@ -75,39 +67,11 @@
<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)
{