diff options
Diffstat (limited to 'src/fe-gtk/ignoregui.c')
-rw-r--r-- | src/fe-gtk/ignoregui.c | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/src/fe-gtk/ignoregui.c b/src/fe-gtk/ignoregui.c new file mode 100644 index 00000000..dc5fce9c --- /dev/null +++ b/src/fe-gtk/ignoregui.c @@ -0,0 +1,449 @@ +/* X-Chat + * Copyright (C) 1998 Peter Zelezny. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "fe-gtk.h" + +#include <gtk/gtkcheckbutton.h> +#include <gtk/gtkentry.h> +#include <gtk/gtkstock.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtkhbbox.h> +#include <gtk/gtkframe.h> +#include <gtk/gtkhseparator.h> +#include <gtk/gtkversion.h> + +#include <gtk/gtkliststore.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtkcellrenderertext.h> +#include <gtk/gtkcellrenderertoggle.h> + +#include "../common/xchat.h" +#include "../common/ignore.h" +#include "../common/cfgfiles.h" +#include "../common/fe.h" +#include "gtkutil.h" +#include "maingui.h" + +enum +{ + MASK_COLUMN, + CHAN_COLUMN, + PRIV_COLUMN, + NOTICE_COLUMN, + CTCP_COLUMN, + DCC_COLUMN, + INVITE_COLUMN, + UNIGNORE_COLUMN, + N_COLUMNS +}; + +static GtkWidget *ignorewin = 0; + +static GtkWidget *num_ctcp; +static GtkWidget *num_priv; +static GtkWidget *num_chan; +static GtkWidget *num_noti; +static GtkWidget *num_invi; + +static GtkTreeModel * +get_store (void) +{ + return gtk_tree_view_get_model (g_object_get_data (G_OBJECT (ignorewin), "view")); +} + +static int +ignore_get_flags (GtkTreeModel *model, GtkTreeIter *iter) +{ + gboolean chan, priv, noti, ctcp, dcc, invi, unig; + int flags = 0; + + gtk_tree_model_get (model, iter, 1, &chan, 2, &priv, 3, ¬i, + 4, &ctcp, 5, &dcc, 6, &invi, 7, &unig, -1); + if (chan) + flags |= IG_CHAN; + if (priv) + flags |= IG_PRIV; + if (noti) + flags |= IG_NOTI; + if (ctcp) + flags |= IG_CTCP; + if (dcc) + flags |= IG_DCC; + if (invi) + flags |= IG_INVI; + if (unig) + flags |= IG_UNIG; + return flags; +} + +static void +mask_edited (GtkCellRendererText *render, gchar *path, gchar *new, gpointer dat) +{ + GtkListStore *store = GTK_LIST_STORE (get_store ()); + GtkTreeIter iter; + char *old; + int flags; + + gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter); + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &old, -1); + + if (!strcmp (old, new)) /* no change */ + ; + else if (ignore_exists (new)) /* duplicate, ignore */ + fe_message (_("That mask already exists."), FE_MSG_ERROR); + else + { + /* delete old mask, and add new one with original flags */ + ignore_del (old, NULL); + flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter); + ignore_add (new, flags); + + /* update tree */ + gtk_list_store_set (store, &iter, MASK_COLUMN, new, -1); + } + g_free (old); + +} + +static void +option_toggled (GtkCellRendererToggle *render, gchar *path, gpointer data) +{ + GtkListStore *store = GTK_LIST_STORE (get_store ()); + GtkTreeIter iter; + int col_id = GPOINTER_TO_INT (data); + gboolean active; + char *mask; + int flags; + + gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter); + + /* update model */ + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, col_id, &active, -1); + gtk_list_store_set (store, &iter, col_id, !active, -1); + + /* update ignore list */ + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &mask, -1); + flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter); + if (ignore_add (mask, flags) != 2) + g_warning ("ignore treeview is out of sync!\n"); + + g_free (mask); +} + +static GtkWidget * +ignore_treeview_new (GtkWidget *box) +{ + GtkListStore *store; + GtkWidget *view; + GtkTreeViewColumn *col; + GtkCellRenderer *render; + int col_id; + + store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + g_return_val_if_fail (store != NULL, NULL); + + view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store), + NULL, + MASK_COLUMN, _("Mask"), + CHAN_COLUMN, _("Channel"), + PRIV_COLUMN, _("Private"), + NOTICE_COLUMN, _("Notice"), + CTCP_COLUMN, _("CTCP"), + DCC_COLUMN, _("DCC"), + INVITE_COLUMN, _("Invite"), + UNIGNORE_COLUMN, _("Unignore"), + -1); + + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); + gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE); + + /* attach to signals and customise columns */ + for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id)); + col_id++) + { + GList *list = gtk_tree_view_column_get_cell_renderers (col); + GList *tmp; + + for (tmp = list; tmp; tmp = tmp->next) + { + render = tmp->data; + if (col_id > 0) /* it's a toggle button column */ + { + g_signal_connect (render, "toggled", G_CALLBACK (option_toggled), + GINT_TO_POINTER (col_id)); + } else /* mask column */ + { + g_object_set (G_OBJECT (render), "editable", TRUE, NULL); + g_signal_connect (render, "edited", G_CALLBACK (mask_edited), NULL); + /* make this column sortable */ + gtk_tree_view_column_set_sort_column_id (col, col_id); + gtk_tree_view_column_set_min_width (col, 272); + } + /* centre titles */ + gtk_tree_view_column_set_alignment (col, 0.5); + } + + g_list_free (list); + } + + gtk_widget_show (view); + return view; +} + +static void +ignore_delete_entry_clicked (GtkWidget * wid, struct session *sess) +{ + GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view"); + GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); + GtkTreeIter iter; + GtkTreePath *path; + char *mask = NULL; + + if (gtkutil_treeview_get_selected (view, &iter, 0, &mask, -1)) + { + /* delete this row, select next one */ +#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0) + gtk_list_store_remove (store, &iter); +#else + if (gtk_list_store_remove (store, &iter)) + { + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0); + gtk_tree_view_set_cursor (view, path, NULL, FALSE); + gtk_tree_path_free (path); + } +#endif + + ignore_del (mask, NULL); + g_free (mask); + } +} + +static void +ignore_store_new (int cancel, char *mask, gpointer data) +{ + GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view"); + GtkListStore *store = GTK_LIST_STORE (get_store ()); + GtkTreeIter iter; + GtkTreePath *path; + int flags = IG_CHAN | IG_PRIV | IG_NOTI | IG_CTCP | IG_DCC | IG_INVI; + + if (cancel) + return; + /* check if it already exists */ + if (ignore_exists (mask)) + { + fe_message (_("That mask already exists."), FE_MSG_ERROR); + return; + } + + ignore_add (mask, flags); + + gtk_list_store_append (store, &iter); + /* ignore everything by default */ + gtk_list_store_set (store, &iter, 0, mask, 1, TRUE, 2, TRUE, 3, TRUE, + 4, TRUE, 5, TRUE, 6, TRUE, 7, FALSE, -1); + /* make sure the new row is visible and selected */ + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0); + gtk_tree_view_set_cursor (view, path, NULL, FALSE); + gtk_tree_path_free (path); +} + +static void +ignore_clear_entry_clicked (GtkWidget * wid, gpointer unused) +{ + GtkListStore *store = GTK_LIST_STORE (get_store ()); + GtkTreeIter iter; + char *mask; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) + { + /* remove from ignore_list */ + do + { + mask = NULL; + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, MASK_COLUMN, &mask, -1); + ignore_del (mask, NULL); + g_free (mask); + } + while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); + + /* remove from GUI */ + gtk_list_store_clear (store); + } +} + +static void +ignore_new_entry_clicked (GtkWidget * wid, struct session *sess) +{ + fe_get_str (_("Enter mask to ignore:"), "nick!userid@host.com", + ignore_store_new, NULL); + +} + +static void +close_ignore_gui_callback () +{ + ignore_save (); + ignorewin = 0; +} + +static GtkWidget * +ignore_stats_entry (GtkWidget * box, char *label, int value) +{ + GtkWidget *wid; + char buf[16]; + + sprintf (buf, "%d", value); + gtkutil_label_new (label, box); + wid = gtkutil_entry_new (16, box, 0, 0); + gtk_widget_set_size_request (wid, 30, -1); + gtk_editable_set_editable (GTK_EDITABLE (wid), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (wid), FALSE); + gtk_entry_set_text (GTK_ENTRY (wid), buf); + + return wid; +} + +void +ignore_gui_open () +{ + GtkWidget *vbox, *box, *stat_box, *frame; + GtkWidget *view; + GtkListStore *store; + GtkTreeIter iter; + GSList *temp = ignore_list; + char *mask; + gboolean private, chan, notice, ctcp, dcc, invite, unignore; + + if (ignorewin) + { + mg_bring_tofront (ignorewin); + return; + } + + ignorewin = + mg_create_generic_tab ("IgnoreList", _("XChat: Ignore list"), + FALSE, TRUE, close_ignore_gui_callback, + NULL, 600, 256, &vbox, 0); + + view = ignore_treeview_new (vbox); + g_object_set_data (G_OBJECT (ignorewin), "view", view); + + frame = gtk_frame_new (_("Ignore Stats:")); + gtk_widget_show (frame); + + stat_box = gtk_hbox_new (0, 2); + gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6); + gtk_container_add (GTK_CONTAINER (frame), stat_box); + gtk_widget_show (stat_box); + + num_chan = ignore_stats_entry (stat_box, _("Channel:"), ignored_chan); + num_priv = ignore_stats_entry (stat_box, _("Private:"), ignored_priv); + num_noti = ignore_stats_entry (stat_box, _("Notice:"), ignored_noti); + num_ctcp = ignore_stats_entry (stat_box, _("CTCP:"), ignored_ctcp); + num_invi = ignore_stats_entry (stat_box, _("Invite:"), ignored_invi); + + gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 5); + + box = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD); + gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (box), 5); + gtk_widget_show (box); + + gtkutil_button (box, GTK_STOCK_NEW, 0, ignore_new_entry_clicked, 0, + _("Add...")); + gtkutil_button (box, GTK_STOCK_DELETE, 0, ignore_delete_entry_clicked, + 0, _("Delete")); + gtkutil_button (box, GTK_STOCK_CLEAR, 0, ignore_clear_entry_clicked, + 0, _("Clear")); + + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); + + while (temp) + { + struct ignore *ignore = temp->data; + + mask = ignore->mask; + chan = (ignore->type & IG_CHAN); + private = (ignore->type & IG_PRIV); + notice = (ignore->type & IG_NOTI); + ctcp = (ignore->type & IG_CTCP); + dcc = (ignore->type & IG_DCC); + invite = (ignore->type & IG_INVI); + unignore = (ignore->type & IG_UNIG); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + MASK_COLUMN, mask, + CHAN_COLUMN, chan, + PRIV_COLUMN, private, + NOTICE_COLUMN, notice, + CTCP_COLUMN, ctcp, + DCC_COLUMN, dcc, + INVITE_COLUMN, invite, + UNIGNORE_COLUMN, unignore, + -1); + + temp = temp->next; + } + gtk_widget_show (ignorewin); +} + +void +fe_ignore_update (int level) +{ + /* some ignores have changed via /ignore, we should update + the gui now */ + /* level 1 = the list only. */ + /* level 2 = the numbers only. */ + /* for now, ignore level 1, since the ignore GUI isn't realtime, + only saved when you click OK */ + char buf[16]; + + if (level == 2 && ignorewin) + { + sprintf (buf, "%d", ignored_ctcp); + gtk_entry_set_text (GTK_ENTRY (num_ctcp), buf); + + sprintf (buf, "%d", ignored_noti); + gtk_entry_set_text (GTK_ENTRY (num_noti), buf); + + sprintf (buf, "%d", ignored_chan); + gtk_entry_set_text (GTK_ENTRY (num_chan), buf); + + sprintf (buf, "%d", ignored_invi); + gtk_entry_set_text (GTK_ENTRY (num_invi), buf); + + sprintf (buf, "%d", ignored_priv); + gtk_entry_set_text (GTK_ENTRY (num_priv), buf); + } +} |