2005-01-22 [colin] 1.0.0cvs8.1
[claws.git] / src / gtk / quicksearch.c
index 26a9037b829a8ce3a461dc680c4d9611a3a3591a..01d5972ff567eb406dc6cec2816c9f9061ce1f09 100644 (file)
@@ -21,6 +21,8 @@
 #  include "config.h"
 #endif
 
+#include <ctype.h>
+
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -32,6 +34,8 @@
 #include "matcher.h"
 #include "matcher_parser.h"
 #include "quicksearch.h"
+#include "folderview.h"
+#include "folder.h"
 
 struct _QuickSearch
 {
@@ -48,9 +52,13 @@ struct _QuickSearch
        QuickSearchExecuteCallback       callback;
        gpointer                         callback_data;
        gboolean                         running;
+       gboolean                         has_focus;
+       FolderItem                      *root_folder_item;
 };
 
 static void quicksearch_set_running(QuickSearch *quicksearch, gboolean run);
+static void quicksearch_set_active(QuickSearch *quicksearch, gboolean active);
+static void quicksearch_reset_folder_items(QuickSearch *quicksearch, FolderItem *folder_item);
 
 static void prepare_matcher(QuickSearch *quicksearch)
 {
@@ -62,7 +70,7 @@ static void prepare_matcher(QuickSearch *quicksearch)
        }
 
        if (search_string == NULL || search_string[0] == '\0') {
-               quicksearch->active = FALSE;
+               quicksearch_set_active(quicksearch, FALSE);
                return;
        }
 
@@ -75,7 +83,7 @@ static void prepare_matcher(QuickSearch *quicksearch)
                        g_free(newstr);
                } else {
                        quicksearch->matcher_list = NULL;
-                       quicksearch->active = FALSE;
+                       quicksearch_set_active(quicksearch, FALSE);
 
                        return;
                }
@@ -85,7 +93,7 @@ static void prepare_matcher(QuickSearch *quicksearch)
                quicksearch->search_string = g_strdup(search_string);
        }
 
-       quicksearch->active = TRUE;
+       quicksearch_set_active(quicksearch, TRUE);
 }
 
 static void update_extended_button (QuickSearch *quicksearch)
@@ -103,6 +111,18 @@ static void update_extended_button (QuickSearch *quicksearch)
        
 }
 
+static gboolean searchbar_focus_evt(GtkWidget *widget, GdkEventFocus *event,
+                                 QuickSearch *quicksearch)
+{
+       quicksearch->has_focus = (event && event->in);
+       return FALSE;
+}
+
+gboolean quicksearch_has_focus(QuickSearch *quicksearch)
+{
+       return quicksearch->has_focus;
+}
+
 static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event,
                                  QuickSearch *quicksearch)
 {
@@ -155,6 +175,27 @@ static gboolean searchtype_changed(GtkMenuItem *widget, gpointer data)
        if (quicksearch->callback != NULL)
                quicksearch->callback(quicksearch, quicksearch->callback_data);
        quicksearch_set_running(quicksearch, FALSE);
+       return TRUE;
+}
+
+static gboolean searchtype_recursive_changed(GtkMenuItem *widget, gpointer data)
+{
+       QuickSearch *quicksearch = (QuickSearch *)data;
+       gboolean checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+       
+       prefs_common.summary_quicksearch_recurse = checked; 
+
+       /* reselect the search type */
+       gtk_option_menu_set_history(GTK_OPTION_MENU(quicksearch->search_type_opt), 
+                                   prefs_common.summary_quicksearch_type);
+
+       prepare_matcher(quicksearch);
+
+       quicksearch_set_running(quicksearch, TRUE);
+       if (quicksearch->callback != NULL)
+               quicksearch->callback(quicksearch, quicksearch->callback_data);
+       quicksearch_set_running(quicksearch, FALSE);
+       return TRUE;
 }
 
 /*
@@ -229,21 +270,6 @@ static gboolean clear_search_cb(GtkMenuItem *widget, gpointer data)
        return TRUE;
 };
 
-/*
-static void summary_searchbar_focus_evt(GtkWidget *widget, GdkEventFocus *event,
-                                       SummaryView *summaryview)
-{
-       if (event != NULL && event->in)
-               gtk_signal_handler_block_by_func(GTK_OBJECT(summaryview->mainwin->window), 
-                                                GTK_SIGNAL_FUNC(mainwindow_key_pressed),
-                                                summaryview->mainwin);
-       else
-               gtk_signal_handler_unblock_by_func(GTK_OBJECT(summaryview->mainwin->window), 
-                                                  GTK_SIGNAL_FUNC(mainwindow_key_pressed),
-                                                  summaryview->mainwin);
-}
-*/
-
 QuickSearch *quicksearch_new()
 {
        QuickSearch *quicksearch;
@@ -284,6 +310,18 @@ QuickSearch *quicksearch_new()
                         G_CALLBACK(searchtype_changed),
                         quicksearch);
 
+       gtk_menu_shell_append(GTK_MENU_SHELL(search_type), gtk_separator_menu_item_new());
+       
+       menuitem = gtk_check_menu_item_new_with_label(_("Recursive"));
+       gtk_menu_shell_append(GTK_MENU_SHELL(search_type), menuitem);
+       
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
+                                       prefs_common.summary_quicksearch_recurse);
+       
+       g_signal_connect(G_OBJECT(menuitem), "activate",
+                        G_CALLBACK(searchtype_recursive_changed),
+                        quicksearch);
+
        gtk_option_menu_set_menu(GTK_OPTION_MENU(search_type_opt), search_type);
        
        gtk_option_menu_set_history(GTK_OPTION_MENU(search_type_opt), prefs_common.summary_quicksearch_type);
@@ -312,7 +350,7 @@ QuickSearch *quicksearch_new()
                                   FALSE, FALSE, 0);
                gtk_widget_set_usize(clear_search, 120, -1);
                g_signal_connect(G_OBJECT(clear_search), "clicked",
-                                  GTK_SIGNAL_FUNC(clear_search_cb), quicksearch);
+                                G_CALLBACK(clear_search_cb), quicksearch);
                gtk_widget_show(clear_search);
        }
 
@@ -336,17 +374,17 @@ QuickSearch *quicksearch_new()
                           G_CALLBACK(searchbar_pressed),
                           quicksearch);
 
-       /*
-       gtk_signal_connect(GTK_OBJECT(GTK_COMBO(search_string_entry)->entry), 
-                          "focus_in_event",
-                          GTK_SIGNAL_FUNC(searchbar_focus_evt),
-                          quicksearch);
+       
+       g_signal_connect(G_OBJECT(GTK_COMBO(search_string_entry)->entry),
+                        "focus_in_event",
+                        G_CALLBACK(searchbar_focus_evt),
+                        quicksearch);
 
-       gtk_signal_connect(GTK_OBJECT(GTK_COMBO(search_string_entry)->entry), 
-                          "focus_out_event",
-                          GTK_SIGNAL_FUNC(searchbar_focus_evt),
-                          quicksearch);
-       */
+       g_signal_connect(G_OBJECT(GTK_COMBO(search_string_entry)->entry),
+                        "focus_out_event",
+                        G_CALLBACK(searchbar_focus_evt),
+                        quicksearch);
+       
 
        quicksearch->hbox_search = hbox_search;
        quicksearch->search_type = search_type;
@@ -376,7 +414,7 @@ void quicksearch_show(QuickSearch *quicksearch)
 
 void quicksearch_hide(QuickSearch *quicksearch)
 {
-       quicksearch->active = FALSE;
+       quicksearch_set_active(quicksearch, FALSE);
        gtk_widget_hide(quicksearch->hbox_search);
 }
 
@@ -402,6 +440,14 @@ gboolean quicksearch_is_active(QuickSearch *quicksearch)
        return quicksearch->active;
 }
 
+static void quicksearch_set_active(QuickSearch *quicksearch, gboolean active)
+{
+       quicksearch->active = active;
+       if (!active) {
+               quicksearch_reset_cur_folder_item(quicksearch);
+       }
+}
+
 void quicksearch_set_execute_callback(QuickSearch *quicksearch,
                                      QuickSearchExecuteCallback callback,
                                      gpointer data)
@@ -434,10 +480,12 @@ gboolean quicksearch_match(QuickSearch *quicksearch, MsgInfo *msginfo)
                break;
        }
 
-       if (prefs_common.summary_quicksearch_type != QUICK_SEARCH_EXTENDED && quicksearch->search_string &&
+       if (prefs_common.summary_quicksearch_type != QUICK_SEARCH_EXTENDED && 
+           quicksearch->search_string &&
             searched_header && strcasestr(searched_header, quicksearch->search_string) != NULL)
                return TRUE;
-       else if ((quicksearch->matcher_list != NULL) && matcherlist_match(quicksearch->matcher_list, msginfo))
+       else if ((quicksearch->matcher_list != NULL) && 
+                matcherlist_match(quicksearch->matcher_list, msginfo))
                return TRUE;
 
        return FALSE;
@@ -631,3 +679,100 @@ gboolean quicksearch_is_running(QuickSearch *quicksearch)
        return quicksearch->running;
 }
 
+void quicksearch_pass_key(QuickSearch *quicksearch, guint val, GdkModifierType mod)
+{
+       GtkEntry *entry = GTK_ENTRY(GTK_COMBO(quicksearch->search_string_entry)->entry);
+       gint curpos = gtk_editable_get_position(GTK_EDITABLE(entry));
+       char *str = g_strdup(gtk_entry_get_text(entry));
+       char *begin = str;
+       char *end = NULL;
+       char *new = NULL;
+       
+       if (mod == GDK_SHIFT_MASK)
+               val = toupper(val);
+       
+       if (curpos < strlen(str)-1) {
+               end = g_strdup(str+curpos);
+               *(str+curpos) = '\0';
+               new = g_strdup_printf("%s%c%s", begin, val, end);
+               gtk_entry_set_text(entry, new);
+               g_free(end);
+       } else {
+               new = g_strdup_printf("%s%c", begin, val);
+               gtk_entry_set_text(entry, new);
+       }
+       g_free(str);
+       g_free(new);
+       gtk_editable_set_position(GTK_EDITABLE(entry), curpos+1);
+       
+}
+
+static gboolean quicksearch_match_subfolder(QuickSearch *quicksearch, 
+                                FolderItem *src)
+{
+       GSList *msglist = folder_item_get_msg_list(src);
+       GSList *cur;
+       gboolean result = FALSE;
+       
+       for (cur = msglist; cur != NULL; cur = cur->next) {
+               MsgInfo *msg = (MsgInfo *)cur->data;
+               if (quicksearch_match(quicksearch, msg)) {
+                       procmsg_msginfo_free(msg);
+                       result = TRUE;
+                       break;
+               }
+               procmsg_msginfo_free(msg);
+       }
+
+       g_slist_free(msglist);
+       return result;
+}
+
+void quicksearch_search_subfolders(QuickSearch *quicksearch, 
+                                  FolderView *folderview,
+                                  FolderItem *folder_item)
+{
+       FolderItem *cur = NULL;
+       GNode *node = folder_item->node->children;
+       
+       if (!prefs_common.summary_quicksearch_recurse)
+               return;
+
+       for (; node != NULL; node = node->next) {
+               cur = FOLDER_ITEM(node->data);
+               if (quicksearch_match_subfolder(quicksearch, cur)) {
+                       folderview_update_search_icon(cur, TRUE);
+               } else {
+                       folderview_update_search_icon(cur, FALSE);
+               }
+               if (cur->node->children)
+                       quicksearch_search_subfolders(quicksearch,
+                                                     folderview,
+                                                     cur);
+       }
+       quicksearch->root_folder_item = folder_item;
+}
+
+static void quicksearch_reset_folder_items(QuickSearch *quicksearch,
+                                   FolderItem *folder_item)
+{
+       FolderItem *cur = NULL;
+       GNode *node = folder_item->node->children;
+       
+       for (; node != NULL; node = node->next) {
+               cur = FOLDER_ITEM(node->data);
+               folderview_update_search_icon(cur, FALSE);
+               if (cur->node->children)
+                       quicksearch_reset_folder_items(quicksearch,
+                                                      cur);
+       }
+}
+
+void quicksearch_reset_cur_folder_item(QuickSearch *quicksearch)
+{
+       if (quicksearch->root_folder_item)
+               quicksearch_reset_folder_items(quicksearch, 
+                                              quicksearch->root_folder_item);
+       
+       quicksearch->root_folder_item = NULL;
+}