restructure configure so pkg-config derived SSL flags get used
[rofl0r-ixchat.git] / src / fe-gtk / banlist.c
blob5bbfe8cbeb689bd37d1be927ca4b2c578c282f9a
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 <unistd.h>
23 #include <fcntl.h>
24 #include <time.h>
26 #include "fe-gtk.h"
28 #include <gtk/gtkhbox.h>
29 #include <gtk/gtkvbox.h>
30 #include <gtk/gtkhbbox.h>
31 #include <gtk/gtkstock.h>
32 #include <gtk/gtkliststore.h>
33 #include <gtk/gtkmessagedialog.h>
34 #include <gtk/gtktreeview.h>
35 #include <gtk/gtktreeselection.h>
37 #include "../common/xchat.h"
38 #include "../common/fe.h"
39 #include "../common/modes.h"
40 #include "../common/outbound.h"
41 #include "../common/xchatc.h"
42 #include "gtkutil.h"
43 #include "maingui.h"
44 #include "banlist.h"
46 /* model for the banlist tree */
47 enum
49 MASK_COLUMN,
50 FROM_COLUMN,
51 DATE_COLUMN,
52 N_COLUMNS
55 static GtkTreeView *
56 get_view (struct session *sess)
58 return GTK_TREE_VIEW (sess->res->banlist_treeview);
61 static GtkListStore *
62 get_store (struct session *sess)
64 return GTK_LIST_STORE (gtk_tree_view_get_model (get_view (sess)));
67 static gboolean
68 supports_exempt (server *serv)
70 char *cm = serv->chanmodes;
72 if (serv->have_except)
73 return TRUE;
75 if (!cm)
76 return FALSE;
78 while (*cm)
80 if (*cm == ',')
81 break;
82 if (*cm == 'e')
83 return TRUE;
84 cm++;
87 return FALSE;
90 void
91 fe_add_ban_list (struct session *sess, char *mask, char *who, char *when, int is_exempt)
93 GtkListStore *store;
94 GtkTreeIter iter;
95 char buf[512];
97 store = get_store (sess);
98 gtk_list_store_append (store, &iter);
100 if (is_exempt)
102 snprintf (buf, sizeof (buf), "(EX) %s", mask);
103 gtk_list_store_set (store, &iter, 0, buf, 1, who, 2, when, -1);
104 } else
106 gtk_list_store_set (store, &iter, 0, mask, 1, who, 2, when, -1);
110 void
111 fe_ban_list_end (struct session *sess, int is_exemption)
113 gtk_widget_set_sensitive (sess->res->banlist_butRefresh, TRUE);
117 * * Performs the actual refresh operations.
118 * */
119 static void
120 banlist_do_refresh (struct session *sess)
122 char tbuf[256];
123 if (sess->server->connected)
125 GtkListStore *store;
127 gtk_widget_set_sensitive (sess->res->banlist_butRefresh, FALSE);
129 snprintf (tbuf, sizeof tbuf, "XChat: Ban List (%s, %s)",
130 sess->channel, sess->server->servername);
131 mg_set_title (sess->res->banlist_window, tbuf);
133 store = get_store (sess);
134 gtk_list_store_clear (store);
136 handle_command (sess, "ban", FALSE);
137 if (supports_exempt (sess->server))
139 snprintf (tbuf, sizeof (tbuf), "quote mode %s +e", sess->channel);
140 handle_command (sess, tbuf, FALSE);
143 } else
145 fe_message (_("Not connected."), FE_MSG_ERROR);
149 static void
150 banlist_refresh (GtkWidget * wid, struct session *sess)
152 /* JG NOTE: Didn't see actual use of wid here, so just forwarding
153 * * this to chanlist_do_refresh because I use it without any widget
154 * * param in chanlist_build_gui_list when the user presses enter
155 * * or apply for the first time if the list has not yet been
156 * * received.
157 * */
158 banlist_do_refresh (sess);
161 static int
162 banlist_unban_inner (gpointer none, struct session *sess, int do_exempts)
164 GtkTreeModel *model;
165 GtkTreeSelection *sel;
166 GtkTreeIter iter;
167 char tbuf[2048];
168 char **masks, *tmp, *space;
169 int num_sel, i;
171 /* grab the list of selected items */
172 model = GTK_TREE_MODEL (get_store (sess));
173 sel = gtk_tree_view_get_selection (get_view (sess));
174 num_sel = 0;
175 if (gtk_tree_model_get_iter_first (model, &iter))
179 if (gtk_tree_selection_iter_is_selected (sel, &iter))
180 num_sel++;
182 while (gtk_tree_model_iter_next (model, &iter));
185 if (num_sel < 1)
186 return 0;
188 /* create an array of all the masks */
189 masks = calloc (1, num_sel * sizeof (char *));
191 i = 0;
192 gtk_tree_model_get_iter_first (model, &iter);
195 if (gtk_tree_selection_iter_is_selected (sel, &iter))
197 gtk_tree_model_get (model, &iter, MASK_COLUMN, &masks[i], -1);
198 space = strchr (masks[i], ' ');
200 if (do_exempts)
202 if (space)
204 /* remove the "(EX) " */
205 tmp = masks[i];
206 masks[i] = g_strdup (space + 1);
207 g_free (tmp);
208 i++;
210 } else
212 if (!space)
213 i++;
217 while (gtk_tree_model_iter_next (model, &iter));
219 /* and send to server */
220 if (do_exempts)
221 send_channel_modes (sess, tbuf, masks, 0, i, '-', 'e', 0);
222 else
223 send_channel_modes (sess, tbuf, masks, 0, i, '-', 'b', 0);
225 /* now free everything, and refresh banlist */
226 for (i=0; i < num_sel; i++)
227 g_free (masks[i]);
228 free (masks);
230 return num_sel;
233 static void
234 banlist_unban (GtkWidget * wid, struct session *sess)
236 int num = 0;
238 num += banlist_unban_inner (wid, sess, FALSE);
239 num += banlist_unban_inner (wid, sess, TRUE);
241 if (num < 1)
243 fe_message (_("You must select some bans."), FE_MSG_ERROR);
244 return;
247 banlist_do_refresh (sess);
250 static void
251 banlist_clear_cb (GtkDialog *dialog, gint response, gpointer sess)
253 GtkTreeSelection *sel;
255 gtk_widget_destroy (GTK_WIDGET (dialog));
257 if (response == GTK_RESPONSE_OK)
259 sel = gtk_tree_view_get_selection (get_view (sess));
260 gtk_tree_selection_select_all (sel);
261 banlist_unban (NULL, sess);
265 static void
266 banlist_clear (GtkWidget * wid, struct session *sess)
268 GtkWidget *dialog;
270 dialog = gtk_message_dialog_new (NULL, 0,
271 GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
272 _("Are you sure you want to remove all bans in %s?"), sess->channel);
273 g_signal_connect (G_OBJECT (dialog), "response",
274 G_CALLBACK (banlist_clear_cb), sess);
275 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
276 gtk_widget_show (dialog);
279 static void
280 banlist_add_selected_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
282 GSList **lp = data;
283 GSList *list = NULL;
284 GtkTreeIter *copy;
286 if (!lp) return;
287 list = *lp;
288 copy = g_malloc (sizeof (GtkTreeIter));
289 g_return_if_fail (copy != NULL);
290 *copy = *iter;
292 list = g_slist_append (list, copy);
293 *(GSList **)data = list;
296 static void
297 banlist_crop (GtkWidget * wid, struct session *sess)
299 GtkTreeSelection *select;
300 GSList *list = NULL, *node;
301 int num_sel;
303 /* remember which bans are selected */
304 select = gtk_tree_view_get_selection (get_view (sess));
305 /* gtk_tree_selected_get_selected_rows() isn't present in gtk 2.0.x */
306 gtk_tree_selection_selected_foreach (select, banlist_add_selected_cb,
307 &list);
309 num_sel = g_slist_length (list);
310 /* select all, then unselect those that we remembered */
311 if (num_sel)
313 gtk_tree_selection_select_all (select);
315 for (node = list; node; node = node->next)
316 gtk_tree_selection_unselect_iter (select, node->data);
318 g_slist_foreach (list, (GFunc)g_free, NULL);
319 g_slist_free (list);
321 banlist_unban (NULL, sess);
322 } else
323 fe_message (_("You must select some bans."), FE_MSG_ERROR);
326 static GtkWidget *
327 banlist_treeview_new (GtkWidget *box)
329 GtkListStore *store;
330 GtkWidget *view;
331 GtkTreeSelection *select;
332 GtkTreeViewColumn *col;
334 store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
335 G_TYPE_STRING);
336 g_return_val_if_fail (store != NULL, NULL);
337 view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store), NULL,
338 MASK_COLUMN, _("Mask"),
339 FROM_COLUMN, _("From"),
340 DATE_COLUMN, _("Date"), -1);
342 col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), MASK_COLUMN);
343 gtk_tree_view_column_set_alignment (col, 0.5);
344 gtk_tree_view_column_set_min_width (col, 300);
345 gtk_tree_view_column_set_sort_column_id (col, MASK_COLUMN);
347 col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), FROM_COLUMN);
348 gtk_tree_view_column_set_alignment (col, 0.5);
349 gtk_tree_view_column_set_sort_column_id (col, FROM_COLUMN);
351 col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), DATE_COLUMN);
352 gtk_tree_view_column_set_alignment (col, 0.5);
354 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
355 gtk_tree_selection_set_mode (select, GTK_SELECTION_MULTIPLE);
357 gtk_widget_show (view);
358 return view;
361 static void
362 banlist_closegui (GtkWidget *wid, session *sess)
364 if (is_session (sess))
365 sess->res->banlist_window = 0;
368 void
369 banlist_opengui (struct session *sess)
371 GtkWidget *vbox1;
372 GtkWidget *bbox;
373 char tbuf[256];
375 if (sess->res->banlist_window)
377 mg_bring_tofront (sess->res->banlist_window);
378 return;
381 if (sess->type != SESS_CHANNEL)
383 fe_message (_("You can only open the Ban List window while in a channel tab."), FE_MSG_ERROR);
384 return;
387 snprintf (tbuf, sizeof tbuf, _("XChat: Ban List (%s)"),
388 sess->server->servername);
390 sess->res->banlist_window = mg_create_generic_tab ("BanList", tbuf, FALSE,
391 TRUE, banlist_closegui, sess, 550, 200, &vbox1, sess->server);
393 /* create banlist view */
394 sess->res->banlist_treeview = banlist_treeview_new (vbox1);
396 bbox = gtk_hbutton_box_new ();
397 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
398 gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
399 gtk_box_pack_end (GTK_BOX (vbox1), bbox, 0, 0, 0);
400 gtk_widget_show (bbox);
402 gtkutil_button (bbox, GTK_STOCK_REMOVE, 0, banlist_unban, sess,
403 _("Remove"));
404 gtkutil_button (bbox, GTK_STOCK_REMOVE, 0, banlist_crop, sess,
405 _("Crop"));
406 gtkutil_button (bbox, GTK_STOCK_CLEAR, 0, banlist_clear, sess,
407 _("Clear"));
409 sess->res->banlist_butRefresh = gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, banlist_refresh, sess, _("Refresh"));
411 banlist_do_refresh (sess);
413 gtk_widget_show (sess->res->banlist_window);