configure: fix bug when one of libsexy/gtkspell is either found or desired
[rofl0r-ixchat.git] / src / fe-gtk / textgui.c
blob604da44b214ed7eff83a28e4c8c7fd68faad34a7
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 <time.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
27 #include "fe-gtk.h"
29 #include <gtk/gtkbutton.h>
30 #include <gtk/gtkentry.h>
31 #include <gtk/gtkhbox.h>
32 #include <gtk/gtkhbbox.h>
33 #include <gtk/gtkliststore.h>
34 #include <gtk/gtkstock.h>
35 #include <gtk/gtkvbox.h>
36 #include <gtk/gtkvpaned.h>
37 #include <gtk/gtkvscrollbar.h>
39 #include "../common/xchat.h"
40 #include "../common/xchatc.h"
41 #include "../common/cfgfiles.h"
42 #include "../common/outbound.h"
43 #include "../common/fe.h"
44 #include "../common/text.h"
45 #include "gtkutil.h"
46 #include "xtext.h"
47 #include "maingui.h"
48 #include "palette.h"
49 #include "textgui.h"
51 extern struct text_event te[];
52 extern char *pntevts_text[];
53 extern char *pntevts[];
55 static GtkWidget *pevent_dialog = NULL, *pevent_dialog_twid,
56 *pevent_dialog_entry,
57 *pevent_dialog_list, *pevent_dialog_hlist;
59 enum
61 COL_EVENT_NAME,
62 COL_EVENT_TEXT,
63 COL_ROW,
64 N_COLUMNS
68 /* this is only used in xtext.c for indented timestamping */
69 int
70 xtext_get_stamp_str (time_t tim, char **ret)
72 return get_stamp_str (prefs.stamp_format, tim, ret);
75 static void
76 PrintTextLine (xtext_buffer *xtbuf, unsigned char *text, int len, int indent, time_t timet)
78 unsigned char *tab, *new_text;
79 int leftlen;
81 if (len == 0)
82 len = 1;
84 if (!indent)
86 if (prefs.timestamp)
88 int stamp_size;
89 char *stamp;
91 if (timet == 0)
92 timet = time (0);
94 stamp_size = get_stamp_str (prefs.stamp_format, timet, &stamp);
95 new_text = malloc (len + stamp_size + 1);
96 memcpy (new_text, stamp, stamp_size);
97 g_free (stamp);
98 memcpy (new_text + stamp_size, text, len);
99 gtk_xtext_append (xtbuf, new_text, len + stamp_size);
100 free (new_text);
101 } else
102 gtk_xtext_append (xtbuf, text, len);
103 return;
106 tab = strchr (text, '\t');
107 if (tab && tab < (text + len))
109 leftlen = tab - text;
110 gtk_xtext_append_indent (xtbuf,
111 text, leftlen, tab + 1, len - (leftlen + 1), timet);
112 } else
113 gtk_xtext_append_indent (xtbuf, 0, 0, text, len, timet);
116 void
117 PrintTextRaw (void *xtbuf, unsigned char *text, int indent, time_t stamp)
119 char *last_text = text;
120 int len = 0;
121 int beep_done = FALSE;
123 /* split the text into separate lines */
124 while (1)
126 switch (*text)
128 case 0:
129 PrintTextLine (xtbuf, last_text, len, indent, stamp);
130 return;
131 case '\n':
132 PrintTextLine (xtbuf, last_text, len, indent, stamp);
133 text++;
134 if (*text == 0)
135 return;
136 last_text = text;
137 len = 0;
138 break;
139 case ATTR_BEEP:
140 *text = ' ';
141 if (!beep_done) /* beeps may be slow, so only do 1 per line */
143 beep_done = TRUE;
144 if (!prefs.filterbeep)
145 gdk_beep ();
147 default:
148 text++;
149 len++;
154 static void
155 pevent_dialog_close (GtkWidget *wid, gpointer arg)
157 pevent_dialog = NULL;
158 pevent_save (NULL);
161 static void
162 pevent_dialog_update (GtkWidget * wid, GtkWidget * twid)
164 int len, m;
165 const char *text;
166 char *out;
167 int sig;
168 GtkTreeIter iter;
169 GtkListStore *store;
171 if (!gtkutil_treeview_get_selected (GTK_TREE_VIEW (pevent_dialog_list),
172 &iter, COL_ROW, &sig, -1))
173 return;
175 text = gtk_entry_get_text (GTK_ENTRY (wid));
176 len = strlen (text);
178 if (pevt_build_string (text, &out, &m) != 0)
180 fe_message (_("There was an error parsing the string"), FE_MSG_ERROR);
181 return;
183 if (m > (te[sig].num_args & 0x7f))
185 free (out);
186 out = malloc (4096);
187 snprintf (out, 4096,
188 _("This signal is only passed %d args, $%d is invalid"),
189 te[sig].num_args & 0x7f, m);
190 fe_message (out, FE_MSG_WARN);
191 free (out);
192 return;
195 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (pevent_dialog_list));
196 gtk_list_store_set (store, &iter, COL_EVENT_TEXT, text, -1);
198 if (pntevts_text[sig])
199 free (pntevts_text[sig]);
200 if (pntevts[sig])
201 free (pntevts[sig]);
203 pntevts_text[sig] = malloc (len + 1);
204 memcpy (pntevts_text[sig], text, len + 1);
205 pntevts[sig] = out;
207 out = malloc (len + 2);
208 memcpy (out, text, len + 1);
209 out[len] = '\n';
210 out[len + 1] = 0;
211 check_special_chars (out, TRUE);
213 PrintTextRaw (GTK_XTEXT (twid)->buffer, out, 0, 0);
214 free (out);
216 /* save this when we exit */
217 prefs.save_pevents = 1;
220 static void
221 pevent_dialog_hfill (GtkWidget * list, int e)
223 int i = 0;
224 char *text;
225 GtkTreeIter iter;
226 GtkListStore *store;
228 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (pevent_dialog_hlist));
229 gtk_list_store_clear (store);
230 while (i < (te[e].num_args & 0x7f))
232 text = _(te[e].help[i]);
233 i++;
234 if (text[0] == '\001')
235 text++;
236 gtk_list_store_insert_with_values (store, &iter, -1,
237 0, i,
238 1, text, -1);
242 static void
243 pevent_dialog_unselect (void)
245 gtk_entry_set_text (GTK_ENTRY (pevent_dialog_entry), "");
246 gtk_list_store_clear ((GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (pevent_dialog_hlist)));
249 static void
250 pevent_dialog_select (GtkTreeSelection *sel, gpointer store)
252 char *text;
253 int sig;
254 GtkTreeIter iter;
256 if (!gtkutil_treeview_get_selected (GTK_TREE_VIEW (pevent_dialog_list),
257 &iter, COL_ROW, &sig, -1))
259 pevent_dialog_unselect ();
261 else
263 gtk_tree_model_get (store, &iter, COL_EVENT_TEXT, &text, -1);
264 gtk_entry_set_text (GTK_ENTRY (pevent_dialog_entry), text);
265 g_free (text);
266 pevent_dialog_hfill (pevent_dialog_hlist, sig);
270 static void
271 pevent_dialog_fill (GtkWidget * list)
273 int i;
274 GtkListStore *store;
275 GtkTreeIter iter;
277 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (list));
278 gtk_list_store_clear (store);
280 i = NUM_XP;
283 i--;
284 gtk_list_store_insert_with_values (store, &iter, 0,
285 COL_EVENT_NAME, te[i].name,
286 COL_EVENT_TEXT, pntevts_text[i],
287 COL_ROW, i, -1);
289 while (i != 0);
292 static void
293 pevent_save_req_cb (void *arg1, char *file)
295 if (file)
296 pevent_save (file);
299 static void
300 pevent_save_cb (GtkWidget * wid, void *data)
302 if (data)
304 gtkutil_file_req (_("Print Texts File"), pevent_save_req_cb, NULL,
305 NULL, FRF_WRITE);
306 return;
308 pevent_save (NULL);
311 static void
312 pevent_load_req_cb (void *arg1, char *file)
314 if (file)
316 pevent_load (file);
317 pevent_make_pntevts ();
318 pevent_dialog_fill (pevent_dialog_list);
319 pevent_dialog_unselect ();
320 prefs.save_pevents = 1;
324 static void
325 pevent_load_cb (GtkWidget * wid, void *data)
327 gtkutil_file_req (_("Print Texts File"), pevent_load_req_cb, NULL, NULL, 0);
330 static void
331 pevent_ok_cb (GtkWidget * wid, void *data)
333 gtk_widget_destroy (pevent_dialog);
336 static void
337 pevent_test_cb (GtkWidget * wid, GtkWidget * twid)
339 int len, n;
340 char *out, *text;
342 for (n = 0; n < NUM_XP; n++)
344 text = _(pntevts_text[n]);
345 len = strlen (text);
347 out = malloc (len + 2);
348 memcpy (out, text, len + 1);
349 out[len] = '\n';
350 out[len + 1] = 0;
351 check_special_chars (out, TRUE);
353 PrintTextRaw (GTK_XTEXT (twid)->buffer, out, 0, 0);
354 free (out);
358 void
359 pevent_dialog_show ()
361 GtkWidget *vbox, *hbox, *tbox, *wid, *bh, *th;
362 GtkListStore *store, *hstore;
363 GtkTreeSelection *sel;
365 if (pevent_dialog)
367 mg_bring_tofront (pevent_dialog);
368 return;
371 pevent_dialog =
372 mg_create_generic_tab ("edit events", _("Edit Events"),
373 TRUE, FALSE, pevent_dialog_close, NULL,
374 600, 455, &vbox, 0);
376 wid = gtk_vpaned_new ();
377 th = gtk_vbox_new (0, 2);
378 bh = gtk_vbox_new (0, 2);
379 gtk_widget_show (th);
380 gtk_widget_show (bh);
381 gtk_paned_pack1 (GTK_PANED (wid), th, 1, 1);
382 gtk_paned_pack2 (GTK_PANED (wid), bh, 0, 1);
383 gtk_box_pack_start (GTK_BOX (vbox), wid, 1, 1, 0);
384 gtk_widget_show (wid);
386 store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING,
387 G_TYPE_STRING, G_TYPE_INT);
388 pevent_dialog_list = gtkutil_treeview_new (th, GTK_TREE_MODEL (store), NULL,
389 COL_EVENT_NAME, _("Event"),
390 COL_EVENT_TEXT, _("Text"), -1);
391 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (pevent_dialog_list));
392 g_signal_connect (G_OBJECT (sel), "changed",
393 G_CALLBACK (pevent_dialog_select), store);
395 pevent_dialog_twid = gtk_xtext_new (colors, 0);
396 gtk_xtext_set_tint (GTK_XTEXT (pevent_dialog_twid), prefs.tint_red, prefs.tint_green, prefs.tint_blue);
397 gtk_xtext_set_background (GTK_XTEXT (pevent_dialog_twid),
398 channelwin_pix, prefs.transparent);
400 pevent_dialog_entry = gtk_entry_new_with_max_length (255);
401 g_signal_connect (G_OBJECT (pevent_dialog_entry), "activate",
402 G_CALLBACK (pevent_dialog_update), pevent_dialog_twid);
403 gtk_box_pack_start (GTK_BOX (bh), pevent_dialog_entry, 0, 0, 0);
404 gtk_widget_show (pevent_dialog_entry);
406 tbox = gtk_hbox_new (0, 0);
407 gtk_container_add (GTK_CONTAINER (bh), tbox);
408 gtk_widget_show (tbox);
410 gtk_widget_set_usize (pevent_dialog_twid, 150, 20);
411 gtk_container_add (GTK_CONTAINER (tbox), pevent_dialog_twid);
412 gtk_xtext_set_font (GTK_XTEXT (pevent_dialog_twid), prefs.font_normal);
414 wid = gtk_vscrollbar_new (GTK_XTEXT (pevent_dialog_twid)->adj);
415 gtk_box_pack_start (GTK_BOX (tbox), wid, FALSE, FALSE, 0);
416 show_and_unfocus (wid);
418 gtk_widget_show (pevent_dialog_twid);
420 hstore = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
421 pevent_dialog_hlist = gtkutil_treeview_new (bh, GTK_TREE_MODEL (hstore),
422 NULL,
423 0, _("$ Number"),
424 1, _("Description"), -1);
425 gtk_widget_show (pevent_dialog_hlist);
427 pevent_dialog_fill (pevent_dialog_list);
428 gtk_widget_show (pevent_dialog_list);
430 hbox = gtk_hbutton_box_new ();
431 gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 2);
432 /*wid = gtk_button_new_with_label (_("Save"));
433 gtk_box_pack_end (GTK_BOX (hbox), wid, 0, 0, 0);
434 gtk_signal_connect (GTK_OBJECT (wid), "clicked",
435 GTK_SIGNAL_FUNC (pevent_save_cb), NULL);
436 gtk_widget_show (wid);*/
437 gtkutil_button (hbox, GTK_STOCK_SAVE_AS, NULL, pevent_save_cb,
438 (void *) 1, _("Save As..."));
439 gtkutil_button (hbox, GTK_STOCK_OPEN, NULL, pevent_load_cb,
440 (void *) 0, _("Load From..."));
441 wid = gtk_button_new_with_label (_("Test All"));
442 gtk_box_pack_end (GTK_BOX (hbox), wid, 0, 0, 0);
443 g_signal_connect (G_OBJECT (wid), "clicked",
444 G_CALLBACK (pevent_test_cb), pevent_dialog_twid);
445 gtk_widget_show (wid);
447 wid = gtk_button_new_from_stock (GTK_STOCK_OK);
448 gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
449 g_signal_connect (G_OBJECT (wid), "clicked",
450 G_CALLBACK (pevent_ok_cb), NULL);
451 gtk_widget_show (wid);
453 gtk_widget_show (hbox);
455 gtk_widget_show (pevent_dialog);