aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2010-02-10 09:31:53 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2010-02-10 09:31:53 +0000
commit3f9703a3fd35f7d8b835c62869c0db74bd213e2f (patch)
treeacbaf735dc3a1d98d0322f6a5634ea51c7c1b707 /src
parent6ab1d3cf538aa7f6c5385f7010e9a2d7e71b8dc0 (diff)
added a new filter match type: is (not) in addressbook.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2461 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src')
-rw-r--r--src/addressbook.c87
-rw-r--r--src/addressbook.h2
-rw-r--r--src/main.c1
-rw-r--r--src/prefs_filter_edit.c91
-rw-r--r--src/prefs_filter_edit.h5
5 files changed, 169 insertions, 17 deletions
diff --git a/src/addressbook.c b/src/addressbook.c
index f7d9e9b5..2c95c580 100644
--- a/src/addressbook.c
+++ b/src/addressbook.c
@@ -333,6 +333,9 @@ static void addressbook_list_select_set (GList *row_list);
static void addressbook_import_ldif_cb (void);
static void addressbook_import_csv_cb (void);
+static void addressbook_modified (void);
+
+
static GtkItemFactoryEntry addressbook_entries[] =
{
{N_("/_File"), NULL, NULL, 0, "<Branch>"},
@@ -408,6 +411,7 @@ static GtkItemFactoryEntry addressbook_list_popup_entries[] =
{N_("/_Paste"), NULL, addressbook_paste_address_cb, 0, NULL}
};
+
void addressbook_open(Compose *target)
{
if (!addrbook.window) {
@@ -2181,7 +2185,7 @@ static void addressbook_edit_address_cb(gpointer data, guint action, GtkWidget *
if (addressbook_edit_person(abf, NULL, person, TRUE) == NULL)
return;
addressbook_reopen();
- invalidate_address_completion();
+ addressbook_modified();
return;
}
} else if (obj->type == ADDR_ITEM_PERSON) {
@@ -2191,7 +2195,7 @@ static void addressbook_edit_address_cb(gpointer data, guint action, GtkWidget *
if (addressbook_edit_person(abf, NULL, person, FALSE) == NULL)
return;
addressbook_reopen();
- invalidate_address_completion();
+ addressbook_modified();
return;
} else if (obj->type == ADDR_ITEM_GROUP) {
ItemGroup *itemGrp = (ItemGroup *)obj;
@@ -3237,7 +3241,7 @@ void addressbook_export_to_file( void ) {
}
/* Notify address completion of new data */
- invalidate_address_completion();
+ addressbook_modified();
}
}
@@ -4151,7 +4155,7 @@ static void addressbook_import_ldif_cb(void)
}
/* Notify address completion */
- invalidate_address_completion();
+ addressbook_modified();
}
/*
@@ -4191,9 +4195,84 @@ static void addressbook_import_csv_cb(void)
}
/* Notify address completion */
+ addressbook_modified();
+}
+
+/* **********************************************************************
+* Address Book Fast Search.
+* ***********************************************************************
+*/
+
+static GHashTable *addr_table;
+
+static gint load_address(const gchar *name, const gchar *address,
+ const gchar *nickname)
+{
+ gchar *addr;
+
+ if (!address)
+ return -1;
+
+ addr = g_ascii_strdown(address, -1);
+
+ if (g_hash_table_lookup(addr_table, addr) == NULL)
+ g_hash_table_insert(addr_table, addr, addr);
+ else
+ g_free(addr);
+
+ return 0;
+}
+
+static void addressbook_modified(void)
+{
+ if (addr_table) {
+ hash_free_strings(addr_table);
+ g_hash_table_destroy(addr_table);
+ addr_table = NULL;
+ }
+
invalidate_address_completion();
}
+gboolean addressbook_has_address(const gchar *address)
+{
+ GSList *list, *cur;
+ gchar *addr;
+ gboolean found = FALSE;
+
+ if (!address)
+ return FALSE;
+
+ debug_print("addressbook_has_address: check if addressbook has address: %s\n", address);
+
+ list = address_list_append(NULL, address);
+ if (!list)
+ return FALSE;
+
+ if (!addr_table) {
+ addr_table = g_hash_table_new(g_str_hash, g_str_equal);
+ addressbook_load_completion(load_address);
+ }
+
+ for (cur = list; cur != NULL; cur = cur->next) {
+ addr = g_ascii_strdown((gchar *)cur->data, -1);
+
+ if (g_hash_table_lookup(addr_table, addr)) {
+ found = TRUE;
+ debug_print("'%s' is in addressbook\n", addr);
+ } else {
+ found = FALSE;
+ g_free(addr);
+ break;
+ }
+ g_free(addr);
+ }
+
+ slist_free_strings(list);
+
+ return found;
+}
+
/*
* End of Source.
*/
diff --git a/src/addressbook.h b/src/addressbook.h
index 70a51da4..41d0cb37 100644
--- a/src/addressbook.h
+++ b/src/addressbook.h
@@ -49,4 +49,6 @@ gboolean addressbook_add_contact_autoreg(const gchar *name,
gboolean addressbook_load_completion ( gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) );
+gboolean addressbook_has_address (const gchar *address);
+
#endif /* __ADDRESSBOOK_H__ */
diff --git a/src/main.c b/src/main.c
index f2ed5eac..1f11b213 100644
--- a/src/main.c
+++ b/src/main.c
@@ -257,6 +257,7 @@ int main(int argc, char *argv[])
CHDIR_EXIT_IF_FAIL(get_home_dir(), 1);
prefs_common_read_config();
+ filter_set_addressbook_func(addressbook_has_address);
filter_read_config();
prefs_actions_read_config();
prefs_display_header_read_config();
diff --git a/src/prefs_filter_edit.c b/src/prefs_filter_edit.c
index 9250cfb7..ac39deae 100644
--- a/src/prefs_filter_edit.c
+++ b/src/prefs_filter_edit.c
@@ -129,6 +129,8 @@ static void prefs_filter_edit_cancel (void);
static void prefs_filter_cond_activated_cb (GtkWidget *widget,
gpointer data);
+static void prefs_filter_match_activated_cb (GtkWidget *widget,
+ gpointer data);
static void prefs_filter_action_activated_cb (GtkWidget *widget,
gpointer data);
@@ -472,6 +474,8 @@ CondHBox *prefs_filter_edit_cond_hbox_create(FilterCondEdit *cond_edit)
GtkWidget *add_btn;
GtkWidget *del_img;
GtkWidget *add_img;
+ GtkWidget *match_menu_in_addr;
+ GtkWidget *match_menu_not_in_addr;
cond_hbox = g_new0(CondHBox, 1);
@@ -518,24 +522,31 @@ CondHBox *prefs_filter_edit_cond_hbox_create(FilterCondEdit *cond_edit)
gtk_widget_show(match_type_optmenu);
gtk_box_pack_start(GTK_BOX(hbox), match_type_optmenu, FALSE, FALSE, 0);
+#define MATCH_MENUITEM_ADD(str, action) \
+{ \
+ MENUITEM_ADD(menu, menuitem, str, action); \
+ g_signal_connect(G_OBJECT(menuitem), "activate", \
+ G_CALLBACK(prefs_filter_match_activated_cb), \
+ cond_hbox); \
+}
menu = gtk_menu_new();
gtk_widget_show(menu);
- MENUITEM_ADD(menu, menuitem, _("contains"),
- PF_MATCH_CONTAIN);
- MENUITEM_ADD(menu, menuitem, _("doesn't contain"),
- PF_MATCH_NOT_CONTAIN);
- MENUITEM_ADD(menu, menuitem, _("is"),
- PF_MATCH_EQUAL);
- MENUITEM_ADD(menu, menuitem, _("is not"),
- PF_MATCH_NOT_EQUAL);
+ MATCH_MENUITEM_ADD(_("contains"), PF_MATCH_CONTAIN);
+ MATCH_MENUITEM_ADD(_("doesn't contain"), PF_MATCH_NOT_CONTAIN);
+ MATCH_MENUITEM_ADD(_("is"), PF_MATCH_EQUAL);
+ MATCH_MENUITEM_ADD(_("is not"), PF_MATCH_NOT_EQUAL);
#if defined(USE_ONIGURUMA) || defined(HAVE_REGCOMP)
- MENUITEM_ADD(menu, menuitem, _("match to regex"),
- PF_MATCH_REGEX);
- MENUITEM_ADD(menu, menuitem, _("doesn't match to regex"),
- PF_MATCH_NOT_REGEX);
+ MATCH_MENUITEM_ADD(_("match to regex"), PF_MATCH_REGEX);
+ MATCH_MENUITEM_ADD(_("doesn't match to regex"), PF_MATCH_NOT_REGEX);
#endif
+ MATCH_MENUITEM_ADD(_("is in addressbook"), PF_MATCH_IN_ADDRESSBOOK);
+ match_menu_in_addr = menuitem;
+ MATCH_MENUITEM_ADD(_("isn't in addressbook"), PF_MATCH_NOT_IN_ADDRESSBOOK);
+ match_menu_not_in_addr = menuitem;
gtk_option_menu_set_menu(GTK_OPTION_MENU(match_type_optmenu), menu);
+#undef MATCH_MENUITEM_ADD
+
size_match_optmenu = gtk_option_menu_new();
gtk_widget_show(size_match_optmenu);
gtk_box_pack_start(GTK_BOX(hbox), size_match_optmenu, FALSE, FALSE, 0);
@@ -612,6 +623,8 @@ CondHBox *prefs_filter_edit_cond_hbox_create(FilterCondEdit *cond_edit)
cond_hbox->key_entry = key_entry;
cond_hbox->spin_btn = spin_btn;
cond_hbox->label = label;
+ cond_hbox->match_menu_in_addr = match_menu_in_addr;
+ cond_hbox->match_menu_not_in_addr = match_menu_not_in_addr;
cond_hbox->del_btn = del_btn;
cond_hbox->add_btn = add_btn;
cond_hbox->cur_type = PF_COND_HEADER;
@@ -841,6 +854,12 @@ void prefs_filter_edit_cond_hbox_set(CondHBox *hbox, FilterCond *cond)
else
match_type = PF_MATCH_REGEX;
break;
+ case FLT_IN_ADDRESSBOOK:
+ if (FLT_IS_NOT_MATCH(cond->match_flag))
+ match_type = PF_MATCH_NOT_IN_ADDRESSBOOK;
+ else
+ match_type = PF_MATCH_IN_ADDRESSBOOK;
+ break;
}
break;
case FLT_COND_UNREAD:
@@ -895,6 +914,10 @@ void prefs_filter_edit_cond_hbox_set(CondHBox *hbox, FilterCond *cond)
gtk_option_menu_set_history
(GTK_OPTION_MENU(hbox->status_match_optmenu),
status_type);
+
+ if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
+ match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
+ gtk_widget_hide(hbox->key_entry);
}
void prefs_filter_edit_action_hbox_set(ActionHBox *hbox, FilterAction *action)
@@ -977,6 +1000,8 @@ void prefs_filter_edit_cond_hbox_select(CondHBox *hbox, CondMenuType type,
void prefs_filter_edit_set_cond_hbox_widgets(CondHBox *hbox, CondMenuType type)
{
+ MatchMenuType match_type;
+
switch (type) {
case PF_COND_HEADER:
case PF_COND_TO_OR_CC:
@@ -986,9 +1011,27 @@ void prefs_filter_edit_set_cond_hbox_widgets(CondHBox *hbox, CondMenuType type)
gtk_widget_hide(hbox->size_match_optmenu);
gtk_widget_hide(hbox->age_match_optmenu);
gtk_widget_hide(hbox->status_match_optmenu);
- gtk_widget_show(hbox->key_entry);
+ match_type = menu_get_option_menu_active_index
+ (GTK_OPTION_MENU(hbox->match_type_optmenu));
+ if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
+ match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
+ gtk_widget_hide(hbox->key_entry);
+ else
+ gtk_widget_show(hbox->key_entry);
gtk_widget_hide(hbox->spin_btn);
gtk_widget_hide(hbox->label);
+ if (type == PF_COND_HEADER || type == PF_COND_TO_OR_CC) {
+ gtk_widget_show(hbox->match_menu_in_addr);
+ gtk_widget_show(hbox->match_menu_not_in_addr);
+ } else {
+ gtk_widget_hide(hbox->match_menu_in_addr);
+ gtk_widget_hide(hbox->match_menu_not_in_addr);
+ if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
+ match_type == PF_MATCH_NOT_IN_ADDRESSBOOK) {
+ gtk_option_menu_set_history(GTK_OPTION_MENU(hbox->match_type_optmenu), 0);
+ gtk_widget_show(hbox->key_entry);
+ }
+ }
break;
case PF_COND_CMD_TEST:
gtk_widget_hide(hbox->match_type_optmenu);
@@ -1703,6 +1746,13 @@ FilterCond *prefs_filter_edit_cond_hbox_to_cond(CondHBox *hbox,
match_type = FLT_REGEX;
match_flag |= FLT_NOT_MATCH;
break;
+ case PF_MATCH_IN_ADDRESSBOOK:
+ match_type = FLT_IN_ADDRESSBOOK;
+ break;
+ case PF_MATCH_NOT_IN_ADDRESSBOOK:
+ match_type = FLT_IN_ADDRESSBOOK;
+ match_flag |= FLT_NOT_MATCH;
+ break;
default:
break;
}
@@ -2035,6 +2085,21 @@ static void prefs_filter_cond_activated_cb(GtkWidget *widget, gpointer data)
}
}
+static void prefs_filter_match_activated_cb(GtkWidget *widget, gpointer data)
+{
+ CondHBox *hbox = (CondHBox *)data;
+ GtkWidget *cond_type_menuitem;
+ CondMenuType cond_menu_type;
+
+ cond_type_menuitem = gtk_menu_get_active
+ (GTK_MENU(gtk_option_menu_get_menu
+ (GTK_OPTION_MENU(hbox->cond_type_optmenu))));
+ cond_menu_type = GPOINTER_TO_INT
+ (g_object_get_data(G_OBJECT(cond_type_menuitem), MENU_VAL_ID));
+
+ prefs_filter_edit_set_cond_hbox_widgets(hbox, cond_menu_type);
+}
+
static void prefs_filter_action_activated_cb(GtkWidget *widget, gpointer data)
{
ActionHBox *hbox = (ActionHBox *)data;
diff --git a/src/prefs_filter_edit.h b/src/prefs_filter_edit.h
index 7fdf2037..c6f056fa 100644
--- a/src/prefs_filter_edit.h
+++ b/src/prefs_filter_edit.h
@@ -55,6 +55,8 @@ typedef enum
PF_MATCH_NOT_EQUAL,
PF_MATCH_REGEX,
PF_MATCH_NOT_REGEX,
+ PF_MATCH_IN_ADDRESSBOOK,
+ PF_MATCH_NOT_IN_ADDRESSBOOK,
PF_MATCH_NONE
} MatchMenuType;
@@ -118,6 +120,9 @@ struct _CondHBox {
GtkWidget *spin_btn;
GtkWidget *label;
+ GtkWidget *match_menu_in_addr;
+ GtkWidget *match_menu_not_in_addr;
+
GtkWidget *del_btn;
GtkWidget *add_btn;