home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
yagirc-0.51.tar.gz
/
yagirc-0.51.tar
/
yagirc-0.51
/
gui_nicklist.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-09
|
11KB
|
396 lines
/*
gui_nicklist.c : User interface for handling nicklist
Copyright (C) 1998 Timo Sirainen
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "irc.h"
#include "gui.h"
#include "commands.h"
#include "script.h"
static int doubleclick = 0;
static char *doublesel = NULL;
/* Redraw nick list */
void gui_nicklist_redraw(WINDOW_REC *window)
{
GtkWidget *listitem;
GList *nicks;
GList *nlist;
g_return_if_fail(window != NULL);
g_return_if_fail(window->gui != NULL);
if (window->gui->parent->nicklistlen > 0)
{
/* first clear list */
GList *tmp;
for (tmp = GTK_LIST(window->gui->parent->nicklist)->children; tmp != NULL; tmp = tmp->next)
g_free(gtk_object_get_data(GTK_OBJECT(tmp->data), "nick"));
gtk_list_clear_items(GTK_LIST(window->gui->parent->nicklist), 0, window->gui->parent->nicklistlen);
window->gui->parent->nicklistlen = 0;
}
if (window->curchan == NULL)
{
/* no channel selected in this window */
return;
}
if (window->gui->parent->selected != window)
{
/* this window is hidden right now.. */
return;
}
/* draw all items.. */
nlist = NULL;
nicks = g_list_first(window->curchan->nicks);
while (nicks != NULL)
{
listitem = gtk_list_item_new_with_label((char *) nicks->data);
gtk_object_set_data(GTK_OBJECT(listitem), "nick", g_strdup(nicks->data));
nlist = g_list_append(nlist, listitem);
gtk_widget_show(listitem);
nicks = nicks->next;
window->gui->parent->nicklistlen++;
}
gtk_list_append_items(GTK_LIST(window->gui->parent->nicklist), nlist);
}
/* Remove nick from GUI nicklist */
static char *gui_nicklist_remove(CHAN_REC *chan, char *nick)
{
GList *pos, *list;
char *data;
g_return_val_if_fail(chan != NULL, 0);
g_return_val_if_fail(nick != NULL, 0);
if (chan->window->curchan != chan) return NULL;
if (isircflag(*nick)) nick++; /* Skip @ and + */
for (pos = GTK_LIST(chan->window->gui->parent->nicklist)->children; pos != NULL; pos = pos->next)
{
data = gtk_object_get_data(GTK_OBJECT(pos->data), "nick");
if (strcasecmp(isircflag(*data) ? data+1 : data, nick) == 0)
break;
}
if (pos == NULL) return NULL;
list = g_list_append(NULL, pos->data);
gtk_list_remove_items(GTK_LIST(chan->window->gui->parent->nicklist), list);
chan->window->gui->parent->nicklistlen--;
g_list_free(list);
return data;
}
/* Add nick to list */
static int gui_nicklist_add(CHAN_REC *chan, char *nick)
{
g_return_val_if_fail(chan != NULL, 0);
g_return_val_if_fail(nick != NULL, 0);
if (chan->window->curchan == chan)
{
GList *list, *nlist;
GtkWidget *listitem;
int pos;
listitem = gtk_list_item_new_with_label(nick);
gtk_object_set_data(GTK_OBJECT(listitem), "nick", g_strdup(nick));
gtk_widget_show(listitem);
list = g_list_append(NULL, listitem);
nlist = GTK_LIST(chan->window->gui->parent->nicklist)->children;
for (pos = 0; nlist != NULL; pos++, nlist = nlist->next)
{
char *data;
data = gtk_object_get_data(GTK_OBJECT(nlist->data), "nick");
if (irc_nicks_compare(data, nick) > 0) break;
}
gtk_list_insert_items(GTK_LIST(chan->window->gui->parent->nicklist), list, pos);
chan->window->gui->parent->nicklistlen++;
}
return 1;
}
/* Change nick name */
void gui_nick_change(SERVER_REC *server, char *from, char *to)
{
GList *chanlist, *win;
char *tmp, *ptr;
g_return_if_fail(server != NULL);
g_return_if_fail(from != NULL);
g_return_if_fail(to != NULL);
tmp = (char *) g_malloc(strlen(to)+2);
strcpy(tmp+1, to);
/* scan all windows */
for (win = g_list_first(winlist); win != NULL; win = win->next)
{
/* scan all channels */
for (chanlist = g_list_first(((WINDOW_REC *) win->data)->chanlist); chanlist != NULL; chanlist = chanlist->next)
{
char *rnick;
CHAN_REC *chan;
chan = (CHAN_REC *) chanlist->data;
if (chan->server != server)
{
/* nick wasn't changed in this server.. */
continue;
}
rnick = gui_nicklist_remove(chan, from);
if (rnick != NULL)
{
/* nick found from this channel */
tmp[0] = *rnick;
ptr = isircflag(tmp[0]) ? tmp : tmp+1;
gui_nicklist_add(chan, ptr);
g_free(rnick);
}
}
}
g_free(tmp);
}
/* Change nick's mode (@, +) */
void gui_change_nick_mode(CHAN_REC *chan, char *nick, char type)
{
char *rnick, *tmp, *ptr;
g_return_if_fail(chan != NULL);
g_return_if_fail(nick != NULL);
rnick = gui_nicklist_remove(chan, nick);
if (rnick != NULL)
{
tmp = (char *) g_malloc(strlen(nick)+2);
sprintf(tmp, "%c%s", type, nick);
ptr = tmp[0] == ' ' ? tmp+1 : tmp;
gui_nicklist_add(chan, ptr);
g_free(tmp);
g_free(rnick);
}
}
/* Someone joined some channel.. If nick==NULL, you joined */
void gui_channel_join(CHAN_REC *chan, char *nick)
{
int scroll_down;
g_return_if_fail(chan != NULL);
if (nick == NULL)
{
/* You joined to channel */
scroll_down = gui_is_sb_down(chan->window);
chan->gui = gui_private_add_channel_button(GTK_BOX(chan->window->gui->parent->chanbox), chan);
gui_draw_channel(chan->window, chan);
if (scroll_down) gui_set_sb_down(chan->window);
return;
}
/* someone else joined some channel */
gui_nicklist_add(chan, nick);
}
/* Someone left some channel.. If nick==NULL, you left, if chan==NULL someone
quit from IRC */
void gui_channel_part(CHAN_REC *chan, char *nick)
{
GList *tmplist, *win;
if (nick == NULL)
{
/* You've left some channel */
int scroll_down;
if (chan == NULL) return;
scroll_down = gui_is_sb_down(chan->window);
gui_draw_channel(chan->window, chan->window->curchan);
gui_private_remove_channel_button(chan);
if (scroll_down) gui_set_sb_down(chan->window);
return;
}
if (chan != NULL)
{
/* Someone left some channel */
char *rnick = gui_nicklist_remove(chan, nick);
if (rnick != NULL) g_free(rnick);
return;
}
/* Someone quit IRC, remove nick from all channels */
for (win = g_list_first(winlist); win != NULL; win = win->next)
{
WINDOW_REC *winrec;
winrec = (WINDOW_REC *) win->data;
for (tmplist = g_list_first(winrec->chanlist); tmplist != NULL; tmplist = tmplist->next)
{
char *rnick;
rnick = gui_nicklist_remove((CHAN_REC *) tmplist->data, nick);
if (rnick != NULL) g_free(rnick);
}
}
}
/* signal: button pressed */
void signick_button_pressed(GtkWidget *widget, GdkEventButton *event)
{
GList *sel;
g_return_if_fail(widget != NULL);
g_return_if_fail(event != NULL);
if (event->button == 1)
{
if (!doubleclick || doublesel == NULL)
{
sel = GTK_LIST(widget)->selection;
if (sel != NULL)
doublesel = gtk_object_get_data(GTK_OBJECT(sel->data), "nick");
else
doublesel = NULL;
}
if (doubleclick)
{
/* doubleclicked - query user */
doubleclick = 0;
if (doublesel != NULL)
{
if (isircflag(*doublesel)) doublesel++;
irccmd_query(doublesel);
doublesel = NULL;
}
}
else
{
doubleclick = 1;
}
}
}
/* signal: button released */
void signick_button_released(GtkWidget *widget, GdkEventButton *event)
{
char *nick;
g_return_if_fail(widget != NULL);
g_return_if_fail(event != NULL);
if (event->button == 1)
{
doubleclick = 0;
doublesel = NULL;
}
if (event->button == 3)
{
/* show popup menu */
GList *sel;
sel = (GList *) GTK_LIST(widget)->selection;
if (sel == NULL) return;
nick = gtk_object_get_data(GTK_OBJECT(sel->data), "nick");
if (isircflag(*nick)) nick++;
nicklist_popup(NULL, nick, event);
}
}
/* gtk_menu_popup() position function */
static void posfunc(GtkMenu *menu, gint *x, gint *y, GdkEventButton *event)
{
g_return_if_fail(x != NULL);
g_return_if_fail(y != NULL);
g_return_if_fail(event != NULL);
*x = event->x_root;
*y = event->y_root;
}
/* popup menu: CTCP PING */
static void nicklist_ctcp_ping(char *nick)
{
char *tmp;
g_return_if_fail(nick != NULL);
tmp = (char *) g_malloc(strlen(nick)+6);
sprintf(tmp, "%s PING", nick);
irccmd_ctcp(tmp);
}
/* popup menu: CTCP VERSION */
static void nicklist_ctcp_version(char *nick)
{
char *tmp;
g_return_if_fail(nick != NULL);
tmp = (char *) g_malloc(strlen(nick)+9);
sprintf(tmp, "%s VERSION", nick);
irccmd_ctcp(tmp);
}
/* Nicklist's popup menu */
void nicklist_popup(GtkWidget *menu, char *nick, GdkEventButton *event)
{
GtkWidget *mymenu, *ctcpmenu;
g_return_if_fail(nick != NULL);
g_return_if_fail(menu != NULL || event != NULL);
mymenu = menu != NULL ? menu : gtk_menu_new();
ctcpmenu = gtk_menu_new();
add_popup(mymenu, "Whois", irccmd_whois, nick);
add_popup(mymenu, "Query", irccmd_query, nick);
add_popup(ctcpmenu, "Ping", nicklist_ctcp_ping, nick);
add_popup(ctcpmenu, "Version", nicklist_ctcp_version, nick);
add_popup_sub(mymenu, "CTCP", ctcpmenu);
#ifdef USE_SCRIPT
script_add_popups(mymenu, POPUPMENU_NICK, nick);
#endif
if (menu == NULL)
gtk_menu_popup (GTK_MENU(mymenu), NULL, NULL, (GtkMenuPositionFunc) posfunc, event, 0, event->time);
}