~ubuntu-branches/ubuntu/feisty/irssi/feisty-backports

« back to all changes in this revision

Viewing changes to src/fe-common/core/fe-channels.c

  • Committer: Bazaar Package Importer
  • Author(s): David Pashley
  • Date: 2005-12-10 21:25:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051210212551-5qwm108g7inyu2f2
Tags: upstream-0.8.10
ImportĀ upstreamĀ versionĀ 0.8.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 fe-channels.c : irssi
 
3
 
 
4
    Copyright (C) 1999-2000 Timo Sirainen
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
#include "module.h"
 
22
#include "module-formats.h"
 
23
#include "modules.h"
 
24
#include "signals.h"
 
25
#include "commands.h"
 
26
#include "levels.h"
 
27
#include "misc.h"
 
28
#include "settings.h"
 
29
 
 
30
#include "chat-protocols.h"
 
31
#include "chatnets.h"
 
32
#include "servers.h"
 
33
#include "channels.h"
 
34
#include "channels-setup.h"
 
35
#include "nicklist.h"
 
36
 
 
37
#include "fe-windows.h"
 
38
#include "fe-channels.h"
 
39
#include "window-items.h"
 
40
#include "printtext.h"
 
41
 
 
42
static void signal_channel_created(CHANNEL_REC *channel, void *automatic)
 
43
{
 
44
        if (window_item_window(channel) == NULL) {
 
45
                window_item_create((WI_ITEM_REC *) channel,
 
46
                                   GPOINTER_TO_INT(automatic));
 
47
        }
 
48
}
 
49
 
 
50
static void signal_channel_created_curwin(CHANNEL_REC *channel)
 
51
{
 
52
        g_return_if_fail(channel != NULL);
 
53
 
 
54
        window_item_add(active_win, (WI_ITEM_REC *) channel, FALSE);
 
55
}
 
56
 
 
57
static void signal_channel_destroyed(CHANNEL_REC *channel)
 
58
{
 
59
        WINDOW_REC *window;
 
60
 
 
61
        g_return_if_fail(channel != NULL);
 
62
 
 
63
        window = window_item_window((WI_ITEM_REC *) channel);
 
64
        if (window == NULL)
 
65
                return;
 
66
 
 
67
        window_item_destroy((WI_ITEM_REC *) channel);
 
68
 
 
69
        if (channel->joined && !channel->left &&
 
70
            !channel->server->disconnected) {
 
71
                /* kicked out from channel */
 
72
                window_bind_add(window, channel->server->tag,
 
73
                                channel->visible_name);
 
74
        } else if (!channel->joined || channel->left)
 
75
                window_auto_destroy(window);
 
76
}
 
77
 
 
78
static void sig_disconnected(SERVER_REC *server)
 
79
{
 
80
        WINDOW_REC *window;
 
81
        GSList *tmp;
 
82
 
 
83
        g_return_if_fail(IS_SERVER(server));
 
84
 
 
85
        for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
 
86
                CHANNEL_REC *channel = tmp->data;
 
87
 
 
88
                window = window_item_window((WI_ITEM_REC *) channel);
 
89
                window_bind_add(window, server->tag, channel->name);
 
90
        }
 
91
}
 
92
 
 
93
static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item)
 
94
{
 
95
        g_return_if_fail(window != NULL);
 
96
        if (item == NULL) return;
 
97
 
 
98
        if (g_slist_length(window->items) > 1 && IS_CHANNEL(item)) {
 
99
                printformat(item->server, item->visible_name,
 
100
                            MSGLEVEL_CLIENTNOTICE,
 
101
                            TXT_TALKING_IN, item->visible_name);
 
102
                signal_stop();
 
103
        }
 
104
}
 
105
 
 
106
static void sig_channel_joined(CHANNEL_REC *channel)
 
107
{
 
108
        if (settings_get_bool("show_names_on_join") &&
 
109
            !channel->session_rejoin)
 
110
                fe_channels_nicklist(channel, CHANNEL_NICKLIST_FLAG_ALL);
 
111
}
 
112
 
 
113
static void cmd_wjoin_pre(const char *data, SERVER_REC *server)
 
114
{
 
115
        GHashTable *optlist;
 
116
        char *nick;
 
117
        void *free_arg;
 
118
 
 
119
        if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
 
120
                            PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
 
121
                            "join", &optlist, &nick))
 
122
                return;
 
123
 
 
124
        /* kludge for /join -invite -window if there is no invite */
 
125
        if (g_hash_table_lookup(optlist, "invite") &&
 
126
            server != NULL && server->last_invite == NULL) {
 
127
                cmd_params_free(free_arg);
 
128
                return;
 
129
        }                    
 
130
        if (g_hash_table_lookup(optlist, "window") != NULL) {
 
131
                signal_add("channel created",
 
132
                           (SIGNAL_FUNC) signal_channel_created_curwin);
 
133
        }
 
134
        cmd_params_free(free_arg);
 
135
}
 
136
 
 
137
static void cmd_join(const char *data, SERVER_REC *server)
 
138
{
 
139
        WINDOW_REC *window;
 
140
        CHANNEL_REC *channel;
 
141
        GHashTable *optlist;
 
142
        char *channelname;
 
143
        void *free_arg;
 
144
 
 
145
        if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
 
146
                            PARAM_FLAG_UNKNOWN_OPTIONS,
 
147
                            "join", &optlist, &channelname))
 
148
                return;
 
149
 
 
150
        /* -<server tag> */
 
151
        server = cmd_options_get_server("join", optlist, server);
 
152
        
 
153
        channel = channel_find(server, channelname);
 
154
        if (channel != NULL) {
 
155
                /* already joined to channel, set it active */
 
156
                window = window_item_window(channel);
 
157
                if (window != active_win)
 
158
                        window_set_active(window);
 
159
 
 
160
                window_item_set_active(active_win, (WI_ITEM_REC *) channel);
 
161
        }
 
162
        cmd_params_free(free_arg);
 
163
}
 
164
 
 
165
static void cmd_wjoin_post(const char *data)
 
166
{
 
167
        GHashTable *optlist;
 
168
        char *nick;
 
169
        void *free_arg;
 
170
 
 
171
        if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
 
172
                            PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
 
173
                            "join", &optlist, &nick))
 
174
                return;
 
175
 
 
176
        if (g_hash_table_lookup(optlist, "window") != NULL) {
 
177
                signal_remove("channel created",
 
178
                           (SIGNAL_FUNC) signal_channel_created_curwin);
 
179
        }
 
180
        cmd_params_free(free_arg);
 
181
}
 
182
 
 
183
static void cmd_channel_list_joined(void)
 
184
{
 
185
        CHANNEL_REC *channel;
 
186
        GString *nicks;
 
187
        GSList *nicklist, *tmp, *ntmp;
 
188
 
 
189
        if (channels == NULL) {
 
190
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_NOT_IN_CHANNELS);
 
191
                return;
 
192
        }
 
193
 
 
194
        /* print active channel */
 
195
        channel = CHANNEL(active_win->active);
 
196
        if (channel != NULL)
 
197
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
 
198
                            TXT_CURRENT_CHANNEL, channel->visible_name);
 
199
 
 
200
        /* print list of all channels, their modes, server tags and nicks */
 
201
        printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_HEADER);
 
202
        for (tmp = channels; tmp != NULL; tmp = tmp->next) {
 
203
                channel = tmp->data;
 
204
 
 
205
                nicklist = nicklist_getnicks(channel);
 
206
                nicks = g_string_new(NULL);
 
207
                for (ntmp = nicklist; ntmp != NULL; ntmp = ntmp->next) {
 
208
                        NICK_REC *rec = ntmp->data;
 
209
 
 
210
                        g_string_sprintfa(nicks, "%s ", rec->nick);
 
211
                }
 
212
 
 
213
                if (nicks->len > 1) g_string_truncate(nicks, nicks->len-1);
 
214
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANLIST_LINE,
 
215
                            channel->visible_name, channel->mode,
 
216
                            channel->server->tag, nicks->str);
 
217
 
 
218
                g_slist_free(nicklist);
 
219
                g_string_free(nicks, TRUE);
 
220
        }
 
221
}
 
222
 
 
223
/* SYNTAX: CHANNEL LIST */
 
224
static void cmd_channel_list(void)
 
225
{
 
226
        GString *str;
 
227
        GSList *tmp;
 
228
 
 
229
        str = g_string_new(NULL);
 
230
        printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANSETUP_HEADER);
 
231
        for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
 
232
                CHANNEL_SETUP_REC *rec = tmp->data;
 
233
 
 
234
                g_string_truncate(str, 0);
 
235
                if (rec->autojoin)
 
236
                        g_string_append(str, "autojoin, ");
 
237
                if (rec->botmasks != NULL && *rec->botmasks != '\0')
 
238
                        g_string_sprintfa(str, "bots: %s, ", rec->botmasks);
 
239
                if (rec->autosendcmd != NULL && *rec->autosendcmd != '\0')
 
240
                        g_string_sprintfa(str, "botcmd: %s, ", rec->autosendcmd);
 
241
 
 
242
                if (str->len > 2) g_string_truncate(str, str->len-2);
 
243
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANSETUP_LINE,
 
244
                            rec->name, rec->chatnet == NULL ? "" : rec->chatnet,
 
245
                            rec->password == NULL ? "" : rec->password, str->str);
 
246
        }
 
247
        g_string_free(str, TRUE);
 
248
        printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_CHANSETUP_FOOTER);
 
249
}
 
250
 
 
251
static void cmd_channel(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
252
{
 
253
        if (*data == '\0')
 
254
                cmd_channel_list_joined();
 
255
        else if (server != NULL && server_ischannel(server, data)) {
 
256
                signal_emit("command join", 3, data, server, item);
 
257
        } else {
 
258
                command_runsub("channel", data, server, item);
 
259
        }
 
260
}
 
261
 
 
262
/* SYNTAX: CHANNEL ADD [-auto | -noauto] [-bots <masks>] [-botcmd <command>]
 
263
                       <channel> <network> [<password>] */
 
264
static void cmd_channel_add(const char *data)
 
265
{
 
266
        GHashTable *optlist;
 
267
        CHATNET_REC *chatnetrec;
 
268
        CHANNEL_SETUP_REC *rec;
 
269
        char *botarg, *botcmdarg, *chatnet, *channel, *password;
 
270
        void *free_arg;
 
271
 
 
272
        if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS,
 
273
                            "channel add", &optlist, &channel, &chatnet, &password))
 
274
                return;
 
275
 
 
276
        if (*chatnet == '\0' || *channel == '\0')
 
277
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
278
 
 
279
        chatnetrec = chatnet_find(chatnet);
 
280
        if (chatnetrec == NULL) {
 
281
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
 
282
                            TXT_UNKNOWN_CHATNET, chatnet);
 
283
                cmd_params_free(free_arg);
 
284
                return;
 
285
        }
 
286
 
 
287
        botarg = g_hash_table_lookup(optlist, "bots");
 
288
        botcmdarg = g_hash_table_lookup(optlist, "botcmd");
 
289
 
 
290
        rec = channel_setup_find(channel, chatnet);
 
291
        if (rec == NULL) {
 
292
                rec = CHAT_PROTOCOL(chatnetrec)->create_channel_setup();
 
293
                rec->name = g_strdup(channel);
 
294
                rec->chatnet = g_strdup(chatnet);
 
295
        } else {
 
296
                if (g_hash_table_lookup(optlist, "bots")) g_free_and_null(rec->botmasks);
 
297
                if (g_hash_table_lookup(optlist, "botcmd")) g_free_and_null(rec->autosendcmd);
 
298
                if (*password != '\0') g_free_and_null(rec->password);
 
299
        }
 
300
        if (g_hash_table_lookup(optlist, "auto")) rec->autojoin = TRUE;
 
301
        if (g_hash_table_lookup(optlist, "noauto")) rec->autojoin = FALSE;
 
302
        if (botarg != NULL && *botarg != '\0') rec->botmasks = g_strdup(botarg);
 
303
        if (botcmdarg != NULL && *botcmdarg != '\0') rec->autosendcmd = g_strdup(botcmdarg);
 
304
        if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password);
 
305
 
 
306
        signal_emit("channel add fill", 2, rec, optlist);
 
307
 
 
308
        channel_setup_create(rec);
 
309
        printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
 
310
                    TXT_CHANSETUP_ADDED, channel, chatnet);
 
311
 
 
312
        cmd_params_free(free_arg);
 
313
}
 
314
 
 
315
/* SYNTAX: CHANNEL REMOVE <channel> <network> */
 
316
static void cmd_channel_remove(const char *data)
 
317
{
 
318
        CHANNEL_SETUP_REC *rec;
 
319
        char *chatnet, *channel;
 
320
        void *free_arg;
 
321
 
 
322
        if (!cmd_get_params(data, &free_arg, 2, &channel, &chatnet))
 
323
                return;
 
324
        if (*chatnet == '\0' || *channel == '\0')
 
325
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
326
 
 
327
        rec = channel_setup_find(channel, chatnet);
 
328
        if (rec == NULL)
 
329
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CHANSETUP_NOT_FOUND, channel, chatnet);
 
330
        else {
 
331
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CHANSETUP_REMOVED, channel, chatnet);
 
332
                channel_setup_remove(rec);
 
333
        }
 
334
        cmd_params_free(free_arg);
 
335
}
 
336
 
 
337
static int get_nick_length(void *data)
 
338
{
 
339
        return strlen(((NICK_REC *) data)->nick);
 
340
}
 
341
 
 
342
static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist)
 
343
{
 
344
        WINDOW_REC *window;
 
345
        TEXT_DEST_REC dest;
 
346
        GString *str;
 
347
        GSList *tmp;
 
348
        char *format, *stripped, *prefix_format;
 
349
        char *linebuf, nickmode[2] = { 0, 0 };
 
350
        int *columns, cols, rows, last_col_rows, col, row, max_width;
 
351
        int item_extra, linebuf_size, formatnum;
 
352
 
 
353
        window = window_find_closest(channel->server, channel->visible_name,
 
354
                                     MSGLEVEL_CLIENTCRAP);
 
355
        max_width = window->width;
 
356
 
 
357
        /* get the length of item extra stuff ("[ ] ") */
 
358
        format = format_get_text(MODULE_NAME, NULL,
 
359
                                 channel->server, channel->visible_name,
 
360
                                 TXT_NAMES_NICK, " ", "");
 
361
        stripped = strip_codes(format);
 
362
        item_extra = strlen(stripped);
 
363
        g_free(stripped);
 
364
        g_free(format);
 
365
 
 
366
        if (settings_get_int("names_max_width") > 0 &&
 
367
            settings_get_int("names_max_width") < max_width)
 
368
                max_width = settings_get_int("names_max_width");
 
369
 
 
370
        /* remove width of the timestamp from max_width */
 
371
        format_create_dest(&dest, channel->server, channel->visible_name,
 
372
                           MSGLEVEL_CLIENTCRAP, NULL);
 
373
        format = format_get_line_start(current_theme, &dest, time(NULL));
 
374
        if (format != NULL) {
 
375
                stripped = strip_codes(format);
 
376
                max_width -= strlen(stripped);
 
377
                g_free(stripped);
 
378
                g_free(format);
 
379
        }
 
380
 
 
381
        /* remove width of the prefix from max_width */
 
382
        prefix_format = format_get_text(MODULE_NAME, NULL,
 
383
                                        channel->server, channel->visible_name,
 
384
                                        TXT_NAMES_PREFIX,
 
385
                                        channel->visible_name);
 
386
        if (prefix_format != NULL) {
 
387
                stripped = strip_codes(prefix_format);
 
388
                max_width -= strlen(stripped);
 
389
                g_free(stripped);
 
390
        }
 
391
 
 
392
        if (max_width <= 0) {
 
393
                /* we should always have at least some space .. if we
 
394
                   really don't, it won't show properly anyway. */
 
395
                max_width = 10;
 
396
        }
 
397
 
 
398
        /* calculate columns */
 
399
        cols = get_max_column_count(nicklist, get_nick_length, max_width,
 
400
                                    settings_get_int("names_max_columns"),
 
401
                                    item_extra, 3, &columns, &rows);
 
402
        nicklist = columns_sort_list(nicklist, rows);
 
403
 
 
404
        /* rows in last column */
 
405
        last_col_rows = rows-(cols*rows-g_slist_length(nicklist));
 
406
        if (last_col_rows == 0)
 
407
                last_col_rows = rows;
 
408
 
 
409
        str = g_string_new(prefix_format);
 
410
        linebuf_size = max_width+1; linebuf = g_malloc(linebuf_size);
 
411
 
 
412
        col = 0; row = 0;
 
413
        for (tmp = nicklist; tmp != NULL; tmp = tmp->next) {
 
414
                NICK_REC *rec = tmp->data;
 
415
 
 
416
                if (rec->other)
 
417
                        nickmode[0] = rec->other;
 
418
                else if (rec->op)
 
419
                        nickmode[0] = '@';
 
420
                else if (rec->halfop)
 
421
                        nickmode[0] = '%';
 
422
                else if (rec->voice)
 
423
                        nickmode[0] = '+';
 
424
                else
 
425
                        nickmode[0] = ' ';
 
426
                
 
427
                if (linebuf_size < columns[col]-item_extra+1) {
 
428
                        linebuf_size = (columns[col]-item_extra+1)*2;
 
429
                        linebuf = g_realloc(linebuf, linebuf_size);
 
430
                }
 
431
                memset(linebuf, ' ', columns[col]-item_extra);
 
432
                linebuf[columns[col]-item_extra] = '\0';
 
433
                memcpy(linebuf, rec->nick, strlen(rec->nick));
 
434
 
 
435
                formatnum = rec->op ? TXT_NAMES_NICK_OP :
 
436
                        rec->halfop ? TXT_NAMES_NICK_HALFOP :
 
437
                        rec->voice ? TXT_NAMES_NICK_VOICE :
 
438
                        TXT_NAMES_NICK;
 
439
                format = format_get_text(MODULE_NAME, NULL,
 
440
                                         channel->server,
 
441
                                         channel->visible_name,
 
442
                                         formatnum, nickmode, linebuf);
 
443
                g_string_append(str, format);
 
444
                g_free(format);
 
445
 
 
446
                if (++col == cols) {
 
447
                        printtext(channel->server, channel->visible_name,
 
448
                                  MSGLEVEL_CLIENTCRAP, "%s", str->str);
 
449
                        g_string_truncate(str, 0);
 
450
                        if (prefix_format != NULL)
 
451
                                g_string_assign(str, prefix_format);
 
452
                        col = 0; row++;
 
453
 
 
454
                        if (row == last_col_rows)
 
455
                                cols--;
 
456
                }
 
457
        }
 
458
 
 
459
        if (str->len > strlen(prefix_format)) {
 
460
                printtext(channel->server, channel->visible_name,
 
461
                          MSGLEVEL_CLIENTCRAP, "%s", str->str);
 
462
        }
 
463
 
 
464
        g_slist_free(nicklist);
 
465
        g_string_free(str, TRUE);
 
466
        g_free_not_null(columns);
 
467
        g_free_not_null(prefix_format);
 
468
        g_free(linebuf);
 
469
}
 
470
 
 
471
void fe_channels_nicklist(CHANNEL_REC *channel, int flags)
 
472
{
 
473
        NICK_REC *nick;
 
474
        GSList *tmp, *nicklist, *sorted;
 
475
        int nicks, normal, voices, halfops, ops;
 
476
 
 
477
        nicks = normal = voices = halfops = ops = 0;
 
478
        nicklist = nicklist_getnicks(channel);
 
479
        sorted = NULL;
 
480
 
 
481
        /* sort the nicklist */
 
482
        for (tmp = nicklist; tmp != NULL; tmp = tmp->next) {
 
483
                nick = tmp->data;
 
484
 
 
485
                nicks++;
 
486
                if (nick->op) {
 
487
                        ops++;
 
488
                        if ((flags & CHANNEL_NICKLIST_FLAG_OPS) == 0)
 
489
                                continue;
 
490
                } else if (nick->halfop) {
 
491
                        halfops++;
 
492
                        if ((flags & CHANNEL_NICKLIST_FLAG_HALFOPS) == 0)
 
493
                                continue;
 
494
                } else if (nick->voice) {
 
495
                        voices++;
 
496
                        if ((flags & CHANNEL_NICKLIST_FLAG_VOICES) == 0)
 
497
                                continue;
 
498
                } else {
 
499
                        normal++;
 
500
                        if ((flags & CHANNEL_NICKLIST_FLAG_NORMAL) == 0)
 
501
                                continue;
 
502
                }
 
503
 
 
504
                sorted = g_slist_insert_sorted(sorted, nick, (GCompareFunc)
 
505
                                               nicklist_compare);
 
506
        }
 
507
        g_slist_free(nicklist);
 
508
 
 
509
        /* display the nicks */
 
510
        if ((flags & CHANNEL_NICKLIST_FLAG_COUNT) == 0) {
 
511
                printformat(channel->server, channel->visible_name,
 
512
                            MSGLEVEL_CLIENTCRAP, TXT_NAMES,
 
513
                            channel->visible_name,
 
514
                            nicks, ops, halfops, voices, normal);
 
515
                display_sorted_nicks(channel, sorted);
 
516
        }
 
517
        g_slist_free(sorted);
 
518
 
 
519
        printformat(channel->server, channel->visible_name,
 
520
                    MSGLEVEL_CLIENTNOTICE, TXT_ENDOFNAMES,
 
521
                    channel->visible_name, nicks, ops, halfops, voices, normal);
 
522
}
 
523
 
 
524
/* SYNTAX: NAMES [-count | -ops -halfops -voices -normal] [<channels> | **] */
 
525
static void cmd_names(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
526
{
 
527
        CHANNEL_REC *chanrec;
 
528
        GHashTable *optlist;
 
529
        GString *unknowns;
 
530
        char *channel, **channels, **tmp;
 
531
        int flags;
 
532
        void *free_arg;
 
533
 
 
534
        g_return_if_fail(data != NULL);
 
535
        if (!IS_SERVER(server) || !server->connected)
 
536
                cmd_return_error(CMDERR_NOT_CONNECTED);
 
537
 
 
538
        if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
 
539
                            "names", &optlist, &channel))
 
540
                return;
 
541
 
 
542
        if (strcmp(channel, "*") == 0 || *channel == '\0') {
 
543
                if (!IS_CHANNEL(item))
 
544
                        cmd_param_error(CMDERR_NOT_JOINED);
 
545
 
 
546
                channel = CHANNEL(item)->name;
 
547
        }
 
548
 
 
549
        flags = 0;
 
550
        if (g_hash_table_lookup(optlist, "ops") != NULL)
 
551
                flags |= CHANNEL_NICKLIST_FLAG_OPS;
 
552
        if (g_hash_table_lookup(optlist, "halfops") != NULL)
 
553
                flags |= CHANNEL_NICKLIST_FLAG_HALFOPS;
 
554
        if (g_hash_table_lookup(optlist, "voices") != NULL)
 
555
                flags |= CHANNEL_NICKLIST_FLAG_VOICES;
 
556
        if (g_hash_table_lookup(optlist, "normal") != NULL)
 
557
                flags |= CHANNEL_NICKLIST_FLAG_NORMAL;
 
558
        if (g_hash_table_lookup(optlist, "count") != NULL)
 
559
                flags |= CHANNEL_NICKLIST_FLAG_COUNT;
 
560
 
 
561
        if (flags == 0) flags = CHANNEL_NICKLIST_FLAG_ALL;
 
562
 
 
563
        unknowns = g_string_new(NULL);
 
564
 
 
565
        channels = g_strsplit(channel, ",", -1);
 
566
        for (tmp = channels; *tmp != NULL; tmp++) {
 
567
                chanrec = channel_find(server, *tmp);
 
568
                if (chanrec == NULL)
 
569
                        g_string_sprintfa(unknowns, "%s,", *tmp);
 
570
                else {
 
571
                        fe_channels_nicklist(chanrec, flags);
 
572
                        signal_stop();
 
573
                }
 
574
        }
 
575
        g_strfreev(channels);
 
576
 
 
577
        if (unknowns->len > 1)
 
578
                g_string_truncate(unknowns, unknowns->len-1);
 
579
 
 
580
        if (unknowns->len > 0 && strcmp(channel, unknowns->str) != 0)
 
581
                signal_emit("command names", 3, unknowns->str, server, item);
 
582
        g_string_free(unknowns, TRUE);
 
583
 
 
584
        cmd_params_free(free_arg);
 
585
}
 
586
 
 
587
/* SYNTAX: CYCLE [<channel>] [<message>] */
 
588
static void cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
589
{
 
590
        CHANNEL_REC *chanrec;
 
591
        char *channame, *msg, *joindata;
 
592
        void *free_arg;
 
593
 
 
594
        g_return_if_fail(data != NULL);
 
595
        if (!IS_SERVER(server) || !server->connected)
 
596
                cmd_return_error(CMDERR_NOT_CONNECTED);
 
597
 
 
598
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN,
 
599
                            item, &channame, &msg))
 
600
                return;
 
601
        if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
602
 
 
603
        chanrec = channel_find(server, channame);
 
604
        if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
 
605
 
 
606
        joindata = chanrec->get_join_data(chanrec);
 
607
        window_bind_add(window_item_window(chanrec),
 
608
                        chanrec->server->tag, chanrec->name);
 
609
 
 
610
        /* FIXME: kludgy kludgy... */
 
611
        signal_emit("command part", 3, data, server, item);
 
612
 
 
613
        if (g_slist_find(channels, chanrec) != NULL) {
 
614
                chanrec->left = TRUE;
 
615
                channel_destroy(chanrec);
 
616
        }
 
617
 
 
618
        server->channels_join(server, joindata, FALSE);
 
619
        g_free(joindata);
 
620
 
 
621
        cmd_params_free(free_arg);
 
622
}
 
623
 
 
624
void fe_channels_init(void)
 
625
{
 
626
        settings_add_bool("lookandfeel", "autoclose_windows", TRUE);
 
627
        settings_add_bool("lookandfeel", "show_names_on_join", TRUE);
 
628
        settings_add_int("lookandfeel", "names_max_columns", 6);
 
629
        settings_add_int("lookandfeel", "names_max_width", 0);
 
630
 
 
631
        signal_add("channel created", (SIGNAL_FUNC) signal_channel_created);
 
632
        signal_add("channel destroyed", (SIGNAL_FUNC) signal_channel_destroyed);
 
633
        signal_add_last("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
 
634
        signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
 
635
        signal_add_last("channel joined", (SIGNAL_FUNC) sig_channel_joined);
 
636
 
 
637
        command_bind_first("join", NULL, (SIGNAL_FUNC) cmd_wjoin_pre);
 
638
        command_bind("join", NULL, (SIGNAL_FUNC) cmd_join);
 
639
        command_bind_last("join", NULL, (SIGNAL_FUNC) cmd_wjoin_post);
 
640
        command_bind("channel", NULL, (SIGNAL_FUNC) cmd_channel);
 
641
        command_bind("channel add", NULL, (SIGNAL_FUNC) cmd_channel_add);
 
642
        command_bind("channel remove", NULL, (SIGNAL_FUNC) cmd_channel_remove);
 
643
        command_bind("channel list", NULL, (SIGNAL_FUNC) cmd_channel_list);
 
644
        command_bind("names", NULL, (SIGNAL_FUNC) cmd_names);
 
645
        command_bind("cycle", NULL, (SIGNAL_FUNC) cmd_cycle);
 
646
 
 
647
        command_set_options("channel add", "auto noauto -bots -botcmd");
 
648
        command_set_options("names", "count ops halfops voices normal");
 
649
        command_set_options("join", "window");
 
650
}
 
651
 
 
652
void fe_channels_deinit(void)
 
653
{
 
654
        signal_remove("channel created", (SIGNAL_FUNC) signal_channel_created);
 
655
        signal_remove("channel destroyed", (SIGNAL_FUNC) signal_channel_destroyed);
 
656
        signal_remove("window item changed", (SIGNAL_FUNC) signal_window_item_changed);
 
657
        signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
 
658
        signal_remove("channel joined", (SIGNAL_FUNC) sig_channel_joined);
 
659
 
 
660
        command_unbind("join", (SIGNAL_FUNC) cmd_wjoin_pre);
 
661
        command_unbind("join", (SIGNAL_FUNC) cmd_join);
 
662
        command_unbind("join", (SIGNAL_FUNC) cmd_wjoin_post);
 
663
        command_unbind("channel", (SIGNAL_FUNC) cmd_channel);
 
664
        command_unbind("channel add", (SIGNAL_FUNC) cmd_channel_add);
 
665
        command_unbind("channel remove", (SIGNAL_FUNC) cmd_channel_remove);
 
666
        command_unbind("channel list", (SIGNAL_FUNC) cmd_channel_list);
 
667
        command_unbind("names", (SIGNAL_FUNC) cmd_names);
 
668
        command_unbind("cycle", (SIGNAL_FUNC) cmd_cycle);
 
669
}