aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2002-06-18 03:58:22 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2002-06-18 03:58:22 +0800
commit6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e (patch)
tree247bf2fe7ba662a6b29c7ab68e92a22c47b2ac78 /mail
parentc1d568de74f928d28a8cf0f9f02028b69e068f80 (diff)
downloadgsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar.gz
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar.bz2
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar.lz
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar.xz
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.tar.zst
gsoc2013-evolution-6bd5d23da7d5676989cd40ce848c4b8bbb6f7f3e.zip
New convenience function to get a cached normalised string.
2002-06-17 Jeffrey Stedfast <fejj@ximian.com> * message-list.c (get_normalised_string): New convenience function to get a cached normalised string. (subject_compare): Removed, as we strip Re:'s when normalising the subject strings now. (ml_tree_value_at): Added support for the normalised columns (used for a sorting optimisation). (message_list_init): Initialise normalised_hash. (message_list_destroy): Destroy normalised_hash. (message_list_create_extras): Removed subject_compare. (main_folder_changed): De-cache normalised strings for any removed uids. svn path=/trunk/; revision=17213
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog14
-rw-r--r--mail/message-list.c183
-rw-r--r--mail/message-list.etspec28
-rw-r--r--mail/message-list.h11
4 files changed, 164 insertions, 72 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 74cac78fae..be51adaa64 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,17 @@
+2002-06-17 Jeffrey Stedfast <fejj@ximian.com>
+
+ * message-list.c (get_normalised_string): New convenience function
+ to get a cached normalised string.
+ (subject_compare): Removed, as we strip Re:'s when normalising the
+ subject strings now.
+ (ml_tree_value_at): Added support for the normalised columns (used
+ for a sorting optimisation).
+ (message_list_init): Initialise normalised_hash.
+ (message_list_destroy): Destroy normalised_hash.
+ (message_list_create_extras): Removed subject_compare.
+ (main_folder_changed): De-cache normalised strings for any removed
+ uids.
+
2002-06-17 Not Zed <NotZed@Ximian.com>
* message-list.c (regen_list_regen): If we dont support searching,
diff --git a/mail/message-list.c b/mail/message-list.c
index e868744d3d..1d5c4595d4 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -93,6 +93,13 @@
#define COL_SIZE_EXPANSION (6.0)
#define COL_SIZE_WIDTH_MIN (32)
+enum {
+ NORMALISED_SUBJECT,
+ NORMALISED_FROM,
+ NORMALISED_TO,
+ NORMALISED_LAST,
+};
+
#define PARENT_TYPE (e_tree_scrolled_get_type ())
/* #define SMART_ADDRESS_COMPARE */
@@ -196,12 +203,15 @@ e_mail_address_free (EMailAddress *addr)
g_free (addr);
}
-static gint
+/* Note: by the time this function is called, the strings have already
+ been normalised which means we can assume all lowercase chars and
+ we can just use strcmp for the final comparison. */
+static int
e_mail_address_compare (gconstpointer address1, gconstpointer address2)
{
const EMailAddress *addr1 = address1;
const EMailAddress *addr2 = address2;
- gint retval;
+ int retval;
g_return_val_if_fail (addr1 != NULL, 1);
g_return_val_if_fail (addr2 != NULL, -1);
@@ -211,7 +221,7 @@ e_mail_address_compare (gconstpointer address1, gconstpointer address2)
g_return_val_if_fail (addr1->address != NULL, 1);
g_return_val_if_fail (addr2->address != NULL, -1);
- return g_strcasecmp (addr1->address, addr2->address);
+ return strcmp (addr1->address, addr2->address);
}
if (!addr1->wname)
@@ -224,44 +234,47 @@ e_mail_address_compare (gconstpointer address1, gconstpointer address2)
/* FIXME: what do we compare next? */
g_return_val_if_fail (addr1->address != NULL, 1);
g_return_val_if_fail (addr2->address != NULL, -1);
-
- return g_strcasecmp (addr1->address, addr2->address);
- }
+
+ return strcmp (addr1->address, addr2->address);
+ }
if (!addr1->wname->last)
return -1;
if (!addr2->wname->last)
return 1;
- retval = g_utf8_collate (addr1->wname->last, addr2->wname->last);
- if (retval)
+ retval = strcmp (addr1->wname->last, addr2->wname->last);
+ if (retval)
return retval;
/* last names are identical - compare first names */
if (!addr1->wname->first && !addr2->wname->first)
- return g_strcasecmp (addr1->address, addr2->address);
+ return strcmp (addr1->address, addr2->address);
if (!addr1->wname->first)
return -1;
if (!addr2->wname->first)
return 1;
- retval = g_utf8_collate (addr1->wname->first, addr2->wname->first);
- if (retval)
+ retval = strcmp (addr1->wname->first, addr2->wname->first);
+ if (retval)
return retval;
- return g_strcasecmp (addr1->address, addr2->address);
+ return strcmp (addr1->address, addr2->address);
}
#endif /* SMART_ADDRESS_COMPARE */
-static gint
+/* Note: by the time this function is called, the strings have already
+ been normalised which means we can assume all lowercase chars and
+ we can just use strcmp for the final comparison. */
+static int
address_compare (gconstpointer address1, gconstpointer address2)
{
#ifdef SMART_ADDRESS_COMPARE
EMailAddress *addr1, *addr2;
#endif /* SMART_ADDRESS_COMPARE */
- gint retval;
+ int retval;
g_return_val_if_fail (address1 != NULL, 1);
g_return_val_if_fail (address2 != NULL, -1);
@@ -273,47 +286,12 @@ address_compare (gconstpointer address1, gconstpointer address2)
e_mail_address_free (addr1);
e_mail_address_free (addr2);
#else
- retval = g_utf8_collate ((const char *) address1, (const char *) address2);
+ retval = strcmp ((const char *) address1, (const char *) address2);
#endif /* SMART_ADDRESS_COMPARE */
return retval;
}
-static gint
-subject_compare (gconstpointer subject1, gconstpointer subject2)
-{
- char *sub1;
- char *sub2;
-
- g_return_val_if_fail (subject1 != NULL, 1);
- g_return_val_if_fail (subject2 != NULL, -1);
-
- /* trim off any "Re:"'s at the beginning of subject1 */
- sub1 = (char *) subject1;
- while (!g_strncasecmp (sub1, "Re:", 3)) {
- sub1 += 3;
- /* jump over any spaces */
- while (*sub1 && g_unichar_isspace (g_utf8_get_char (sub1)))
- sub1 = g_utf8_next_char (sub1);
- }
-
- /* trim off any "Re:"'s at the beginning of subject2 */
- sub2 = (char *) subject2;
- while (!g_strncasecmp (sub2, "Re:", 3)) {
- sub2 += 3;
- while (*sub2 && g_unichar_isspace (g_utf8_get_char (sub2)))
- sub2 = g_utf8_next_char (sub2);
- }
-
- /* jump over any spaces */
- while (*sub1 && g_unichar_isspace (g_utf8_get_char (sub1)))
- sub1 = g_utf8_next_char (sub1);
- while (*sub2 && g_unichar_isspace (g_utf8_get_char (sub2)))
- sub2 = g_utf8_next_char (sub2);
-
- return g_utf8_collate (sub1, sub2);
-}
-
static gchar *
filter_size (gint size)
{
@@ -361,6 +339,72 @@ get_message_info (MessageList *message_list, ETreePath node)
return info;
}
+static const char *
+get_normalised_string (MessageList *message_list, CamelMessageInfo *info, int col)
+{
+ const char *string, *str;
+ char *normalised;
+ EPoolv *poolv;
+ int index;
+
+ switch (col) {
+ case COL_SUBJECT_NORM:
+ string = camel_message_info_subject (info);
+ index = NORMALISED_SUBJECT;
+ break;
+ case COL_FROM_NORM:
+ string = camel_message_info_from (info);
+ index = NORMALISED_FROM;
+ break;
+ case COL_TO_NORM:
+ string = camel_message_info_to (info);
+ index = NORMALISED_TO;
+ break;
+ default:
+ string = NULL;
+ index = NORMALISED_LAST;
+ g_assert_not_reached ();
+ }
+
+ /* slight optimisation */
+ if (string == NULL || string[0] == '\0')
+ return "";
+
+ poolv = g_hash_table_lookup (message_list->normalised_hash, camel_message_info_uid (info));
+ if (poolv == NULL) {
+ poolv = e_poolv_new (NORMALISED_LAST);
+ g_hash_table_insert (message_list->normalised_hash, (char *) camel_message_info_uid (info), poolv);
+ } else {
+ str = e_poolv_get (poolv, index);
+ if (*str)
+ return str;
+ }
+
+ if (col == COL_SUBJECT_NORM) {
+ const unsigned char *subject;
+
+ subject = (const unsigned char *) string;
+ while (!g_strncasecmp (subject, "Re:", 3)) {
+ subject += 3;
+
+ /* jump over any spaces */
+ while (*subject && isspace ((int) *subject))
+ subject++;
+ }
+
+ /* jump over any spaces */
+ while (*subject && isspace ((int) *subject))
+ subject++;
+
+ string = (const char *) subject;
+ }
+
+ normalised = g_utf8_collate_key (string, -1);
+ e_poolv_set (poolv, index, normalised, TRUE);
+
+ return e_poolv_get (poolv, index);
+}
+
struct search_func_data {
MessageList *message_list;
guint32 flags;
@@ -904,14 +948,20 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data)
return GINT_TO_POINTER ((msg_info->flags & CAMEL_MESSAGE_ATTACHMENTS) != 0);
case COL_FROM:
return (void *)camel_message_info_from(msg_info);
+ case COL_FROM_NORM:
+ return (void *)get_normalised_string (message_list, msg_info, col);
case COL_SUBJECT:
return (void *)camel_message_info_subject(msg_info);
+ case COL_SUBJECT_NORM:
+ return (void *)get_normalised_string (message_list, msg_info, col);
case COL_SENT:
return GINT_TO_POINTER (msg_info->date_sent);
case COL_RECEIVED:
return GINT_TO_POINTER (msg_info->date_received);
case COL_TO:
return (void *)camel_message_info_to(msg_info);
+ case COL_TO_NORM:
+ return (void *)get_normalised_string (message_list, msg_info, col);
case COL_SIZE:
return GINT_TO_POINTER (msg_info->size);
case COL_DELETED:
@@ -1082,7 +1132,6 @@ message_list_create_extras (void)
e_table_extras_add_pixbuf (extras, "followup", states_pixmaps [15].pixbuf);
e_table_extras_add_compare (extras, "address_compare", address_compare);
- e_table_extras_add_compare (extras, "subject_compare", subject_compare);
for (i = 0; i < 5; i++)
images [i] = states_pixmaps [i].pixbuf;
@@ -1188,27 +1237,38 @@ message_list_init (GtkObject *object)
e_scroll_frame_set_policy (E_SCROLL_FRAME (message_list),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);
-
+
+ message_list->normalised_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
message_list->hidden = NULL;
message_list->hidden_pool = NULL;
message_list->hide_before = ML_HIDE_NONE_START;
message_list->hide_after = ML_HIDE_NONE_END;
-
+
message_list->search = NULL;
-
+
message_list->hide_lock = g_mutex_new();
-
+
message_list->uid_nodemap = g_hash_table_new (g_str_hash, g_str_equal);
message_list->async_event = mail_async_event_new();
}
static void
+normalised_free (gpointer key, gpointer value, gpointer user_data)
+{
+ e_poolv_destroy (value);
+}
+
+static void
message_list_destroy (GtkObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
mail_async_event_destroy(message_list->async_event);
-
+
+ g_hash_table_foreach (message_list->normalised_hash, normalised_free, NULL);
+ g_hash_table_destroy (message_list->normalised_hash);
+
if (message_list->folder) {
save_tree_state(message_list);
hide_save_state(message_list);
@@ -1909,6 +1969,17 @@ main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
d(printf("changed = %d added = %d removed = %d\n",
changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
+ for (i = 0; i < changes->uid_removed->len; i++) {
+ /* uncache the normalised strings for these uids */
+ EPoolv *poolv;
+
+ poolv = g_hash_table_lookup (ml->normalised_hash, changes->uid_removed->pdata[i]);
+ if (poolv != NULL) {
+ g_hash_table_remove (ml->normalised_hash, changes->uid_removed->pdata[i]);
+ e_poolv_destroy (poolv);
+ }
+ }
+
/* check if the hidden state has changed, if so modify accordingly, then regenerate */
if (ml->hidedeleted) {
newchanges = camel_folder_change_info_new ();
diff --git a/mail/message-list.etspec b/mail/message-list.etspec
index d153a1440a..1ba8a64187 100644
--- a/mail/message-list.etspec
+++ b/mail/message-list.etspec
@@ -1,31 +1,31 @@
<ETableSpecification cursor-mode="line" draw-grid="false" draw-focus="true" selection-mode="browse">
- <ETableColumn model_col= "0" _title="Status" pixbuf="status" expansion="0.0" minimum_width="18" resizable="false" cell="render_message_status" compare="integer" sortable="false"/>
+ <ETableColumn model_col="0" _title="Status" pixbuf="status" expansion="0.0" minimum_width="18" resizable="false" cell="render_message_status" compare="integer" sortable="false"/>
- <ETableColumn model_col= "1" _title="Flagged" pixbuf="flagged" expansion="0.0" minimum_width="18" resizable="false" cell="render_flagged" compare="integer"/>
+ <ETableColumn model_col="1" _title="Flagged" pixbuf="flagged" expansion="0.0" minimum_width="18" resizable="false" cell="render_flagged" compare="integer"/>
- <ETableColumn model_col= "2" _title="Score" pixbuf="score" expansion="0.0" minimum_width="18" disabled="true" resizable="false" cell="render_score" compare="integer"/>
+ <ETableColumn model_col="2" _title="Score" pixbuf="score" expansion="0.0" minimum_width="18" disabled="true" resizable="false" cell="render_score" compare="integer"/>
- <ETableColumn model_col= "3" _title="Attachment" pixbuf="attachment" expansion="0.0" minimum_width="18" resizable="false" cell="render_attachment" compare="integer" sortable="false"/>
+ <ETableColumn model_col="3" _title="Attachment" pixbuf="attachment" expansion="0.0" minimum_width="18" resizable="false" cell="render_attachment" compare="integer" sortable="false"/>
- <ETableColumn model_col= "4" _title="From" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/>
+ <ETableColumn model_col="4" compare_col="14" _title="From" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/>
- <ETableColumn model_col= "5" _title="Subject" expansion="1.6" minimum_width="32" resizable="true" cell="render_tree" compare="subject_compare" search="string"/>
+ <ETableColumn model_col="5" compare_col="15" _title="Subject" expansion="1.6" minimum_width="32" resizable="true" cell="render_tree" compare="string" search="string"/>
- <ETableColumn model_col= "6" _title="Date" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
+ <ETableColumn model_col="6" _title="Date" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
- <ETableColumn model_col= "7" _title="Received" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
+ <ETableColumn model_col="7" _title="Received" expansion="0.4" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
- <ETableColumn model_col= "8" _title="To" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="5"/>
+ <ETableColumn model_col="8" compare_col="16" _title="To" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="5"/>
- <ETableColumn model_col= "9" _title="Size" expansion="0.2" minimum_width="32" resizable="true" cell="render_size" compare="integer"/>
+ <ETableColumn model_col="9" _title="Size" expansion="0.2" minimum_width="32" resizable="true" cell="render_size" compare="integer"/>
- <ETableColumn model_col= "10" _title="Flag Status" pixbuf="followup" expansion="0.0" minimum_width="18" resizable="false" cell="render_flag_status" compare="integer"/>
+ <ETableColumn model_col="10" _title="Flag Status" pixbuf="followup" expansion="0.0" minimum_width="18" resizable="false" cell="render_flag_status" compare="integer"/>
- <ETableColumn model_col= "11" _title="Follow Up Flag" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/>
+ <ETableColumn model_col="11" _title="Follow Up Flag" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/>
- <ETableColumn model_col= "12" _title="Due By" expansion="0.2" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
+ <ETableColumn model_col="12" _title="Due By" expansion="0.2" minimum_width="32" resizable="true" cell="render_date" compare="integer"/>
- <ETableColumn model_col= "13" _title="Original Location" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/>
+ <ETableColumn model_col="13" _title="Original Location" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/>
<ETableState>
<column source="0"/> <column source="3"/> <column source="1"/>
diff --git a/mail/message-list.h b/mail/message-list.h
index 3cc412f6cc..dd57d69d1d 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -30,7 +30,12 @@ enum {
COL_FOLLOWUP_FLAG,
COL_FOLLOWUP_DUE_BY,
COL_LOCATION, /* vfolder location? */
-
+
+ /* normalised strings */
+ COL_FROM_NORM,
+ COL_SUBJECT_NORM,
+ COL_TO_NORM,
+
COL_LAST,
/* Invisible columns */
@@ -60,7 +65,9 @@ struct _MessageList {
CamelFolder *folder;
GHashTable *uid_nodemap; /* uid (from info) -> tree node mapping */
-
+
+ GHashTable *normalised_hash;
+
/* UID's to hide. Keys in the mempool */
/* IMPORTANT: You MUST have obtained the hide lock, to operate on this data */
GHashTable *hidden;