X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fgrouplistdialog.c;h=9a90027d8747067df864a67b741acfdba149f061;hp=6a7ff8bb242ab2496bab115228ae3447b3ba692d;hb=9a4a9146ff83aaf4390ff8a9f02b19707fd2c47e;hpb=dd4b62708a6d5956a9ec1953f2544c941b535451 diff --git a/src/grouplistdialog.c b/src/grouplistdialog.c index 6a7ff8bb2..9a90027d8 100644 --- a/src/grouplistdialog.c +++ b/src/grouplistdialog.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2001 Hiroyuki Yamamoto + * Copyright (C) 1999-2003 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -52,57 +52,56 @@ #include "recv.h" #include "socket.h" -#define GROUPLIST_DIALOG_WIDTH 500 -#define GROUPLIST_NAMES 250 -#define GROUPLIST_DIALOG_HEIGHT 400 - -static GList * subscribed = NULL; -gboolean dont_unsubscribed = FALSE; +#define GROUPLIST_DIALOG_WIDTH 450 +#define GROUPLIST_DIALOG_HEIGHT 400 +#define GROUPLIST_COL_NAME_WIDTH 250 static gboolean ack; static gboolean locked; static GtkWidget *dialog; static GtkWidget *entry; -static GtkWidget *clist; +static GtkWidget *ctree; static GtkWidget *status_label; static GtkWidget *ok_button; -static GSList *group_list = NULL; +static GSList *group_list; static Folder *news_folder; +static GSList *subscribed; + static void grouplist_dialog_create (void); -static void grouplist_dialog_set_list (gchar * pattern); +static void grouplist_dialog_set_list (const gchar *pattern, + gboolean refresh); +static void grouplist_search (void); static void grouplist_clear (void); -static void grouplist_recv_func (SockInfo *sock, +static gboolean grouplist_recv_func (SockInfo *sock, gint count, gint read_bytes, gpointer data); +static gint window_deleted (GtkWidget *widget, + GdkEventAny *event, + gpointer data); static void ok_clicked (GtkWidget *widget, gpointer data); static void cancel_clicked (GtkWidget *widget, gpointer data); static void refresh_clicked (GtkWidget *widget, gpointer data); -static void key_pressed (GtkWidget *widget, +static gboolean key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer data); -static void clist_selected (GtkCList *clist, - gint row, - gint column, - GdkEventButton *event, - gpointer user_data); -static void clist_unselected (GtkCList *clist, - gint row, - gint column, - GdkEventButton *event, - gpointer user_data); +static gboolean button_press_cb (GtkCTree *ctree, + GdkEventButton *button, + gpointer data); static void entry_activated (GtkEditable *editable); +static void search_clicked (GtkWidget *widget, + gpointer data); -GList *grouplist_dialog(Folder *folder, GList * cur_subscriptions) +GSList *grouplist_dialog(Folder *folder) { - gchar *str; - GList * l; + GNode *node; + FolderItem *item; if (dialog && GTK_WIDGET_VISIBLE(dialog)) return NULL; @@ -114,83 +113,67 @@ GList *grouplist_dialog(Folder *folder, GList * cur_subscriptions) gtk_widget_show(dialog); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); manage_window_set_transient(GTK_WINDOW(dialog)); + gtk_widget_grab_focus(ok_button); + gtk_widget_grab_focus(ctree); GTK_EVENTS_FLUSH(); subscribed = NULL; + for (node = folder->node->children; node != NULL; node = node->next) { + item = FOLDER_ITEM(node->data); + subscribed = g_slist_append(subscribed, g_strdup(item->path)); + } - for(l = cur_subscriptions ; l != NULL ; l = l->next) - subscribed = g_list_append(subscribed, g_strdup((gchar *) l->data)); - - grouplist_dialog_set_list(NULL); + grouplist_dialog_set_list(NULL, TRUE); - gtk_main(); + if (ack) gtk_main(); manage_window_focus_out(dialog, NULL, NULL); gtk_widget_hide(dialog); - /* - if (ack) { - str = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - if (str && *str == '\0') { - g_free(str); - str = NULL; - } - } else - str = NULL; - */ if (!ack) { - list_free_strings(subscribed); - g_list_free(subscribed); - - subscribed = NULL; - - for(l = cur_subscriptions ; l != NULL ; l = l->next) - subscribed = g_list_append(subscribed, g_strdup((gchar *) l->data)); + slist_free_strings(subscribed); + g_slist_free(subscribed); + subscribed = NULL; + + for (node = folder->node->children; node != NULL; + node = node->next) { + item = FOLDER_ITEM(node->data); + subscribed = g_slist_append(subscribed, + g_strdup(item->path)); + } } - GTK_EVENTS_FLUSH(); + grouplist_clear(); - debug_print("return string = %s\n", str ? str : "(none)"); return subscribed; } -static void grouplist_clear(void) -{ - dont_unsubscribed = TRUE; - gtk_clist_clear(GTK_CLIST(clist)); - gtk_entry_set_text(GTK_ENTRY(entry), ""); - dont_unsubscribed = FALSE; -} - static void grouplist_dialog_create(void) { GtkWidget *vbox; GtkWidget *hbox; GtkWidget *msg_label; + GtkWidget *search_button; GtkWidget *confirm_area; GtkWidget *cancel_button; GtkWidget *refresh_button; GtkWidget *scrolledwin; - gchar * col_names[3] = { - _("name"), _("count of messages"), _("type") - }; + gchar *titles[3]; + gint i; dialog = gtk_dialog_new(); - gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, TRUE, FALSE); - gtk_widget_set_usize(dialog, - GROUPLIST_DIALOG_WIDTH, GROUPLIST_DIALOG_HEIGHT); + gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE); + gtk_widget_set_size_request(dialog, + GROUPLIST_DIALOG_WIDTH, GROUPLIST_DIALOG_HEIGHT); gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 5); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); - gtk_window_set_title(GTK_WINDOW(dialog), _("Subscribe to newsgroup")); - gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", - GTK_SIGNAL_FUNC(cancel_clicked), NULL); - gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event", - GTK_SIGNAL_FUNC(key_pressed), NULL); - gtk_signal_connect(GTK_OBJECT(dialog), "focus_in_event", - GTK_SIGNAL_FUNC(manage_window_focus_in), NULL); - gtk_signal_connect(GTK_OBJECT(dialog), "focus_out_event", - GTK_SIGNAL_FUNC(manage_window_focus_out), NULL); + gtk_window_set_title(GTK_WINDOW(dialog), _("Newsgroup subscription")); + g_signal_connect(G_OBJECT(dialog), "delete_event", + G_CALLBACK(window_deleted), NULL); + g_signal_connect(G_OBJECT(dialog), "key_press_event", + G_CALLBACK(key_pressed), NULL); + MANAGE_WINDOW_SIGNALS_CONNECT(dialog); gtk_widget_realize(dialog); @@ -201,13 +184,25 @@ static void grouplist_dialog_create(void) hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); - msg_label = gtk_label_new(_("Input subscribing newsgroup:")); + msg_label = gtk_label_new(_("Select newsgroups for subscription:")); + gtk_box_pack_start(GTK_BOX(hbox), msg_label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 8); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + msg_label = gtk_label_new(_("Find groups:")); gtk_box_pack_start(GTK_BOX(hbox), msg_label, FALSE, FALSE, 0); entry = gtk_entry_new(); - gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0); - gtk_signal_connect(GTK_OBJECT(entry), "activate", - GTK_SIGNAL_FUNC(entry_activated), NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(entry_activated), NULL); + + search_button = gtk_button_new_with_label(_(" Search ")); + gtk_box_pack_start(GTK_BOX(hbox), search_button, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(search_button), "clicked", + G_CALLBACK(search_clicked), NULL); scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX (vbox), scrolledwin, TRUE, TRUE, 0); @@ -215,15 +210,22 @@ static void grouplist_dialog_create(void) GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - clist = gtk_clist_new_with_titles(3, col_names); - gtk_container_add(GTK_CONTAINER(scrolledwin), clist); - gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE); - GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[0].button, - GTK_CAN_FOCUS); - gtk_signal_connect(GTK_OBJECT(clist), "select_row", - GTK_SIGNAL_FUNC(clist_selected), NULL); - gtk_signal_connect(GTK_OBJECT(clist), "unselect_row", - GTK_SIGNAL_FUNC(clist_unselected), NULL); + titles[0] = _("Newsgroup name"); + titles[1] = _("Messages"); + titles[2] = _("Type"); + ctree = gtk_ctree_new_with_titles(3, 0, titles); + gtk_container_add(GTK_CONTAINER(scrolledwin), ctree); + gtk_clist_set_column_width + (GTK_CLIST(ctree), 0, GROUPLIST_COL_NAME_WIDTH); + gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_MULTIPLE); + gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_DOTTED); + gtk_ctree_set_expander_style(GTK_CTREE(ctree), + GTK_CTREE_EXPANDER_SQUARE); + for (i = 0; i < 3; i++) + GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[i].button, + GTK_CAN_FOCUS); + g_signal_connect(G_OBJECT(ctree), "button-press-event", + G_CALLBACK(button_press_cb), NULL); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -239,101 +241,228 @@ static void grouplist_dialog_create(void) confirm_area); gtk_widget_grab_default(ok_button); - gtk_signal_connect(GTK_OBJECT(ok_button), "clicked", - GTK_SIGNAL_FUNC(ok_clicked), NULL); - gtk_signal_connect(GTK_OBJECT(cancel_button), "clicked", - GTK_SIGNAL_FUNC(cancel_clicked), NULL); - gtk_signal_connect(GTK_OBJECT(refresh_button), "clicked", - GTK_SIGNAL_FUNC(refresh_clicked), NULL); + g_signal_connect(G_OBJECT(ok_button), "clicked", + G_CALLBACK(ok_clicked), NULL); + g_signal_connect(G_OBJECT(cancel_button), "clicked", + G_CALLBACK(cancel_clicked), NULL); + g_signal_connect(G_OBJECT(refresh_button), "clicked", + G_CALLBACK(refresh_clicked), NULL); gtk_widget_show_all(GTK_DIALOG(dialog)->vbox); } -static void grouplist_dialog_set_list(gchar * pattern) +static GHashTable *branch_node_table; + +static void grouplist_hash_init(void) { - GSList *cur; - gint row; + branch_node_table = g_hash_table_new(g_str_hash, g_str_equal); +} - if (pattern == NULL) - pattern = "*"; +static void grouplist_hash_done(void) +{ + hash_free_strings(branch_node_table); + g_hash_table_destroy(branch_node_table); +} + +static GtkCTreeNode *grouplist_hash_get_branch_node(const gchar *name) +{ + return g_hash_table_lookup(branch_node_table, name); +} + +static void grouplist_hash_set_branch_node(const gchar *name, + GtkCTreeNode *node) +{ + g_hash_table_insert(branch_node_table, g_strdup(name), node); +} + +static gchar *grouplist_get_parent_name(const gchar *name) +{ + gchar *p; + + p = strrchr(name, '.'); + if (!p) + return g_strdup(""); + return g_strndup(name, p - name); +} + +static GtkCTreeNode *grouplist_create_parent(const gchar *name, + const gchar *pattern) +{ + GtkCTreeNode *parent; + GtkCTreeNode *node; + gchar *cols[3]; + gchar *parent_name; + + if (*name == '\0') return NULL; + node = grouplist_hash_get_branch_node(name); + if (node != NULL) return node; + + cols[0] = (gchar *)name; + cols[1] = cols[2] = ""; + + parent_name = grouplist_get_parent_name(name); + parent = grouplist_create_parent(parent_name, pattern); + + node = parent ? GTK_CTREE_ROW(parent)->children + : GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); + node = gtk_ctree_insert_node(GTK_CTREE(ctree), parent, node, + cols, 0, NULL, NULL, NULL, NULL, + FALSE, FALSE); + if (parent && fnmatch(pattern, parent_name, 0) != 0) + gtk_ctree_expand(GTK_CTREE(ctree), parent); + gtk_ctree_node_set_selectable(GTK_CTREE(ctree), node, FALSE); + + grouplist_hash_set_branch_node(name, node); + + g_free(parent_name); + + return node; +} + +static GtkCTreeNode *grouplist_create_branch(NewsGroupInfo *ginfo, + const gchar *pattern) +{ + GtkCTreeNode *node; + GtkCTreeNode *parent; + gchar *name = (gchar *)ginfo->name; + gchar *parent_name; + gchar *count_str; + gchar *cols[3]; + gint count; + + count = ginfo->last - ginfo->first; + if (count < 0) + count = 0; + count_str = itos(count); + + cols[0] = ginfo->name; + cols[1] = count_str; + if (ginfo->type == 'y') + cols[2] = ""; + else if (ginfo->type == 'm') + cols[2] = _("moderated"); + else if (ginfo->type == 'n') + cols[2] = _("readonly"); + else + cols[2] = _("unknown"); + + parent_name = grouplist_get_parent_name(name); + parent = grouplist_create_parent(parent_name, pattern); + node = grouplist_hash_get_branch_node(name); + if (node) { + gtk_ctree_set_node_info(GTK_CTREE(ctree), node, cols[0], 0, + NULL, NULL, NULL, NULL, FALSE, FALSE); + gtk_ctree_node_set_text(GTK_CTREE(ctree), node, 1, cols[1]); + gtk_ctree_node_set_text(GTK_CTREE(ctree), node, 2, cols[2]); + } else { + node = parent ? GTK_CTREE_ROW(parent)->children + : GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); + node = gtk_ctree_insert_node(GTK_CTREE(ctree), parent, node, + cols, 0, NULL, NULL, NULL, NULL, + TRUE, FALSE); + if (parent && fnmatch(pattern, parent_name, 0) != 0) + gtk_ctree_expand(GTK_CTREE(ctree), parent); + } + gtk_ctree_node_set_selectable(GTK_CTREE(ctree), node, TRUE); + if (node) + gtk_ctree_node_set_row_data(GTK_CTREE(ctree), node, ginfo); + + g_free(parent_name); + + return node; +} + +static void grouplist_expand_upwards(GtkCTree *ctree, const gchar *name) { + const gchar *ptr; + gchar *newname=g_malloc0(strlen(name)); + + for (ptr=name; *ptr; ptr++) { + if (*ptr == '.') + gtk_ctree_expand(ctree, + grouplist_hash_get_branch_node(newname)); + newname[ptr-name] = *ptr; + } + g_free(newname); +} + +static void grouplist_dialog_set_list(const gchar *pattern, gboolean refresh) +{ + GSList *cur; + GtkCTreeNode *node; if (locked) return; locked = TRUE; - grouplist_clear(); + if (!pattern || *pattern == '\0') + pattern = "*"; - recv_set_ui_func(grouplist_recv_func, NULL); - group_list = news_get_group_list(news_folder); - recv_set_ui_func(NULL, NULL); - if (group_list == NULL) { - alertpanel_error(_("Can't retrieve newsgroup list.")); - locked = FALSE; - return; - } + if (refresh) { + ack = TRUE; + grouplist_clear(); + recv_set_ui_func(grouplist_recv_func, NULL); + group_list = news_get_group_list(news_folder); + group_list = g_slist_reverse(group_list); + recv_set_ui_func(NULL, NULL); + if (group_list == NULL && ack == TRUE) { + alertpanel_error(_("Can't retrieve newsgroup list.")); + locked = FALSE; + return; + } + } else + gtk_clist_clear(GTK_CLIST(ctree)); + + gtk_entry_set_text(GTK_ENTRY(entry), pattern); + + grouplist_hash_init(); + + gtk_clist_freeze(GTK_CLIST(ctree)); - dont_unsubscribed = TRUE; - gtk_clist_freeze(GTK_CLIST(clist)); for (cur = group_list; cur != NULL ; cur = cur->next) { - struct NNTPGroupInfo * info; - - info = (struct NNTPGroupInfo *) cur->data; - - if (fnmatch(pattern, info->name, 0) == 0) { - gchar count_str[10]; - gchar * cols[3]; - gint count; - GList * l; - - count = info->last - info->first; - if (count < 0) - count = 0; - snprintf(count_str, 10, "%i", count); - - cols[0] = info->name; - cols[1] = count_str; - if (info->type == 'y') - cols[2] = ""; - else if (info->type == 'm') - cols[2] = "moderated"; - else if (info->type == 'n') - cols[2] = "readonly"; - else - cols[2] = "unkown"; - - row = gtk_clist_append(GTK_CLIST(clist), cols); - gtk_clist_set_row_data(GTK_CLIST(clist), row, info); - - l = g_list_find_custom(subscribed, info->name, - (GCompareFunc) g_strcasecmp); - - if (l != NULL) - gtk_clist_select_row(GTK_CLIST(clist), row, 0); + NewsGroupInfo *ginfo = (NewsGroupInfo *)cur->data; + + if (fnmatch(pattern, ginfo->name, 0) == 0) { + node = grouplist_create_branch(ginfo, pattern); + if (g_slist_find_custom(subscribed, ginfo->name, + (GCompareFunc)g_strcasecmp) + != NULL) { + gtk_ctree_select(GTK_CTREE(ctree), node); + } } } + for (cur = subscribed; cur; cur = g_slist_next(cur)) + grouplist_expand_upwards(GTK_CTREE(ctree), (gchar *)cur->data); - gtk_clist_moveto(GTK_CLIST(clist), 0, 0, 0, 0); + gtk_clist_thaw(GTK_CLIST(ctree)); - dont_unsubscribed = FALSE; + grouplist_hash_done(); - gtk_clist_set_column_width(GTK_CLIST(clist), 0, GROUPLIST_NAMES); - gtk_clist_set_column_justification (GTK_CLIST(clist), 1, - GTK_JUSTIFY_RIGHT); - gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE); - gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 2, TRUE); + gtk_label_set_text(GTK_LABEL(status_label), _("Done.")); - gtk_clist_thaw(GTK_CLIST(clist)); + locked = FALSE; +} - gtk_widget_grab_focus(ok_button); - gtk_widget_grab_focus(clist); +static void grouplist_search(void) +{ + gchar *str; - gtk_label_set_text(GTK_LABEL(status_label), _("Done.")); + if (locked) return; - locked = FALSE; + str = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); + grouplist_dialog_set_list(str, FALSE); + g_free(str); } -static void grouplist_recv_func(SockInfo *sock, gint count, gint read_bytes, - gpointer data) +static void grouplist_clear(void) +{ + gtk_clist_clear(GTK_CLIST(ctree)); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + news_group_list_free(group_list); + group_list = NULL; +} + +static gboolean grouplist_recv_func(SockInfo *sock, gint count, gint read_bytes, + gpointer data) { gchar buf[BUFFSIZE]; @@ -342,30 +471,26 @@ static void grouplist_recv_func(SockInfo *sock, gint count, gint read_bytes, count, to_human_readable(read_bytes)); gtk_label_set_text(GTK_LABEL(status_label), buf); GTK_EVENTS_FLUSH(); + if (ack == FALSE) + return FALSE; + else + return TRUE; } -static void ok_clicked(GtkWidget *widget, gpointer data) +static gint window_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data) { - gchar * str; - gboolean update_list; - - str = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - - update_list = FALSE; + ack = FALSE; + if (gtk_main_level() > 1) + gtk_main_quit(); - if (strchr(str, '*') != NULL) - update_list = TRUE; + return TRUE; +} - if (update_list) { - grouplist_dialog_set_list(str); - g_free(str); - } - else { - g_free(str); - ack = TRUE; - if (gtk_main_level() > 1) - gtk_main_quit(); - } +static void ok_clicked(GtkWidget *widget, gpointer data) +{ + ack = TRUE; + if (gtk_main_level() > 1) + gtk_main_quit(); } static void cancel_clicked(GtkWidget *widget, gpointer data) @@ -376,79 +501,75 @@ static void cancel_clicked(GtkWidget *widget, gpointer data) } static void refresh_clicked(GtkWidget *widget, gpointer data) -{ - gchar * str; - +{ + gchar *str; + if (locked) return; - news_cancel_group_list_cache(news_folder); + news_remove_group_list_cache(news_folder); str = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - grouplist_dialog_set_list(str); + grouplist_dialog_set_list(str, TRUE); g_free(str); } -static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) +static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event && event->keyval == GDK_Escape) cancel_clicked(NULL, NULL); + return FALSE; } -static void clist_selected(GtkCList *clist, gint row, gint column, - GdkEventButton *event, gpointer user_data) +/* clist/ctree clear old selection on click (gtk2 only) + * - intercept all button clicks (always return TRUE) + * - only allow left button single click + * - handle click on expander + * - update "subscribed" list and un-/select row + */ +static gboolean button_press_cb(GtkCTree *ctree, GdkEventButton *button, + gpointer data) { - struct NNTPGroupInfo * group; - GList * l; - - group = (struct NNTPGroupInfo *) - gtk_clist_get_row_data(GTK_CLIST(clist), row); - - if (!dont_unsubscribed) { - subscribed = g_list_append(subscribed, g_strdup(group->name)); + gint row, col; + GtkCTreeNode *node; + NewsGroupInfo *ginfo; + GSList *list; + + if (button->type != GDK_BUTTON_PRESS) return TRUE; + if (button->button != 1) return TRUE; + + gtk_clist_get_selection_info(GTK_CLIST(ctree), + button->x, button->y, &row, &col); + node = gtk_ctree_node_nth(ctree, row); + if (!node) return TRUE; + + if (gtk_ctree_is_hot_spot(ctree, button->x, button->y)) { + gtk_ctree_toggle_expansion(ctree, node); + return TRUE; } -} -static void clist_unselected(GtkCList *clist, gint row, gint column, - GdkEventButton *event, gpointer user_data) -{ - struct NNTPGroupInfo * group; - GList * l; - - group = (struct NNTPGroupInfo *) - gtk_clist_get_row_data(GTK_CLIST(clist), row); - - if (!dont_unsubscribed) { - l = g_list_find_custom(subscribed, group->name, - (GCompareFunc) g_strcasecmp); - if (l != NULL) { - g_free(l->data); - subscribed = g_list_remove(subscribed, l->data); - } + ginfo = gtk_ctree_node_get_row_data(ctree, node); + if (!ginfo) return TRUE; + + list = g_slist_find_custom(subscribed, ginfo->name, + (GCompareFunc)g_strcasecmp); + if (list) { + g_free(list->data); + subscribed = g_slist_remove(subscribed, list->data); + gtk_clist_unselect_row(GTK_CLIST(ctree), row, 0); + } else { + subscribed = g_slist_append(subscribed, g_strdup(ginfo->name)); + gtk_clist_select_row(GTK_CLIST(ctree), row, 0); } -} -static gboolean match_string(gchar * str, gchar * expr) -{ + return TRUE; } static void entry_activated(GtkEditable *editable) { - gchar * str; - gboolean update_list; - - str = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); - - update_list = FALSE; - - if (strchr(str, '*') != NULL) - update_list = TRUE; + grouplist_search(); +} - if (update_list) { - grouplist_dialog_set_list(str); - g_free(str); - } - else { - g_free(str); - ok_clicked(NULL, NULL); - } +static void search_clicked(GtkWidget *widget, gpointer data) +{ + grouplist_search(); }