📄 menu.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 <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include "fe-gtk.h"#include "../common/xchat.h"#include "../common/xchatc.h"#include "../common/cfgfiles.h"#include "../common/outbound.h"#include "../common/ignore.h"#include "../common/fe.h"#include "../common/util.h"#include "../common/plugin.h"#include "../common/perlc.h"#include "xtext.h"#include "about.h"#include "banlist.h"#include "chanlist.h"#include "editlist.h"#include "fkeys.h"#include "gtkutil.h"#include "maingui.h"#include "notifygui.h"#include "rawlog.h"#include "palette.h"#include "search.h"#include "settings.h"#include "textgui.h"#include "usermenu.h"#include "urlgrab.h"#include "menu.h"#ifdef USE_ZVT#include <zvt/zvtterm.h>#endifextern void module_glist (struct session *sess);static GSList *submenu_list;voidgoto_url (char *url){#ifdef USE_GNOME gnome_url_show (url);#else char tbuf[512];#ifdef WIN32 snprintf (tbuf, sizeof (tbuf), "start %s", url);#else snprintf (tbuf, sizeof (tbuf), "netscape -remote 'openURL(%s)'", url);#endif xchat_exec (tbuf);#endif}/* execute a userlistbutton/popupmenu command */static voidnick_command (session * sess, char *cmd){ if (*cmd == '!') xchat_exec (cmd + 1); else handle_command (cmd, sess, FALSE, FALSE);}/* fill in the %a %s %n etc and execute the command */voidnick_command_parse (session *sess, char *cmd, char *nick, char *allnick){ char *buf; char *host = _("Host unknown"); struct User *user; if (sess->type == SESS_DIALOG) { buf = gtk_entry_get_text (GTK_ENTRY (sess->gui->topicgad)); buf = strchr (buf, '@'); if (buf) host = buf + 1; } else { user = find_name (sess, nick); if (user && user->hostname) host = strchr (user->hostname, '@') + 1; } /* this can't overflow, since popup->cmd is only 256 */ buf = malloc (strlen (cmd) + strlen (nick) + strlen (allnick) + 512); auto_insert (buf, cmd, 0, 0, allnick, sess->channel, "", host, sess->server->nick, nick); nick_command (sess, buf); free (buf);}/* userlist button has been clicked */voiduserlist_button_cb (GtkWidget * button, char *cmd){ int nicks, using_allnicks = FALSE; char *nick = NULL, *allnicks; struct User *user; GList *sel_list; session *sess; /* this is set in maingui.c userlist_button() */ sess = gtk_object_get_user_data (GTK_OBJECT (button)); if (strstr (cmd, "%a")) using_allnicks = TRUE; /* count number of selected rows */ sel_list = (GTK_CLIST (sess->gui->namelistgad))->selection; nicks = g_list_length (sel_list); if (nicks == 0) { nick_command_parse (sess, cmd, "", ""); return; } /* create "allnicks" string */ allnicks = malloc (65 * nicks); *allnicks = 0; nicks = 0; while (sel_list) { user = gtk_clist_get_row_data (GTK_CLIST (sess->gui->namelistgad), (gint) sel_list->data); if (!nick) nick = user->nick; if (nicks > 0) strcat (allnicks, " "); strcat (allnicks, user->nick); sel_list = sel_list->next; nicks++; /* if not using "%a", execute the command once for each nickname */ if (!using_allnicks) nick_command_parse (sess, cmd, user->nick, ""); } if (using_allnicks) { if (!nick) nick = ""; nick_command_parse (sess, cmd, nick, allnicks); } free (allnicks);}/* a popup-menu-item has been selected */static voidpopup_menu_cb (GtkWidget * item, char *cmd){ char *nick; /* the userdata is set in menu_quick_item() */ nick = gtk_object_get_user_data (GTK_OBJECT (item)); if (!menu_sess) /* for url grabber window */ nick_command_parse (sess_list->data, cmd, nick, nick); else nick_command_parse (menu_sess, cmd, nick, nick);}static voidmenu_toggle_item (char *label, GtkWidget *menu, void *callback, void *userdata, int state){ GtkWidget *item; item = gtk_check_menu_item_new_with_label (label); /* Always show checkbox, not just when it is moused over. */ gtk_check_menu_item_set_show_toggle ((GtkCheckMenuItem*)item, TRUE); gtk_check_menu_item_set_state ((GtkCheckMenuItem*)item, state); gtk_menu_append (GTK_MENU (menu), item); gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (callback), userdata); gtk_widget_show (item);}static GtkWidget *menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags, gpointer userdata){ GtkWidget *item; if (!label) item = gtk_menu_item_new (); else item = gtk_menu_item_new_with_label (label); gtk_menu_append (GTK_MENU (menu), item); gtk_object_set_user_data (GTK_OBJECT (item), userdata); if (cmd) gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (popup_menu_cb), cmd); if (flags & (1 << 0)) gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); gtk_widget_show (item); return item;}voidmenu_quick_item_with_callback (void *callback, char *label, GtkWidget * menu, void *arg){ GtkWidget *item; item = gtk_menu_item_new_with_label (label); gtk_menu_append (GTK_MENU (menu), item); gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (callback), arg); gtk_widget_show (item);}static GtkWidget *menu_quick_sub (char *name, GtkWidget * menu){ GtkWidget *sub_menu; GtkWidget *sub_item; if (!name) return menu; /* Code to add a submenu */ sub_menu = gtk_menu_new (); sub_item = gtk_menu_item_new_with_label (name); gtk_menu_append (GTK_MENU (menu), sub_item); gtk_widget_show (sub_item); gtk_menu_item_set_submenu (GTK_MENU_ITEM (sub_item), sub_menu); /* We create a new element in the list */ submenu_list = g_slist_prepend (submenu_list, sub_menu); return (sub_menu);}static GtkWidget *menu_quick_endsub (){ /* Just delete the first element in the linked list pointed to by first */ if (submenu_list) submenu_list = g_slist_remove (submenu_list, submenu_list->data); if (submenu_list) return (submenu_list->data); else return NULL;}static voidtoggle_cb (GtkWidget *item, char *pref_name){ char buf[256]; if (GTK_CHECK_MENU_ITEM (item)->active) snprintf (buf, sizeof (buf), "/set %s 1", pref_name); else snprintf (buf, sizeof (buf), "/set %s 0", pref_name); handle_command (buf, menu_sess, FALSE, FALSE);}/* append items to "menu" using the (struct popup*) list provided */voidmenu_create (GtkWidget *menu, GSList *list, char *target){ struct popup *pop; GtkWidget *tempmenu = menu; submenu_list = g_slist_prepend (0, menu); while (list) { pop = (struct popup *) list->data; if (!strncasecmp (pop->name, "SUB", 3)) tempmenu = menu_quick_sub (pop->cmd, tempmenu); else if (!strncasecmp (pop->name, "TOGGLE", 6)) { menu_toggle_item (pop->name + 7, tempmenu, toggle_cb, pop->cmd, cfg_get_bool (pop->cmd)); } else if (!strncasecmp (pop->name, "ENDSUB", 6)) { if (tempmenu != menu) tempmenu = menu_quick_endsub (); /* If we get here and tempmenu equals menu that means we havent got any submenus to exit from */ } else if (!strncasecmp (pop->name, "SEP", 3)) menu_quick_item (0, 0, tempmenu, 1, 0); else menu_quick_item (pop->cmd, pop->name, tempmenu, 0, target); list = list->next; } /* Let's clean up the linked list from mem */ while (submenu_list) submenu_list = g_slist_remove (submenu_list, submenu_list->data);}static voidmenu_destroy (GtkObject *object, gpointer unused){ gtk_widget_destroy (GTK_WIDGET (object));}static voidmenu_popup (GtkWidget *menu, GdkEventButton *event){ gtk_signal_connect (GTK_OBJECT (menu), "selection-done", GTK_SIGNAL_FUNC (menu_destroy), NULL); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);}static char *str_copy = 0; /* for all pop-up menus */voidmenu_nickmenu (session *sess, GdkEventButton *event, char *nick){ char buf[256]; struct User *user; GtkWidget *wid, *submenu, *menu = gtk_menu_new (); if (str_copy) free (str_copy); str_copy = strdup (nick); submenu_list = 0; /* first time though, might not be 0 */ user = find_name_global (menu_sess->server, nick); if (user) { submenu = menu_quick_sub (str_copy, menu); sprintf (buf, _("User: %s"), user->hostname ? user->hostname : _("Unknown")); wid = menu_quick_item (0, buf, submenu, 0, 0); sprintf (buf, _("Country: %s"), user->hostname ? country(user->hostname) : _("Unknown")); wid = menu_quick_item (0, buf, submenu, 0, 0); sprintf (buf, _("Realname: %s"), user->realname ? user->realname : _("Unknown")); wid = menu_quick_item (0, buf, submenu, 0, 0); sprintf (buf, _("Server: %s"), user->servername ? user->servername : _("Unknown")); wid = menu_quick_item (0, buf, submenu, 0, 0); sprintf (buf, _("Last Msg: %s"), user->lasttalk ? ctime (&(user->lasttalk)) : _("Unknown")); if (user->lasttalk) buf[strlen (buf) - 1] = 0; wid = menu_quick_item (0, buf, submenu, 0, 0); gtk_label_set_justify (GTK_LABEL (GTK_BIN (wid)->child), GTK_JUSTIFY_LEFT); menu_quick_endsub (); menu_quick_item (0, 0, menu, 1, 0); } menu_create (menu, popup_list, str_copy); menu_popup (menu, event);}voidmenu_showhide (void){ session *sess; GSList *list; GtkWidget *menu;#ifdef USE_GNOME GtkWidget *win; int resize_done = FALSE; /* resize main_window only once */#endif list = sess_list; while (list) { sess = list->data; if (sess->is_tab) { menu = main_menu_bar; } else { if (!sess->gui->menu) goto cont; menu = sess->gui->menu->parent; /* really the handlebox */ } if (prefs.hidemenu) { gtk_widget_hide (menu);#ifdef USE_GNOME /* needed to hide the menubar properly under gnome. */ if (!resize_done || !sess->is_tab) { win = gtk_widget_get_toplevel (menu); gdk_window_resize (win->window, win->allocation.width-1, win->allocation.height); gdk_window_resize (win->window, win->allocation.width, win->allocation.height); if (sess->is_tab) resize_done = TRUE; }#endif } else { gtk_widget_show (menu); }cont: list = list->next; }}static voidmenu_middle_cb (GtkWidget *item, int n){ switch (n) { case 0: if (prefs.hidemenu) { prefs.hidemenu = 0; menu_showhide (); } else { prefs.hidemenu = 1; menu_showhide (); } break; case 1: maingui_showhide_topic (menu_sess); break; case 2: userlist_hide (0, menu_sess); break; }}voidmenu_middlemenu (session *sess, GdkEventButton *event){ GtkWidget *menu; menu = createmenus (0, sess, 0); menu_toggle_item (_("Menu Bar"), menu, (void*)menu_middle_cb, 0, !prefs.hidemenu); menu_toggle_item (_("Topic Bar"), menu, (void*)menu_middle_cb, (void*)1, prefs.topicbar); menu_toggle_item (_("User List"), menu, (void*)menu_middle_cb, (void*)2, !prefs.hideuserlist); menu_popup (menu, event);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -