2006-08-22 [colin] 2.4.0cvs73
authorColin Leroy <colin@colino.net>
Tue, 22 Aug 2006 16:28:00 +0000 (16:28 +0000)
committerColin Leroy <colin@colino.net>
Tue, 22 Aug 2006 16:28:00 +0000 (16:28 +0000)
* src/folder.c
Set folder's mtime after writing its
cache
* src/folderview.c
Add some timing
* src/procmsg.c
Don't do useless stuff if we don't
thread by subject
* src/summaryview.c
Add some timing, don't deselect prior
to selecting (gtksctree does it itself),
remove crash avoidance hacks as it's been
properly fixed since a while
* src/common/utils.c
Optimize to_human_readable(): _() is slow,
do it only once, and avoid %f format for KB
(the most common in a summaryview)
* src/gtk/gtksctree.c
Don't uselessly freeze/thaw (fixes flicker
on next unread and friends), reduce number
of g_list_nth/g_list_position where possible
* src/gtk/gtkutils.c
* src/gtk/gtkutils.h
Reduce number of g_list_nth/g_list_position
where possible.
All of this makes loading as 70k folder 2.1
seconds instead of 3.2 (with hot FS caches).
(1.3 seconds without Date and Size columns...)

ChangeLog
PATCHSETS
configure.ac
src/common/utils.c
src/folder.c
src/folderview.c
src/gtk/gtksctree.c
src/gtk/gtkutils.c
src/gtk/gtkutils.h
src/procmsg.c
src/summaryview.c

index 8c37ca7..a7d4a20 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2006-08-22 [colin]     2.4.0cvs73
+
+       * src/folder.c
+               Set folder's mtime after writing its
+               cache
+       * src/folderview.c
+               Add some timing
+       * src/procmsg.c
+               Don't do useless stuff if we don't 
+               thread by subject
+       * src/summaryview.c
+               Add some timing, don't deselect prior
+               to selecting (gtksctree does it itself),
+               remove crash avoidance hacks as it's been
+               properly fixed since a while
+       * src/common/utils.c
+               Optimize to_human_readable(): _() is slow,
+               do it only once, and avoid %f format for KB
+               (the most common in a summaryview)
+       * src/gtk/gtksctree.c
+               Don't uselessly freeze/thaw (fixes flicker
+               on next unread and friends), reduce number
+               of g_list_nth/g_list_position where possible
+       * src/gtk/gtkutils.c
+       * src/gtk/gtkutils.h
+               Reduce number of g_list_nth/g_list_position
+               where possible.
+               All of this makes loading as 70k folder 2.1
+               seconds instead of 3.2 (with hot FS caches).
+               (1.3 seconds without Date and Size columns...)
+
 2006-08-22 [paul]      2.4.0cvs72
 
        wrap documents and do some items from mones' MANUAL-TODO:
index e2ab26a..d3a2af6 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/Makefile.am;  cvs diff -u -r 1.60.2.61 -r 1.60.2.62 src/addressbook.c;  cvs diff -u -r 1.3.2.42 -r 1.3.2.43 src/prefs_themes.c;  cvs diff -u -r 1.5.2.37 -r 1.5.2.38 src/gtk/gtkutils.c;  cvs diff -u -r 1.5.2.32 -r 1.5.2.33 src/gtk/pluginwindow.c;  cvs diff -u -r 1.1.2.12 -r 1.1.2.13 src/plugins/pgpcore/prefs_gpg.c;  cvs diff -u -r 1.1.2.26 -r 1.1.2.27 src/plugins/pgpcore/sgpgme.c;  ) > 2.4.0cvs70.patchset
 ( cvs diff -u -r 1.5.2.33 -r 1.5.2.34 src/gtk/pluginwindow.c;  ) > 2.4.0cvs71.patchset
 ( cvs diff -u -r 1.1.2.6 -r 1.1.2.7 manual/account.xml;  cvs diff -u -r 1.1.2.9 -r 1.1.2.10 manual/faq.xml;  cvs diff -u -r 1.1.2.8 -r 1.1.2.9 manual/handling.xml;  ) > 2.4.0cvs72.patchset
+( cvs diff -u -r 1.213.2.106 -r 1.213.2.107 src/folder.c;  cvs diff -u -r 1.207.2.112 -r 1.207.2.113 src/folderview.c;  cvs diff -u -r 1.150.2.73 -r 1.150.2.74 src/procmsg.c;  cvs diff -u -r 1.395.2.230 -r 1.395.2.231 src/summaryview.c;  cvs diff -u -r 1.36.2.75 -r 1.36.2.76 src/common/utils.c;  cvs diff -u -r 1.1.4.21 -r 1.1.4.22 src/gtk/gtksctree.c;  cvs diff -u -r 1.5.2.38 -r 1.5.2.39 src/gtk/gtkutils.c;  cvs diff -u -r 1.4.2.23 -r 1.4.2.24 src/gtk/gtkutils.h;  ) > 2.4.0cvs73.patchset
index cf46011..62bd591 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=4
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=72
+EXTRA_VERSION=73
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index a069522..111c329 100644 (file)
@@ -334,20 +334,44 @@ gchar *itos(gint n)
        return itos_buf(nstr, n);
 }
 
+#define divide(num,divisor,i,d)                \
+{                                      \
+       register int tmp;               \
+       i = num/divisor;                \
+       tmp = i*divisor;                \
+       d = num-tmp;                    \
+       if (d > 1000) d /= 1000;        \
+       else if (d > 100) d /= 100;     \
+       else if (d > 10) d /= 10;               \
+}
+
 gchar *to_human_readable(off_t size)
 {
        static gchar str[14];
-
-       if (size < 1024)
-               g_snprintf(str, sizeof(str), _("%dB"), (gint)size);
-       else if (size >> 10 < 1024)
-               g_snprintf(str, sizeof(str), _("%.1fKB"), (gfloat)size / (1 << 10));
-       else if (size >> 20 < 1024)
-               g_snprintf(str, sizeof(str), _("%.2fMB"), (gfloat)size / (1 << 20));
-       else
-               g_snprintf(str, sizeof(str), _("%.2fGB"), (gfloat)size / (1 << 30));
-
-       return str;
+       static gchar *b_format = NULL, *kb_format = NULL, 
+                    *mb_format = NULL, *gb_format = NULL;
+       register int t = 0, r = 0;
+       if (b_format == NULL) {
+               b_format  = _("%dB");
+               kb_format = _("%d.%dKB");
+               mb_format = _("%.2fMB");
+               gb_format = _("%.2fGB");
+       }
+       
+       if (size < 1024) {
+               g_snprintf(str, sizeof(str), b_format, (gint)size);
+               return str;
+       } else if (size >> 10 < 1024) {
+               divide(size, (1 << 10), t, r);
+               g_snprintf(str, sizeof(str), kb_format, t, r);
+               return str;
+       } else if (size >> 20 < 1024) {
+               g_snprintf(str, sizeof(str), mb_format, (gfloat)size / (1 << 20));
+               return str;
+       } else {
+               g_snprintf(str, sizeof(str), gb_format, (gfloat)size / (1 << 30));
+               return str;
+       }
 }
 
 /* strcmp with NULL-checking */
index 23b4ab9..8793a75 100644 (file)
@@ -2277,6 +2277,9 @@ void folder_item_write_cache(FolderItem *item)
                }
         }
 
+       if (FOLDER_TYPE(item->folder) == F_MH)
+               item->mtime = time(NULL);
+
        g_free(cache_file);
        g_free(mark_file);
 }
index d195286..e905c13 100644 (file)
@@ -67,6 +67,7 @@
 #include "filtering.h"
 #include "quicksearch.h"
 #include "manual.h"
+#include "timing.h"
 
 #define COL_FOLDER_WIDTH       150
 #define COL_NUM_WIDTH          32
@@ -2000,11 +2001,12 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
        FolderItem *item;
        gchar *buf;
        int res = 0;
-
+       START_TIMING("--- folderview_selected");
        folderview->selected = row;
 
        if (folderview->opened == row) {
                folderview->open_folder = FALSE;
+               END_TIMING();
                return;
        }
        
@@ -2013,13 +2015,19 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
                        gtkut_ctree_set_focus_row(ctree, folderview->opened);
                        gtk_ctree_select(ctree, folderview->opened);
                }
+               END_TIMING();
                return;
        }
 
-       if (!folderview->open_folder) return;
-
+       if (!folderview->open_folder) {
+               END_TIMING();
+               return;
+       }
        item = gtk_ctree_node_get_row_data(ctree, row);
-       if (!item || item->no_select) return;
+       if (!item || item->no_select) {
+               END_TIMING();
+               return;
+       }
 
        can_select = FALSE;
 
@@ -2086,7 +2094,7 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
 
                folderview->open_folder = FALSE;
                can_select = TRUE;
-
+               END_TIMING();
                return;
         } else if (res == -2) {
                PostponedSelectData *data = g_new0(PostponedSelectData, 1);
@@ -2099,6 +2107,7 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
                folderview->open_folder = FALSE;
                can_select = TRUE;
                g_timeout_add(500, postpone_select, data);
+               END_TIMING();
                return;
        }
        
@@ -2124,6 +2133,7 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
 
        folderview->open_folder = FALSE;
        can_select = TRUE;
+       END_TIMING();
 }
 
 static void folderview_tree_expanded(GtkCTree *ctree, GtkCTreeNode *node,
index 0926f40..851c0ea 100644 (file)
@@ -255,8 +255,11 @@ select_range (GtkSCTree *sctree, gint row)
 }
 
 /* Handles row selection according to the specified modifier state */
+/* in certain cases, we arrive here from a function knowing the GtkCTreeNode, and having
+ * already slowly found row using g_list_position. In which case, _node will be non-NULL
+ * to avoid this function having to slowly find it with g_list_nth. */
 static void
-select_row (GtkSCTree *sctree, gint row, gint col, guint state)
+select_row (GtkSCTree *sctree, gint row, gint col, guint state, GtkCTreeNode *_node)
 {
        gboolean range, additive;
        g_return_if_fail (sctree != NULL);
@@ -269,20 +272,41 @@ select_row (GtkSCTree *sctree, gint row, gint col, guint state)
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_SINGLE) &&
                   (GTK_CLIST(sctree)->selection_mode != GTK_SELECTION_BROWSE);
 
-       gtk_clist_freeze (GTK_CLIST (sctree));
+       /* heavy GUI updates will be done only if we're selecting a range.
+        * additive selection is ctrl-click, where the user is the slow factor.
+        * So we only freeze the list if selecting a range (potentially thousands 
+        * of lines. */
+       if (range)
+               gtk_clist_freeze (GTK_CLIST (sctree));
 
        GTK_CLIST(sctree)->focus_row = row;
 
        if (!additive) {
-               sctree->selecting_range = TRUE;
+               /* if this selection isn't additive, we have to unselect what
+                * is selected. Here, heavy GUI updates can occur if we have 
+                * a big selection. See if more than one line is selected, in
+                * which case, freeze, else don't. */
+
+               gboolean should_freeze = FALSE;
+               if (GTK_CLIST(sctree)->selection
+                && GTK_CLIST(sctree)->selection->next) {
+                       should_freeze = TRUE;
+                       sctree->selecting_range = TRUE;
+                       gtk_clist_freeze (GTK_CLIST (sctree));
+               }
+
                gtk_clist_unselect_all (GTK_CLIST (sctree));
-               sctree->selecting_range = FALSE;
+
+               if (should_freeze) {
+                       gtk_clist_thaw (GTK_CLIST (sctree));
+                       sctree->selecting_range = FALSE;
+               }
        }
 
        if (!range) {
                GtkCTreeNode *node;
 
-               node = gtk_ctree_node_nth (GTK_CTREE(sctree), row);
+               node = _node ? _node : gtk_ctree_node_nth (GTK_CTREE(sctree), row);
 
                /*No need to manage overlapped list*/
                if (additive) {
@@ -301,7 +325,8 @@ select_row (GtkSCTree *sctree, gint row, gint col, guint state)
        } else
                select_range (sctree, row);
        
-       gtk_clist_thaw (GTK_CLIST (sctree));
+       if (range)
+               gtk_clist_thaw (GTK_CLIST (sctree));
 }
 
 /* Our handler for button_press events.  We override all of GtkCList's broken
@@ -360,7 +385,7 @@ gtk_sctree_button_press (GtkWidget *widget, GdkEventButton *event)
                                        sctree->dnd_select_pending_state = event->state;
                                        sctree->dnd_select_pending_row = row;
                                } else {
-                                       select_row (sctree, row, col, event->state);
+                                       select_row (sctree, row, col, event->state, NULL);
                                }
                        } else {
                                sctree->selecting_range = TRUE;
@@ -373,7 +398,7 @@ gtk_sctree_button_press (GtkWidget *widget, GdkEventButton *event)
                        /* Emit *_popup_menu signal*/
                        if (on_row) {
                                if (!row_is_selected(sctree,row))
-                                       select_row (sctree, row, col, 0);
+                                       select_row (sctree, row, col, 0, NULL);
                                g_signal_emit (G_OBJECT (sctree),
                                                 sctree_signals[ROW_POPUP_MENU],
                                                 0, event);
@@ -445,7 +470,7 @@ gtk_sctree_button_release (GtkWidget *widget, GdkEventButton *event)
 
        if (on_row) {
                if (sctree->dnd_select_pending) {
-                       select_row (sctree, row, col, sctree->dnd_select_pending_state);
+                       select_row (sctree, row, col, sctree->dnd_select_pending_state, NULL);
                        sctree->dnd_select_pending = FALSE;
                        sctree->dnd_select_pending_state = 0;
                }
@@ -492,7 +517,8 @@ gtk_sctree_motion (GtkWidget *widget, GdkEventMotion *event)
                        select_row (sctree,
                                    sctree->dnd_select_pending_row,
                                    -1,
-                                   sctree->dnd_select_pending_state);
+                                   sctree->dnd_select_pending_state,
+                                   NULL);
 
                sctree->dnd_select_pending = FALSE;
                sctree->dnd_select_pending_state = 0;
@@ -620,14 +646,14 @@ void gtk_sctree_select (GtkSCTree *sctree, GtkCTreeNode *node)
 {
        select_row(sctree, 
                   g_list_position(GTK_CLIST(sctree)->row_list, (GList *)node),
-                  -1, 0);
+                  -1, 0, node);
 }
 
 void gtk_sctree_select_with_state (GtkSCTree *sctree, GtkCTreeNode *node, int state)
 {
        select_row(sctree, 
                   g_list_position(GTK_CLIST(sctree)->row_list, (GList *)node),
-                  -1, state);
+                  -1, state, node);
 }
 
 void gtk_sctree_unselect_all (GtkSCTree *sctree)
index a3df654..a2b17af 100644 (file)
@@ -275,7 +275,7 @@ ComboButton *gtkut_combo_button_create(GtkWidget *button,
 #define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \
                                   ((clist)->row_height + CELL_SPACING))
 
-void gtkut_ctree_node_move_if_on_the_edge(GtkCTree *ctree, GtkCTreeNode *node)
+void gtkut_ctree_node_move_if_on_the_edge(GtkCTree *ctree, GtkCTreeNode *node, gint _row)
 {
        GtkCList *clist = GTK_CLIST(ctree);
        gint row;
@@ -284,7 +284,8 @@ void gtkut_ctree_node_move_if_on_the_edge(GtkCTree *ctree, GtkCTreeNode *node)
        g_return_if_fail(ctree != NULL);
        g_return_if_fail(node != NULL);
 
-       row = g_list_position(clist->row_list, (GList *)node);
+       row = (_row != -1 ? _row : g_list_position(clist->row_list, (GList *)node));
+
        if (row < 0 || row >= clist->rows || clist->row_height == 0) return;
        row_visibility = gtk_clist_row_is_visible(clist, row);
        prev_row_visibility = gtk_clist_row_is_visible(clist, row - 1);
index ca8d884..25815a5 100644 (file)
@@ -120,7 +120,8 @@ ComboButton *gtkut_combo_button_create      (GtkWidget              *button,
 
 void gtkut_ctree_node_move_if_on_the_edge
                                        (GtkCTree       *ctree,
-                                        GtkCTreeNode   *node);
+                                        GtkCTreeNode   *node,
+                                        gint            _row);
 gint gtkut_ctree_get_nth_from_node     (GtkCTree       *ctree,
                                         GtkCTreeNode   *node);
 GtkCTreeNode *gtkut_ctree_node_next    (GtkCTree       *ctree,
index 1069639..85c889e 100644 (file)
@@ -251,8 +251,11 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
        START_TIMING("procmsg_get_thread_tree");
        root = g_node_new(NULL);
        msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
-       subject_relation = g_relation_new(2);
-       g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);
+       
+       if (prefs_common.thread_by_subject) {
+               subject_relation = g_relation_new(2);
+               g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);
+       }
 
        for (; mlist != NULL; mlist = mlist->next) {
                msginfo = (MsgInfo *)mlist->data;
@@ -334,7 +337,9 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
                END_TIMING();
        }
        
-       g_relation_destroy(subject_relation);
+       if (prefs_common.thread_by_subject)
+               g_relation_destroy(subject_relation);
+
        g_hash_table_destroy(msgid_table);
        END_TIMING();
        return root;
index 832332c..d885d6f 100644 (file)
@@ -854,7 +854,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        if (!summaryview->mainwin)
                return FALSE;
-
+START_TIMING("--------- summary_show");
        summaryview->last_displayed = NULL;
        summary_switch_from_to(summaryview, item);
 
@@ -901,6 +901,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                } else {
                        summary_unlock(summaryview);
                        inc_unlock();
+                       END_TIMING();
                        return FALSE;
                }
                if (changed || !quicksearch_is_active(summaryview->quicksearch))
@@ -933,7 +934,8 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                                              summaryview->folderview,
                                              summaryview->folder_item);
                        main_window_cursor_normal(summaryview->mainwin);
-               }                       
+               }       
+               END_TIMING();           
                return TRUE;
        }
        g_free(buf);
@@ -1018,6 +1020,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                        summary_unlock(summaryview);
                        inc_unlock();
                        summary_show(summaryview, summaryview->folder_item);
+                       END_TIMING();
                        return FALSE;
                }
                g_slist_free(mlist);
@@ -1169,7 +1172,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        main_window_cursor_normal(summaryview->mainwin);
        summary_unlock(summaryview);
        inc_unlock();
-
+       END_TIMING();
        return TRUE;
 }
 
@@ -1766,18 +1769,8 @@ void summary_select_node(SummaryView *summaryview, GtkCTreeNode *node,
                        GTK_EVENTS_FLUSH();
                        summary_unlock(summaryview);
                        gtk_widget_grab_focus(GTK_WIDGET(ctree));
-                       if (GTK_CTREE_ROW(node) == NULL) {
-                               g_warning("crash avoidance hack 1\n");
-                               return;
-                       }
-                       if (((GtkCListRow *)(GTK_CTREE_ROW(node)))->state < GTK_STATE_NORMAL
-                       ||  ((GtkCListRow *)(GTK_CTREE_ROW(node)))->state > GTK_STATE_INSENSITIVE) {
-                               g_warning("crash avoidance hack 2\n");
-                               return;
-                       }
                        gtk_ctree_node_moveto(ctree, node, 0, 0.5, 0);
                }
-               summary_unselect_all(summaryview);
                if (display_msg && summaryview->displayed == node)
                        summaryview->displayed = NULL;
                summaryview->display_msg = display_msg;
@@ -2593,6 +2586,7 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        else
                text[col_pos[S_COL_NUMBER]] = "";
 
+       /* slow! */
        if (summaryview->col_state[summaryview->col_pos[S_COL_SIZE]].visible)
                text[col_pos[S_COL_SIZE]] = to_human_readable(msginfo->size);
        else
@@ -2603,6 +2597,7 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        else
                text[col_pos[S_COL_SCORE]] = "";
 
+       /* slow! */
        if (summaryview->col_state[summaryview->col_pos[S_COL_DATE]].visible) {
                if (msginfo->date_t) {
                        procheader_date_get_localtime(date_modified,
@@ -2849,7 +2844,8 @@ static void summary_display_msg_full(SummaryView *summaryview,
                val = messageview_show(msgview, msginfo, all_headers);
                if (GTK_CLIST(msgview->mimeview->ctree)->row_list == NULL)
                        gtk_widget_grab_focus(summaryview->ctree);
-               gtkut_ctree_node_move_if_on_the_edge(ctree, row);
+               gtkut_ctree_node_move_if_on_the_edge(ctree, row,
+                       GTK_CLIST(summaryview->ctree)->focus_row);
        }
 
        if (val == 0 && MSG_IS_UNREAD(msginfo->flags)) {