diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2020-04-13 15:51:22 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2020-04-13 15:51:22 +0200 |
commit | 8067958728bf3ebc9784bfb1d9fd842946e95824 (patch) | |
tree | 13cdebf6c35e4d596145af2ed959761e6f110ebc /src | |
parent | f359f4dcae47a69031b5ae719131c980f9160e47 (diff) | |
parent | 81b704e9e098c84fc79243e383e8633c45d02b94 (diff) |
Merge branch 'release/debian/3.36.1-1'debian/3.36.1-1
Diffstat (limited to 'src')
-rw-r--r-- | src/app-window.ui | 697 | ||||
-rw-r--r-- | src/app-window.vala | 313 | ||||
-rw-r--r-- | src/autosave-manager.vala | 8 | ||||
-rw-r--r-- | src/book-view.vala | 2 | ||||
-rw-r--r-- | src/help-overlay.ui | 27 | ||||
-rw-r--r-- | src/meson.build | 1 | ||||
-rw-r--r-- | src/page-icon.vala | 76 | ||||
-rw-r--r-- | src/page-view.vala | 35 | ||||
-rw-r--r-- | src/page.vala | 4 | ||||
-rw-r--r-- | src/preferences-dialog.ui | 73 | ||||
-rw-r--r-- | src/preferences-dialog.vala | 229 | ||||
-rw-r--r-- | src/sane-backends.vapi | 10 | ||||
-rw-r--r-- | src/scanner.vala | 130 | ||||
-rw-r--r-- | src/simple-scan.vala | 12 |
14 files changed, 1023 insertions, 594 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 7901cd7..6f2d353 100644 --- a/src/app-window.vala +++ b/src/app-window.vala @@ -23,6 +23,12 @@ public class AppWindow : Gtk.ApplicationWindow { "scan_adf", scan_adf_cb }, { "scan_batch", scan_batch_cb }, { "scan_stop", scan_stop_cb }, + { "rotate_left", rotate_left_cb }, + { "rotate_right", rotate_right_cb }, + { "move_left", move_left_cb }, + { "move_right", move_right_cb }, + { "copy_page", copy_page_cb }, + { "delete_page", delete_page_cb }, { "reorder", reorder_document_cb }, { "save", save_document_activate_cb }, { "email", email_document_cb }, @@ -38,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] @@ -47,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; @@ -92,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; @@ -171,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 (); @@ -184,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); @@ -193,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 () @@ -249,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) { @@ -264,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 { @@ -272,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; } } @@ -279,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 */ @@ -537,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, @@ -618,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 () @@ -648,6 +805,36 @@ public class AppWindow : Gtk.ApplicationWindow stop_scan (); } + private void rotate_left_cb () + { + rotate_left_button_clicked_cb (); + } + + private void rotate_right_cb () + { + rotate_right_button_clicked_cb (); + } + + private void move_left_cb () + { + page_move_left_menuitem_activate_cb (); + } + + private void move_right_cb () + { + page_move_right_menuitem_activate_cb (); + } + + private void copy_page_cb () + { + copy_to_clipboard_button_clicked_cb (); + } + + private void delete_page_cb () + { + page_delete_menuitem_activate_cb (); + } + private void set_scan_type (ScanType scan_type) { this.scan_type = scan_type; @@ -697,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) @@ -721,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 (); @@ -745,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) @@ -757,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 (); } @@ -856,7 +1065,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void rotate_left_button_clicked_cb (Gtk.Widget widget) + private void rotate_left_button_clicked_cb () { if (updating_page_menu) return; @@ -866,7 +1075,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void rotate_right_button_clicked_cb (Gtk.Widget widget) + private void rotate_right_button_clicked_cb () { if (updating_page_menu) return; @@ -968,7 +1177,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void crop_rotate_menuitem_activate_cb (Gtk.Widget widget) + private void crop_rotate_menuitem_activate_cb () { var page = book_view.selected_page; if (page == null) @@ -977,7 +1186,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void page_move_left_menuitem_activate_cb (Gtk.Widget widget) + private void page_move_left_menuitem_activate_cb () { var page = book_view.selected_page; var index = book.get_page_index (page); @@ -986,7 +1195,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void page_move_right_menuitem_activate_cb (Gtk.Widget widget) + private void page_move_right_menuitem_activate_cb () { var page = book_view.selected_page; var index = book.get_page_index (page); @@ -995,7 +1204,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void page_delete_menuitem_activate_cb (Gtk.Widget widget) + private void page_delete_menuitem_activate_cb () { book_view.book.delete_page (book_view.selected_page); } @@ -1179,7 +1388,7 @@ public class AppWindow : Gtk.ApplicationWindow } [GtkCallback] - private void copy_to_clipboard_button_clicked_cb (Gtk.Widget widget) + private void copy_to_clipboard_button_clicked_cb () { var page = book_view.selected_page; if (page != null) @@ -1562,20 +1771,28 @@ public class AppWindow : Gtk.ApplicationWindow app.set_accels_for_action ("app.scan_adf", { "<Ctrl>F" }); app.set_accels_for_action ("app.scan_batch", { "<Ctrl>M" }); app.set_accels_for_action ("app.scan_stop", { "Escape" }); + app.set_accels_for_action ("app.rotate_left", { "bracketleft" }); + app.set_accels_for_action ("app.rotate_right", { "bracketright" }); + app.set_accels_for_action ("app.move_left", { "less" }); + app.set_accels_for_action ("app.move_right", { "greater" }); + app.set_accels_for_action ("app.copy_page", { "<Ctrl>C" }); + app.set_accels_for_action ("app.delete_page", { "Delete" }); app.set_accels_for_action ("app.save", { "<Ctrl>S" }); app.set_accels_for_action ("app.email", { "<Ctrl>E" }); 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"); @@ -1708,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) @@ -1756,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 ()); @@ -1769,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"><ctrl>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"><ctrl>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..fbcc6c6 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 */ }; @@ -1071,22 +1094,6 @@ public class Scanner : Object set_bool_option (handle, option, index, (job.type != ScanType.SINGLE) && (job.type != ScanType.BATCH), null); } - /* Disable compression, we will compress after scanning */ - option = get_option_by_name (handle, "compression", out index); - if (option != null) - { - string[] disable_compression_names = - { - Sane.I18N ("None"), - Sane.I18N ("none"), - "None", - "none" - }; - - if (!set_constrained_string_option (handle, option, index, disable_compression_names, null)) - warning ("Unable to disable compression, please file a bug"); - } - /* Set resolution and bit depth */ option = get_option_by_name (handle, Sane.NAME_SCAN_RESOLUTION, out index); if (option != null) @@ -1131,8 +1138,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 +1157,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 +1202,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 +1228,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 +1276,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 +1616,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 +1694,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) { |