2006-08-29 [colin] 2.4.0cvs111
authorColin Leroy <colin@colino.net>
Tue, 29 Aug 2006 16:27:14 +0000 (16:27 +0000)
committerColin Leroy <colin@colino.net>
Tue, 29 Aug 2006 16:27:14 +0000 (16:27 +0000)
* src/folderview.c
Handle "popup_menu" signal (for popping the
menu via the keyboard)
* src/mimeview.c
* src/mimeview.h
* src/summaryview.c
* src/textview.c
* src/gtk/gtkutils.c
* src/gtk/gtkutils.h
Factorize scrolling code, and add an API
for MimeViewers to handle scroll orders

ChangeLog
PATCHSETS
configure.ac
src/folderview.c
src/gtk/gtkutils.c
src/gtk/gtkutils.h
src/mimeview.c
src/mimeview.h
src/summaryview.c
src/textview.c

index 15220dc..5460305 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-08-29 [colin]     2.4.0cvs111
+
+       * src/folderview.c
+               Handle "popup_menu" signal (for popping the 
+               menu via the keyboard)
+       * src/mimeview.c
+       * src/mimeview.h
+       * src/summaryview.c
+       * src/textview.c
+       * src/gtk/gtkutils.c
+       * src/gtk/gtkutils.h
+               Factorize scrolling code, and add an API 
+               for MimeViewers to handle scroll orders
+
 2006-08-29 [wwp]       2.4.0cvs110
 
        * src/plugins//bogofilter/bogofilter.c
index 04d7120..bd7705d 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.26.2.26 -r 1.26.2.27 src/foldersel.c;  cvs diff -u -r 1.15.2.31 -r 1.15.2.32 src/summary_search.c;  cvs diff -u -r 1.1.4.16 -r 1.1.4.17 src/gtk/progressdialog.c;  cvs diff -u -r 1.1.2.18 -r 1.1.2.19 src/plugins/pgpcore/passphrase.c;  ) > 2.4.0cvs108.patchset
 ( cvs diff -u -r 1.24.2.13 -r 1.24.2.14 Makefile.am;  ) > 2.4.0cvs109.patchset
 ( cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/plugins//bogofilter/bogofilter.c;  cvs diff -u -r 1.18.2.38 -r 1.18.2.39 src/plugins//spamassassin/spamassassin.c;  ) > 2.4.0cvs110.patchset
+( cvs diff -u -r 1.207.2.113 -r 1.207.2.114 src/folderview.c;  cvs diff -u -r 1.83.2.82 -r 1.83.2.83 src/mimeview.c;  cvs diff -u -r 1.20.2.14 -r 1.20.2.15 src/mimeview.h;  cvs diff -u -r 1.395.2.236 -r 1.395.2.237 src/summaryview.c;  cvs diff -u -r 1.96.2.141 -r 1.96.2.142 src/textview.c;  cvs diff -u -r 1.5.2.39 -r 1.5.2.40 src/gtk/gtkutils.c;  cvs diff -u -r 1.4.2.24 -r 1.4.2.25 src/gtk/gtkutils.h;  ) > 2.4.0cvs111.patchset
index 9d242fd..2f8ee8c 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=4
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=110
+EXTRA_VERSION=111
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index e905c13..dd6d837 100644 (file)
@@ -280,6 +280,8 @@ gboolean folderview_update_item_claws        (gpointer          source,
                                          gpointer          data);
 static void folderview_processing_cb(FolderView *folderview, guint action,
                                     GtkWidget *widget);
+static void folderview_set_sens_and_popup_menu(FolderView *folderview, gint row, 
+                               GdkEventButton *event);
 
 GHashTable *folderview_popups;
 
@@ -416,6 +418,23 @@ static void folderview_column_set_titles(FolderView *folderview)
        gtk_clist_set_column_widget(GTK_CLIST(ctree),col_pos[F_COL_TOTAL],hbox_total);
 }
 
+static gboolean folderview_popup_menu(GtkWidget *widget, gpointer data)
+{
+       FolderView *folderview = (FolderView *)data;
+       GdkEventButton event;
+       if (folderview_get_selected_item(folderview) == NULL)
+               return FALSE;
+       
+       event.button = 3;
+       event.time = gtk_get_current_event_time();
+       
+       folderview_set_sens_and_popup_menu(folderview, -1, 
+                               &event);
+
+       return TRUE;
+}
+
+
 GtkWidget *folderview_ctree_create(FolderView *folderview)
 {
        GtkWidget *ctree;
@@ -480,6 +499,8 @@ GtkWidget *folderview_ctree_create(FolderView *folderview)
        g_signal_connect(G_OBJECT(ctree), "button_press_event",
                         G_CALLBACK(folderview_button_pressed),
                         folderview);
+       g_signal_connect(G_OBJECT(ctree), "popup-menu",
+                        G_CALLBACK(folderview_popup_menu), folderview);
        g_signal_connect(G_OBJECT(ctree), "button_release_event",
                         G_CALLBACK(folderview_button_released),
                         folderview);
@@ -1791,12 +1812,10 @@ static void folderview_append_folder(FolderView *folderview, Folder *folder)
 }
 
 /* callback functions */
-
-static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
-                                         FolderView *folderview)
+static void folderview_set_sens_and_popup_menu(FolderView *folderview, gint row, 
+                               GdkEventButton *event)
 {
-       GtkCList *clist = GTK_CLIST(ctree);
-       gint prev_row = -1, row = -1, column = -1;
+       GtkCList *clist = GTK_CLIST(folderview->ctree);
        FolderItem *item;
        Folder *folder;
        FolderViewPopup *fpopup;
@@ -1805,56 +1824,13 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        FolderItem *special_trash = NULL, *special_queue = NULL;
        PrefsAccount *ac;
 
-       if (!event) return FALSE;
-
-       if (event->button == 1 || event->button == 2) {
-               folderview->open_folder = TRUE;
-
-               if (event->type == GDK_2BUTTON_PRESS) {
-                       if (clist->selection) {
-                               GtkCTreeNode *node;
-
-                               node = GTK_CTREE_NODE(clist->selection->data);
-                               if (node)
-                                       gtk_ctree_toggle_expansion(
-                                               GTK_CTREE(ctree),
-                                               node);
-                       }
-               }
-               return FALSE;
-       }
-
-       if (event->button == 2 || event->button == 3) {
-               /* right clicked */
-               if (clist->selection) {
-                       GtkCTreeNode *node;
-
-                       node = GTK_CTREE_NODE(clist->selection->data);
-                       if (node)
-                               prev_row = gtkut_ctree_get_nth_from_node
-                                       (GTK_CTREE(ctree), node);
-               }
-
-               if (!gtk_clist_get_selection_info(clist, event->x, event->y,
-                                                 &row, &column))
-                       return FALSE;
-               if (prev_row != row) {
-                       gtk_clist_unselect_all(clist);
-                       if (event->button == 2)
-                               folderview_select_node
-                                       (folderview,
-                                        gtk_ctree_node_nth(GTK_CTREE(ctree),
-                                                           row));
-                       else
-                               gtk_clist_select_row(clist, row, column);
-               }
-       }
-
-       if (event->button != 3) return FALSE;
+       if (row > 0)
+               item = gtk_clist_get_row_data(clist, row);
+       else
+               item = folderview_get_selected_item(folderview);
 
-       item = gtk_clist_get_row_data(clist, row);
-       g_return_val_if_fail(item != NULL, FALSE);
-       g_return_val_if_fail(item->folder != NULL, FALSE);
+       g_return_if_fail(item != NULL);
+       g_return_if_fail(item->folder != NULL);
        folder = item->folder;
 
        fpopup = g_hash_table_lookup(folderview_popups, folder->klass->idstr);
@@ -1921,6 +1897,63 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
                       event->button, event->time);
 
+
+}
+
+static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
+                                         FolderView *folderview)
+{
+       GtkCList *clist = GTK_CLIST(ctree);
+       gint prev_row = -1, row = -1, column = -1;
+
+       if (!event) return FALSE;
+
+       if (event->button == 1 || event->button == 2) {
+               folderview->open_folder = TRUE;
+
+               if (event->type == GDK_2BUTTON_PRESS) {
+                       if (clist->selection) {
+                               GtkCTreeNode *node;
+
+                               node = GTK_CTREE_NODE(clist->selection->data);
+                               if (node)
+                                       gtk_ctree_toggle_expansion(
+                                               GTK_CTREE(ctree),
+                                               node);
+                       }
+               }
+               return FALSE;
+       }
+
+       if (event->button == 2 || event->button == 3) {
+               /* right clicked */
+               if (clist->selection) {
+                       GtkCTreeNode *node;
+
+                       node = GTK_CTREE_NODE(clist->selection->data);
+                       if (node)
+                               prev_row = gtkut_ctree_get_nth_from_node
+                                       (GTK_CTREE(ctree), node);
+               }
+
+               if (!gtk_clist_get_selection_info(clist, event->x, event->y,
+                                                 &row, &column))
+                       return FALSE;
+               if (prev_row != row) {
+                       gtk_clist_unselect_all(clist);
+                       if (event->button == 2)
+                               folderview_select_node
+                                       (folderview,
+                                        gtk_ctree_node_nth(GTK_CTREE(ctree),
+                                                           row));
+                       else
+                               gtk_clist_select_row(clist, row, column);
+               }
+       }
+
+       if (event->button != 3) return FALSE;
+
+       folderview_set_sens_and_popup_menu(folderview, row, event);
        return FALSE;
 }
 
index a2b17af..7cac212 100644 (file)
@@ -1283,3 +1283,162 @@ GtkWidget *gtkut_sc_combobox_create(GtkWidget *eventbox, gboolean focus_on_click
 #endif
        return combobox;
 }
+
+static void gtkutils_smooth_scroll_do(GtkWidget *widget, GtkAdjustment *vadj,
+                                     gfloat old_value, gfloat last_value,
+                                     gint step)
+{
+       gint change_value;
+       gboolean up;
+       gint i;
+
+       if (old_value < last_value) {
+               change_value = last_value - old_value;
+               up = FALSE;
+       } else {
+               change_value = old_value - last_value;
+               up = TRUE;
+       }
+
+       for (i = step; i <= change_value; i += step) {
+               vadj->value = old_value + (up ? -i : i);
+               g_signal_emit_by_name(G_OBJECT(vadj),
+                                     "value_changed", 0);
+       }
+
+       vadj->value = last_value;
+       g_signal_emit_by_name(G_OBJECT(vadj), "value_changed", 0);
+
+       gtk_widget_queue_draw(widget);
+}
+
+static gboolean gtkutils_smooth_scroll_page(GtkWidget *widget, GtkAdjustment *vadj, gboolean up)
+{
+       gfloat upper;
+       gfloat page_incr;
+       gfloat old_value;
+       gfloat last_value;
+
+       if (prefs_common.scroll_halfpage)
+               page_incr = vadj->page_increment / 2;
+       else
+               page_incr = vadj->page_increment;
+
+       if (!up) {
+               upper = vadj->upper - vadj->page_size;
+               if (vadj->value < upper) {
+                       old_value = vadj->value;
+                       last_value = vadj->value + page_incr;
+                       last_value = MIN(last_value, upper);
+
+                       gtkutils_smooth_scroll_do(widget, vadj, old_value,
+                                                 last_value,
+                                                 prefs_common.scroll_step);
+               } else
+                       return FALSE;
+       } else {
+               if (vadj->value > 0.0) {
+                       old_value = vadj->value;
+                       last_value = vadj->value - page_incr;
+                       last_value = MAX(last_value, 0.0);
+
+                       gtkutils_smooth_scroll_do(widget, vadj, old_value,
+                                                 last_value,
+                                                 prefs_common.scroll_step);
+               } else
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+gboolean gtkutils_scroll_page(GtkWidget *widget, GtkAdjustment *vadj, gboolean up)
+{
+       gfloat upper;
+       gfloat page_incr;
+
+       if (prefs_common.enable_smooth_scroll)
+               return gtkutils_smooth_scroll_page(widget, vadj, up);
+
+       if (prefs_common.scroll_halfpage)
+               page_incr = vadj->page_increment / 2;
+       else
+               page_incr = vadj->page_increment;
+
+       if (!up) {
+               upper = vadj->upper - vadj->page_size;
+               if (vadj->value < upper) {
+                       vadj->value += page_incr;
+                       vadj->value = MIN(vadj->value, upper);
+                       g_signal_emit_by_name(G_OBJECT(vadj),
+                                             "value_changed", 0);
+               } else
+                       return FALSE;
+       } else {
+               if (vadj->value > 0.0) {
+                       vadj->value -= page_incr;
+                       vadj->value = MAX(vadj->value, 0.0);
+                       g_signal_emit_by_name(G_OBJECT(vadj),
+                                             "value_changed", 0);
+               } else
+                       return FALSE;
+       }
+       return TRUE;
+}
+
+static void gtkutils_smooth_scroll_one_line(GtkWidget *widget, GtkAdjustment *vadj, gboolean up)
+{
+       gfloat upper;
+       gfloat old_value;
+       gfloat last_value;
+
+       if (!up) {
+               upper = vadj->upper - vadj->page_size;
+               if (vadj->value < upper) {
+                       old_value = vadj->value;
+                       last_value = vadj->value + vadj->step_increment;
+                       last_value = MIN(last_value, upper);
+
+                       gtkutils_smooth_scroll_do(widget, vadj, old_value,
+                                                 last_value,
+                                                 prefs_common.scroll_step);
+               }
+       } else {
+               if (vadj->value > 0.0) {
+                       old_value = vadj->value;
+                       last_value = vadj->value - vadj->step_increment;
+                       last_value = MAX(last_value, 0.0);
+
+                       gtkutils_smooth_scroll_do(widget, vadj, old_value,
+                                                 last_value,
+                                                 prefs_common.scroll_step);
+               }
+       }
+}
+
+void gtkutils_scroll_one_line(GtkWidget *widget, GtkAdjustment *vadj, gboolean up)
+{
+       gfloat upper;
+
+       if (prefs_common.enable_smooth_scroll) {
+               gtkutils_smooth_scroll_one_line(widget, vadj, up);
+               return;
+       }
+
+       if (!up) {
+               upper = vadj->upper - vadj->page_size;
+               if (vadj->value < upper) {
+                       vadj->value += vadj->step_increment;
+                       vadj->value = MIN(vadj->value, upper);
+                       g_signal_emit_by_name(G_OBJECT(vadj),
+                                             "value_changed", 0);
+               }
+       } else {
+               if (vadj->value > 0.0) {
+                       vadj->value -= vadj->step_increment;
+                       vadj->value = MAX(vadj->value, 0.0);
+                       g_signal_emit_by_name(G_OBJECT(vadj),
+                                             "value_changed", 0);
+               }
+       }
+}
index 25815a5..54bcdef 100644 (file)
@@ -214,5 +214,10 @@ GtkWidget *face_get_from_header(const gchar *o_face);
 GtkWidget *gtkut_get_link_btn(GtkWidget *window, const gchar *url, const gchar *label);
 
 GtkWidget *gtkut_sc_combobox_create(GtkWidget *eventbox, gboolean focus_on_click);
-
+void gtkutils_scroll_one_line  (GtkWidget *widget, 
+                                GtkAdjustment *vadj, 
+                                gboolean up);
+gboolean gtkutils_scroll_page  (GtkWidget *widget, 
+                                GtkAdjustment *vadj, 
+                                gboolean up);
 #endif /* __GTKUTILS_H__ */
index 3a3cff2..371b35f 100644 (file)
@@ -1204,7 +1204,7 @@ static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                
        switch (event->keyval) {
        case GDK_space:
-               if (textview_scroll_page(mimeview->textview, FALSE))
+               if (mimeview_scroll_page(mimeview, FALSE))
                        return TRUE;
 
                node = GTK_CTREE_NODE_NEXT(mimeview->opened);
@@ -1215,10 +1215,10 @@ static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                }
                break;
        case GDK_BackSpace:
-               textview_scroll_page(mimeview->textview, TRUE);
+               mimeview_scroll_page(mimeview, TRUE);
                return TRUE;
        case GDK_Return:
-               textview_scroll_one_line(mimeview->textview,
+               mimeview_scroll_one_line(mimeview,
                                         (event->state & GDK_MOD1_MASK) != 0);
                return TRUE;
        case GDK_n:
@@ -1816,7 +1816,7 @@ static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
                if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
                        /* stop the button being untoggled */
                        KEY_PRESS_EVENT_STOP();
-                       if (textview_scroll_page(textview, FALSE))
+                       if (mimeview_scroll_page(mimeview, FALSE))
                                return TRUE;
 
                        if (icon_list_select_by_number(mimeview, num + 1))
@@ -1829,12 +1829,12 @@ static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
 
                break;
        case GDK_BackSpace:
-               textview_scroll_page(textview, TRUE);
+               mimeview_scroll_page(mimeview, TRUE);
                return TRUE;
        case GDK_Return:
                if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
                        KEY_PRESS_EVENT_STOP();
-                       textview_scroll_one_line(textview,
+                       mimeview_scroll_one_line(mimeview,
                                                 (event->state & GDK_MOD1_MASK) != 0);
                        return TRUE;
                } else {
@@ -2247,3 +2247,25 @@ void mimeview_handle_cmd(MimeView *mimeview, const gchar *cmd, GdkEventButton *e
        }
 }
 
+gboolean mimeview_scroll_page(MimeView *mimeview, gboolean up)
+{
+       if (mimeview->type == MIMEVIEW_TEXT)
+               return textview_scroll_page(mimeview->textview, up);
+       else if (mimeview->mimeviewer) {
+               MimeViewer *mimeviewer = mimeview->mimeviewer;
+               if (mimeviewer->scroll_page)
+                       return mimeviewer->scroll_page(mimeviewer, up);
+       }
+       return TRUE;
+}
+
+void mimeview_scroll_one_line(MimeView *mimeview, gboolean up)
+{
+       if (mimeview->type == MIMEVIEW_TEXT)
+               textview_scroll_one_line(mimeview->textview, up);
+       else if (mimeview->mimeviewer) {
+               MimeViewer *mimeviewer = mimeview->mimeviewer;
+               if (mimeviewer->scroll_one_line)
+                       mimeviewer->scroll_one_line(mimeviewer, up);
+       }
+}
index c2cf339..2e260b8 100644 (file)
@@ -123,6 +123,8 @@ struct _MimeViewer
        void            (*clear_viewer)         (MimeViewer *);
        void            (*destroy_viewer)       (MimeViewer *);
        gchar           *(*get_selection)       (MimeViewer *);
+       gboolean        (*scroll_page)          (MimeViewer *, gboolean up);
+       void            (*scroll_one_line)      (MimeViewer *, gboolean up);
        MimeView        *mimeview;
 };
 
@@ -156,6 +158,10 @@ void mimeview_handle_cmd           (MimeView       *mimeview,
                                         gpointer        data);
 void mimeview_select_mimepart_icon     (MimeView       *mimeview, 
                                         MimeInfo       *partinfo);
+gboolean mimeview_scroll_page          (MimeView       *mimeview, 
+                                        gboolean        up);
+void mimeview_scroll_one_line          (MimeView       *mimeview, 
+                                        gboolean        up);
 
 
 #ifdef __cplusplus
index 979ff1e..d651b95 100644 (file)
@@ -5184,7 +5184,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
        switch (event->keyval) {
        case GDK_space:         /* Page down or go to the next */
                if (event->state & GDK_SHIFT_MASK) 
-                       textview_scroll_page(textview, TRUE);
+                       mimeview_scroll_page(messageview->mimeview, TRUE);
                else {
                        if (summaryview->displayed != summaryview->selected) {
                                summary_display_msg(summaryview,
@@ -5192,16 +5192,16 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                                break;
                        }
                        if (mod_pressed) {
-                               if (!textview_scroll_page(textview, TRUE))
+                               if (!mimeview_scroll_page(messageview->mimeview, TRUE))
                                        summary_select_prev_unread(summaryview);
                        } else {
-                               if (!textview_scroll_page(textview, FALSE))
+                               if (!mimeview_scroll_page(messageview->mimeview, FALSE))
                                        summary_select_next_unread(summaryview);
                        }                               
                }
                break;
        case GDK_BackSpace:     /* Page up */
-               textview_scroll_page(textview, TRUE);
+               mimeview_scroll_page(messageview->mimeview, TRUE);
                break;
        case GDK_Return:        /* Scroll up/down one line */
                if (summaryview->displayed != summaryview->selected) {
@@ -5209,7 +5209,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                                            summaryview->selected);
                        break;
                }
-               textview_scroll_one_line(textview, mod_pressed);
+               mimeview_scroll_one_line(messageview->mimeview, mod_pressed);
                break;
        case GDK_Delete:
                BREAK_ON_MODIFIER_KEY();
index ef1585a..8c37ca8 100644 (file)
@@ -194,15 +194,6 @@ static gboolean textview_uri_button_pressed        (GtkTextTag     *tag,
                                                 GtkTextIter    *iter,
                                                 TextView       *textview);
 
-static void textview_smooth_scroll_do          (TextView       *textview,
-                                                gfloat          old_value,
-                                                gfloat          last_value,
-                                                gint            step);
-static void textview_smooth_scroll_one_line    (TextView       *textview,
-                                                gboolean        up);
-static gboolean textview_smooth_scroll_page    (TextView       *textview,
-                                                gboolean        up);
-
 static gboolean textview_uri_security_check    (TextView       *textview,
                                                 ClickableText  *uri);
 static void textview_uri_list_remove_all       (GSList         *uri_list);
@@ -1842,170 +1833,16 @@ void textview_scroll_one_line(TextView *textview, gboolean up)
 {
        GtkTextView *text = GTK_TEXT_VIEW(textview->text);
        GtkAdjustment *vadj = text->vadjustment;
-       gfloat upper;
-
-       if (prefs_common.enable_smooth_scroll) {
-               textview_smooth_scroll_one_line(textview, up);
-               return;
-       }
 
-       if (!up) {
-               upper = vadj->upper - vadj->page_size;
-               if (vadj->value < upper) {
-                       vadj->value += vadj->step_increment;
-                       vadj->value = MIN(vadj->value, upper);
-                       g_signal_emit_by_name(G_OBJECT(vadj),
-                                             "value_changed", 0);
-               }
-       } else {
-               if (vadj->value > 0.0) {
-                       vadj->value -= vadj->step_increment;
-                       vadj->value = MAX(vadj->value, 0.0);
-                       g_signal_emit_by_name(G_OBJECT(vadj),
-                                             "value_changed", 0);
-               }
-       }
+       gtkutils_scroll_one_line(text, vadj, up);
 }
 
 gboolean textview_scroll_page(TextView *textview, gboolean up)
 {
        GtkTextView *text = GTK_TEXT_VIEW(textview->text);
        GtkAdjustment *vadj = text->vadjustment;
-       gfloat upper;
-       gfloat page_incr;
-
-       if (prefs_common.enable_smooth_scroll)
-               return textview_smooth_scroll_page(textview, up);
-
-       if (prefs_common.scroll_halfpage)
-               page_incr = vadj->page_increment / 2;
-       else
-               page_incr = vadj->page_increment;
-
-       if (!up) {
-               upper = vadj->upper - vadj->page_size;
-               if (vadj->value < upper) {
-                       vadj->value += page_incr;
-                       vadj->value = MIN(vadj->value, upper);
-                       g_signal_emit_by_name(G_OBJECT(vadj),
-                                             "value_changed", 0);
-               } else
-                       return FALSE;
-       } else {
-               if (vadj->value > 0.0) {
-                       vadj->value -= page_incr;
-                       vadj->value = MAX(vadj->value, 0.0);
-                       g_signal_emit_by_name(G_OBJECT(vadj),
-                                             "value_changed", 0);
-               } else
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-static void textview_smooth_scroll_do(TextView *textview,
-                                     gfloat old_value, gfloat last_value,
-                                     gint step)
-{
-       GtkTextView *text = GTK_TEXT_VIEW(textview->text);
-       GtkAdjustment *vadj = text->vadjustment;
-       gint change_value;
-       gboolean up;
-       gint i;
-
-       if (old_value < last_value) {
-               change_value = last_value - old_value;
-               up = FALSE;
-       } else {
-               change_value = old_value - last_value;
-               up = TRUE;
-       }
 
-       for (i = step; i <= change_value; i += step) {
-               vadj->value = old_value + (up ? -i : i);
-               g_signal_emit_by_name(G_OBJECT(vadj),
-                                     "value_changed", 0);
-       }
-
-       vadj->value = last_value;
-       g_signal_emit_by_name(G_OBJECT(vadj), "value_changed", 0);
-
-       gtk_widget_queue_draw(GTK_WIDGET(text));
-}
-
-static void textview_smooth_scroll_one_line(TextView *textview, gboolean up)
-{
-       GtkTextView *text = GTK_TEXT_VIEW(textview->text);
-       GtkAdjustment *vadj = text->vadjustment;
-       gfloat upper;
-       gfloat old_value;
-       gfloat last_value;
-
-       if (!up) {
-               upper = vadj->upper - vadj->page_size;
-               if (vadj->value < upper) {
-                       old_value = vadj->value;
-                       last_value = vadj->value + vadj->step_increment;
-                       last_value = MIN(last_value, upper);
-
-                       textview_smooth_scroll_do(textview, old_value,
-                                                 last_value,
-                                                 prefs_common.scroll_step);
-               }
-       } else {
-               if (vadj->value > 0.0) {
-                       old_value = vadj->value;
-                       last_value = vadj->value - vadj->step_increment;
-                       last_value = MAX(last_value, 0.0);
-
-                       textview_smooth_scroll_do(textview, old_value,
-                                                 last_value,
-                                                 prefs_common.scroll_step);
-               }
-       }
-}
-
-static gboolean textview_smooth_scroll_page(TextView *textview, gboolean up)
-{
-       GtkTextView *text = GTK_TEXT_VIEW(textview->text);
-       GtkAdjustment *vadj = text->vadjustment;
-       gfloat upper;
-       gfloat page_incr;
-       gfloat old_value;
-       gfloat last_value;
-
-       if (prefs_common.scroll_halfpage)
-               page_incr = vadj->page_increment / 2;
-       else
-               page_incr = vadj->page_increment;
-
-       if (!up) {
-               upper = vadj->upper - vadj->page_size;
-               if (vadj->value < upper) {
-                       old_value = vadj->value;
-                       last_value = vadj->value + page_incr;
-                       last_value = MIN(last_value, upper);
-
-                       textview_smooth_scroll_do(textview, old_value,
-                                                 last_value,
-                                                 prefs_common.scroll_step);
-               } else
-                       return FALSE;
-       } else {
-               if (vadj->value > 0.0) {
-                       old_value = vadj->value;
-                       last_value = vadj->value - page_incr;
-                       last_value = MAX(last_value, 0.0);
-
-                       textview_smooth_scroll_do(textview, old_value,
-                                                 last_value,
-                                                 prefs_common.scroll_step);
-               } else
-                       return FALSE;
-       }
-
-       return TRUE;
+       return gtkutils_scroll_page(text, vadj, up);
 }
 
 #define KEY_PRESS_EVENT_STOP() \
@@ -2039,17 +1876,17 @@ static gint textview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                if (summaryview)
                        summary_pass_key_press_event(summaryview, event);
                else
-                       textview_scroll_page
-                               (textview,
+                       mimeview_scroll_page
+                               (messageview->mimeview,
                                 (event->state &
                                  (GDK_SHIFT_MASK|GDK_MOD1_MASK)) != 0);
                break;
        case GDK_BackSpace:
-               textview_scroll_page(textview, TRUE);
+               mimeview_scroll_page(messageview->mimeview, TRUE);
                break;
        case GDK_Return:
-               textview_scroll_one_line
-                       (textview, (event->state &
+               mimeview_scroll_one_line
+                       (messageview->mimeview, (event->state &
                                    (GDK_SHIFT_MASK|GDK_MOD1_MASK)) != 0);
                break;
        case GDK_Delete: