📄 maingui.c
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include <stdlib.h>#include <string.h>#include "../../config.h"#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <stdio.h>#include <fcntl.h>#include <signal.h>#include <unistd.h>#include <ctype.h>#define WANTSOCKET#define WANTARPA#include "fe-gtk.h"#include "../common/inet.h"#include "../common/xchat.h"#include "../common/fe.h"#include "../common/xchatc.h"#include "../common/util.h"#include "../common/outbound.h"#include <gdk/gdkkeysyms.h>#include "ascii.h"#include "banlist.h"#include "dialog.h"#include "gtkutil.h"#include "menu.h"#include "palette.h"#include "panel.h"#include "pixmaps.h"#include "xtext.h"#include "wins.h"#include "fkeys.h"#include "userlistgui.h"#include "maingui.h"#ifdef USE_PANEL#include <applet-widget.h>#endifGtkWidget *main_window = 0;GtkWidget *main_book;GtkWidget *main_menu_bar;static GtkWidget *main_menu;static GtkWidget *main_menu_away_item = 0;GtkStyle *redtab_style = 0;GtkStyle *bluetab_style;GtkStyle *inputgad_style;static char chan_flags[] = { 't', 'n', 's', 'i', 'p', 'm', 'l', 'k' };static void userlist_button (GtkWidget * box, char *label, char *cmd, struct session *sess, int a, int b, int c, int d);static void my_gtk_togglebutton_state (GtkWidget * wid, int state);static void tree_update ();static void tree_default_style (struct session *sess);static void channelmode_button_cb (GtkWidget *but, char *flag);static void maingui_code (GtkWidget * button, char *code);voidmaingui_showhide_topic (session *sess){ if (GTK_WIDGET_VISIBLE (sess->gui->tbox)) { gtk_widget_hide (sess->gui->tbox); prefs.topicbar = 0; } else { gtk_widget_show (sess->gui->tbox); prefs.topicbar = 1; }}GtkWidget *maingui_window (char *name, char *title, int force_toplevel, int link_buttons, void *close_callback, void *userdata, int width, int height, GtkWidget **child_ret){ GtkWidget *win; if (prefs.windows_as_tabs && main_window && !force_toplevel) { win = wins_new (name, title, close_callback, userdata, NULL, NULL, TRUE, TRUE, child_ret); gtk_widget_show (win); if (prefs.newtabstofront) wins_bring_tofront (win); } else { win = wins_new (name, title, close_callback, userdata, NULL, NULL, FALSE, TRUE, child_ret); gtk_widget_set_usize (win, width, height); } if (link_buttons) wins_create_linkbuttons (win, wins_get_vbox (win)); return win;}voidfe_set_away (server *serv){ GSList *list = sess_list; session *sess; while (list) { sess = list->data; if (sess->server == serv) { if (!sess->gui->awaymenuitem) sess->gui->awaymenuitem = main_menu_away_item; if (sess->gui->awaymenuitem) ((GtkCheckMenuItem*)sess->gui->awaymenuitem)->active = serv->is_away; } list = list->next; }}voidfe_set_nonchannel (struct session *sess, int state){ int i; if (sess->gui->flag_wid[0]) { for (i = 0; i < NUM_FLAG_WIDS; i++) { gtk_widget_set_sensitive (sess->gui->flag_wid[i], state); } gtk_widget_set_sensitive (sess->gui->limit_entry, state); gtk_widget_set_sensitive (sess->gui->key_entry, state); } if (prefs.inputgad_superfocus) /* sanity */ gtk_entry_set_editable ((GtkEntry *) sess->gui->topicgad, FALSE); else gtk_entry_set_editable ((GtkEntry *) sess->gui->topicgad, state);}static voidmaingui_createbuttons (session * sess){ struct popup *pop; GSList *list = button_list; int a = 0, b = 0; sess->gui->button_box = gtk_table_new (5, 2, FALSE); gtk_box_pack_end (GTK_BOX (sess->gui->nl_box), sess->gui->button_box, FALSE, FALSE, 1); gtk_widget_show (sess->gui->button_box); while (list) { pop = (struct popup *) list->data; if (pop->cmd[0]) { userlist_button (sess->gui->button_box, pop->name, pop->cmd, sess, a, a + 1, b, b + 1); a++; if (a == 2) { a = 0; b++; } } list = list->next; }}voidfe_buttons_update (struct session *sess){ if (sess->gui->button_box) { gtk_widget_destroy (sess->gui->button_box); sess->gui->button_box = 0; } if (prefs.userlistbuttons) maingui_createbuttons (sess);}voidfe_set_title (struct session *sess){ char tbuf[256]; int type; type = sess->type; if (sess->server->connected == FALSE && sess->type != SESS_DIALOG) type = SESS_SHELL; /* force default */ switch (type) { case SESS_DIALOG: snprintf (tbuf, sizeof (tbuf), "X-Chat ["VERSION"]: Dialog with %s @ %s", sess->channel, sess->server->servername); break; case SESS_SERVER: snprintf (tbuf, sizeof (tbuf), "X-Chat ["VERSION"]: %s @ %s", sess->server->nick, sess->server->servername); break; case SESS_CHANNEL: snprintf (tbuf, sizeof (tbuf), "X-Chat ["VERSION"]: %s @ %s / %s (%s)", sess->server->nick, sess->server->servername, sess->channel, sess->current_modes); break; case SESS_NOTICES: case SESS_SNOTICES: snprintf (tbuf, sizeof (tbuf), "X-Chat ["VERSION"]: %s @ %s (notices)", sess->server->nick, sess->server->servername); break; default: wins_set_title (sess->gui->window, "X-Chat ["VERSION"]"); return; } wins_set_title (sess->gui->window, tbuf);}voidfe_set_channel (struct session *sess){ wins_set_name (sess->gui->window, sess->channel); /* toplevel dialogs dont have a changad */ if (sess->gui->changad != NULL) gtk_label_set_text (GTK_LABEL (sess->gui->changad), sess->channel);#ifdef USE_PANEL if (sess->gui->panel_button) gtk_label_set_text (GTK_LABEL (GTK_BIN (sess->gui->panel_button)->child), sess->channel);#endif if (prefs.treeview) tree_update ();}voidfe_clear_channel (struct session *sess){ char tbuf[CHANLEN+4]; int i; if (sess->waitchannel[0]) sprintf(tbuf, "(%s)", sess->waitchannel); else strcpy (tbuf, _("<none>")); gtk_entry_set_text (GTK_ENTRY (sess->gui->topicgad), ""); gtk_label_set_text (GTK_LABEL (sess->gui->changad), tbuf); add_tip (sess->gui->topicgad, _("The channel topic"));#ifdef USE_PANEL if (sess->gui->panel_button) gtk_label_set_text (GTK_LABEL (GTK_BIN (sess->gui->panel_button)->child), tbuf);#endif gtk_widget_hide (sess->gui->namelistinfo); if (sess->gui->flag_wid[0]) { for (i = 0; i < NUM_FLAG_WIDS - 1; i++) my_gtk_togglebutton_state (sess->gui->flag_wid[i], FALSE); gtk_entry_set_text ((GtkEntry*)sess->gui->limit_entry, ""); gtk_entry_set_text ((GtkEntry*)sess->gui->key_entry, ""); } if (sess->gui->op_xpm) { gtk_widget_destroy (sess->gui->op_xpm); sess->gui->op_xpm = 0; } if (prefs.treeview) tree_update ();}voidfe_set_nick (struct server *serv, char *newnick){ GSList *list = sess_list; struct session *sess; strcpy (serv->nick, newnick); if (prefs.nickgad) { while (list) { sess = (struct session *) list->data; if (sess->server == serv && sess->type != SESS_DIALOG) gtk_label_set_text (GTK_LABEL (sess->gui->nickgad), newnick); list = list->next; } }}static voidhandle_topicgad (GtkWidget * igad, struct session *sess){ char *topic = gtk_entry_get_text (GTK_ENTRY (igad)); if (sess->channel[0] && sess->server->connected) { char *fmt = "TOPIC %s :%s\r\n"; char *tbuf; int len = strlen (fmt) - 3 + strlen (sess->channel) + strlen (topic); tbuf = malloc (len); snprintf (tbuf, len, fmt, sess->channel, topic); tcp_send (sess->server, tbuf); free (tbuf); } else gtk_entry_set_text (GTK_ENTRY (igad), ""); /* restore focus to the input widget, where the next input will mostlikely be */ gtk_widget_grab_focus (sess->gui->inputgad);}static char *find_selected_nick (struct session *sess){ int row; struct User *user; row = gtkutil_clist_selection (sess->gui->namelistgad); if (row == -1) return 0; user = gtk_clist_get_row_data (GTK_CLIST (sess->gui->namelistgad), row); if (!user) return 0; return user->nick;}static voidul_button_rel (GtkWidget * widget, GdkEventButton * even, struct session *sess){ char *nick; int row, col; char buf[67]; if (!even) return; if (even->button == 3) { if (gtk_clist_get_selection_info (GTK_CLIST (widget), even->x, even->y, &row, &col) < 0) return; gtk_clist_unselect_all (GTK_CLIST (widget)); gtk_clist_select_row (GTK_CLIST (widget), row, 0); nick = find_selected_nick (sess); if (nick) { menu_nickmenu (sess, even, nick); } return; } if (even->button == 2) { if (gtk_clist_get_selection_info (GTK_CLIST (widget), even->x, even->y, &row, &col) != -1) { gtk_clist_select_row (GTK_CLIST (widget), row, col); nick = find_selected_nick (sess); if (nick) { snprintf (buf, sizeof (buf), "%s: ", nick); gtk_entry_set_text (GTK_ENTRY (sess->gui->inputgad), buf); gtk_widget_grab_focus (sess->gui->inputgad); } } }}voidfocus_in (GtkWindow * win, GtkWidget * wid, session *sess){ if (!sess) { if (current_tab) { if (current_tab->type != SESS_SHELL) gtk_widget_grab_focus (current_tab->gui->inputgad); else gtk_widget_grab_focus (current_tab->gui->textgad); menu_sess = current_tab; if (!prefs.use_server_tab) current_tab->server->front_session = current_tab; } } else { if (!prefs.use_server_tab) sess->server->front_session = sess; if (sess->type != SESS_SHELL) gtk_widget_grab_focus (sess->gui->inputgad); else gtk_widget_grab_focus (sess->gui->textgad); menu_sess = sess;#ifdef USE_PANEL if (sess->gui->panel_button) gtk_widget_set_rc_style (GTK_BIN (sess->gui->panel_button)->child);#endif if (prefs.treeview) tree_default_style (sess); }}static intcheck_is_number (char *t){ while (*t) { if (*t < '0' || *t > '9') return FALSE; t++; } return TRUE;}static voidchange_channel_flag (GtkWidget * wid, struct session *sess, char flag){ char outbuf[512]; if (sess->server->connected && sess->channel[0]) { if (GTK_TOGGLE_BUTTON (wid)->active) sprintf (outbuf, "MODE %s +%c\r\n", sess->channel, flag); else sprintf (outbuf, "MODE %s -%c\r\n", sess->channel, flag); tcp_send (sess->server, outbuf); sprintf (outbuf, "MODE %s\r\n", sess->channel); tcp_send (sess->server, outbuf); sess->ignore_mode = TRUE; sess->ignore_date = TRUE; }}static voidflagl_hit (GtkWidget * wid, struct session *sess){ char outbuf[512]; char *limit_str; if (GTK_TOGGLE_BUTTON (wid)->active) { if (sess->server->connected && sess->channel[0]) { limit_str = gtk_entry_get_text (GTK_ENTRY (sess->gui->limit_entry)); if (check_is_number (limit_str) == FALSE) { gtkutil_simpledialog (_("User limit must be a number!\n")); gtk_entry_set_text (GTK_ENTRY (sess->gui->limit_entry), ""); gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (wid), FALSE); return; } sprintf (outbuf, "MODE %s +l %d\r\n", sess->channel, atoi (limit_str)); tcp_send (sess->server, outbuf); sprintf (outbuf, "MODE %s\r\n", sess->channel); tcp_send (sess->server, outbuf); } } else change_channel_flag (wid, sess, 'l');}static voidflagk_hit (GtkWidget * wid, struct session *sess){ char outbuf[512]; if (GTK_TOGGLE_BUTTON (wid)->active) { if (sess->server->connected && sess->channel[0]) { snprintf (outbuf, 512, "MODE %s +k %s\r\n", sess->channel, gtk_entry_get_text (GTK_ENTRY (sess->gui->key_entry))); tcp_send (sess->server, outbuf); snprintf (outbuf, 512, "MODE %s\r\n", sess->channel); tcp_send (sess->server, outbuf); } } else { if (sess->server->connected && sess->channel[0]) { snprintf (outbuf, 512, "MODE %s -k %s\r\n", sess->channel, gtk_entry_get_text (GTK_ENTRY (sess->gui->key_entry))); tcp_send (sess->server, outbuf); snprintf (outbuf, 512, "MODE %s\r\n", sess->channel); tcp_send (sess->server, outbuf); } }}static voidchannelmode_button_cb (GtkWidget *but, char *flag){ session *sess; char mode; sess = gtk_object_get_user_data (GTK_OBJECT (but)); if (!sess) /* can be zero if called from my_gtk_togglebutton_state() */ return; mode = tolower (flag[0]); switch (mode) { case 'l': flagl_hit (but, sess); break; case 'k':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -