summaryrefslogtreecommitdiff
path: root/src/ui.c
diff options
context:
space:
mode:
authorAlessio Treglia <alessio@debian.org>2010-07-12 19:34:33 +0200
committerAlessio Treglia <alessio@debian.org>2010-07-12 19:34:33 +0200
commit88ed5294e45c9a82b309c08aa5533388d90b1a1f (patch)
tree0f7ecf0420c14bed82d615e98005327e8e613fe8 /src/ui.c
parent046e95e38e048f663efbf421894f3f84a212525b (diff)
parentc15dc3b14e35850849f3559ac0305b4cac4a7046 (diff)
Merge commit 'upstream/2.31.5.bzr424'
Diffstat (limited to 'src/ui.c')
-rw-r--r--src/ui.c632
1 files changed, 423 insertions, 209 deletions
diff --git a/src/ui.c b/src/ui.c
index d67ee5e..0d23d25 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -28,7 +28,6 @@
enum {
START_SCAN,
STOP_SCAN,
- SAVE,
EMAIL,
QUIT,
LAST_SIGNAL
@@ -43,7 +42,10 @@ struct SimpleScanPrivate
GtkBuilder *builder;
GtkWidget *window, *main_vbox;
+ GtkWidget *info_bar, *info_bar_image, *info_bar_label;
+ GtkWidget *info_bar_close_button, *info_bar_change_scanner_button;
GtkWidget *page_delete_menuitem, *crop_rotate_menuitem;
+ GtkWidget *save_menuitem, *save_as_menuitem, *save_toolbutton;
GtkWidget *stop_menuitem, *stop_toolbutton;
GtkWidget *text_toolbar_menuitem, *text_menu_menuitem;
@@ -58,14 +60,18 @@ struct SimpleScanPrivate
GtkTreeModel *device_model, *text_dpi_model, *photo_dpi_model, *page_side_model, *paper_size_model;
gboolean setting_devices, user_selected_device;
+ gboolean have_error;
+ gchar *error_title, *error_text;
+ gboolean error_change_scanner_hint;
+
Book *book;
+ gchar *book_uri;
+
BookView *book_view;
gboolean updating_page_menu;
gint default_page_width, default_page_height, default_page_dpi;
Orientation default_page_orientation;
- gboolean have_device_list;
-
gchar *document_hint;
gchar *default_file_name;
@@ -110,6 +116,22 @@ find_scan_device (SimpleScan *ui, const char *device, GtkTreeIter *iter)
}
+static void
+show_error_dialog (SimpleScan *ui, const char *error_title, const char *error_text)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "%s", error_title);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error_text);
+ gtk_widget_destroy (dialog);
+}
+
+
void
ui_set_default_file_name (SimpleScan *ui, const gchar *default_file_name)
{
@@ -154,6 +176,47 @@ device_combo_changed_cb (GtkWidget *widget, SimpleScan *ui)
}
+static void
+update_info_bar (SimpleScan *ui)
+{
+ GtkMessageType type;
+ const gchar *title, *text, *image_id;
+ gchar *message;
+ gboolean show_close_button = FALSE;
+ gboolean show_change_scanner_button = FALSE;
+
+ if (ui->priv->have_error) {
+ type = GTK_MESSAGE_ERROR;
+ image_id = GTK_STOCK_DIALOG_ERROR;
+ title = ui->priv->error_title;
+ text = ui->priv->error_text;
+ show_close_button = TRUE;
+ show_change_scanner_button = ui->priv->error_change_scanner_hint;
+ }
+ else if (gtk_tree_model_iter_n_children (ui->priv->device_model, NULL) == 0) {
+ type = GTK_MESSAGE_WARNING;
+ image_id = GTK_STOCK_DIALOG_WARNING;
+ /* Warning displayed when no scanners are detected */
+ title = _("No scanners detected");
+ /* Hint to user on why there are no scanners detected */
+ text = _("Please check your scanner is connected and powered on");
+ }
+ else {
+ gtk_widget_hide (ui->priv->info_bar);
+ return;
+ }
+
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (ui->priv->info_bar), type);
+ gtk_image_set_from_stock (GTK_IMAGE (ui->priv->info_bar_image), image_id, GTK_ICON_SIZE_DIALOG);
+ message = g_strdup_printf ("<big><b>%s</b></big>\n\n%s", title, text);
+ gtk_label_set_markup (GTK_LABEL (ui->priv->info_bar_label), message);
+ g_free (message);
+ gtk_widget_set_visible (ui->priv->info_bar_close_button, show_close_button);
+ gtk_widget_set_visible (ui->priv->info_bar_change_scanner_button, show_change_scanner_button);
+ gtk_widget_show (ui->priv->info_bar);
+}
+
+
void
ui_set_scan_devices (SimpleScan *ui, GList *devices)
{
@@ -222,18 +285,7 @@ ui_set_scan_devices (SimpleScan *ui, GList *devices)
ui->priv->setting_devices = FALSE;
- if (!ui->priv->have_device_list) {
- ui->priv->have_device_list = TRUE;
-
- if (!devices) {
- ui_show_error (ui,
- /* Warning displayed when no scanners are detected */
- _("No scanners detected"),
- /* Hint to user on why there are no scanners detected */
- _("Please check your scanner is connected and powered on"),
- FALSE);
- }
- }
+ update_info_bar (ui);
}
@@ -279,13 +331,272 @@ add_default_page (SimpleScan *ui)
}
+static void
+on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *path, *filename, *extension, *new_filename;
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, 1, &extension, -1);
+ path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ filename = g_path_get_basename (path);
+
+ /* Replace extension */
+ if (g_strrstr (filename, "."))
+ new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension);
+ else
+ new_filename = g_strdup_printf ("%s%s", filename, extension);
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename);
+
+ g_free (path);
+ g_free (filename);
+ g_free (new_filename);
+ g_free (extension);
+}
+
+
+static gchar *
+choose_file_location (SimpleScan *ui)
+{
+ GtkWidget *dialog;
+ gint response;
+ GtkFileFilter *filter;
+ GtkWidget *expander, *file_type_view;
+ GtkListStore *file_type_store;
+ GtkTreeIter iter;
+ GtkTreeViewColumn *column;
+ const gchar *extension;
+ gchar *directory, *uri = NULL;
+ gint i;
+
+ struct
+ {
+ gchar *label, *extension;
+ } file_types[] =
+ {
+ /* Save dialog: Label for saving in PDF format */
+ { _("PDF (multi-page document)"), ".pdf" },
+ /* Save dialog: Label for saving in JPEG format */
+ { _("JPEG (compressed)"), ".jpg" },
+ /* Save dialog: Label for saving in PNG format */
+ { _("PNG (lossless)"), ".png" },
+ { NULL, NULL }
+ };
+
+ /* Get directory to save to */
+ directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL);
+ if (!directory || directory[0] == '\0') {
+ g_free (directory);
+ directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
+ }
+
+ dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */
+ _("Save As..."),
+ GTK_WINDOW (ui->priv->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory);
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name);
+ g_free (directory);
+
+ /* Filter to only show images by default */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter,
+ /* Save dialog: Filter name to show only image files */
+ _("Image Files"));
+ gtk_file_filter_add_pixbuf_formats (filter);
+ gtk_file_filter_add_mime_type (filter, "application/pdf");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter,
+ /* Save dialog: Filter name to show all files */
+ _("All Files"));
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ expander = gtk_expander_new_with_mnemonic (/* */
+ _("Select File _Type"));
+ gtk_expander_set_spacing (GTK_EXPANDER (expander), 5);
+ gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander);
+
+ extension = strstr (ui->priv->default_file_name, ".");
+ if (!extension)
+ extension = "";
+
+ file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ for (i = 0; file_types[i].label; i++) {
+ gtk_list_store_append (file_type_store, &iter);
+ gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1);
+ }
+
+ file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE);
+ column = gtk_tree_view_column_new_with_attributes ("",
+ gtk_cell_renderer_text_new (),
+ "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column);
+ gtk_container_add (GTK_CONTAINER (expander), file_type_view);
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) {
+ do {
+ gchar *e;
+ gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1);
+ if (strcmp (extension, e) == 0)
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter);
+ g_free (e);
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter));
+ }
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)),
+ "changed",
+ G_CALLBACK (on_file_type_changed),
+ dialog);
+
+ gtk_widget_show_all (expander);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+
+ gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory",
+ gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)),
+ NULL);
+
+ gtk_widget_destroy (dialog);
+
+ return uri;
+}
+
+
+static gboolean
+save_document (SimpleScan *ui, gboolean force_choose_location)
+{
+ gboolean result;
+ gchar *uri, *uri_lower;
+ GError *error = NULL;
+ GFile *file;
+
+ if (ui->priv->book_uri && !force_choose_location)
+ uri = g_strdup (ui->priv->book_uri);
+ else
+ uri = choose_file_location (ui);
+ if (!uri)
+ return FALSE;
+
+ file = g_file_new_for_uri (uri);
+
+ g_debug ("Saving to '%s'", uri);
+
+ uri_lower = g_utf8_strdown (uri, -1);
+ if (g_str_has_suffix (uri_lower, ".pdf"))
+ result = book_save (ui->priv->book, "pdf", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".ps"))
+ result = book_save (ui->priv->book, "ps", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".png"))
+ result = book_save (ui->priv->book, "png", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".tif") || g_str_has_suffix (uri_lower, ".tiff"))
+ result = book_save (ui->priv->book, "tiff", file, &error);
+ else
+ result = book_save (ui->priv->book, "jpeg", file, &error);
+
+ g_free (uri_lower);
+
+ if (result) {
+ g_free (ui->priv->book_uri);
+ ui->priv->book_uri = uri;
+ book_set_needs_saving (ui->priv->book, FALSE);
+ }
+ else {
+ g_free (uri);
+
+ g_warning ("Error saving file: %s", error->message);
+ ui_show_error (ui,
+ /* Title of error dialog when save failed */
+ _("Failed to save file"),
+ error->message,
+ FALSE);
+ g_clear_error (&error);
+ }
+
+ g_object_unref (file);
+
+ return result;
+}
+
+
+static gboolean
+prompt_to_save (SimpleScan *ui, const gchar *title, const gchar *discard_label)
+{
+ GtkWidget *dialog;
+ gint response;
+
+ if (!book_get_needs_saving (ui->priv->book))
+ return TRUE;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "%s", title);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
+ /* Text in dialog warning when a document is about to be lost*/
+ _("If you don't save, changes will be permanently lost."));
+ gtk_dialog_add_button (GTK_DIALOG (dialog), discard_label, GTK_RESPONSE_NO);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_SAVE, GTK_RESPONSE_YES);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ switch (response) {
+ case GTK_RESPONSE_YES:
+ if (save_document (ui, FALSE))
+ return TRUE;
+ else
+ return FALSE;
+ case GTK_RESPONSE_CANCEL:
+ return FALSE;
+ case GTK_RESPONSE_NO:
+ default:
+ return TRUE;
+ }
+}
+
+
+static void
+clear_document (SimpleScan *ui)
+{
+ book_clear (ui->priv->book);
+ add_default_page (ui);
+ g_free (ui->priv->book_uri);
+ ui->priv->book_uri = NULL;
+ book_set_needs_saving (ui->priv->book, FALSE);
+ gtk_widget_set_sensitive (ui->priv->save_as_menuitem, FALSE);
+}
+
+
void new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
G_MODULE_EXPORT
void
new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
{
- book_clear (ui->priv->book);
- add_default_page (ui);
+ if (!prompt_to_save (ui,
+ /* Text in dialog warning when a document is about to be lost */
+ _("Save current document?"),
+ /* Button in dialog to create new document and discard unsaved document */
+ _("Discard Changes")))
+ return;
+
+ clear_document (ui);
}
@@ -633,11 +944,10 @@ show_page_cb (BookView *view, Page *page, SimpleScan *ui)
g_object_unref (file);
if (error) {
- ui_show_error (ui,
- /* Error message display when unable to preview image */
- _("Unable to open image preview application"),
- error->message,
- FALSE);
+ show_error_dialog (ui,
+ /* Error message display when unable to preview image */
+ _("Unable to open image preview application"),
+ error->message);
g_clear_error (&error);
}
}
@@ -835,154 +1145,21 @@ page_delete_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
}
-static void
-on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *path, *filename, *extension, *new_filename;
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, 1, &extension, -1);
- path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- filename = g_path_get_basename (path);
-
- /* Replace extension */
- if (g_strrstr (filename, "."))
- new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension);
- else
- new_filename = g_strdup_printf ("%s%s", filename, extension);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename);
-
- g_free (path);
- g_free (filename);
- g_free (new_filename);
- g_free (extension);
-}
-
-
void save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
G_MODULE_EXPORT
void
save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
{
- GtkWidget *dialog;
- gint response;
- GtkFileFilter *filter;
- GtkWidget *expander, *file_type_view;
- GtkListStore *file_type_store;
- GtkTreeIter iter;
- GtkTreeViewColumn *column;
- const gchar *extension;
- gchar *directory;
- gint i;
-
- struct
- {
- gchar *label, *extension;
- } file_types[] =
- {
- /* Save dialog: Label for saving in PDF format */
- { _("PDF (multi-page document)"), ".pdf" },
- /* Save dialog: Label for saving in JPEG format */
- { _("JPEG (compressed)"), ".jpg" },
- /* Save dialog: Label for saving in PNG format */
- { _("PNG (lossless)"), ".png" },
- { NULL, NULL }
- };
-
- /* Get directory to save to */
- directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL);
- if (!directory || directory[0] == '\0') {
- g_free (directory);
- directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
- }
-
- dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */
- _("Save As..."),
- GTK_WINDOW (ui->priv->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name);
- g_free (directory);
-
- /* Filter to only show images by default */
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter,
- /* Save dialog: Filter name to show only image files */
- _("Image Files"));
- gtk_file_filter_add_pixbuf_formats (filter);
- gtk_file_filter_add_mime_type (filter, "application/pdf");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter,
- /* Save dialog: Filter name to show all files */
- _("All Files"));
- gtk_file_filter_add_pattern (filter, "*");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-
- expander = gtk_expander_new_with_mnemonic (/* */
- _("Select File _Type"));
- gtk_expander_set_spacing (GTK_EXPANDER (expander), 5);
- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander);
-
- extension = strstr (ui->priv->default_file_name, ".");
- if (!extension)
- extension = "";
-
- file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- for (i = 0; file_types[i].label; i++) {
- gtk_list_store_append (file_type_store, &iter);
- gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1);
- }
-
- file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store));
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE);
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE);
- column = gtk_tree_view_column_new_with_attributes ("",
- gtk_cell_renderer_text_new (),
- "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column);
- gtk_container_add (GTK_CONTAINER (expander), file_type_view);
-
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) {
- do {
- gchar *e;
- gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1);
- if (strcmp (extension, e) == 0)
- gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter);
- g_free (e);
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter));
- }
- g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)),
- "changed",
- G_CALLBACK (on_file_type_changed),
- dialog);
-
- gtk_widget_show_all (expander);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- if (response == GTK_RESPONSE_ACCEPT) {
- gchar *uri;
-
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
- g_signal_emit (G_OBJECT (ui), signals[SAVE], 0, uri);
+ save_document (ui, FALSE);
+}
- g_free (uri);
- }
- gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory",
- gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)),
- NULL);
-
- gtk_widget_destroy (dialog);
+void save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
+G_MODULE_EXPORT
+void
+save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
+{
+ save_document (ui, TRUE);
}
@@ -1063,11 +1240,10 @@ help_contents_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
if (error)
{
- ui_show_error (ui,
- /* Error message displayed when unable to launch help browser */
- _("Unable to open help file"),
- error->message,
- FALSE);
+ show_error_dialog (ui,
+ /* Error message displayed when unable to launch help browser */
+ _("Unable to open help file"),
+ error->message);
g_clear_error (&error);
}
}
@@ -1116,14 +1292,19 @@ about_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
}
-static void
+static gboolean
quit (SimpleScan *ui)
{
char *device;
gint paper_width = 0, paper_height = 0;
gint i;
- // FIXME: Warn if document with unsaved changes
+ if (!prompt_to_save (ui,
+ /* Text in dialog warning when a document is about to be lost */
+ _("Save document before quitting?"),
+ /* Button in dialog to quit and discard unsaved document */
+ _("Quit without Saving")))
+ return FALSE;
device = get_selected_device (ui);
if (device) {
@@ -1151,6 +1332,8 @@ quit (SimpleScan *ui)
gconf_client_set_int (ui->priv->client, GCONF_DIR "/page_dpi", ui->priv->default_page_dpi, NULL);
g_signal_emit (G_OBJECT (ui), signals[QUIT], 0);
+
+ return TRUE;
}
@@ -1177,6 +1360,24 @@ simple_scan_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *eve
}
+static void
+info_bar_response_cb (GtkWidget *widget, gint response_id, SimpleScan *ui)
+{
+ if (response_id == 1) {
+ gtk_widget_grab_focus (ui->priv->device_combo);
+ gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog));
+ }
+ else {
+ ui->priv->have_error = FALSE;
+ g_free (ui->priv->error_title);
+ ui->priv->error_title = NULL;
+ g_free (ui->priv->error_text);
+ ui->priv->error_text = NULL;
+ update_info_bar (ui);
+ }
+}
+
+
gboolean simple_scan_window_window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event, SimpleScan *ui);
G_MODULE_EXPORT
gboolean
@@ -1193,8 +1394,7 @@ G_MODULE_EXPORT
gboolean
window_delete_event_cb (GtkWidget *widget, GdkEvent *event, SimpleScan *ui)
{
- quit (ui);
- return TRUE;
+ return !quit (ui);
}
@@ -1290,10 +1490,21 @@ set_dpi_combo (GtkWidget *combo, gint default_dpi, gint current_dpi)
static void
+needs_saving_cb (Book *book, GParamSpec *param, SimpleScan *ui)
+{
+ gtk_widget_set_sensitive (ui->priv->save_menuitem, book_get_needs_saving (book));
+ gtk_widget_set_sensitive (ui->priv->save_toolbutton, book_get_needs_saving (book));
+ if (book_get_needs_saving (book))
+ gtk_widget_set_sensitive (ui->priv->save_as_menuitem, TRUE);
+}
+
+
+static void
ui_load (SimpleScan *ui)
{
GtkBuilder *builder;
GError *error = NULL;
+ GtkWidget *hbox;
GtkCellRenderer *renderer;
gchar *device, *document_type, *scan_direction, *page_side;
gint dpi, paper_width, paper_height;
@@ -1306,12 +1517,11 @@ ui_load (SimpleScan *ui)
gtk_builder_add_from_file (builder, UI_DIR "simple-scan.ui", &error);
if (error) {
g_critical ("Unable to load UI: %s\n", error->message);
- ui_show_error (ui,
- /* Title of dialog when cannot load required files */
- _("Files missing"),
- /* Description in dialog when cannot load required files */
- _("Please check your installation"),
- FALSE);
+ show_error_dialog (ui,
+ /* Title of dialog when cannot load required files */
+ _("Files missing"),
+ /* Description in dialog when cannot load required files */
+ _("Please check your installation"));
exit (1);
}
gtk_builder_connect_signals (builder, ui);
@@ -1320,6 +1530,9 @@ ui_load (SimpleScan *ui)
ui->priv->main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_vbox"));
ui->priv->page_delete_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "page_delete_menuitem"));
ui->priv->crop_rotate_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "crop_rotate_menuitem"));
+ ui->priv->save_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_menuitem"));
+ ui->priv->save_as_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_as_menuitem"));
+ ui->priv->save_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "save_toolbutton"));
ui->priv->stop_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "stop_scan_menuitem"));
ui->priv->stop_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "stop_toolbutton"));
@@ -1345,6 +1558,28 @@ ui_load (SimpleScan *ui)
ui->priv->paper_size_combo = GTK_WIDGET (gtk_builder_get_object (builder, "paper_size_combo"));
ui->priv->paper_size_model = gtk_combo_box_get_model (GTK_COMBO_BOX (ui->priv->paper_size_combo));
+ /* Add InfoBar (not supported in Glade) */
+ ui->priv->info_bar = gtk_info_bar_new ();
+ g_signal_connect (ui->priv->info_bar, "response", G_CALLBACK (info_bar_response_cb), ui);
+ gtk_box_pack_start (GTK_BOX(ui->priv->main_vbox), ui->priv->info_bar, FALSE, TRUE, 0);
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (ui->priv->info_bar))), hbox);
+ gtk_widget_show (hbox);
+
+ ui->priv->info_bar_image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_image, FALSE, TRUE, 0);
+ gtk_widget_show (ui->priv->info_bar_image);
+
+ ui->priv->info_bar_label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (ui->priv->info_bar_label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_label, TRUE, TRUE, 0);
+ gtk_widget_show (ui->priv->info_bar_label);
+
+ ui->priv->info_bar_close_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+ ui->priv->info_bar_change_scanner_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar),
+ /* Button in error infobar to open preferences dialog and change scanner */
+ _("Change _Scanner"), 1);
+
GtkTreeIter iter;
gtk_list_store_append (GTK_LIST_STORE (ui->priv->paper_size_model), &iter);
gtk_list_store_set (GTK_LIST_STORE (ui->priv->paper_size_model), &iter, 0, 0, 1, 0, 2,
@@ -1451,6 +1686,8 @@ ui_load (SimpleScan *ui)
if (book_get_n_pages (ui->priv->book) == 0)
add_default_page (ui);
+ book_set_needs_saving (ui->priv->book, FALSE);
+ g_signal_connect (ui->priv->book, "notify::needs-saving", G_CALLBACK (needs_saving_cb), ui);
}
@@ -1495,28 +1732,13 @@ ui_set_scanning (SimpleScan *ui, gboolean scanning)
void
ui_show_error (SimpleScan *ui, const gchar *error_title, const gchar *error_text, gboolean change_scanner_hint)
{
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- "%s", error_title);
- if (change_scanner_hint)
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- /* Button in error dialog to open prefereces dialog and change scanner */
- _("Change _Scanner"),
- 1);
- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0);
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- "%s", error_text);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == 1) {
- gtk_widget_grab_focus (ui->priv->device_combo);
- gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog));
- }
-
- gtk_widget_destroy (dialog);
+ ui->priv->have_error = TRUE;
+ g_free (ui->priv->error_title);
+ ui->priv->error_title = g_strdup (error_title);
+ g_free (ui->priv->error_text);
+ ui->priv->error_text = g_strdup (error_text);
+ ui->priv->error_change_scanner_hint = change_scanner_hint;
+ update_info_bar (ui);
}
@@ -1606,14 +1828,6 @@ ui_class_init (SimpleScanClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- signals[SAVE] =
- g_signal_new ("save",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (SimpleScanClass, save),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
signals[EMAIL] =
g_signal_new ("email",
G_TYPE_FROM_CLASS (klass),
@@ -1650,5 +1864,5 @@ ui_init (SimpleScan *ui)
ui->priv->document_hint = g_strdup ("photo");
ui->priv->default_file_name = g_strdup (_("Scanned Document.pdf"));
ui->priv->scanning = FALSE;
- ui_load (ui);
+ ui_load (ui);
}