From c15dc3b14e35850849f3559ac0305b4cac4a7046 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 12 Jul 2010 19:34:33 +0200 Subject: Imported Upstream version 2.31.5~bzr424 --- src/ui.c | 632 ++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 423 insertions(+), 209 deletions(-) (limited to 'src/ui.c') 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 ("%s\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); } @@ -1289,11 +1489,22 @@ 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); } -- cgit v1.2.3