]> www.fi.muni.cz Git - evince.git/commitdiff
Use a message area instead of a popup dialog for error notifications.
authorCarlos Garcia Campos <carlosgc@gnome.org>
Sun, 2 Dec 2007 20:02:01 +0000 (20:02 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Sun, 2 Dec 2007 20:02:01 +0000 (20:02 +0000)
2007-12-02  Carlos Garcia Campos  <carlosgc@gnome.org>
* configure.ac:
* cut-n-paste/gedit-message-area/Makefile.am:
* cut-n-paste/gedit-message-area/gedit-message-area.[ch]:
* shell/Makefile.am:
* shell/ev-message-area.[ch]:
* shell/ev-window.c: (ev_window_set_message_area),
(ev_window_error_message_response_cb), (ev_window_error_message),
(ev_window_load_job_cb), (ev_window_cmd_file_open_copy_at_dest),
(ev_window_save_job_cb), (image_save_dialog_response_cb),
(ev_attachment_popup_cmd_open_attachment),
(attachment_save_dialog_response_cb), (ev_window_set_document),
(ev_window_init):
Use a message area instead of a popup dialog for error
notifications. Fixes bug #337495.

svn path=/trunk/; revision=2757

ChangeLog
configure.ac
cut-n-paste/Makefile.am
cut-n-paste/gedit-message-area/Makefile.am [new file with mode: 0644]
cut-n-paste/gedit-message-area/gedit-message-area.c [new file with mode: 0644]
cut-n-paste/gedit-message-area/gedit-message-area.h [new file with mode: 0644]
shell/Makefile.am
shell/ev-message-area.c [new file with mode: 0644]
shell/ev-message-area.h [new file with mode: 0644]
shell/ev-window.c

index 23af1c204ec92f6a9f678b49c96dc649447ce7f3..8806552834de8a587817328ad2b098617fac9530 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2007-12-02  Carlos Garcia Campos  <carlosgc@gnome.org>
+
+       * configure.ac:
+       * cut-n-paste/gedit-message-area/Makefile.am:
+       * cut-n-paste/gedit-message-area/gedit-message-area.[ch]:
+       * shell/Makefile.am:
+       * shell/ev-message-area.[ch]:
+       * shell/ev-window.c: (ev_window_set_message_area),
+       (ev_window_error_message_response_cb), (ev_window_error_message),
+       (ev_window_load_job_cb), (ev_window_cmd_file_open_copy_at_dest),
+       (ev_window_save_job_cb), (image_save_dialog_response_cb),
+       (ev_attachment_popup_cmd_open_attachment),
+       (attachment_save_dialog_response_cb), (ev_window_set_document),
+       (ev_window_init):
+
+       Use a message area instead of a popup dialog for error
+       notifications. Fixes bug #337495.
+       
 2007-12-02  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * shell/ev-window.c: (fullscreen_toolbar_remove_shadow),
index d8801fa77457e6a58ad9aa139541f8543316b57e..01a9ce762ecb7626d537db23da22e4f2543436e9 100644 (file)
@@ -448,6 +448,7 @@ backend/pixbuf/Makefile
 backend/ps/Makefile
 backend/tiff/Makefile
 cut-n-paste/Makefile
+cut-n-paste/gedit-message-area/Makefile
 cut-n-paste/toolbar-editor/Makefile
 cut-n-paste/zoom-control/Makefile
 cut-n-paste/totem-screensaver/Makefile
index e30813155245e6303d248883992ccde266a7d4bf..3c5609cfb35759fa08fbf9d2603022b28360ed07 100644 (file)
@@ -1 +1 @@
-SUBDIRS = zoom-control toolbar-editor totem-screensaver
+SUBDIRS = zoom-control toolbar-editor totem-screensaver gedit-message-area
diff --git a/cut-n-paste/gedit-message-area/Makefile.am b/cut-n-paste/gedit-message-area/Makefile.am
new file mode 100644 (file)
index 0000000..8e6368b
--- /dev/null
@@ -0,0 +1,10 @@
+noinst_LTLIBRARIES = libgeditmsgarea.la
+libgeditmsgarea_la_SOURCES =   \
+       gedit-message-area.c    \
+       gedit-message-area.h
+
+libgeditmsgarea_la_CFLAGS =    \
+       -I$(top_srcdir)/lib     \
+       $(LIB_CFLAGS)           \
+       $(WARNING_CFLAGS)       \
+       $(DISABLE_DEPRECATED)
diff --git a/cut-n-paste/gedit-message-area/gedit-message-area.c b/cut-n-paste/gedit-message-area/gedit-message-area.c
new file mode 100644 (file)
index 0000000..7fb88cc
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * gedit-message-area.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-message-area.c 5887 2007-09-07 07:20:19Z pborelli $
+ */
+
+/* TODO: Style properties */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gedit-message-area.h"
+
+#define GEDIT_MESSAGE_AREA_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+                                              GEDIT_TYPE_MESSAGE_AREA, \
+                                              GeditMessageAreaPrivate))
+
+struct _GeditMessageAreaPrivate
+{
+       GtkWidget *main_hbox;
+
+       GtkWidget *contents;
+       GtkWidget *action_area;
+
+       gboolean changing_style;
+};
+
+typedef struct _ResponseData ResponseData;
+
+struct _ResponseData
+{
+       gint response_id;
+};
+
+enum {
+       RESPONSE,
+       CLOSE,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE(GeditMessageArea, gedit_message_area, GTK_TYPE_HBOX)
+
+
+static void
+gedit_message_area_finalize (GObject *object)
+{
+       /*
+       GeditMessageArea *message_area = GEDIT_MESSAGE_AREA (object);
+       */
+
+       G_OBJECT_CLASS (gedit_message_area_parent_class)->finalize (object);
+}
+
+static ResponseData *
+get_response_data (GtkWidget *widget,
+                  gboolean   create)
+{
+       ResponseData *ad = g_object_get_data (G_OBJECT (widget),
+                                                     "gedit-message-area-response-data");
+
+       if (ad == NULL && create)
+       {
+               ad = g_new (ResponseData, 1);
+
+               g_object_set_data_full (G_OBJECT (widget),
+                                       "gedit-message-area-response-data",
+                                       ad,
+                                       g_free);
+       }
+
+       return ad;
+}
+
+static GtkWidget *
+find_button (GeditMessageArea *message_area,
+            gint              response_id)
+{
+       GList *children, *tmp_list;
+       GtkWidget *child = NULL;
+
+       children = gtk_container_get_children (
+                       GTK_CONTAINER (message_area->priv->action_area));
+
+       for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
+       {
+               ResponseData *rd = get_response_data (tmp_list->data, FALSE);
+
+               if (rd && rd->response_id == response_id)
+               {
+                       child = tmp_list->data;
+                       break;
+               }
+       }
+
+       g_list_free (children);
+
+       return child;
+}
+
+static void
+gedit_message_area_close (GeditMessageArea *message_area)
+{
+       if (!find_button (message_area, GTK_RESPONSE_CANCEL))
+               return;
+
+       /* emit response signal */
+       gedit_message_area_response (GEDIT_MESSAGE_AREA (message_area),
+                                    GTK_RESPONSE_CANCEL);
+}
+
+static gboolean
+paint_message_area (GtkWidget      *widget,
+                   GdkEventExpose *event,
+                   gpointer        user_data)
+{
+       gtk_paint_flat_box (widget->style,
+                           widget->window,
+                           GTK_STATE_NORMAL,
+                           GTK_SHADOW_OUT,
+                           NULL,
+                           widget,
+                           "tooltip",
+                           widget->allocation.x + 1,
+                           widget->allocation.y + 1,
+                           widget->allocation.width - 2,
+                           widget->allocation.height - 2);
+
+       return FALSE;
+}
+
+static void
+gedit_message_area_class_init (GeditMessageAreaClass *klass)
+{
+       GObjectClass *object_class;
+       GtkBindingSet *binding_set;
+
+       object_class = G_OBJECT_CLASS (klass);
+       object_class->finalize = gedit_message_area_finalize;
+
+       klass->close = gedit_message_area_close;
+
+       g_type_class_add_private (object_class, sizeof(GeditMessageAreaPrivate));
+
+       signals[RESPONSE] = g_signal_new ("response",
+                                         G_OBJECT_CLASS_TYPE (klass),
+                                         G_SIGNAL_RUN_LAST,
+                                         G_STRUCT_OFFSET (GeditMessageAreaClass, response),
+                                         NULL, NULL,
+                                         g_cclosure_marshal_VOID__INT,
+                                         G_TYPE_NONE, 1,
+                                         G_TYPE_INT);
+
+       signals[CLOSE] =  g_signal_new ("close",
+                                       G_OBJECT_CLASS_TYPE (klass),
+                                       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                       G_STRUCT_OFFSET (GeditMessageAreaClass, close),
+                                       NULL, NULL,
+                                       g_cclosure_marshal_VOID__VOID,
+                                       G_TYPE_NONE, 0);
+
+       binding_set = gtk_binding_set_by_class (klass);
+
+       gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
+}
+
+static void
+style_set (GtkWidget        *widget,
+          GtkStyle         *prev_style,
+          GeditMessageArea *message_area)
+{
+       GtkWidget *window;
+       GtkStyle *style;
+
+       if (message_area->priv->changing_style)
+               return;
+
+       /* This is a hack needed to use the tooltip background color */
+       window = gtk_window_new (GTK_WINDOW_POPUP);
+       gtk_widget_set_name (window, "gtk-tooltip");
+       gtk_widget_ensure_style (window);
+       style = gtk_widget_get_style (window);
+
+       message_area->priv->changing_style = TRUE;
+       gtk_widget_set_style (GTK_WIDGET (message_area), style);
+       message_area->priv->changing_style = FALSE;
+
+       gtk_widget_destroy (window);
+
+       gtk_widget_queue_draw (GTK_WIDGET (message_area));
+}
+
+static void
+gedit_message_area_init (GeditMessageArea *message_area)
+{
+       message_area->priv = GEDIT_MESSAGE_AREA_GET_PRIVATE (message_area);
+
+       message_area->priv->main_hbox = gtk_hbox_new (FALSE, 16); /* FIXME: use style properties */
+       gtk_widget_show (message_area->priv->main_hbox);
+       gtk_container_set_border_width (GTK_CONTAINER (message_area->priv->main_hbox),
+                                       8); /* FIXME: use style properties */
+
+       message_area->priv->action_area = gtk_vbox_new (TRUE, 10); /* FIXME: use style properties */
+       gtk_widget_show (message_area->priv->action_area);
+       gtk_box_pack_end (GTK_BOX (message_area->priv->main_hbox),
+                           message_area->priv->action_area,
+                           FALSE,
+                           TRUE,
+                           0);
+
+       gtk_box_pack_start (GTK_BOX (message_area),
+                           message_area->priv->main_hbox,
+                           TRUE,
+                           TRUE,
+                           0);
+
+       gtk_widget_set_app_paintable (GTK_WIDGET (message_area), TRUE);
+
+       g_signal_connect (message_area,
+                         "expose-event",
+                         G_CALLBACK (paint_message_area),
+                         NULL);
+
+       /* Note that we connect to style-set on one of the internal
+        * widgets, not on the message area itself, since gtk does
+        * not deliver any further style-set signals for a widget on
+        * which the style has been forced with gtk_widget_set_style() */
+       g_signal_connect (message_area->priv->main_hbox,
+                         "style-set",
+                         G_CALLBACK (style_set),
+                         message_area);
+}
+
+static gint
+get_response_for_widget (GeditMessageArea *message_area,
+                        GtkWidget        *widget)
+{
+       ResponseData *rd;
+
+       rd = get_response_data (widget, FALSE);
+       if (!rd)
+               return GTK_RESPONSE_NONE;
+       else
+               return rd->response_id;
+}
+
+static void
+action_widget_activated (GtkWidget *widget, GeditMessageArea *message_area)
+{
+       gint response_id;
+
+       response_id = get_response_for_widget (message_area, widget);
+
+       gedit_message_area_response (message_area, response_id);
+}
+
+void
+gedit_message_area_add_action_widget (GeditMessageArea *message_area,
+                                     GtkWidget        *child,
+                                     gint              response_id)
+{
+       ResponseData *ad;
+       guint signal_id;
+
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+       g_return_if_fail (GTK_IS_WIDGET (child));
+
+       ad = get_response_data (child, TRUE);
+
+       ad->response_id = response_id;
+
+       if (GTK_IS_BUTTON (child))
+               signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
+       else
+               signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
+
+       if (signal_id)
+       {
+               GClosure *closure;
+
+               closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
+                                                G_OBJECT (message_area));
+
+               g_signal_connect_closure_by_id (child,
+                                               signal_id,
+                                               0,
+                                               closure,
+                                               FALSE);
+       }
+       else
+               g_warning ("Only 'activatable' widgets can be packed into the action area of a GeditMessageArea");
+
+       if (response_id != GTK_RESPONSE_HELP)
+               gtk_box_pack_start (GTK_BOX (message_area->priv->action_area),
+                                   child,
+                                   FALSE,
+                                   FALSE,
+                                   0);
+       else
+               gtk_box_pack_end (GTK_BOX (message_area->priv->action_area),
+                                   child,
+                                   FALSE,
+                                   FALSE,
+                                   0);
+}
+
+void
+gedit_message_area_set_contents        (GeditMessageArea *message_area,
+                                GtkWidget        *contents)
+{
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+       g_return_if_fail (GTK_IS_WIDGET (contents));
+
+       message_area->priv->contents = contents;
+       gtk_box_pack_start (GTK_BOX (message_area->priv->main_hbox),
+                           message_area->priv->contents,
+                           TRUE,
+                           TRUE,
+                           0);
+}
+
+GtkWidget*
+gedit_message_area_add_button (GeditMessageArea *message_area,
+                              const gchar      *button_text,
+                              gint              response_id)
+{
+       GtkWidget *button;
+
+       g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
+       g_return_val_if_fail (button_text != NULL, NULL);
+
+       button = gtk_button_new_from_stock (button_text);
+
+       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+
+       gtk_widget_show (button);
+
+       gedit_message_area_add_action_widget (message_area,
+                                             button,
+                                             response_id);
+
+       return button;
+}
+
+void
+gedit_message_area_add_buttons_valist (GeditMessageArea *message_area,
+                                      const gchar      *first_button_text,
+                                      va_list           args)
+{
+       const gchar* text;
+       gint response_id;
+
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+
+       if (first_button_text == NULL)
+               return;
+
+       text = first_button_text;
+       response_id = va_arg (args, gint);
+
+       while (text != NULL)
+       {
+               gedit_message_area_add_button (message_area,
+                                              text,
+                                              response_id);
+
+               text = va_arg (args, gchar*);
+               if (text == NULL)
+                       break;
+
+               response_id = va_arg (args, int);
+       }
+}
+
+void
+gedit_message_area_add_buttons (GeditMessageArea *message_area,
+                               const gchar      *first_button_text,
+                               ...)
+{
+       va_list args;
+
+       va_start (args, first_button_text);
+
+       gedit_message_area_add_buttons_valist (message_area,
+                                              first_button_text,
+                                              args);
+
+       va_end (args);
+}
+
+GtkWidget *
+gedit_message_area_new (void)
+{
+       return g_object_new (GEDIT_TYPE_MESSAGE_AREA, NULL);
+}
+
+GtkWidget *
+gedit_message_area_new_with_buttons (const gchar *first_button_text,
+                                     ...)
+{
+       GeditMessageArea *message_area;
+       va_list args;
+
+       message_area = GEDIT_MESSAGE_AREA (gedit_message_area_new ());
+
+       va_start (args, first_button_text);
+
+       gedit_message_area_add_buttons_valist (message_area,
+                                              first_button_text,
+                                              args);
+
+       va_end (args);
+
+       return GTK_WIDGET (message_area);
+}
+
+void
+gedit_message_area_set_response_sensitive (GeditMessageArea *message_area,
+                                          gint              response_id,
+                                          gboolean          setting)
+{
+       GList *children;
+       GList *tmp_list;
+
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+
+       children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
+
+       tmp_list = children;
+       while (tmp_list != NULL)
+       {
+               GtkWidget *widget = tmp_list->data;
+               ResponseData *rd = get_response_data (widget, FALSE);
+
+               if (rd && rd->response_id == response_id)
+                       gtk_widget_set_sensitive (widget, setting);
+
+               tmp_list = g_list_next (tmp_list);
+       }
+
+       g_list_free (children);
+}
+
+void
+gedit_message_area_set_default_response (GeditMessageArea *message_area,
+                                        gint              response_id)
+{
+       GList *children;
+       GList *tmp_list;
+
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+
+       children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
+
+       tmp_list = children;
+       while (tmp_list != NULL)
+       {
+               GtkWidget *widget = tmp_list->data;
+               ResponseData *rd = get_response_data (widget, FALSE);
+
+               if (rd && rd->response_id == response_id)
+               gtk_widget_grab_default (widget);
+
+               tmp_list = g_list_next (tmp_list);
+       }
+
+       g_list_free (children);
+}
+
+void
+gedit_message_area_response (GeditMessageArea *message_area,
+                            gint              response_id)
+{
+       g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
+
+       g_signal_emit (message_area,
+                      signals[RESPONSE],
+                      0,
+                      response_id);
+}
+
+GtkWidget *
+gedit_message_area_add_stock_button_with_text (GeditMessageArea *message_area,
+                                              const gchar      *text,
+                                              const gchar      *stock_id,
+                                              gint              response_id)
+{
+       GtkWidget *button;
+
+       g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
+       g_return_val_if_fail (text != NULL, NULL);
+       g_return_val_if_fail (stock_id != NULL, NULL);
+
+       button = gtk_button_new_with_mnemonic (text);
+        gtk_button_set_image (GTK_BUTTON (button),
+                              gtk_image_new_from_stock (stock_id,
+                                                        GTK_ICON_SIZE_BUTTON));
+
+       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+
+       gtk_widget_show (button);
+
+       gedit_message_area_add_action_widget (message_area,
+                                             button,
+                                             response_id);
+
+       return button;
+}
+
diff --git a/cut-n-paste/gedit-message-area/gedit-message-area.h b/cut-n-paste/gedit-message-area/gedit-message-area.h
new file mode 100644 (file)
index 0000000..c53a800
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * gedit-message-area.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi 
+ *
+ * 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a 
+ * list of people on the gedit Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: gedit-message-area.h 5666 2007-06-29 19:52:25Z sfre $
+ */
+
+#ifndef __GEDIT_MESSAGE_AREA_H__
+#define __GEDIT_MESSAGE_AREA_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GEDIT_TYPE_MESSAGE_AREA              (gedit_message_area_get_type())
+#define GEDIT_MESSAGE_AREA(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_MESSAGE_AREA, GeditMessageArea))
+#define GEDIT_MESSAGE_AREA_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_MESSAGE_AREA, GeditMessageAreaClass))
+#define GEDIT_IS_MESSAGE_AREA(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_MESSAGE_AREA))
+#define GEDIT_IS_MESSAGE_AREA_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_MESSAGE_AREA))
+#define GEDIT_MESSAGE_AREA_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_MESSAGE_AREA, GeditMessageAreaClass))
+
+/* Private structure type */
+typedef struct _GeditMessageAreaPrivate GeditMessageAreaPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GeditMessageArea GeditMessageArea;
+
+struct _GeditMessageArea 
+{
+       GtkHBox parent;
+
+       /*< private > */
+       GeditMessageAreaPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GeditMessageAreaClass GeditMessageAreaClass;
+
+struct _GeditMessageAreaClass 
+{
+       GtkHBoxClass parent_class;
+
+       /* Signals */
+       void (* response) (GeditMessageArea *message_area, gint response_id);
+
+       /* Keybinding signals */
+       void (* close)    (GeditMessageArea *message_area);
+
+       /* Padding for future expansion */
+       void (*_gedit_reserved1) (void);
+       void (*_gedit_reserved2) (void);        
+};
+
+/*
+ * Public methods
+ */
+GType           gedit_message_area_get_type            (void) G_GNUC_CONST;
+
+GtkWidget      *gedit_message_area_new                 (void);
+
+GtkWidget      *gedit_message_area_new_with_buttons    (const gchar      *first_button_text,
+                                                        ...);
+
+void            gedit_message_area_set_contents        (GeditMessageArea *message_area,
+                                                        GtkWidget        *contents);
+                                        
+void            gedit_message_area_add_action_widget   (GeditMessageArea *message_area,
+                                                        GtkWidget        *child,
+                                                        gint              response_id);
+                                                        
+GtkWidget      *gedit_message_area_add_button          (GeditMessageArea *message_area,
+                                                        const gchar      *button_text,
+                                                        gint              response_id);
+                        
+GtkWidget      *gedit_message_area_add_stock_button_with_text 
+                                                       (GeditMessageArea *message_area, 
+                                                        const gchar      *text, 
+                                                        const gchar      *stock_id, 
+                                                        gint              response_id);
+
+void            gedit_message_area_add_buttons         (GeditMessageArea *message_area,
+                                                        const gchar      *first_button_text,
+                                                        ...);
+void             gedit_message_area_add_buttons_valist  (GeditMessageArea *message_area,
+                                                        const gchar      *first_button_text,
+                                                        va_list           args);
+
+void            gedit_message_area_set_response_sensitive 
+                                                       (GeditMessageArea *message_area,
+                                                        gint              response_id,
+                                                        gboolean          setting);
+void            gedit_message_area_set_default_response 
+                                                       (GeditMessageArea *message_area,
+                                                        gint              response_id);
+
+/* Emit response signal */
+void            gedit_message_area_response            (GeditMessageArea *message_area,
+                                                        gint              response_id);
+
+G_END_DECLS
+
+#endif  /* __GEDIT_MESSAGE_AREA_H__  */
index 34dc0ffc5758335159a729f3aab169073dea9879..973882b79e957b666162d4e1b7852f5aa9e1e954 100644 (file)
@@ -4,6 +4,7 @@ INCLUDES=                                               \
        -I$(top_srcdir)/cut-n-paste/zoom-control/       \
        -I$(top_srcdir)/cut-n-paste/toolbar-editor/     \
        -I$(top_srcdir)/cut-n-paste/totem-screensaver/  \
+       -I$(top_srcdir)/cut-n-paste/gedit-message-area/ \
        -I$(top_srcdir)/libdocument                     \
        -I$(top_srcdir)/properties                      \
        -DGNOMELOCALEDIR=\"$(datadir)/locale\"          \
@@ -29,6 +30,8 @@ evince_SOURCES=                               \
        ev-history.h                    \
        ev-marshal.c                    \
        ev-marshal.h                    \
+       ev-message-area.c               \
+       ev-message-area.h               \
        ev-metadata-manager.c           \
        ev-metadata-manager.h           \
        ev-navigation-action.c          \
@@ -89,13 +92,14 @@ evince_SOURCES+=                    \
 endif
 
 
-evince_LDADD=                                                          \
-       $(top_builddir)/cut-n-paste/zoom-control/libephyzoom.la         \
-       $(top_builddir)/cut-n-paste/toolbar-editor/libtoolbareditor.la  \
+evince_LDADD=                                                                  \
+       $(top_builddir)/cut-n-paste/zoom-control/libephyzoom.la                 \
+       $(top_builddir)/cut-n-paste/toolbar-editor/libtoolbareditor.la          \
        $(top_builddir)/cut-n-paste/totem-screensaver/libtotemscrsaver.la       \
-       $(top_builddir)/properties/libevproperties.la                   \
-       $(top_builddir)/libdocument/libevbackend.la                     \
-       $(SHELL_LIBS)                                                   \
+       $(top_builddir)/cut-n-paste/gedit-message-area/libgeditmsgarea.la       \
+       $(top_builddir)/properties/libevproperties.la                           \
+       $(top_builddir)/libdocument/libevbackend.la                             \
+       $(SHELL_LIBS)                                                           \
        $(GNOME_PRINT_LIBS)
 
 if ENABLE_DJVU
diff --git a/shell/ev-message-area.c b/shell/ev-message-area.c
new file mode 100644 (file)
index 0000000..93e227d
--- /dev/null
@@ -0,0 +1,324 @@
+/* ev-message-area.c
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos
+ *
+ * Author:
+ *   Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkaccessible.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkstock.h>
+
+#include "ev-message-area.h"
+
+#define EV_MESSAGE_AREA_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_MESSAGE_AREA, EvMessageAreaPrivate))
+
+struct _EvMessageAreaPrivate {
+       GtkWidget *image;
+       GtkWidget *label;
+       GtkWidget *secondary_label;
+       
+       guint      message_type : 3;
+};
+
+enum {
+       PROP_0,
+       PROP_MESSAGE_TYPE,
+       PROP_TEXT,
+       PROP_SECONDARY_TEXT,
+       PROP_IMAGE
+};
+
+static void ev_message_area_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec);
+static void ev_message_area_get_property (GObject      *object,
+                                         guint         prop_id,
+                                         GValue       *value,
+                                         GParamSpec   *pspec);
+
+G_DEFINE_TYPE (EvMessageArea, ev_message_area, GEDIT_TYPE_MESSAGE_AREA)
+
+static void
+ev_message_area_class_init (EvMessageAreaClass *class)
+{
+       GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+       gobject_class->set_property = ev_message_area_set_property;
+       gobject_class->get_property = ev_message_area_get_property;
+
+       g_object_class_install_property (gobject_class,
+                                        PROP_MESSAGE_TYPE,
+                                        g_param_spec_enum ("message-type",
+                                                           "Message Type",
+                                                           "The type of message",
+                                                           GTK_TYPE_MESSAGE_TYPE,
+                                                           GTK_MESSAGE_INFO,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+       g_object_class_install_property (gobject_class,
+                                        PROP_TEXT,
+                                        g_param_spec_string ("text",
+                                                             "Text",
+                                                             "The primary text of the message dialog",
+                                                             NULL,
+                                                             G_PARAM_READWRITE));
+       g_object_class_install_property (gobject_class,
+                                        PROP_SECONDARY_TEXT,
+                                        g_param_spec_string ("secondary-text",
+                                                             "Secondary Text",
+                                                             "The secondary text of the message dialog",
+                                                             NULL,
+                                                             G_PARAM_READWRITE));
+       g_object_class_install_property (gobject_class,
+                                        PROP_IMAGE,
+                                        g_param_spec_object ("image",
+                                                             "Image",
+                                                             "The image",
+                                                             GTK_TYPE_WIDGET,
+                                                             G_PARAM_READWRITE));
+
+       g_type_class_add_private (gobject_class, sizeof (EvMessageAreaPrivate));
+}
+
+static void
+ev_message_area_init (EvMessageArea *area)
+{
+       GtkWidget *hbox, *vbox;
+       
+       area->priv = EV_MESSAGE_AREA_GET_PRIVATE (area);
+
+       hbox = gtk_hbox_new (FALSE, 12);
+       vbox = gtk_vbox_new (FALSE, 12);
+       
+       area->priv->label = gtk_label_new (NULL);
+       gtk_label_set_use_markup (GTK_LABEL (area->priv->label), TRUE);
+       gtk_label_set_line_wrap (GTK_LABEL (area->priv->label), TRUE);
+       gtk_label_set_selectable (GTK_LABEL (area->priv->label), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (area->priv->label), 0.0, 0.5);
+       GTK_WIDGET_SET_FLAGS (area->priv->label, GTK_CAN_FOCUS);
+       gtk_box_pack_start (GTK_BOX (vbox), area->priv->label, TRUE, TRUE, 0);
+       gtk_widget_show (area->priv->label);
+       
+       area->priv->secondary_label = gtk_label_new (NULL);
+       gtk_label_set_use_markup (GTK_LABEL (area->priv->secondary_label), TRUE);
+       gtk_label_set_line_wrap (GTK_LABEL (area->priv->secondary_label), TRUE);
+       gtk_label_set_selectable (GTK_LABEL (area->priv->secondary_label), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (area->priv->secondary_label), 0.0, 0.5);
+       GTK_WIDGET_SET_FLAGS (area->priv->secondary_label, GTK_CAN_FOCUS);
+       gtk_box_pack_start (GTK_BOX (vbox), area->priv->secondary_label, TRUE, TRUE, 0);
+
+       area->priv->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
+       gtk_misc_set_alignment (GTK_MISC (area->priv->image), 0.5, 0.0);
+       gtk_box_pack_start (GTK_BOX (hbox), area->priv->image, FALSE, FALSE, 0);
+       gtk_widget_show (area->priv->image);
+
+       gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+       gtk_widget_show (vbox);
+
+       gedit_message_area_set_contents (GEDIT_MESSAGE_AREA (area), hbox);
+       gtk_widget_show (hbox);
+}
+
+static void
+ev_message_area_set_image_for_type (EvMessageArea *area,
+                                   GtkMessageType type)
+{
+       const gchar *stock_id = NULL;
+       AtkObject   *atk_obj;
+
+       switch (type) {
+       case GTK_MESSAGE_INFO:
+               stock_id = GTK_STOCK_DIALOG_INFO;
+               break;
+       case GTK_MESSAGE_QUESTION:
+               stock_id = GTK_STOCK_DIALOG_QUESTION;
+               break;
+       case GTK_MESSAGE_WARNING:
+               stock_id = GTK_STOCK_DIALOG_WARNING;
+               break;
+       case GTK_MESSAGE_ERROR:
+               stock_id = GTK_STOCK_DIALOG_ERROR;
+               break;
+       case GTK_MESSAGE_OTHER:
+               break;
+       default:
+               g_warning ("Unknown GtkMessageType %u", type);
+               break;
+       }
+
+       if (stock_id)
+               gtk_image_set_from_stock (GTK_IMAGE (area->priv->image), stock_id,
+                                         GTK_ICON_SIZE_DIALOG);
+
+       atk_obj = gtk_widget_get_accessible (GTK_WIDGET (area));
+       if (GTK_IS_ACCESSIBLE (atk_obj)) {
+               atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
+               if (stock_id) {
+                       GtkStockItem item;
+
+                       gtk_stock_lookup (stock_id, &item);
+                       atk_object_set_name (atk_obj, item.label);
+               }
+       }
+}
+
+static void
+ev_message_area_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+       EvMessageArea *area = EV_MESSAGE_AREA (object);
+
+       switch (prop_id) {
+       case PROP_MESSAGE_TYPE:
+               area->priv->message_type = g_value_get_enum (value);
+               ev_message_area_set_image_for_type (area, area->priv->message_type);
+               break;
+       case PROP_TEXT:
+               ev_message_area_set_text (area, g_value_get_string (value));
+               break;
+       case PROP_SECONDARY_TEXT:
+               ev_message_area_set_secondary_text (area, g_value_get_string (value));
+               break;
+       case PROP_IMAGE:
+               ev_message_area_set_image (area, (GtkWidget *)g_value_get_object (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+ev_message_area_get_property (GObject     *object,
+                             guint        prop_id,
+                             GValue      *value,
+                             GParamSpec  *pspec)
+{
+       EvMessageArea *area = EV_MESSAGE_AREA (object);
+
+       switch (prop_id) {
+       case PROP_MESSAGE_TYPE:
+               g_value_set_enum (value, (GtkMessageType) area->priv->message_type);
+               break;
+       case PROP_TEXT:
+               g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->label)));
+               break;
+       case PROP_SECONDARY_TEXT:
+               g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->secondary_label)));
+               break;
+       case PROP_IMAGE:
+               g_value_set_object (value, area->priv->image);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+GtkWidget *
+ev_message_area_new (GtkMessageType type,
+                    const gchar   *text,
+                    const gchar   *first_button_text,
+                    ...)
+{
+       GtkWidget *widget;
+
+       widget = g_object_new (EV_TYPE_MESSAGE_AREA,
+                              "message-type", type,
+                              "text", text,
+                              NULL);
+       if (first_button_text) {
+               va_list args;
+               
+               va_start (args, first_button_text);
+               gedit_message_area_add_buttons_valist (GEDIT_MESSAGE_AREA (widget),
+                                                      first_button_text,
+                                                      args);
+               va_end (args);
+       }
+
+       return widget;
+}
+
+void
+ev_message_area_set_image (EvMessageArea *area,
+                          GtkWidget     *image)
+{
+       GtkWidget *parent;
+
+       g_return_if_fail (EV_IS_MESSAGE_AREA (area));
+
+       area->priv->message_type = GTK_MESSAGE_OTHER;
+
+       parent = area->priv->image->parent;
+       gtk_container_add (GTK_CONTAINER (parent), image);
+       gtk_container_remove (GTK_CONTAINER (parent), area->priv->image);
+       gtk_box_reorder_child (GTK_BOX (parent), image, 0);
+
+       area->priv->image = image;
+
+       g_object_notify (G_OBJECT (area), "image");
+}
+
+void
+ev_message_area_set_text (EvMessageArea *area,
+                         const gchar   *str)
+{
+       g_return_if_fail (EV_IS_MESSAGE_AREA (area));
+
+       if (str) {
+               gchar *msg;
+
+               msg = g_strdup_printf ("<b>%s</b>", str);
+               gtk_label_set_markup (GTK_LABEL (area->priv->label), msg);
+               g_free (msg);
+       } else {
+               gtk_label_set_markup (GTK_LABEL (area->priv->label), NULL);
+       }
+
+       g_object_notify (G_OBJECT (area), "text");
+}
+
+void
+ev_message_area_set_secondary_text (EvMessageArea *area,
+                                   const gchar   *str)
+{
+       g_return_if_fail (EV_IS_MESSAGE_AREA (area));
+
+       if (str) {
+               gchar *msg;
+
+               msg = g_strdup_printf ("<small>%s</small>", str);
+               gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), msg);
+               g_free (msg);
+               gtk_widget_show (area->priv->secondary_label);
+       } else {
+               gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), NULL);
+               gtk_widget_hide (area->priv->secondary_label);
+       }
+
+       g_object_notify (G_OBJECT (area), "secondary-text");
+}
diff --git a/shell/ev-message-area.h b/shell/ev-message-area.h
new file mode 100644 (file)
index 0000000..bb29545
--- /dev/null
@@ -0,0 +1,69 @@
+/* ev-message-area.h
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos
+ *
+ * Author:
+ *   Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_MESSAGE_AREA_H
+#define EV_MESSAGE_AREA_H
+
+#include <gtk/gtkmessagedialog.h>
+
+#include "gedit-message-area.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_MESSAGE_AREA                  (ev_message_area_get_type ())
+#define EV_MESSAGE_AREA(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_MESSAGE_AREA, EvMessageArea))
+#define EV_MESSAGE_AREA_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_MESSAGE_AREA, EvMessageAreaClass))
+#define EV_IS_MESSAGE_AREA(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_MESSAGE_AREA))
+#define EV_IS_MESSAGE_AREA_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_MESSAGE_AREA))
+#define EV_MESSAGE_AREA_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_MESSAGE_AREA, EvMessageAreaClass))
+
+typedef struct _EvMessageArea        EvMessageArea;
+typedef struct _EvMessageAreaClass   EvMessageAreaClass;
+typedef struct _EvMessageAreaPrivate EvMessageAreaPrivate;
+
+struct _EvMessageArea {
+       GeditMessageArea parent_instance;
+
+       /*< private >*/
+       EvMessageAreaPrivate *priv;
+};
+
+struct _EvMessageAreaClass {
+       GeditMessageAreaClass parent_class;
+};
+
+GType      ev_message_area_get_type           (void) G_GNUC_CONST;
+GtkWidget *ev_message_area_new                (GtkMessageType type,
+                                              const gchar   *text,
+                                              const gchar   *first_button_text,
+                                              ...);
+void       ev_message_area_set_image          (EvMessageArea *area,
+                                              GtkWidget     *image);
+void       ev_message_area_set_text           (EvMessageArea *area,
+                                              const gchar   *str);
+void       ev_message_area_set_secondary_text (EvMessageArea *area,
+                                              const gchar   *str);
+
+G_END_DECLS
+
+#endif /* EV_MESSAGE_AREA_H */
index ed568f953873985d2b7c2286485fd594c05a7818..ca2a14ee8e8022e499ec084267992a9db85a5d70 100644 (file)
@@ -91,6 +91,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "ev-message-area.h"
+
 #if !GLIB_CHECK_VERSION (2, 13, 3)
 char *xdg_user_dir_lookup (char *type);
 #endif
@@ -119,10 +121,12 @@ struct _EvWindowPrivate {
        GtkWidget *menubar;
        GtkWidget *toolbar;
        GtkWidget *hpaned;
+       GtkWidget *view_box;
        GtkWidget *sidebar;
        GtkWidget *find_bar;
        GtkWidget *scrolled_window;
        GtkWidget *view;
+       GtkWidget *message_area;
        GtkWidget *password_view;
        GtkWidget *sidebar_thumbs;
        GtkWidget *sidebar_links;
@@ -624,29 +628,55 @@ ev_window_is_empty (const EvWindow *ev_window)
 }
 
 static void
-ev_window_error_dialog_response_cb (GtkWidget *dialog,
-                                  gint       response_id,
-                                  EvWindow  *ev_window)
+ev_window_set_message_area (EvWindow  *window,
+                           GtkWidget *area)
 {
-       gtk_widget_destroy (dialog);
+       if (window->priv->message_area == area)
+               return;
+
+       if (window->priv->message_area)
+               gtk_widget_destroy (window->priv->message_area);
+       window->priv->message_area = area;
+
+       if (!area)
+               return;
+
+       gtk_box_pack_start (GTK_BOX (window->priv->view_box),
+                           window->priv->message_area,
+                           FALSE, FALSE, 0);
+       gtk_box_reorder_child (GTK_BOX (window->priv->view_box),
+                              window->priv->message_area, 0);
+       g_object_add_weak_pointer (G_OBJECT (window->priv->message_area),
+                                  (gpointer) &(window->priv->message_area));
 }
 
 static void
-ev_window_error_dialog (GtkWindow *window, const gchar *msg, GError *error)
+ev_window_error_message_response_cb (EvMessageArea *area,
+                                    gint           response_id,
+                                    EvWindow      *window)
 {
-       GtkWidget *dialog;
+       ev_window_set_message_area (window, NULL);
+}
 
-       dialog = gtk_message_dialog_new (GTK_WINDOW (window),
-                                        GTK_DIALOG_DESTROY_WITH_PARENT,
-                                        GTK_MESSAGE_ERROR,
-                                        GTK_BUTTONS_CLOSE,
-                                        msg);
-       gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                 "%s", error->message);
-       g_signal_connect (dialog, "response",
-                         G_CALLBACK (ev_window_error_dialog_response_cb),
-                          window);
-       gtk_widget_show (dialog);
+static void
+ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error)
+{
+       GtkWidget *area;
+
+       if (EV_WINDOW (window)->priv->message_area)
+               return;
+
+       area = ev_message_area_new (GTK_MESSAGE_ERROR,
+                                   msg,
+                                   GTK_STOCK_CLOSE,
+                                   GTK_RESPONSE_CANCEL,
+                                   NULL);
+       ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message);
+       g_signal_connect (area, "response",
+                         G_CALLBACK (ev_window_error_message_response_cb),
+                         window);
+       gtk_widget_show (area);
+       ev_window_set_message_area (EV_WINDOW (window), area);
 }
 
 static void
@@ -1149,6 +1179,8 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document)
        if (ev_window->priv->document)
                g_object_unref (ev_window->priv->document);
        ev_window->priv->document = g_object_ref (document);
+
+       ev_window_set_message_area (ev_window, NULL);
        
        ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document);
        g_signal_connect (ev_window->priv->page_cache, "page-changed",
@@ -1384,9 +1416,9 @@ ev_window_load_job_cb  (EvJobLoad *job,
                
                ev_window_popup_password_dialog (ev_window);
        } else {
-               ev_window_error_dialog (GTK_WINDOW (ev_window), 
-                                       _("Unable to open document"),
-                                       job->error);
+               ev_window_error_message (GTK_WINDOW (ev_window), 
+                                        _("Unable to open document"),
+                                        job->error);
                ev_window_clear_load_job (ev_window);
                ev_window->priv->in_reload = FALSE;
        }       
@@ -1679,9 +1711,9 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest)
        new_filename = ev_window_create_tmp_symlink (old_filename, &error);
 
        if (error) {
-               ev_window_error_dialog (GTK_WINDOW (window),
-                                       _("Cannot open a copy."),
-                                       error);
+               ev_window_error_message (GTK_WINDOW (window),
+                                        _("Cannot open a copy."),
+                                        error);
 
                g_error_free (error);
                g_free (old_filename);
@@ -1998,7 +2030,7 @@ ev_window_save_job_cb (EvJobSave *job,
                gchar *msg;
                
                msg = g_strdup_printf (_("The file could not be saved as ā€œ%sā€."), job->uri);
-               ev_window_error_dialog (GTK_WINDOW (window), msg, job->error);
+               ev_window_error_message (GTK_WINDOW (window), msg, job->error);
                g_free (msg);
        }
 
@@ -4960,9 +4992,9 @@ image_save_dialog_response_cb (GtkWidget *fc,
                         filename, "png", &error, NULL);
        
        if (error) {
-               ev_window_error_dialog (GTK_WINDOW (ev_window),
-                                       _("The image could not be saved."),
-                                       error);
+               ev_window_error_message (GTK_WINDOW (ev_window),
+                                        _("The image could not be saved."),
+                                        error);
                g_error_free (error);
                g_free (filename);
                gnome_vfs_uri_unref (target_uri);
@@ -5051,9 +5083,9 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
                ev_attachment_open (attachment, &error);
 
                if (error) {
-                       ev_window_error_dialog (GTK_WINDOW (window),
-                                               _("Unable to open attachment"),
-                                               error);
+                       ev_window_error_message (GTK_WINDOW (window),
+                                                _("Unable to open attachment"),
+                                                error);
                        g_error_free (error);
                }
        }
@@ -5104,9 +5136,9 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
                ev_attachment_save (attachment, filename, &error);
                
                if (error) {
-                       ev_window_error_dialog (GTK_WINDOW (ev_window),
-                                               _("The attachment could not be saved."),
-                                               error);
+                       ev_window_error_message (GTK_WINDOW (ev_window),
+                                                _("The attachment could not be saved."),
+                                                error);
                        g_error_free (error);
                        g_free (filename);
 
@@ -5338,14 +5370,19 @@ ev_window_init (EvWindow *ev_window)
        ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
                             sidebar_widget);
 
+       ev_window->priv->view_box = gtk_vbox_new (FALSE, 0);
        ev_window->priv->scrolled_window =
                GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
                                          "shadow-type", GTK_SHADOW_IN,
                                          NULL));
+       gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box),
+                           ev_window->priv->scrolled_window,
+                           TRUE, TRUE, 0);
        gtk_widget_show (ev_window->priv->scrolled_window);
 
        gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
-                       ev_window->priv->scrolled_window);
+                       ev_window->priv->view_box);
+       gtk_widget_show (ev_window->priv->view_box);
 
        ev_window->priv->view = ev_view_new ();
        ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),