Use macros instead of raw numbers for login type
[rofl0r-ixchat.git] / src / fe-gtk / ignoregui.c
blob433ab24519b01c4f10ae4b288bcff8810d77c992
1 /* X-Chat
2 * Copyright (C) 1998 Peter Zelezny.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include "fe-gtk.h"
27 #include <gtk/gtkcheckbutton.h>
28 #include <gtk/gtkentry.h>
29 #include <gtk/gtkstock.h>
30 #include <gtk/gtkhbox.h>
31 #include <gtk/gtkhbbox.h>
32 #include <gtk/gtkframe.h>
33 #include <gtk/gtkhseparator.h>
34 #include <gtk/gtkversion.h>
36 #include <gtk/gtkliststore.h>
37 #include <gtk/gtktreeview.h>
38 #include <gtk/gtktreeselection.h>
39 #include <gtk/gtkcellrenderertext.h>
40 #include <gtk/gtkcellrenderertoggle.h>
42 #include "../common/xchat.h"
43 #include "../common/ignore.h"
44 #include "../common/cfgfiles.h"
45 #include "../common/fe.h"
46 #include "gtkutil.h"
47 #include "maingui.h"
49 enum
51 MASK_COLUMN,
52 CHAN_COLUMN,
53 PRIV_COLUMN,
54 NOTICE_COLUMN,
55 CTCP_COLUMN,
56 DCC_COLUMN,
57 INVITE_COLUMN,
58 UNIGNORE_COLUMN,
59 N_COLUMNS
62 static GtkWidget *ignorewin = 0;
64 static GtkWidget *num_ctcp;
65 static GtkWidget *num_priv;
66 static GtkWidget *num_chan;
67 static GtkWidget *num_noti;
68 static GtkWidget *num_invi;
70 static GtkTreeModel *
71 get_store (void)
73 return gtk_tree_view_get_model (g_object_get_data (G_OBJECT (ignorewin), "view"));
76 static int
77 ignore_get_flags (GtkTreeModel *model, GtkTreeIter *iter)
79 gboolean chan, priv, noti, ctcp, dcc, invi, unig;
80 int flags = 0;
82 gtk_tree_model_get (model, iter, 1, &chan, 2, &priv, 3, &noti,
83 4, &ctcp, 5, &dcc, 6, &invi, 7, &unig, -1);
84 if (chan)
85 flags |= IG_CHAN;
86 if (priv)
87 flags |= IG_PRIV;
88 if (noti)
89 flags |= IG_NOTI;
90 if (ctcp)
91 flags |= IG_CTCP;
92 if (dcc)
93 flags |= IG_DCC;
94 if (invi)
95 flags |= IG_INVI;
96 if (unig)
97 flags |= IG_UNIG;
98 return flags;
101 static void
102 mask_edited (GtkCellRendererText *render, gchar *path, gchar *new, gpointer dat)
104 GtkListStore *store = GTK_LIST_STORE (get_store ());
105 GtkTreeIter iter;
106 char *old;
107 int flags;
109 gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter);
110 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &old, -1);
112 if (!strcmp (old, new)) /* no change */
114 else if (ignore_exists (new)) /* duplicate, ignore */
115 fe_message (_("That mask already exists."), FE_MSG_ERROR);
116 else
118 /* delete old mask, and add new one with original flags */
119 ignore_del (old, NULL);
120 flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter);
121 ignore_add (new, flags);
123 /* update tree */
124 gtk_list_store_set (store, &iter, MASK_COLUMN, new, -1);
126 g_free (old);
130 static void
131 option_toggled (GtkCellRendererToggle *render, gchar *path, gpointer data)
133 GtkListStore *store = GTK_LIST_STORE (get_store ());
134 GtkTreeIter iter;
135 int col_id = GPOINTER_TO_INT (data);
136 gboolean active;
137 char *mask;
138 int flags;
140 gtkutil_treemodel_string_to_iter (GTK_TREE_MODEL (store), path, &iter);
142 /* update model */
143 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, col_id, &active, -1);
144 gtk_list_store_set (store, &iter, col_id, !active, -1);
146 /* update ignore list */
147 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &mask, -1);
148 flags = ignore_get_flags (GTK_TREE_MODEL (store), &iter);
149 if (ignore_add (mask, flags) != 2)
150 g_warning ("ignore treeview is out of sync!\n");
152 g_free (mask);
155 static GtkWidget *
156 ignore_treeview_new (GtkWidget *box)
158 GtkListStore *store;
159 GtkWidget *view;
160 GtkTreeViewColumn *col;
161 GtkCellRenderer *render;
162 int col_id;
164 store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING,
165 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
166 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
167 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
168 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
169 g_return_val_if_fail (store != NULL, NULL);
171 view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store),
172 NULL,
173 MASK_COLUMN, _("Mask"),
174 CHAN_COLUMN, _("Channel"),
175 PRIV_COLUMN, _("Private"),
176 NOTICE_COLUMN, _("Notice"),
177 CTCP_COLUMN, _("CTCP"),
178 DCC_COLUMN, _("DCC"),
179 INVITE_COLUMN, _("Invite"),
180 UNIGNORE_COLUMN, _("Unignore"),
181 -1);
183 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
184 gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
186 /* attach to signals and customise columns */
187 for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id));
188 col_id++)
190 GList *list = gtk_tree_view_column_get_cell_renderers (col);
191 GList *tmp;
193 for (tmp = list; tmp; tmp = tmp->next)
195 render = tmp->data;
196 if (col_id > 0) /* it's a toggle button column */
198 g_signal_connect (render, "toggled", G_CALLBACK (option_toggled),
199 GINT_TO_POINTER (col_id));
200 } else /* mask column */
202 g_object_set (G_OBJECT (render), "editable", TRUE, NULL);
203 g_signal_connect (render, "edited", G_CALLBACK (mask_edited), NULL);
204 /* make this column sortable */
205 gtk_tree_view_column_set_sort_column_id (col, col_id);
206 gtk_tree_view_column_set_min_width (col, 272);
208 /* centre titles */
209 gtk_tree_view_column_set_alignment (col, 0.5);
212 g_list_free (list);
215 gtk_widget_show (view);
216 return view;
219 static void
220 ignore_delete_entry_clicked (GtkWidget * wid, struct session *sess)
222 GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view");
223 GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
224 GtkTreeIter iter;
225 GtkTreePath *path;
226 char *mask = NULL;
228 if (gtkutil_treeview_get_selected (view, &iter, 0, &mask, -1))
230 /* delete this row, select next one */
231 if (gtk_list_store_remove (store, &iter))
233 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
234 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0);
235 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
236 gtk_tree_path_free (path);
239 ignore_del (mask, NULL);
240 g_free (mask);
244 static void
245 ignore_store_new (int cancel, char *mask, gpointer data)
247 GtkTreeView *view = g_object_get_data (G_OBJECT (ignorewin), "view");
248 GtkListStore *store = GTK_LIST_STORE (get_store ());
249 GtkTreeIter iter;
250 GtkTreePath *path;
251 int flags = IG_CHAN | IG_PRIV | IG_NOTI | IG_CTCP | IG_DCC | IG_INVI;
253 if (cancel)
254 return;
255 /* check if it already exists */
256 if (ignore_exists (mask))
258 fe_message (_("That mask already exists."), FE_MSG_ERROR);
259 return;
262 ignore_add (mask, flags);
264 gtk_list_store_append (store, &iter);
265 /* ignore everything by default */
266 gtk_list_store_set (store, &iter, 0, mask, 1, TRUE, 2, TRUE, 3, TRUE,
267 4, TRUE, 5, TRUE, 6, TRUE, 7, FALSE, -1);
268 /* make sure the new row is visible and selected */
269 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
270 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 1.0, 0.0);
271 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
272 gtk_tree_path_free (path);
275 static void
276 ignore_clear_entry_clicked (GtkWidget * wid, gpointer unused)
278 GtkListStore *store = GTK_LIST_STORE (get_store ());
279 GtkTreeIter iter;
280 char *mask;
282 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
284 /* remove from ignore_list */
287 mask = NULL;
288 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, MASK_COLUMN, &mask, -1);
289 ignore_del (mask, NULL);
290 g_free (mask);
292 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
294 /* remove from GUI */
295 gtk_list_store_clear (store);
299 static void
300 ignore_new_entry_clicked (GtkWidget * wid, struct session *sess)
302 fe_get_str (_("Enter mask to ignore:"), "nick!userid@host.com",
303 ignore_store_new, NULL);
307 static void
308 close_ignore_gui_callback ()
310 ignore_save ();
311 ignorewin = 0;
314 static GtkWidget *
315 ignore_stats_entry (GtkWidget * box, char *label, int value)
317 GtkWidget *wid;
318 char buf[16];
320 sprintf (buf, "%d", value);
321 gtkutil_label_new (label, box);
322 wid = gtkutil_entry_new (16, box, 0, 0);
323 gtk_widget_set_size_request (wid, 30, -1);
324 gtk_editable_set_editable (GTK_EDITABLE (wid), FALSE);
325 gtk_widget_set_sensitive (GTK_WIDGET (wid), FALSE);
326 gtk_entry_set_text (GTK_ENTRY (wid), buf);
328 return wid;
331 void
332 ignore_gui_open ()
334 GtkWidget *vbox, *box, *stat_box, *frame;
335 GtkWidget *view;
336 GtkListStore *store;
337 GtkTreeIter iter;
338 GSList *temp = ignore_list;
339 char *mask;
340 gboolean private, chan, notice, ctcp, dcc, invite, unignore;
342 if (ignorewin)
344 mg_bring_tofront (ignorewin);
345 return;
348 ignorewin =
349 mg_create_generic_tab ("IgnoreList", _("XChat: Ignore list"),
350 FALSE, TRUE, close_ignore_gui_callback,
351 NULL, 600, 256, &vbox, 0);
353 view = ignore_treeview_new (vbox);
354 g_object_set_data (G_OBJECT (ignorewin), "view", view);
356 frame = gtk_frame_new (_("Ignore Stats:"));
357 gtk_widget_show (frame);
359 stat_box = gtk_hbox_new (0, 2);
360 gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6);
361 gtk_container_add (GTK_CONTAINER (frame), stat_box);
362 gtk_widget_show (stat_box);
364 num_chan = ignore_stats_entry (stat_box, _("Channel:"), ignored_chan);
365 num_priv = ignore_stats_entry (stat_box, _("Private:"), ignored_priv);
366 num_noti = ignore_stats_entry (stat_box, _("Notice:"), ignored_noti);
367 num_ctcp = ignore_stats_entry (stat_box, _("CTCP:"), ignored_ctcp);
368 num_invi = ignore_stats_entry (stat_box, _("Invite:"), ignored_invi);
370 gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 5);
372 box = gtk_hbutton_box_new ();
373 gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
374 gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2);
375 gtk_container_set_border_width (GTK_CONTAINER (box), 5);
376 gtk_widget_show (box);
378 gtkutil_button (box, GTK_STOCK_NEW, 0, ignore_new_entry_clicked, 0,
379 _("Add..."));
380 gtkutil_button (box, GTK_STOCK_DELETE, 0, ignore_delete_entry_clicked,
381 0, _("Delete"));
382 gtkutil_button (box, GTK_STOCK_CLEAR, 0, ignore_clear_entry_clicked,
383 0, _("Clear"));
385 store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
387 while (temp)
389 struct ignore *ignore = temp->data;
391 mask = ignore->mask;
392 chan = (ignore->type & IG_CHAN);
393 private = (ignore->type & IG_PRIV);
394 notice = (ignore->type & IG_NOTI);
395 ctcp = (ignore->type & IG_CTCP);
396 dcc = (ignore->type & IG_DCC);
397 invite = (ignore->type & IG_INVI);
398 unignore = (ignore->type & IG_UNIG);
400 gtk_list_store_append (store, &iter);
401 gtk_list_store_set (store, &iter,
402 MASK_COLUMN, mask,
403 CHAN_COLUMN, chan,
404 PRIV_COLUMN, private,
405 NOTICE_COLUMN, notice,
406 CTCP_COLUMN, ctcp,
407 DCC_COLUMN, dcc,
408 INVITE_COLUMN, invite,
409 UNIGNORE_COLUMN, unignore,
410 -1);
412 temp = temp->next;
414 gtk_widget_show (ignorewin);
417 void
418 fe_ignore_update (int level)
420 /* some ignores have changed via /ignore, we should update
421 the gui now */
422 /* level 1 = the list only. */
423 /* level 2 = the numbers only. */
424 /* for now, ignore level 1, since the ignore GUI isn't realtime,
425 only saved when you click OK */
426 char buf[16];
428 if (level == 2 && ignorewin)
430 sprintf (buf, "%d", ignored_ctcp);
431 gtk_entry_set_text (GTK_ENTRY (num_ctcp), buf);
433 sprintf (buf, "%d", ignored_noti);
434 gtk_entry_set_text (GTK_ENTRY (num_noti), buf);
436 sprintf (buf, "%d", ignored_chan);
437 gtk_entry_set_text (GTK_ENTRY (num_chan), buf);
439 sprintf (buf, "%d", ignored_invi);
440 gtk_entry_set_text (GTK_ENTRY (num_invi), buf);
442 sprintf (buf, "%d", ignored_priv);
443 gtk_entry_set_text (GTK_ENTRY (num_priv), buf);