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_channels.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-11
|
10KB
|
346 lines
/*
gui_channels.c : User interface for handling channels
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 <gtk/gtk.h>
#include <glib.h>
#include "dcc.h"
#include "irc.h"
#include "gui.h"
#include "commands.h"
#include "script.h"
static void chanlist_popup(CHAN_REC *chan, GdkEventButton *event);
/* Hilight channel button */
void gui_channel_hilight(CHAN_REC *chan)
{
GtkStyle style;
GtkWidget *wid;
g_return_if_fail(chan != NULL);
/* hilight new selected channel */
wid = gtk_container_children(GTK_CONTAINER(chan->gui))->data;
memcpy(&style, gtk_widget_get_style(wid), sizeof(style));
style.fg[0] = colors[BRED];
gtk_widget_set_style(wid, &style);
}
/* Dehilight channel button */
void gui_channel_dehilight(CHAN_REC *chan)
{
GtkStyle style;
GtkWidget *wid;
g_return_if_fail(chan != NULL);
/* hilight new selected channel */
wid = gtk_container_children(GTK_CONTAINER(chan->gui))->data;
memcpy(&style, gtk_widget_get_style(wid), sizeof(style));
style.fg[0] = colors[BLACK];
gtk_widget_set_style(wid, &style);
}
/* Channel changed in window - draw new topic, nicks, hilight channel button */
void gui_draw_channel(WINDOW_REC *win, CHAN_REC *chan)
{
g_return_if_fail(win != NULL);
gui_nicklist_redraw(win);
if (win->gui->parent->highchan != NULL)
{
/* Some channel was already hilighted, change it back to black */
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(win->gui->parent->highchan->gui), FALSE);
}
if (chan == NULL)
{
/* just dehighlighted channel - no channel selected now.. */
gtk_window_set_title(GTK_WINDOW(win->gui->parent->mainwin), PROGRAM_TITLE);
win->gui->parent->highchan = NULL;
return;
}
/* draw topic */
gui_change_topic(chan);
/* hilight new selected channel */
win->gui->parent->highchan = chan;
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(chan->gui), TRUE);
}
/* signal: channel clicked */
static void sigchan_clicked(GtkWidget *widget, CHAN_REC *chan)
{
char *tmp;
if (chan->window->gui->parent->highchan == chan) return;
if (chan->window != curwin) gui_window_select(chan->window);
gui_draw_channel(chan->window, chan);
/* gtk's clicked-signal changes this back to TRUE... */
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(chan->gui), FALSE);
tmp = (char *) g_malloc(strlen(chan->name)+20);
sprintf(tmp, "%d %s", chan->server->handle, chan->name);
if (*chan->name == '&' || *chan->name == '#')
irccmd_join(tmp);
else
irccmd_query(tmp);
g_free(tmp);
}
/* signal: button released */
static void sigchan_button_released(GtkWidget *widget, GdkEventButton *event, CHAN_REC *chan)
{
g_return_if_fail(chan != NULL);
if (event->button == 3)
chanlist_popup(chan, event);
}
/* signal: started dragging */
static void sigchan_drag(GtkWidget *widget, GdkEvent *event, CHAN_REC *chan)
{
g_return_if_fail(chan != NULL);
gtk_widget_dnd_data_set (widget, event, &chan, sizeof(CHAN_REC **));
}
/* signal: dropped something here */
static void sigchan_drop(GtkWidget *widget, GdkEvent *event, CHAN_REC *chan)
{
CHAN_REC *from;
g_return_if_fail(chan != NULL);
from = *((CHAN_REC **) event->dropdataavailable.data);
if (from == curwin->curchan)
gui_window_select(chan->window);
gui_select_channel(chan->window, from);
}
/* Draw new channel button */
GtkWidget *gui_private_add_channel_button(GtkBox *box, CHAN_REC *chan)
{
GtkWidget *but;
char *channel_drag_types[] = {"yagirc/channel"};
char *channel_drop_types[] = {"yagirc/channel"};
g_return_val_if_fail(box != NULL, NULL);
g_return_val_if_fail(chan != NULL, NULL);
/* create widget */
but = gtk_toggle_button_new_with_label(chan->name);
gtk_signal_connect (GTK_OBJECT (but), "button_release_event",
GTK_SIGNAL_FUNC(sigchan_button_released), chan);
gtk_signal_connect (GTK_OBJECT (but), "clicked",
GTK_SIGNAL_FUNC(sigchan_clicked), chan);
gtk_signal_connect (GTK_OBJECT (but), "drag_request_event",
GTK_SIGNAL_FUNC(sigchan_drag), chan);
gtk_signal_connect (GTK_OBJECT (but), "drop_data_available_event",
GTK_SIGNAL_FUNC(sigchan_drop), chan);
gtk_box_pack_start(box, but, FALSE, FALSE, 0);
gtk_widget_show(but);
gtk_widget_dnd_drag_set (but, TRUE, channel_drag_types, 1);
gtk_widget_dnd_drop_set (but, TRUE, channel_drop_types, 1, FALSE);
return but;
}
/* Remove channel button */
void gui_private_remove_channel_button(CHAN_REC *chan)
{
g_return_if_fail(chan != NULL);
if (chan->window->gui->parent->highchan == chan)
{
/* this channel was highlighted.. */
chan->window->gui->parent->highchan = NULL;
}
gtk_widget_destroy(chan->gui);
}
/* Select channel in specific window, if channel is in some other window,
move it from there */
void gui_select_channel(WINDOW_REC *win, CHAN_REC *chan)
{
GList *oldchan;
g_return_if_fail(win != NULL);
g_return_if_fail(chan != NULL);
if (chan->window != win)
{
/* we need to move channel into this window.. */
WINDOW_REC *oldwin;
oldwin = chan->window;
gui_private_remove_channel_button(chan);
chan->window = win;
chan->gui = gui_private_add_channel_button(GTK_BOX(win->gui->parent->chanbox), chan);
for (oldchan = g_list_first(oldwin->chanlist); oldchan != NULL; oldchan = oldchan->next)
if (oldchan->data == chan) break;
win->chanlist = g_list_append(win->chanlist, oldchan->data);
if (oldwin->curchan != chan)
oldwin->chanlist = g_list_remove_link(oldwin->chanlist, oldchan);
else
{
int ret;
WINDOW_REC *win;
win = curwin;
/* channel was selected in it's old window */
ret = irc_select_new_channel(oldwin);
oldwin->chanlist = g_list_remove_link(oldwin->chanlist, oldchan);
if (ret == 0)
{
/* no more channels in this window - remove it */
irc_window_close(oldwin);
}
else
{
/* draw topic */
gui_draw_channel(oldwin, oldwin->curchan);
}
curwin = win;
}
}
gui_draw_channel(win, chan);
}
/* Change topic of channel */
void gui_change_topic(CHAN_REC *chan)
{
char *tmp;
g_return_if_fail(chan != NULL);
if (chan->window->curchan != chan) return;
if (chan->topic == NULL || *chan->topic == '\0')
{
/* No topic in channel */
tmp = (char *) g_malloc(strlen(chan->name)+PROGRAM_TITLE_SIZE+10);
sprintf(tmp, "%s - "PROGRAM_TITLE, chan->name);
}
else
{
tmp = (char *) g_malloc(strlen(chan->name)+strlen(chan->topic)+PROGRAM_TITLE_SIZE+10);
sprintf(tmp, "%s - %s - "PROGRAM_TITLE, chan->name, chan->topic);
}
gtk_window_set_title(GTK_WINDOW(chan->window->gui->parent->mainwin), tmp);
g_free(tmp);
}
void sigchantext_button_released(GtkWidget *widget, GdkEventButton *event, WINDOW_REC *win)
{
g_return_if_fail(widget != NULL);
g_return_if_fail(event != NULL);
g_return_if_fail(win != NULL);
if (event->button == 3)
{
/* show popup menu */
if (win->curchan != NULL)
chanlist_popup(win->curchan, event);
}
}
/* channel menu: move channel to new window */
static void move_new_window(CHAN_REC *chan)
{
WINDOW_REC *win;
win = irc_window_new(chan->server, NULL);
win->curchan = chan;
gui_select_channel(win, chan);
}
/* channel menu: move channel to new hidden window */
static void move_new_hidden(CHAN_REC *chan)
{
WINDOW_REC *win;
win = irc_window_new(chan->server, chan->window);
win->curchan = chan;
gui_select_channel(win, chan);
}
/* 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;
}
/* Channel popup menu */
static void chanlist_popup(CHAN_REC *chan, GdkEventButton *event)
{
GtkWidget *menu, *movemenu;
g_return_if_fail(chan != NULL);
g_return_if_fail(event != NULL);
menu = gtk_menu_new();
movemenu = gtk_menu_new();
add_popup(movemenu, "New window", move_new_window, chan);
add_popup(movemenu, "New hidden window", move_new_hidden, chan);
if (*chan->name == '#' || *chan->name == '&')
{
add_popup(menu, "Channel commands", NULL, NULL);
add_popup(menu, NULL, NULL, NULL);
add_popup(menu, "Part", irccmd_part, chan->name);
#ifdef USE_SCRIPT
script_add_popups(menu, POPUPMENU_CHAN, chan->name);
#endif
}
else
{
add_popup(menu, "Query commands", NULL, NULL);
add_popup(menu, NULL, NULL, NULL);
add_popup(menu, "Close query", irccmd_unquery, chan->name);
nicklist_popup(menu, chan->name, event);
}
add_popup_sub(menu, "Move", movemenu);
gtk_menu_popup (GTK_MENU(menu), NULL, NULL, (GtkMenuPositionFunc) posfunc, event, 0, event->time);
}