[eog] Notify user when opening a multipage TIFF
- From: Felix Riemann <friemann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [eog] Notify user when opening a multipage TIFF
- Date: Mon, 25 May 2015 16:59:36 +0000 (UTC)
commit f8c70c212e636b9417f5d8d27ed20e05c2260b77
Author: Felix Riemann <friemann gnome org>
Date: Mon May 25 18:47:14 2015 +0200
Notify user when opening a multipage TIFF
Show an info bar that tries to steer the user to Evince, if available.
This will work if at least gdk-pixbuf-2.31.1 is used.
https://bugzilla.gnome.org/show_bug.cgi?id=739654
src/eog-error-message-area.c | 115 ++++++++++++++++++++++++++++++++++++++----
src/eog-error-message-area.h | 6 ++-
src/eog-image.c | 30 +++++++++++
src/eog-image.h | 2 +
src/eog-window.c | 75 ++++++++++++++++++++++-----
5 files changed, 203 insertions(+), 25 deletions(-)
---
diff --git a/src/eog-error-message-area.c b/src/eog-error-message-area.c
index cdbeda7..6dc9f76 100644
--- a/src/eog-error-message-area.c
+++ b/src/eog-error-message-area.c
@@ -33,12 +33,22 @@
#include <glib/gi18n.h>
#include <glib-object.h>
#include <gtk/gtk.h>
+#include <gio/gdesktopappinfo.h>
+
+/* gboolean <-> gpointer conversion macros taken from gedit */
+#ifndef GBOOLEAN_TO_POINTER
+#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
+#endif
+#ifndef GPOINTER_TO_BOOLEAN
+#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT (i) == 2) ? TRUE : FALSE))
+#endif
typedef enum {
EOG_ERROR_MESSAGE_AREA_NO_BUTTONS = 0,
EOG_ERROR_MESSAGE_AREA_CANCEL_BUTTON = 1 << 0,
EOG_ERROR_MESSAGE_AREA_RELOAD_BUTTON = 1 << 1,
- EOG_ERROR_MESSAGE_AREA_SAVEAS_BUTTON = 1 << 2
+ EOG_ERROR_MESSAGE_AREA_SAVEAS_BUTTON = 1 << 2,
+ EOG_ERROR_MESSAGE_AREA_OPEN_WITH_EVINCE_BUTTON = 1 << 3
} EogErrorMessageAreaButtons;
static void
@@ -103,17 +113,10 @@ set_message_area_text_and_icon (GtkInfoBar *message_area,
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (message_area))),
hbox_content, TRUE, TRUE, 0);
}
-static GtkWidget *
-create_error_message_area (const gchar *primary_text,
- const gchar *secondary_text,
- EogErrorMessageAreaButtons buttons)
+static void
+add_message_area_buttons (GtkWidget *message_area,
+ EogErrorMessageAreaButtons buttons)
{
- GtkWidget *message_area;
-
- /* create a new message area */
- message_area = gtk_info_bar_new ();
-
- /* add requested buttons to the message area */
if (buttons & EOG_ERROR_MESSAGE_AREA_CANCEL_BUTTON)
gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
_("_Cancel"),
@@ -128,6 +131,24 @@ create_error_message_area (const gchar *primary_text,
gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
_("Save _As…"),
EOG_ERROR_MESSAGE_AREA_RESPONSE_SAVEAS);
+ if (buttons & EOG_ERROR_MESSAGE_AREA_OPEN_WITH_EVINCE_BUTTON)
+ gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
+ _("Open with Document Viewer"),
+ EOG_ERROR_MESSAGE_AREA_RESPONSE_OPEN_WITH_EVINCE);
+}
+
+static GtkWidget *
+create_error_message_area (const gchar *primary_text,
+ const gchar *secondary_text,
+ EogErrorMessageAreaButtons buttons)
+{
+ GtkWidget *message_area;
+
+ /* create a new message area */
+ message_area = gtk_info_bar_new ();
+
+ /* add requested buttons to the message area */
+ add_message_area_buttons (message_area, buttons);
/* set message type */
gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area),
@@ -142,6 +163,32 @@ create_error_message_area (const gchar *primary_text,
return message_area;
}
+static GtkWidget *
+create_info_message_area (const gchar *primary_text,
+ const gchar *secondary_text,
+ EogErrorMessageAreaButtons buttons)
+{
+ GtkWidget *message_area;
+
+ /* create a new message area */
+ message_area = gtk_info_bar_new ();
+
+ /* add requested buttons to the message area */
+ add_message_area_buttons (message_area, buttons);
+
+ /* set message type */
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area),
+ GTK_MESSAGE_INFO);
+
+ /* set text and icon */
+ set_message_area_text_and_icon (GTK_INFO_BAR (message_area),
+ "dialog-information",
+ primary_text,
+ secondary_text);
+
+ return message_area;
+}
+
/**
* eog_image_load_error_message_area_new: (skip):
* @caption:
@@ -271,3 +318,49 @@ eog_no_images_error_message_area_new (GFile *file)
return message_area;
}
+
+static gpointer
+_check_evince_availability(gpointer data)
+{
+ gboolean result = FALSE;
+ GDesktopAppInfo *app_info;
+
+ app_info = g_desktop_app_info_new ("evince.desktop");
+ if (app_info) {
+ result = TRUE;
+ g_object_unref (app_info);
+ }
+ return GBOOLEAN_TO_POINTER(result);
+}
+
+GtkWidget *
+eog_multipage_error_message_area_new(void)
+{
+ static GOnce evince_is_available = G_ONCE_INIT;
+ EogErrorMessageAreaButtons buttons = EOG_ERROR_MESSAGE_AREA_NO_BUTTONS;
+ GtkWidget *message_area;
+ const gchar *info_message;
+
+ g_once (&evince_is_available, _check_evince_availability, NULL);
+
+ if (GPOINTER_TO_BOOLEAN (evince_is_available.retval))
+ {
+ buttons = EOG_ERROR_MESSAGE_AREA_OPEN_WITH_EVINCE_BUTTON;
+ info_message = N_("This image contains multiple pages. "
+ "Image Viewer displays only the first page.\n"
+ "Do you want to open the image with the Document Viewer to see all pages?");
+ } else {
+ buttons = EOG_ERROR_MESSAGE_AREA_NO_BUTTONS;
+ info_message = N_("This image contains multiple pages. "
+ "Image Viewer displays only the first page.\n"
+ "You may want to install the Document Viewer to see all pages.");
+ }
+
+ message_area = create_info_message_area (gettext (info_message),
+ NULL,
+ buttons);
+ gtk_info_bar_set_show_close_button (GTK_INFO_BAR (message_area),
+ TRUE);
+
+ return message_area;
+}
diff --git a/src/eog-error-message-area.h b/src/eog-error-message-area.h
index d19e8c9..bd642d9 100644
--- a/src/eog-error-message-area.h
+++ b/src/eog-error-message-area.h
@@ -43,7 +43,8 @@ typedef enum
EOG_ERROR_MESSAGE_AREA_RESPONSE_NONE = 0,
EOG_ERROR_MESSAGE_AREA_RESPONSE_CANCEL = 1,
EOG_ERROR_MESSAGE_AREA_RESPONSE_RELOAD = 2,
- EOG_ERROR_MESSAGE_AREA_RESPONSE_SAVEAS = 3
+ EOG_ERROR_MESSAGE_AREA_RESPONSE_SAVEAS = 3,
+ EOG_ERROR_MESSAGE_AREA_RESPONSE_OPEN_WITH_EVINCE = 4
} EogErrorMessageAreaResponseType;
G_GNUC_INTERNAL
@@ -57,4 +58,7 @@ GtkWidget *eog_image_save_error_message_area_new (const gchar *caption,
G_GNUC_INTERNAL
GtkWidget *eog_no_images_error_message_area_new (GFile *file);
+G_GNUC_INTERNAL
+GtkWidget *eog_multipage_error_message_area_new (void);
+
#endif /* __EOG_ERROR_MESSAGE_AREA__ */
diff --git a/src/eog-image.c b/src/eog-image.c
index 028d93f..0ac6848 100644
--- a/src/eog-image.c
+++ b/src/eog-image.c
@@ -2501,3 +2501,33 @@ eog_image_is_jpeg (EogImage *img)
return ((img->priv->file_type != NULL) && (g_ascii_strcasecmp (img->priv->file_type,
EOG_FILE_FORMAT_JPEG) == 0));
}
+
+/**
+ * eog_image_is_multipaged:
+ * @img: an #EogImage
+ *
+ * Check whether the image actually contains multiple images/pages.
+ * This can happen for TIFF files. GIF animations are not multipaged.
+ *
+ * Note that this only works if the image data is loaded.
+ *
+ * Returns: %TRUE if @img is multipaged, %FALSE if not or the image data wasn't loaded.
+ * Since: 3.18
+ **/
+gboolean
+eog_image_is_multipaged (EogImage *img)
+{
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (EOG_IS_IMAGE (img), FALSE);
+
+ if (img->priv->image != NULL)
+ {
+ const gchar* value = gdk_pixbuf_get_option (img->priv->image,
+ "multipage");
+
+ result = (g_strcmp0 ("yes", value) == 0);
+ }
+
+ return result;
+}
diff --git a/src/eog-image.h b/src/eog-image.h
index d2fe428..de8feba 100644
--- a/src/eog-image.h
+++ b/src/eog-image.h
@@ -219,6 +219,8 @@ gboolean eog_image_is_file_changed (EogImage *img);
gboolean eog_image_is_file_writable (EogImage *img);
+gboolean eog_image_is_multipaged (EogImage *img);
+
G_END_DECLS
#endif /* __EOG_IMAGE_H__ */
diff --git a/src/eog-window.c b/src/eog-window.c
index 529d4c8..30b7069 100644
--- a/src/eog-window.c
+++ b/src/eog-window.c
@@ -206,6 +206,9 @@ static gboolean eog_window_save_images (EogWindow *window, GList *images);
static void eog_window_finish_saving (EogWindow *window);
static void eog_window_zoom_scale_value_changed_cb (GtkRange *range,
gpointer user_data);
+static void eog_window_error_message_area_response (GtkInfoBar *message_area,
+ gint response_id,
+ EogWindow *window);
static GQuark
eog_window_error_quark (void)
@@ -968,6 +971,41 @@ eog_window_display_image (EogWindow *window, EogImage *image)
update_status_bar (window);
eog_window_update_open_with_menu (window, image);
+
+ if (eog_image_is_multipaged (image)) {
+ GtkWidget *info_bar;
+
+ eog_debug_message (DEBUG_IMAGE_DATA, "Image is multipaged");
+
+ info_bar = eog_multipage_error_message_area_new ();
+ g_signal_connect (info_bar,
+ "response",
+ G_CALLBACK (eog_window_error_message_area_response),
+ window);
+ gtk_widget_show (info_bar);
+ eog_window_set_message_area (window, info_bar);
+ }
+}
+
+static void
+_eog_window_launch_appinfo_with_files (EogWindow *window,
+ GAppInfo *appinfo,
+ GList *files)
+{
+ GdkAppLaunchContext *context;
+
+ context = gdk_display_get_app_launch_context (
+ gtk_widget_get_display (GTK_WIDGET (window)));
+ gdk_app_launch_context_set_screen (context,
+ gtk_widget_get_screen (GTK_WIDGET (window)));
+ gdk_app_launch_context_set_icon (context,
+ g_app_info_get_icon (appinfo));
+ gdk_app_launch_context_set_timestamp (context,
+ gtk_get_current_event_time ());
+
+ g_app_info_launch (appinfo, files, G_APP_LAUNCH_CONTEXT (context), NULL);
+
+ g_object_unref (context);
}
static void
@@ -980,7 +1018,7 @@ eog_window_action_open_with (GSimpleAction *action,
GFile *file;
GList *files = NULL;
guint32 index = -1;
- GdkAppLaunchContext *context;
+
g_return_if_fail (EOG_IS_WINDOW (user_data));
window = EOG_WINDOW (user_data);
@@ -996,20 +1034,10 @@ eog_window_action_open_with (GSimpleAction *action,
file = eog_image_get_file (window->priv->image);
files = g_list_append (files, file);
- context = gdk_display_get_app_launch_context (
- gtk_widget_get_display (GTK_WIDGET (window)));
- gdk_app_launch_context_set_screen (context,
- gtk_widget_get_screen (GTK_WIDGET (window)));
- gdk_app_launch_context_set_icon (context,
- g_app_info_get_icon (app));
- gdk_app_launch_context_set_timestamp (context,
- gtk_get_current_event_time ());
-
- g_app_info_launch (app, files, G_APP_LAUNCH_CONTEXT (context), NULL);
+ _eog_window_launch_appinfo_with_files (window, app, files);
- g_object_unref (file);
- g_object_unref (context);
g_list_free (files);
+ g_object_unref (file);
}
static void
@@ -1277,6 +1305,7 @@ eog_window_error_message_area_response (GtkInfoBar *message_area,
switch (response_id) {
case EOG_ERROR_MESSAGE_AREA_RESPONSE_NONE:
case EOG_ERROR_MESSAGE_AREA_RESPONSE_CANCEL:
+ case GTK_RESPONSE_CLOSE:
/* nothing to do in this case */
break;
case EOG_ERROR_MESSAGE_AREA_RESPONSE_RELOAD:
@@ -1289,6 +1318,26 @@ eog_window_error_message_area_response (GtkInfoBar *message_area,
"save-as");
eog_window_action_save_as (G_SIMPLE_ACTION (action_save_as), NULL, window);
break;
+ case EOG_ERROR_MESSAGE_AREA_RESPONSE_OPEN_WITH_EVINCE:
+ {
+ GDesktopAppInfo *app_info;
+ GFile *img_file;
+ GList *img_files = NULL;
+
+ app_info = g_desktop_app_info_new ("evince.desktop");
+
+ if (app_info) {
+ img_file = eog_image_get_file (window->priv->image);
+ if (img_file) {
+ img_files = g_list_append (img_files, img_file);
+ }
+ _eog_window_launch_appinfo_with_files (window,
+ G_APP_INFO (app_info),
+ img_files);
+ g_list_free_full (img_files, g_object_unref);
+ }
+ }
+ break;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]