2011-02-23 22:14:30 -05:00
/* X-Chat
* Copyright ( C ) 1998 - 2007 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>
# ifdef WIN32
# include <windows.h>
# endif
# include "fe-gtk.h"
# include <gtk/gtkhbox.h>
# include <gtk/gtkcheckmenuitem.h>
# include <gtk/gtkentry.h>
# include <gtk/gtkimage.h>
# include <gtk/gtkimagemenuitem.h>
# include <gtk/gtkradiomenuitem.h>
# include <gtk/gtklabel.h>
# include <gtk/gtkmessagedialog.h>
# include <gtk/gtkmenu.h>
# include <gtk/gtkmenubar.h>
# include <gtk/gtkstock.h>
# include <gtk/gtkversion.h>
# include <gdk/gdkkeysyms.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/server.h"
# include "../common/servlist.h"
# include "../common/notify.h"
# include "../common/util.h"
# include "xtext.h"
# include "about.h"
# include "ascii.h"
# include "banlist.h"
# include "chanlist.h"
# include "editlist.h"
# include "fkeys.h"
# include "gtkutil.h"
# include "maingui.h"
# include "notifygui.h"
# include "pixmaps.h"
# include "rawlog.h"
# include "palette.h"
# include "plugingui.h"
# include "search.h"
# include "textgui.h"
# include "urlgrab.h"
# include "userlistgui.h"
# include "menu.h"
static GSList * submenu_list ;
enum
{
M_MENUITEM ,
M_NEWMENU ,
M_END ,
M_SEP ,
M_MENUTOG ,
M_MENURADIO ,
M_MENUSTOCK ,
M_MENUPIX ,
M_MENUSUB
} ;
struct mymenu
{
char * text ;
void * callback ;
char * image ;
unsigned char type ; /* M_XXX */
unsigned char id ; /* MENU_ID_XXX (menu.h) */
unsigned char state ; /* ticked or not? */
unsigned char sensitive ; /* shaded out? */
guint key ; /* GDK_x */
} ;
# define XCMENU_DOLIST 1
# define XCMENU_SHADED 1
# define XCMENU_MARKUP 2
# define XCMENU_MNEMONIC 4
/* execute a userlistbutton/popupmenu command */
static void
nick_command ( session * sess , char * cmd )
{
if ( * cmd = = ' ! ' )
xchat_exec ( cmd + 1 ) ;
else
handle_command ( sess , cmd , TRUE ) ;
}
/* fill in the %a %s %n etc and execute the command */
void
nick_command_parse ( session * sess , char * cmd , char * nick , char * allnick )
{
char * buf ;
char * host = _ ( " Host unknown " ) ;
struct User * user ;
int len ;
/* if (sess->type == SESS_DIALOG)
{
buf = ( char * ) ( GTK_ENTRY ( sess - > gui - > topic_entry ) - > text ) ;
buf = strrchr ( buf , ' @ ' ) ;
if ( buf )
host = buf + 1 ;
} else */
{
user = userlist_find ( sess , nick ) ;
if ( user & & user - > hostname )
host = strchr ( user - > hostname , ' @ ' ) + 1 ;
}
/* this can't overflow, since popup->cmd is only 256 */
len = strlen ( cmd ) + strlen ( nick ) + strlen ( allnick ) + 512 ;
buf = malloc ( len ) ;
auto_insert ( buf , len , cmd , 0 , 0 , allnick , sess - > channel , " " ,
server_get_network ( sess - > server , TRUE ) , host ,
sess - > server - > nick , nick ) ;
nick_command ( sess , buf ) ;
free ( buf ) ;
}
/* userlist button has been clicked */
void
userlist_button_cb ( GtkWidget * button , char * cmd )
{
int i , num_sel , using_allnicks = FALSE ;
char * * nicks , * allnicks ;
char * nick = NULL ;
session * sess ;
sess = current_sess ;
if ( strstr ( cmd , " %a " ) )
using_allnicks = TRUE ;
if ( sess - > type = = SESS_DIALOG )
{
/* fake a selection */
nicks = malloc ( sizeof ( char * ) * 2 ) ;
nicks [ 0 ] = g_strdup ( sess - > channel ) ;
nicks [ 1 ] = NULL ;
num_sel = 1 ;
} else
{
/* find number of selected rows */
nicks = userlist_selection_list ( sess - > gui - > user_tree , & num_sel ) ;
if ( num_sel < 1 )
{
nick_command_parse ( sess , cmd , " " , " " ) ;
return ;
}
}
/* create "allnicks" string */
allnicks = malloc ( ( ( NICKLEN + 1 ) * num_sel ) + 1 ) ;
* allnicks = 0 ;
i = 0 ;
while ( nicks [ i ] )
{
if ( i > 0 )
strcat ( allnicks , " " ) ;
strcat ( allnicks , nicks [ i ] ) ;
if ( ! nick )
nick = nicks [ 0 ] ;
/* if not using "%a", execute the command once for each nickname */
if ( ! using_allnicks )
nick_command_parse ( sess , cmd , nicks [ i ] , " " ) ;
i + + ;
}
if ( using_allnicks )
{
if ( ! nick )
nick = " " ;
nick_command_parse ( sess , cmd , nick , allnicks ) ;
}
while ( num_sel )
{
num_sel - - ;
g_free ( nicks [ num_sel ] ) ;
}
free ( nicks ) ;
free ( allnicks ) ;
}
/* a popup-menu-item has been selected */
static void
popup_menu_cb ( GtkWidget * item , char * cmd )
{
char * nick ;
/* the userdata is set in menu_quick_item() */
nick = g_object_get_data ( G_OBJECT ( item ) , " u " ) ;
if ( ! nick ) /* userlist popup menu */
{
/* treat it just like a userlist button */
userlist_button_cb ( NULL , cmd ) ;
return ;
}
if ( ! current_sess ) /* for url grabber window */
nick_command_parse ( sess_list - > data , cmd , nick , nick ) ;
else
nick_command_parse ( current_sess , cmd , nick , nick ) ;
}
GtkWidget *
menu_toggle_item ( char * label , GtkWidget * menu , void * callback , void * userdata ,
int state )
{
GtkWidget * item ;
item = gtk_check_menu_item_new_with_mnemonic ( label ) ;
gtk_check_menu_item_set_active ( ( GtkCheckMenuItem * ) item , state ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( callback ) , userdata ) ;
gtk_widget_show ( item ) ;
return item ;
}
GtkWidget *
menu_quick_item ( char * cmd , char * label , GtkWidget * menu , int flags ,
gpointer userdata , char * icon )
{
GtkWidget * img , * item ;
char * path ;
if ( ! label )
item = gtk_menu_item_new ( ) ;
else
{
if ( icon )
{
/*if (flags & XCMENU_MARKUP)
item = gtk_image_menu_item_new_with_markup ( label ) ;
else */
item = gtk_image_menu_item_new_with_mnemonic ( label ) ;
img = NULL ;
if ( access ( icon , R_OK ) = = 0 ) /* try fullpath */
img = gtk_image_new_from_file ( icon ) ;
else
{
/* try relative to ~/.xchat2 */
path = g_strdup_printf ( " %s/%s " , get_xdir_fs ( ) , icon ) ;
if ( access ( path , R_OK ) = = 0 )
img = gtk_image_new_from_file ( path ) ;
else
img = gtk_image_new_from_stock ( icon , GTK_ICON_SIZE_MENU ) ;
g_free ( path ) ;
}
if ( img )
gtk_image_menu_item_set_image ( ( GtkImageMenuItem * ) item , img ) ;
}
else
{
if ( flags & XCMENU_MARKUP )
{
item = gtk_menu_item_new_with_label ( " " ) ;
if ( flags & XCMENU_MNEMONIC )
gtk_label_set_markup_with_mnemonic ( GTK_LABEL ( GTK_BIN ( item ) - > child ) , label ) ;
else
gtk_label_set_markup ( GTK_LABEL ( GTK_BIN ( item ) - > child ) , label ) ;
} else
{
if ( flags & XCMENU_MNEMONIC )
item = gtk_menu_item_new_with_mnemonic ( label ) ;
else
item = gtk_menu_item_new_with_label ( label ) ;
}
}
}
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
g_object_set_data ( G_OBJECT ( item ) , " u " , userdata ) ;
if ( cmd )
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( popup_menu_cb ) , cmd ) ;
if ( flags & XCMENU_SHADED )
gtk_widget_set_sensitive ( GTK_WIDGET ( item ) , FALSE ) ;
gtk_widget_show_all ( item ) ;
return item ;
}
static void
menu_quick_item_with_callback ( void * callback , char * label , GtkWidget * menu ,
void * arg )
{
GtkWidget * item ;
item = gtk_menu_item_new_with_label ( label ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( callback ) , arg ) ;
gtk_widget_show ( item ) ;
}
GtkWidget *
menu_quick_sub ( char * name , GtkWidget * menu , GtkWidget * * sub_item_ret , int flags , int pos )
{
GtkWidget * sub_menu ;
GtkWidget * sub_item ;
if ( ! name )
return menu ;
/* Code to add a submenu */
sub_menu = gtk_menu_new ( ) ;
if ( flags & XCMENU_MARKUP )
{
sub_item = gtk_menu_item_new_with_label ( " " ) ;
gtk_label_set_markup ( GTK_LABEL ( GTK_BIN ( sub_item ) - > child ) , name ) ;
}
else
{
if ( flags & XCMENU_MNEMONIC )
sub_item = gtk_menu_item_new_with_mnemonic ( name ) ;
else
sub_item = gtk_menu_item_new_with_label ( name ) ;
}
gtk_menu_shell_insert ( GTK_MENU_SHELL ( menu ) , sub_item , pos ) ;
gtk_widget_show ( sub_item ) ;
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( sub_item ) , sub_menu ) ;
if ( sub_item_ret )
* sub_item_ret = sub_item ;
if ( flags & XCMENU_DOLIST )
/* 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 void
toggle_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 ( current_sess , buf , FALSE ) ;
}
static int
is_in_path ( char * cmd )
{
char * prog = strdup ( cmd + 1 ) ; /* 1st char is "!" */
char * space , * path , * orig ;
orig = prog ; /* save for free()ing */
/* special-case these default entries. */
/* 123456789012345678 */
if ( strncmp ( prog , " gnome-terminal -x " , 18 ) = = 0 )
/* don't check for gnome-terminal, but the thing it's executing! */
prog + = 18 ;
space = strchr ( prog , ' ' ) ; /* this isn't 100% but good enuf */
if ( space )
* space = 0 ;
path = g_find_program_in_path ( prog ) ;
if ( path )
{
g_free ( path ) ;
g_free ( orig ) ;
return 1 ;
}
g_free ( orig ) ;
return 0 ;
}
/* syntax: "LABEL~ICON~STUFF~ADDED~LATER~" */
static void
menu_extract_icon ( char * name , char * * label , char * * icon )
{
char * p = name ;
char * start = NULL ;
char * end = NULL ;
while ( * p )
{
if ( * p = = ' ~ ' )
{
/* escape \~ */
if ( p = = name | | p [ - 1 ] ! = ' \\ ' )
{
if ( ! start )
start = p + 1 ;
else if ( ! end )
end = p + 1 ;
}
}
p + + ;
}
if ( ! end )
end = p ;
if ( start & & start ! = end )
{
* label = g_strndup ( name , ( start - name ) - 1 ) ;
* icon = g_strndup ( start , ( end - start ) - 1 ) ;
}
else
{
* label = g_strdup ( name ) ;
* icon = NULL ;
}
}
/* append items to "menu" using the (struct popup*) list provided */
void
menu_create ( GtkWidget * menu , GSList * list , char * target , int check_path )
{
struct popup * pop ;
GtkWidget * tempmenu = menu , * subitem = NULL ;
int childcount = 0 ;
submenu_list = g_slist_prepend ( 0 , menu ) ;
while ( list )
{
pop = ( struct popup * ) list - > data ;
if ( ! strncasecmp ( pop - > name , " SUB " , 3 ) )
{
childcount = 0 ;
tempmenu = menu_quick_sub ( pop - > cmd , tempmenu , & subitem , XCMENU_DOLIST | XCMENU_MNEMONIC , - 1 ) ;
} else if ( ! strncasecmp ( pop - > name , " TOGGLE " , 6 ) )
{
childcount + + ;
menu_toggle_item ( pop - > name + 7 , tempmenu , toggle_cb , pop - > cmd ,
cfg_get_bool ( pop - > cmd ) ) ;
} else if ( ! strncasecmp ( pop - > name , " ENDSUB " , 6 ) )
{
/* empty sub menu due to no programs in PATH? */
if ( check_path & & childcount < 1 )
gtk_widget_destroy ( subitem ) ;
subitem = NULL ;
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 , XCMENU_SHADED , 0 , 0 ) ;
} else
{
char * icon , * label ;
/* default command in xchat.c */
if ( pop - > cmd [ 0 ] = = ' n ' & & ! strcmp ( pop - > cmd , " notify -n ASK %s " ) )
{
/* don't create this item if already in notify list */
if ( ! target | | notify_is_in_list ( current_sess - > server , target ) )
{
list = list - > next ;
continue ;
}
}
menu_extract_icon ( pop - > name , & label , & icon ) ;
if ( ! check_path | | pop - > cmd [ 0 ] ! = ' ! ' )
{
menu_quick_item ( pop - > cmd , label , tempmenu , 0 , target , icon ) ;
/* check if the program is in path, if not, leave it out! */
} else if ( is_in_path ( pop - > cmd ) )
{
childcount + + ;
menu_quick_item ( pop - > cmd , label , tempmenu , 0 , target , icon ) ;
}
g_free ( label ) ;
g_free ( icon ) ;
}
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 char * str_copy = NULL ; /* for all pop-up menus */
static GtkWidget * nick_submenu = NULL ; /* user info submenu */
static void
menu_destroy ( GtkWidget * menu , gpointer objtounref )
{
gtk_widget_destroy ( menu ) ;
g_object_unref ( menu ) ;
if ( objtounref )
g_object_unref ( G_OBJECT ( objtounref ) ) ;
nick_submenu = NULL ;
}
static void
menu_popup ( GtkWidget * menu , GdkEventButton * event , gpointer objtounref )
{
# if (GTK_MAJOR_VERSION != 2) || (GTK_MINOR_VERSION != 0)
if ( event & & event - > window )
gtk_menu_set_screen ( GTK_MENU ( menu ) , gdk_drawable_get_screen ( event - > window ) ) ;
# endif
g_object_ref ( menu ) ;
g_object_ref_sink ( menu ) ;
g_object_unref ( menu ) ;
g_signal_connect ( G_OBJECT ( menu ) , " selection-done " ,
G_CALLBACK ( menu_destroy ) , objtounref ) ;
gtk_menu_popup ( GTK_MENU ( menu ) , NULL , NULL , NULL , NULL ,
0 , event ? event - > time : 0 ) ;
}
static void
menu_nickinfo_cb ( GtkWidget * menu , session * sess )
{
char buf [ 512 ] ;
if ( ! is_session ( sess ) )
return ;
/* issue a /WHOIS */
snprintf ( buf , sizeof ( buf ) , " WHOIS %s %s " , str_copy , str_copy ) ;
handle_command ( sess , buf , FALSE ) ;
/* and hide the output */
sess - > server - > skip_next_whois = 1 ;
}
static void
copy_to_clipboard_cb ( GtkWidget * item , char * url )
{
gtkutil_copy_to_clipboard ( item , NULL , url ) ;
}
/* returns boolean: Some data is missing */
static gboolean
menu_create_nickinfo_menu ( struct User * user , GtkWidget * submenu )
{
char buf [ 512 ] ;
char unknown [ 96 ] ;
char * real , * fmt ;
struct away_msg * away ;
gboolean missing = FALSE ;
GtkWidget * item ;
/* let the translators tweak this if need be */
fmt = _ ( " <tt><b>%-11s</b></tt> %s " ) ;
snprintf ( unknown , sizeof ( unknown ) , " <i>%s</i> " , _ ( " Unknown " ) ) ;
if ( user - > realname )
{
real = strip_color ( user - > realname , - 1 , STRIP_ALL | STRIP_ESCMARKUP ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Real Name: " ) , real ) ;
g_free ( real ) ;
} else
{
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Real Name: " ) , unknown ) ;
}
item = menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( copy_to_clipboard_cb ) ,
user - > realname ? user - > realname : unknown ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " User: " ) ,
user - > hostname ? user - > hostname : unknown ) ;
item = menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( copy_to_clipboard_cb ) ,
user - > hostname ? user - > hostname : unknown ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Country: " ) ,
user - > hostname ? country ( user - > hostname ) : unknown ) ;
item = menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( copy_to_clipboard_cb ) ,
user - > hostname ? country ( user - > hostname ) : unknown ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Server: " ) ,
user - > servername ? user - > servername : unknown ) ;
item = menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( copy_to_clipboard_cb ) ,
user - > servername ? user - > servername : unknown ) ;
if ( user - > lasttalk )
{
char min [ 96 ] ;
snprintf ( min , sizeof ( min ) , _ ( " %u minutes ago " ) ,
( unsigned int ) ( ( time ( 0 ) - user - > lasttalk ) / 60 ) ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Last Msg: " ) , min ) ;
} else
{
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Last Msg: " ) , unknown ) ;
}
menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
if ( user - > away )
{
away = server_away_find_message ( current_sess - > server , user - > nick ) ;
if ( away )
{
char * msg = strip_color ( away - > message ? away - > message : unknown , - 1 , STRIP_ALL | STRIP_ESCMARKUP ) ;
snprintf ( buf , sizeof ( buf ) , fmt , _ ( " Away Msg: " ) , msg ) ;
g_free ( msg ) ;
item = menu_quick_item ( 0 , buf , submenu , XCMENU_MARKUP , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( copy_to_clipboard_cb ) ,
away - > message ? away - > message : unknown ) ;
}
else
missing = TRUE ;
}
return missing ;
}
void
fe_userlist_update ( session * sess , struct User * user )
{
GList * items , * next ;
if ( ! nick_submenu | | ! str_copy )
return ;
/* not the same nick as the menu? */
if ( sess - > server - > p_cmp ( user - > nick , str_copy ) )
return ;
/* get rid of the "show" signal */
g_signal_handlers_disconnect_by_func ( nick_submenu , menu_nickinfo_cb , sess ) ;
/* destroy all the old items */
items = ( ( GtkMenuShell * ) nick_submenu ) - > children ;
while ( items )
{
next = items - > next ;
gtk_widget_destroy ( items - > data ) ;
items = next ;
}
/* and re-create them with new info */
menu_create_nickinfo_menu ( user , nick_submenu ) ;
}
void
menu_nickmenu ( session * sess , GdkEventButton * event , char * nick , int num_sel )
{
char buf [ 512 ] ;
struct User * user ;
GtkWidget * submenu , * menu = gtk_menu_new ( ) ;
if ( str_copy )
free ( str_copy ) ;
str_copy = strdup ( nick ) ;
submenu_list = 0 ; /* first time through, might not be 0 */
/* more than 1 nick selected? */
if ( num_sel > 1 )
{
snprintf ( buf , sizeof ( buf ) , _ ( " %d nicks selected. " ) , num_sel ) ;
menu_quick_item ( 0 , buf , menu , 0 , 0 , 0 ) ;
menu_quick_item ( 0 , 0 , menu , XCMENU_SHADED , 0 , 0 ) ;
} else
{
user = userlist_find ( sess , nick ) ; /* lasttalk is channel specific */
if ( ! user )
user = userlist_find_global ( current_sess - > server , nick ) ;
if ( user )
{
nick_submenu = submenu = menu_quick_sub ( nick , menu , NULL , XCMENU_DOLIST , - 1 ) ;
if ( menu_create_nickinfo_menu ( user , submenu ) | |
! user - > hostname | | ! user - > realname | | ! user - > servername )
{
g_signal_connect ( G_OBJECT ( submenu ) , " show " , G_CALLBACK ( menu_nickinfo_cb ) , sess ) ;
}
menu_quick_endsub ( ) ;
menu_quick_item ( 0 , 0 , menu , XCMENU_SHADED , 0 , 0 ) ;
}
}
if ( num_sel > 1 )
menu_create ( menu , popup_list , NULL , FALSE ) ;
else
menu_create ( menu , popup_list , str_copy , FALSE ) ;
if ( num_sel = = 0 ) /* xtext click */
menu_add_plugin_items ( menu , " \ x5$NICK " , str_copy ) ;
else /* userlist treeview click */
menu_add_plugin_items ( menu , " \ x5$NICK " , NULL ) ;
menu_popup ( menu , event , NULL ) ;
}
/* stuff for the View menu */
static void
menu_showhide_cb ( session * sess )
{
if ( prefs . hidemenu )
gtk_widget_hide ( sess - > gui - > menu ) ;
else
gtk_widget_show ( sess - > gui - > menu ) ;
}
static void
menu_topic_showhide_cb ( session * sess )
{
if ( prefs . topicbar )
gtk_widget_show ( sess - > gui - > topic_bar ) ;
else
gtk_widget_hide ( sess - > gui - > topic_bar ) ;
}
static void
menu_userlist_showhide_cb ( session * sess )
{
mg_decide_userlist ( sess , TRUE ) ;
}
static void
menu_ulbuttons_showhide_cb ( session * sess )
{
if ( prefs . userlistbuttons )
gtk_widget_show ( sess - > gui - > button_box ) ;
else
gtk_widget_hide ( sess - > gui - > button_box ) ;
}
static void
menu_cmbuttons_showhide_cb ( session * sess )
{
switch ( sess - > type )
{
case SESS_CHANNEL :
if ( prefs . chanmodebuttons )
gtk_widget_show ( sess - > gui - > topicbutton_box ) ;
else
gtk_widget_hide ( sess - > gui - > topicbutton_box ) ;
break ;
default :
gtk_widget_hide ( sess - > gui - > topicbutton_box ) ;
}
}
static void
menu_setting_foreach ( void ( * callback ) ( session * ) , int id , guint state )
{
session * sess ;
GSList * list ;
int maindone = FALSE ; /* do it only once for EVERY tab */
list = sess_list ;
while ( list )
{
sess = list - > data ;
if ( ! sess - > gui - > is_tab | | ! maindone )
{
if ( sess - > gui - > is_tab )
maindone = TRUE ;
if ( id ! = - 1 )
GTK_CHECK_MENU_ITEM ( sess - > gui - > menu_item [ id ] ) - > active = state ;
if ( callback )
callback ( sess ) ;
}
list = list - > next ;
}
}
void
menu_bar_toggle ( void )
{
prefs . hidemenu = ! prefs . hidemenu ;
menu_setting_foreach ( menu_showhide_cb , MENU_ID_MENUBAR , ! prefs . hidemenu ) ;
}
static void
menu_bar_toggle_cb ( void )
{
menu_bar_toggle ( ) ;
if ( prefs . hidemenu )
fe_message ( _ ( " The Menubar is now hidden. You can show it again "
" by pressing F9 or right-clicking in a blank part of "
" the main text area. " ) , FE_MSG_INFO ) ;
}
static void
menu_topicbar_toggle ( GtkWidget * wid , gpointer ud )
{
prefs . topicbar = ! prefs . topicbar ;
menu_setting_foreach ( menu_topic_showhide_cb , MENU_ID_TOPICBAR ,
prefs . topicbar ) ;
}
static void
menu_userlist_toggle ( GtkWidget * wid , gpointer ud )
{
prefs . hideuserlist = ! prefs . hideuserlist ;
menu_setting_foreach ( menu_userlist_showhide_cb , MENU_ID_USERLIST ,
! prefs . hideuserlist ) ;
}
static void
menu_ulbuttons_toggle ( GtkWidget * wid , gpointer ud )
{
prefs . userlistbuttons = ! prefs . userlistbuttons ;
menu_setting_foreach ( menu_ulbuttons_showhide_cb , MENU_ID_ULBUTTONS ,
prefs . userlistbuttons ) ;
}
static void
menu_cmbuttons_toggle ( GtkWidget * wid , gpointer ud )
{
prefs . chanmodebuttons = ! prefs . chanmodebuttons ;
menu_setting_foreach ( menu_cmbuttons_showhide_cb , MENU_ID_MODEBUTTONS ,
prefs . chanmodebuttons ) ;
}
void
menu_middlemenu ( session * sess , GdkEventButton * event )
{
GtkWidget * menu ;
GtkAccelGroup * accel_group ;
accel_group = gtk_accel_group_new ( ) ;
menu = menu_create_main ( accel_group , FALSE , sess - > server - > is_away , ! sess - > gui - > is_tab , NULL ) ;
menu_popup ( menu , event , accel_group ) ;
}
static void
open_url_cb ( GtkWidget * item , char * url )
{
char buf [ 512 ] ;
/* pass this to /URL so it can handle irc:// */
snprintf ( buf , sizeof ( buf ) , " URL %s " , url ) ;
handle_command ( current_sess , buf , FALSE ) ;
}
void
menu_urlmenu ( GdkEventButton * event , char * url )
{
GtkWidget * menu ;
char * tmp , * chop ;
if ( str_copy )
free ( str_copy ) ;
str_copy = strdup ( url ) ;
menu = gtk_menu_new ( ) ;
/* more than 51 chars? Chop it */
if ( g_utf8_strlen ( str_copy , - 1 ) > = 52 )
{
tmp = strdup ( str_copy ) ;
chop = g_utf8_offset_to_pointer ( tmp , 48 ) ;
chop [ 0 ] = chop [ 1 ] = chop [ 2 ] = ' . ' ;
chop [ 3 ] = 0 ;
menu_quick_item ( 0 , tmp , menu , XCMENU_SHADED , 0 , 0 ) ;
free ( tmp ) ;
} else
{
menu_quick_item ( 0 , str_copy , menu , XCMENU_SHADED , 0 , 0 ) ;
}
menu_quick_item ( 0 , 0 , menu , XCMENU_SHADED , 0 , 0 ) ;
/* Two hardcoded entries */
if ( strncmp ( str_copy , " irc:// " , 6 ) = = 0 | |
strncmp ( str_copy , " ircs:// " , 7 ) = = 0 )
menu_quick_item_with_callback ( open_url_cb , _ ( " Connect " ) , menu , str_copy ) ;
else
menu_quick_item_with_callback ( open_url_cb , _ ( " Open Link in Browser " ) , menu , str_copy ) ;
menu_quick_item_with_callback ( copy_to_clipboard_cb , _ ( " Copy Selected Link " ) , menu , str_copy ) ;
/* custom ones from urlhandlers.conf */
menu_create ( menu , urlhandler_list , str_copy , TRUE ) ;
menu_add_plugin_items ( menu , " \ x4$URL " , str_copy ) ;
menu_popup ( menu , event , NULL ) ;
}
static void
menu_chan_cycle ( GtkWidget * menu , char * chan )
{
char tbuf [ 256 ] ;
if ( current_sess )
{
snprintf ( tbuf , sizeof tbuf , " CYCLE %s " , chan ) ;
handle_command ( current_sess , tbuf , FALSE ) ;
}
}
static void
menu_chan_part ( GtkWidget * menu , char * chan )
{
char tbuf [ 256 ] ;
if ( current_sess )
{
snprintf ( tbuf , sizeof tbuf , " part %s " , chan ) ;
handle_command ( current_sess , tbuf , FALSE ) ;
}
}
static void
menu_chan_join ( GtkWidget * menu , char * chan )
{
char tbuf [ 256 ] ;
if ( current_sess )
{
snprintf ( tbuf , sizeof tbuf , " join %s " , chan ) ;
handle_command ( current_sess , tbuf , FALSE ) ;
}
}
void
menu_chanmenu ( struct session * sess , GdkEventButton * event , char * chan )
{
GtkWidget * menu ;
int is_joined = FALSE ;
if ( find_channel ( sess - > server , chan ) )
is_joined = TRUE ;
if ( str_copy )
free ( str_copy ) ;
str_copy = strdup ( chan ) ;
menu = gtk_menu_new ( ) ;
menu_quick_item ( 0 , chan , menu , XCMENU_SHADED , str_copy , 0 ) ;
menu_quick_item ( 0 , 0 , menu , XCMENU_SHADED , str_copy , 0 ) ;
if ( ! is_joined )
menu_quick_item_with_callback ( menu_chan_join , _ ( " Join Channel " ) , menu ,
str_copy ) ;
else
{
menu_quick_item_with_callback ( menu_chan_part , _ ( " Part Channel " ) , menu ,
str_copy ) ;
menu_quick_item_with_callback ( menu_chan_cycle , _ ( " Cycle Channel " ) , menu ,
str_copy ) ;
}
menu_addfavoritemenu ( sess - > server , menu , str_copy ) ;
menu_add_plugin_items ( menu , " \ x5$CHAN " , str_copy ) ;
menu_popup ( menu , event , NULL ) ;
}
static void
menu_delfav_cb ( GtkWidget * item , server * serv )
{
servlist_autojoinedit ( serv - > network , str_copy , FALSE ) ;
}
static void
menu_addfav_cb ( GtkWidget * item , server * serv )
{
servlist_autojoinedit ( serv - > network , str_copy , TRUE ) ;
}
void
menu_addfavoritemenu ( server * serv , GtkWidget * menu , char * channel )
{
if ( ! serv - > network )
return ;
if ( channel ! = str_copy )
{
if ( str_copy )
free ( str_copy ) ;
str_copy = strdup ( channel ) ;
}
if ( joinlist_is_in_list ( serv , channel ) )
mg_create_icon_item ( _ ( " _Remove from Favorites " ) , GTK_STOCK_REMOVE , menu , menu_delfav_cb , serv ) ;
else
mg_create_icon_item ( _ ( " _Add to Favorites " ) , GTK_STOCK_ADD , menu , menu_addfav_cb , serv ) ;
}
static void
menu_open_server_list ( GtkWidget * wid , gpointer none )
{
fe_serverlist_open ( current_sess ) ;
}
static void
menu_settings ( GtkWidget * wid , gpointer none )
{
extern void setup_open ( void ) ;
setup_open ( ) ;
}
static void
menu_usermenu ( void )
{
editlist_gui_open ( NULL , NULL , usermenu_list , _ ( " XChat: User menu " ) ,
" usermenu " , " usermenu.conf " , 0 ) ;
}
static void
usermenu_create ( GtkWidget * menu )
{
menu_create ( menu , usermenu_list , " " , FALSE ) ;
menu_quick_item ( 0 , 0 , menu , XCMENU_SHADED , 0 , 0 ) ; /* sep */
menu_quick_item_with_callback ( menu_usermenu , _ ( " Edit This Menu... " ) , menu , 0 ) ;
}
static void
usermenu_destroy ( GtkWidget * menu )
{
GList * items = ( ( GtkMenuShell * ) menu ) - > children ;
GList * next ;
while ( items )
{
next = items - > next ;
gtk_widget_destroy ( items - > data ) ;
items = next ;
}
}
void
usermenu_update ( void )
{
int done_main = FALSE ;
GSList * list = sess_list ;
session * sess ;
GtkWidget * menu ;
while ( list )
{
sess = list - > data ;
menu = sess - > gui - > menu_item [ MENU_ID_USERMENU ] ;
if ( sess - > gui - > is_tab )
{
if ( ! done_main & & menu )
{
usermenu_destroy ( menu ) ;
usermenu_create ( menu ) ;
done_main = TRUE ;
}
} else if ( menu )
{
usermenu_destroy ( menu ) ;
usermenu_create ( menu ) ;
}
list = list - > next ;
}
}
2011-11-23 07:13:58 -05:00
static void
menu_saveconf ( void )
{
session * sess = current_sess ;
if ( save_config ( ) )
{
2011-11-23 07:23:51 -05:00
PrintText ( sess , " Settings have been saved successfully. \n " ) ;
2011-11-23 07:13:58 -05:00
}
else
{
2011-11-23 07:23:51 -05:00
PrintText ( sess , " Error saving settings. \n " ) ;
2011-11-23 07:13:58 -05:00
}
}
2011-02-23 22:14:30 -05:00
static void
menu_newserver_window ( GtkWidget * wid , gpointer none )
{
int old = prefs . tabchannels ;
prefs . tabchannels = 0 ;
new_ircwindow ( NULL , NULL , SESS_SERVER , 0 ) ;
prefs . tabchannels = old ;
}
static void
menu_newchannel_window ( GtkWidget * wid , gpointer none )
{
int old = prefs . tabchannels ;
prefs . tabchannels = 0 ;
new_ircwindow ( current_sess - > server , NULL , SESS_CHANNEL , 0 ) ;
prefs . tabchannels = old ;
}
static void
menu_newserver_tab ( GtkWidget * wid , gpointer none )
{
int old = prefs . tabchannels ;
int oldf = prefs . newtabstofront ;
prefs . tabchannels = 1 ;
/* force focus if setting is "only requested tabs" */
if ( prefs . newtabstofront = = 2 )
prefs . newtabstofront = 1 ;
new_ircwindow ( NULL , NULL , SESS_SERVER , 0 ) ;
prefs . tabchannels = old ;
prefs . newtabstofront = oldf ;
}
static void
menu_newchannel_tab ( GtkWidget * wid , gpointer none )
{
int old = prefs . tabchannels ;
prefs . tabchannels = 1 ;
new_ircwindow ( current_sess - > server , NULL , SESS_CHANNEL , 0 ) ;
prefs . tabchannels = old ;
}
static void
menu_rawlog ( GtkWidget * wid , gpointer none )
{
open_rawlog ( current_sess - > server ) ;
}
static void
menu_detach ( GtkWidget * wid , gpointer none )
{
mg_detach ( current_sess , 0 ) ;
}
static void
menu_close ( GtkWidget * wid , gpointer none )
{
mg_close_sess ( current_sess ) ;
}
static void
menu_quit ( GtkWidget * wid , gpointer none )
{
mg_open_quit_dialog ( FALSE ) ;
}
static void
menu_search ( )
{
search_open ( current_sess ) ;
}
static void
menu_resetmarker ( GtkWidget * wid , gpointer none )
{
gtk_xtext_reset_marker_pos ( GTK_XTEXT ( current_sess - > gui - > xtext ) ) ;
}
2011-02-28 12:59:32 -05:00
static void
menu_copy_selection ( GtkWidget * wid , gpointer none )
{
gtk_xtext_copy_selection ( GTK_XTEXT ( current_sess - > gui - > xtext ) ) ;
}
2011-02-23 22:14:30 -05:00
static void
menu_flushbuffer ( GtkWidget * wid , gpointer none )
{
fe_text_clear ( current_sess , 0 ) ;
}
static void
savebuffer_req_done ( session * sess , char * file )
{
int fh ;
if ( ! file )
return ;
fh = open ( file , O_TRUNC | O_WRONLY | O_CREAT , 0600 ) ;
if ( fh ! = - 1 )
{
gtk_xtext_save ( GTK_XTEXT ( sess - > gui - > xtext ) , fh ) ;
close ( fh ) ;
}
}
static void
menu_savebuffer ( GtkWidget * wid , gpointer none )
{
gtkutil_file_req ( _ ( " Select an output filename " ) , savebuffer_req_done ,
current_sess , NULL , FRF_WRITE ) ;
}
static void
menu_disconnect ( GtkWidget * wid , gpointer none )
{
handle_command ( current_sess , " DISCON " , FALSE ) ;
}
static void
menu_reconnect ( GtkWidget * wid , gpointer none )
{
if ( current_sess - > server - > hostname [ 0 ] )
handle_command ( current_sess , " RECONNECT " , FALSE ) ;
else
fe_serverlist_open ( current_sess ) ;
}
static void
menu_join_cb ( GtkWidget * dialog , gint response , GtkEntry * entry )
{
switch ( response )
{
case GTK_RESPONSE_ACCEPT :
menu_chan_join ( NULL , entry - > text ) ;
break ;
case GTK_RESPONSE_HELP :
chanlist_opengui ( current_sess - > server , TRUE ) ;
break ;
}
gtk_widget_destroy ( dialog ) ;
}
static void
menu_join_entry_cb ( GtkWidget * entry , GtkDialog * dialog )
{
gtk_dialog_response ( dialog , GTK_RESPONSE_ACCEPT ) ;
}
static void
menu_join ( GtkWidget * wid , gpointer none )
{
GtkWidget * hbox , * dialog , * entry , * label ;
dialog = gtk_dialog_new_with_buttons ( _ ( " Join Channel " ) ,
GTK_WINDOW ( parent_window ) , 0 ,
_ ( " Retrieve channel list... " ) , GTK_RESPONSE_HELP ,
GTK_STOCK_CANCEL , GTK_RESPONSE_REJECT ,
GTK_STOCK_OK , GTK_RESPONSE_ACCEPT ,
NULL ) ;
gtk_box_set_homogeneous ( GTK_BOX ( GTK_DIALOG ( dialog ) - > vbox ) , TRUE ) ;
gtk_window_set_position ( GTK_WINDOW ( dialog ) , GTK_WIN_POS_MOUSE ) ;
hbox = gtk_hbox_new ( TRUE , 0 ) ;
entry = gtk_entry_new ( ) ;
GTK_ENTRY ( entry ) - > editable = 0 ; /* avoid auto-selection */
gtk_entry_set_text ( GTK_ENTRY ( entry ) , " # " ) ;
g_signal_connect ( G_OBJECT ( entry ) , " activate " ,
G_CALLBACK ( menu_join_entry_cb ) , dialog ) ;
gtk_box_pack_end ( GTK_BOX ( hbox ) , entry , 0 , 0 , 0 ) ;
label = gtk_label_new ( _ ( " Enter Channel to Join: " ) ) ;
gtk_box_pack_end ( GTK_BOX ( hbox ) , label , 0 , 0 , 0 ) ;
g_signal_connect ( G_OBJECT ( dialog ) , " response " ,
G_CALLBACK ( menu_join_cb ) , entry ) ;
gtk_container_add ( GTK_CONTAINER ( GTK_DIALOG ( dialog ) - > vbox ) , hbox ) ;
gtk_widget_show_all ( dialog ) ;
gtk_editable_set_editable ( GTK_EDITABLE ( entry ) , TRUE ) ;
gtk_editable_set_position ( GTK_EDITABLE ( entry ) , 1 ) ;
}
static void
menu_away ( GtkCheckMenuItem * item , gpointer none )
{
handle_command ( current_sess , item - > active ? " away " : " back " , FALSE ) ;
}
static void
menu_chanlist ( GtkWidget * wid , gpointer none )
{
chanlist_opengui ( current_sess - > server , FALSE ) ;
}
static void
menu_banlist ( GtkWidget * wid , gpointer none )
{
banlist_opengui ( current_sess ) ;
}
# ifdef USE_PLUGIN
static void
menu_loadplugin ( void )
{
plugingui_load ( ) ;
}
static void
menu_pluginlist ( void )
{
plugingui_open ( ) ;
}
# else
# define menu_pluginlist 0
# define menu_loadplugin 0
# endif
# define usercommands_help _("User Commands - Special codes:\n\n"\
" %c = current channel \n " \
" %e = current network name \n " \
" %m = machine info \n " \
" %n = your nick \n " \
" %t = time/date \n " \
" %v = xchat version \n " \
" %2 = word 2 \n " \
" %3 = word 3 \n " \
" &2 = word 2 to the end of line \n " \
" &3 = word 3 to the end of line \n \n " \
" eg: \n " \
" /cmd john hello \n \n " \
" %2 would be \042 john \042 \n " \
" &2 would be \042 john hello \042 . " )
# define ulbutton_help _("Userlist Buttons - Special codes:\n\n"\
" %a = all selected nicks \n " \
" %c = current channel \n " \
" %e = current network name \n " \
" %h = selected nick's hostname \n " \
" %m = machine info \n " \
" %n = your nick \n " \
" %s = selected nick \n " \
" %t = time/date \n " )
# define dlgbutton_help _("Dialog Buttons - Special codes:\n\n"\
" %a = all selected nicks \n " \
" %c = current channel \n " \
" %e = current network name \n " \
" %h = selected nick's hostname \n " \
" %m = machine info \n " \
" %n = your nick \n " \
" %s = selected nick \n " \
" %t = time/date \n " )
# define ctcp_help _("CTCP Replies - Special codes:\n\n"\
" %d = data (the whole ctcp) \n " \
" %e = current network name \n " \
" %m = machine info \n " \
" %s = nick who sent the ctcp \n " \
" %t = time/date \n " \
" %2 = word 2 \n " \
" %3 = word 3 \n " \
" &2 = word 2 to the end of line \n " \
" &3 = word 3 to the end of line \n \n " )
# define url_help _("URL Handlers - Special codes:\n\n"\
" %s = the URL string \n \n " \
" Putting a ! infront of the command \n " \
" indicates it should be sent to a \n " \
" shell instead of XChat " )
static void
menu_usercommands ( void )
{
editlist_gui_open ( NULL , NULL , command_list , _ ( " XChat: User Defined Commands " ) ,
" commands " , " commands.conf " , usercommands_help ) ;
}
static void
menu_ulpopup ( void )
{
editlist_gui_open ( NULL , NULL , popup_list , _ ( " XChat: Userlist Popup menu " ) , " popup " ,
" popup.conf " , ulbutton_help ) ;
}
static void
menu_rpopup ( void )
{
editlist_gui_open ( _ ( " Text " ) , _ ( " Replace with " ) , replace_list , _ ( " XChat: Replace " ) , " replace " ,
" replace.conf " , 0 ) ;
}
static void
menu_urlhandlers ( void )
{
editlist_gui_open ( NULL , NULL , urlhandler_list , _ ( " XChat: URL Handlers " ) , " urlhandlers " ,
" urlhandlers.conf " , url_help ) ;
}
static void
menu_evtpopup ( void )
{
pevent_dialog_show ( ) ;
}
static void
menu_keypopup ( void )
{
key_dialog_show ( ) ;
}
static void
menu_ulbuttons ( void )
{
editlist_gui_open ( NULL , NULL , button_list , _ ( " XChat: Userlist buttons " ) , " buttons " ,
" buttons.conf " , ulbutton_help ) ;
}
static void
menu_dlgbuttons ( void )
{
editlist_gui_open ( NULL , NULL , dlgbutton_list , _ ( " XChat: Dialog buttons " ) , " dlgbuttons " ,
" dlgbuttons.conf " , dlgbutton_help ) ;
}
static void
menu_ctcpguiopen ( void )
{
editlist_gui_open ( NULL , NULL , ctcp_list , _ ( " XChat: CTCP Replies " ) , " ctcpreply " ,
" ctcpreply.conf " , ctcp_help ) ;
}
static void
menu_docs ( GtkWidget * wid , gpointer none )
{
fe_open_url ( " http://xchat.org/docs/ " ) ;
}
/*static void
menu_webpage ( GtkWidget * wid , gpointer none )
{
fe_open_url ( " http://xchat.org " ) ;
} */
static void
menu_dcc_win ( GtkWidget * wid , gpointer none )
{
fe_dcc_open_recv_win ( FALSE ) ;
fe_dcc_open_send_win ( FALSE ) ;
}
static void
menu_dcc_chat_win ( GtkWidget * wid , gpointer none )
{
fe_dcc_open_chat_win ( FALSE ) ;
}
void
menu_change_layout ( void )
{
if ( prefs . tab_layout = = 0 )
{
menu_setting_foreach ( NULL , MENU_ID_LAYOUT_TABS , 1 ) ;
menu_setting_foreach ( NULL , MENU_ID_LAYOUT_TREE , 0 ) ;
mg_change_layout ( 0 ) ;
} else
{
menu_setting_foreach ( NULL , MENU_ID_LAYOUT_TABS , 0 ) ;
menu_setting_foreach ( NULL , MENU_ID_LAYOUT_TREE , 1 ) ;
mg_change_layout ( 2 ) ;
}
}
static void
menu_layout_cb ( GtkWidget * item , gpointer none )
{
prefs . tab_layout = 2 ;
if ( GTK_CHECK_MENU_ITEM ( item ) - > active )
prefs . tab_layout = 0 ;
menu_change_layout ( ) ;
}
static void
menu_apply_metres_cb ( session * sess )
{
mg_update_meters ( sess - > gui ) ;
}
static void
menu_metres_off ( GtkWidget * item , gpointer none )
{
if ( GTK_CHECK_MENU_ITEM ( item ) - > active )
{
prefs . lagometer = 0 ;
prefs . throttlemeter = 0 ;
menu_setting_foreach ( menu_apply_metres_cb , - 1 , 0 ) ;
}
}
static void
menu_metres_text ( GtkWidget * item , gpointer none )
{
if ( GTK_CHECK_MENU_ITEM ( item ) - > active )
{
prefs . lagometer = 2 ;
prefs . throttlemeter = 2 ;
menu_setting_foreach ( menu_apply_metres_cb , - 1 , 0 ) ;
}
}
static void
menu_metres_graph ( GtkWidget * item , gpointer none )
{
if ( GTK_CHECK_MENU_ITEM ( item ) - > active )
{
prefs . lagometer = 1 ;
prefs . throttlemeter = 1 ;
menu_setting_foreach ( menu_apply_metres_cb , - 1 , 0 ) ;
}
}
static void
menu_metres_both ( GtkWidget * item , gpointer none )
{
if ( GTK_CHECK_MENU_ITEM ( item ) - > active )
{
prefs . lagometer = 3 ;
prefs . throttlemeter = 3 ;
menu_setting_foreach ( menu_apply_metres_cb , - 1 , 0 ) ;
}
}
static struct mymenu mymenu [ ] = {
{ N_ ( " _XChat " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } ,
{ N_ ( " Network Li_st... " ) , menu_open_server_list , ( char * ) & pix_book , M_MENUPIX , 0 , 0 , 1 , GDK_s } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
{ N_ ( " _New " ) , 0 , GTK_STOCK_NEW , M_MENUSUB , 0 , 0 , 1 } ,
{ N_ ( " Server Tab... " ) , menu_newserver_tab , 0 , M_MENUITEM , 0 , 0 , 1 , GDK_t } ,
{ N_ ( " Channel Tab... " ) , menu_newchannel_tab , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Server Window... " ) , menu_newserver_window , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Channel Window... " ) , menu_newchannel_window , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_END , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
# ifdef USE_PLUGIN
{ N_ ( " _Load Plugin or Script... " ) , menu_loadplugin , GTK_STOCK_REVERT_TO_SAVED , M_MENUSTOCK , 0 , 0 , 1 } ,
# else
{ N_ ( " _Load Plugin or Script... " ) , 0 , GTK_STOCK_REVERT_TO_SAVED , M_MENUSTOCK , 0 , 0 , 0 } ,
# endif
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } , /* 11 */
# define DETACH_OFFSET (12)
2011-07-27 20:22:22 -04:00
{ 0 , menu_detach , GTK_STOCK_REDO , M_MENUSTOCK , 0 , 0 , 1 , GDK_i } , /* 12 */
2011-02-23 22:14:30 -05:00
# define CLOSE_OFFSET (13)
{ 0 , menu_close , GTK_STOCK_CLOSE , M_MENUSTOCK , 0 , 0 , 1 , GDK_w } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
{ N_ ( " _Quit " ) , menu_quit , GTK_STOCK_QUIT , M_MENUSTOCK , 0 , 0 , 1 , GDK_q } , /* 15 */
{ N_ ( " _View " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } ,
# define MENUBAR_OFFSET (17)
{ N_ ( " _Menu Bar " ) , menu_bar_toggle_cb , 0 , M_MENUTOG , MENU_ID_MENUBAR , 0 , 1 , GDK_F9 } ,
{ N_ ( " _Topic Bar " ) , menu_topicbar_toggle , 0 , M_MENUTOG , MENU_ID_TOPICBAR , 0 , 1 } ,
{ N_ ( " _User List " ) , menu_userlist_toggle , 0 , M_MENUTOG , MENU_ID_USERLIST , 0 , 1 , GDK_F7 } ,
{ N_ ( " U_serlist Buttons " ) , menu_ulbuttons_toggle , 0 , M_MENUTOG , MENU_ID_ULBUTTONS , 0 , 1 } ,
{ N_ ( " M_ode Buttons " ) , menu_cmbuttons_toggle , 0 , M_MENUTOG , MENU_ID_MODEBUTTONS , 0 , 1 } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
{ N_ ( " _Channel Switcher " ) , 0 , 0 , M_MENUSUB , 0 , 0 , 1 } , /* 23 */
# define TABS_OFFSET (24)
{ N_ ( " _Tabs " ) , menu_layout_cb , 0 , M_MENURADIO , MENU_ID_LAYOUT_TABS , 0 , 1 } ,
{ N_ ( " T_ree " ) , 0 , 0 , M_MENURADIO , MENU_ID_LAYOUT_TREE , 0 , 1 } ,
{ 0 , 0 , 0 , M_END , 0 , 0 , 0 } ,
{ N_ ( " _Network Meters " ) , 0 , 0 , M_MENUSUB , 0 , 0 , 1 } , /* 27 */
# define METRE_OFFSET (28)
{ N_ ( " Off " ) , menu_metres_off , 0 , M_MENURADIO , 0 , 0 , 1 } ,
{ N_ ( " Graph " ) , menu_metres_graph , 0 , M_MENURADIO , 0 , 0 , 1 } ,
{ N_ ( " Text " ) , menu_metres_text , 0 , M_MENURADIO , 0 , 0 , 1 } ,
{ N_ ( " Both " ) , menu_metres_both , 0 , M_MENURADIO , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_END , 0 , 0 , 0 } , /* 32 */
{ N_ ( " _Server " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } ,
{ N_ ( " _Disconnect " ) , menu_disconnect , GTK_STOCK_DISCONNECT , M_MENUSTOCK , MENU_ID_DISCONNECT , 0 , 1 } ,
{ N_ ( " _Reconnect " ) , menu_reconnect , GTK_STOCK_CONNECT , M_MENUSTOCK , MENU_ID_RECONNECT , 0 , 1 } ,
{ N_ ( " Join a Channel... " ) , menu_join , GTK_STOCK_JUMP_TO , M_MENUSTOCK , MENU_ID_JOIN , 0 , 1 } ,
{ N_ ( " List of Channels... " ) , menu_chanlist , GTK_STOCK_INDEX , M_MENUITEM , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
# define AWAY_OFFSET (39)
{ N_ ( " Marked Away " ) , menu_away , 0 , M_MENUTOG , MENU_ID_AWAY , 0 , 1 , GDK_a } ,
{ N_ ( " _Usermenu " ) , 0 , 0 , M_NEWMENU , MENU_ID_USERMENU , 0 , 1 } , /* 40 */
{ N_ ( " S_ettings " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } ,
{ N_ ( " _Preferences " ) , menu_settings , GTK_STOCK_PREFERENCES , M_MENUSTOCK , 0 , 0 , 1 } ,
{ N_ ( " Advanced " ) , 0 , GTK_STOCK_JUSTIFY_LEFT , M_MENUSUB , 0 , 0 , 1 } ,
{ N_ ( " Auto Replace... " ) , menu_rpopup , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " CTCP Replies... " ) , menu_ctcpguiopen , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Dialog Buttons... " ) , menu_dlgbuttons , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Keyboard Shortcuts... " ) , menu_keypopup , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Text Events... " ) , menu_evtpopup , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " URL Handlers... " ) , menu_urlhandlers , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " User Commands... " ) , menu_usercommands , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Userlist Buttons... " ) , menu_ulbuttons , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Userlist Popup... " ) , menu_ulpopup , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_END , 0 , 0 , 0 } , /* 53 */
2011-11-23 07:40:18 -05:00
/* {N_("Save Settings to Disk"), menu_saveconf, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0, 1}, don't use this, a /set auto-save approach will be added instead */
2011-11-23 07:13:58 -05:00
2011-02-23 22:14:30 -05:00
{ N_ ( " _Window " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } ,
{ N_ ( " Ban List... " ) , menu_banlist , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Character Chart... " ) , ascii_open , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Direct Chat... " ) , menu_dcc_chat_win , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " File Transfers... " ) , menu_dcc_win , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Friends List... " ) , notify_opengui , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Ignore List... " ) , ignore_gui_open , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Plugins and Scripts... " ) , menu_pluginlist , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ N_ ( " Raw Log... " ) , menu_rawlog , 0 , M_MENUITEM , 0 , 0 , 1 } , /* 62 */
{ N_ ( " URL Grabber... " ) , url_opengui , 0 , M_MENUITEM , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_SEP , 0 , 0 , 0 } ,
{ N_ ( " Reset Marker Line " ) , menu_resetmarker , 0 , M_MENUITEM , 0 , 0 , 1 , GDK_m } ,
2011-02-28 12:59:32 -05:00
{ N_ ( " _Copy Selection " ) , menu_copy_selection , 0 , M_MENUITEM , 0 , 0 , 1 , GDK_C } ,
2011-02-23 22:14:30 -05:00
{ N_ ( " C_lear Text " ) , menu_flushbuffer , GTK_STOCK_CLEAR , M_MENUSTOCK , 0 , 0 , 1 , GDK_l } ,
2011-11-23 07:40:18 -05:00
# define SEARCH_OFFSET 68
2011-02-23 22:14:30 -05:00
{ N_ ( " Search Text... " ) , menu_search , GTK_STOCK_FIND , M_MENUSTOCK , 0 , 0 , 1 , GDK_f } ,
{ N_ ( " Save Text... " ) , menu_savebuffer , GTK_STOCK_SAVE , M_MENUSTOCK , 0 , 0 , 1 } ,
2011-11-23 07:40:18 -05:00
{ N_ ( " _Help " ) , 0 , 0 , M_NEWMENU , 0 , 0 , 1 } , /* 70 */
2011-02-23 22:14:30 -05:00
{ N_ ( " _Contents " ) , menu_docs , GTK_STOCK_HELP , M_MENUSTOCK , 0 , 0 , 1 , GDK_F1 } ,
#if 0
{ N_ ( " Check for updates " ) , menu_update , 0 , M_MENUITEM , 0 , 1 } ,
# endif
{ N_ ( " _About " ) , menu_about , GTK_STOCK_ABOUT , M_MENUSTOCK , 0 , 0 , 1 } ,
{ 0 , 0 , 0 , M_END , 0 , 0 , 0 } ,
} ;
GtkWidget *
create_icon_menu ( char * labeltext , void * stock_name , int is_stock )
{
GtkWidget * item , * img ;
if ( is_stock )
img = gtk_image_new_from_stock ( stock_name , GTK_ICON_SIZE_MENU ) ;
else
img = gtk_image_new_from_pixbuf ( * ( ( GdkPixbuf * * ) stock_name ) ) ;
item = gtk_image_menu_item_new_with_mnemonic ( labeltext ) ;
gtk_image_menu_item_set_image ( ( GtkImageMenuItem * ) item , img ) ;
gtk_widget_show ( img ) ;
return item ;
}
# if GTK_CHECK_VERSION(2,4,0)
/* Override the default GTK2.4 handler, which would make menu
bindings not work when the menu - bar is hidden . */
static gboolean
menu_canacaccel ( GtkWidget * widget , guint signal_id , gpointer user_data )
{
/* GTK2.2 behaviour */
# if GTK_CHECK_VERSION(2,20,0)
return gtk_widget_is_sensitive ( widget ) ;
# else
return GTK_WIDGET_IS_SENSITIVE ( widget ) ;
# endif
}
# endif
/* === STUFF FOR /MENU === */
static GtkMenuItem *
menu_find_item ( GtkWidget * menu , char * name )
{
GList * items = ( ( GtkMenuShell * ) menu ) - > children ;
GtkMenuItem * item ;
GtkWidget * child ;
const char * labeltext ;
while ( items )
{
item = items - > data ;
child = GTK_BIN ( item ) - > child ;
if ( child ) /* separators arn't labels, skip them */
{
labeltext = g_object_get_data ( G_OBJECT ( item ) , " name " ) ;
if ( ! labeltext )
labeltext = gtk_label_get_text ( GTK_LABEL ( child ) ) ;
if ( ! menu_streq ( labeltext , name , 1 ) )
return item ;
} else if ( name = = NULL )
{
return item ;
}
items = items - > next ;
}
return NULL ;
}
static GtkWidget *
menu_find_path ( GtkWidget * menu , char * path )
{
GtkMenuItem * item ;
char * s ;
char name [ 128 ] ;
int len ;
/* grab the next part of the path */
s = strchr ( path , ' / ' ) ;
len = s - path ;
if ( ! s )
len = strlen ( path ) ;
len = MIN ( len , sizeof ( name ) - 1 ) ;
memcpy ( name , path , len ) ;
name [ len ] = 0 ;
item = menu_find_item ( menu , name ) ;
if ( ! item )
return NULL ;
menu = gtk_menu_item_get_submenu ( item ) ;
if ( ! menu )
return NULL ;
path + = len ;
if ( * path = = 0 )
return menu ;
return menu_find_path ( menu , path + 1 ) ;
}
static GtkWidget *
menu_find ( GtkWidget * menu , char * path , char * label )
{
GtkWidget * item = NULL ;
if ( path [ 0 ] ! = 0 )
menu = menu_find_path ( menu , path ) ;
if ( menu )
item = ( GtkWidget * ) menu_find_item ( menu , label ) ;
return item ;
}
static void
menu_foreach_gui ( menu_entry * me , void ( * callback ) ( GtkWidget * , menu_entry * , char * ) )
{
GSList * list = sess_list ;
int tabdone = FALSE ;
session * sess ;
if ( ! me - > is_main )
return ; /* not main menu */
while ( list )
{
sess = list - > data ;
/* do it only once for tab sessions, since they share a GUI */
if ( ! sess - > gui - > is_tab | | ! tabdone )
{
callback ( sess - > gui - > menu , me , NULL ) ;
if ( sess - > gui - > is_tab )
tabdone = TRUE ;
}
list = list - > next ;
}
}
static void
menu_update_cb ( GtkWidget * menu , menu_entry * me , char * target )
{
GtkWidget * item ;
item = menu_find ( menu , me - > path , me - > label ) ;
if ( item )
{
gtk_widget_set_sensitive ( item , me - > enable ) ;
/* must do it without triggering the callback */
if ( GTK_IS_CHECK_MENU_ITEM ( item ) )
GTK_CHECK_MENU_ITEM ( item ) - > active = me - > state ;
}
}
/* radio state changed via mouse click */
static void
menu_radio_cb ( GtkCheckMenuItem * item , menu_entry * me )
{
me - > state = 0 ;
if ( item - > active )
me - > state = 1 ;
/* update the state, incase this was changed via right-click. */
/* This will update all other windows and menu bars */
menu_foreach_gui ( me , menu_update_cb ) ;
if ( me - > state & & me - > cmd )
handle_command ( current_sess , me - > cmd , FALSE ) ;
}
/* toggle state changed via mouse click */
static void
menu_toggle_cb ( GtkCheckMenuItem * item , menu_entry * me )
{
me - > state = 0 ;
if ( item - > active )
me - > state = 1 ;
/* update the state, incase this was changed via right-click. */
/* This will update all other windows and menu bars */
menu_foreach_gui ( me , menu_update_cb ) ;
if ( me - > state )
handle_command ( current_sess , me - > cmd , FALSE ) ;
else
handle_command ( current_sess , me - > ucmd , FALSE ) ;
}
static GtkWidget *
menu_radio_item ( char * label , GtkWidget * menu , void * callback , void * userdata ,
int state , char * groupname )
{
GtkWidget * item ;
GtkMenuItem * parent ;
GSList * grouplist = NULL ;
parent = menu_find_item ( menu , groupname ) ;
if ( parent )
grouplist = gtk_radio_menu_item_get_group ( ( GtkRadioMenuItem * ) parent ) ;
item = gtk_radio_menu_item_new_with_label ( grouplist , label ) ;
gtk_check_menu_item_set_active ( ( GtkCheckMenuItem * ) item , state ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( callback ) , userdata ) ;
gtk_widget_show ( item ) ;
return item ;
}
static void
menu_reorder ( GtkMenu * menu , GtkWidget * item , int pos )
{
if ( pos = = 0xffff ) /* outbound.c uses this default */
return ;
if ( pos < 0 ) /* position offset from end/bottom */
gtk_menu_reorder_child ( menu , item , ( g_list_length ( GTK_MENU_SHELL ( menu ) - > children ) + pos ) - 1 ) ;
else
gtk_menu_reorder_child ( menu , item , pos ) ;
}
static GtkWidget *
menu_add_radio ( GtkWidget * menu , menu_entry * me )
{
GtkWidget * item = NULL ;
char * path = me - > path + me - > root_offset ;
if ( path [ 0 ] ! = 0 )
menu = menu_find_path ( menu , path ) ;
if ( menu )
{
item = menu_radio_item ( me - > label , menu , menu_radio_cb , me , me - > state , me - > group ) ;
menu_reorder ( GTK_MENU ( menu ) , item , me - > pos ) ;
}
return item ;
}
static GtkWidget *
menu_add_toggle ( GtkWidget * menu , menu_entry * me )
{
GtkWidget * item = NULL ;
char * path = me - > path + me - > root_offset ;
if ( path [ 0 ] ! = 0 )
menu = menu_find_path ( menu , path ) ;
if ( menu )
{
item = menu_toggle_item ( me - > label , menu , menu_toggle_cb , me , me - > state ) ;
menu_reorder ( GTK_MENU ( menu ) , item , me - > pos ) ;
}
return item ;
}
static GtkWidget *
menu_add_item ( GtkWidget * menu , menu_entry * me , char * target )
{
GtkWidget * item = NULL ;
char * path = me - > path + me - > root_offset ;
if ( path [ 0 ] ! = 0 )
menu = menu_find_path ( menu , path ) ;
if ( menu )
{
item = menu_quick_item ( me - > cmd , me - > label , menu , me - > markup ? XCMENU_MARKUP | XCMENU_MNEMONIC : XCMENU_MNEMONIC , target , me - > icon ) ;
menu_reorder ( GTK_MENU ( menu ) , item , me - > pos ) ;
}
return item ;
}
static GtkWidget *
menu_add_sub ( GtkWidget * menu , menu_entry * me )
{
GtkWidget * item = NULL ;
char * path = me - > path + me - > root_offset ;
int pos ;
if ( path [ 0 ] ! = 0 )
menu = menu_find_path ( menu , path ) ;
if ( menu )
{
pos = me - > pos ;
if ( pos < 0 ) /* position offset from end/bottom */
pos = g_list_length ( GTK_MENU_SHELL ( menu ) - > children ) + pos ;
menu_quick_sub ( me - > label , menu , & item , me - > markup ? XCMENU_MARKUP | XCMENU_MNEMONIC : XCMENU_MNEMONIC , pos ) ;
}
return item ;
}
static void
menu_del_cb ( GtkWidget * menu , menu_entry * me , char * target )
{
GtkWidget * item = menu_find ( menu , me - > path + me - > root_offset , me - > label ) ;
if ( item )
gtk_widget_destroy ( item ) ;
}
static void
menu_add_cb ( GtkWidget * menu , menu_entry * me , char * target )
{
GtkWidget * item ;
GtkAccelGroup * accel_group ;
if ( me - > group ) /* have a group name? Must be a radio item */
item = menu_add_radio ( menu , me ) ;
else if ( me - > ucmd ) /* have unselect-cmd? Must be a toggle item */
item = menu_add_toggle ( menu , me ) ;
else if ( me - > cmd | | ! me - > label ) /* label=NULL for separators */
item = menu_add_item ( menu , me , target ) ;
else
item = menu_add_sub ( menu , me ) ;
if ( item )
{
gtk_widget_set_sensitive ( item , me - > enable ) ;
if ( me - > key )
{
accel_group = g_object_get_data ( G_OBJECT ( menu ) , " accel " ) ;
if ( accel_group ) /* popup menus don't have them */
gtk_widget_add_accelerator ( item , " activate " , accel_group , me - > key ,
me - > modifier , GTK_ACCEL_VISIBLE ) ;
}
}
}
char *
fe_menu_add ( menu_entry * me )
{
char * text ;
menu_foreach_gui ( me , menu_add_cb ) ;
if ( ! me - > markup )
return NULL ;
if ( ! pango_parse_markup ( me - > label , - 1 , 0 , NULL , & text , NULL , NULL ) )
return NULL ;
/* return the label with markup stripped */
return text ;
}
void
fe_menu_del ( menu_entry * me )
{
menu_foreach_gui ( me , menu_del_cb ) ;
}
void
fe_menu_update ( menu_entry * me )
{
menu_foreach_gui ( me , menu_update_cb ) ;
}
/* used to add custom menus to the right-click menu */
static void
menu_add_plugin_mainmenu_items ( GtkWidget * menu )
{
GSList * list ;
menu_entry * me ;
list = menu_list ; /* outbound.c */
while ( list )
{
me = list - > data ;
if ( me - > is_main )
menu_add_cb ( menu , me , NULL ) ;
list = list - > next ;
}
}
void
menu_add_plugin_items ( GtkWidget * menu , char * root , char * target )
{
GSList * list ;
menu_entry * me ;
list = menu_list ; /* outbound.c */
while ( list )
{
me = list - > data ;
if ( ! me - > is_main & & ! strncmp ( me - > path , root + 1 , root [ 0 ] ) )
menu_add_cb ( menu , me , target ) ;
list = list - > next ;
}
}
/* === END STUFF FOR /MENU === */
GtkWidget *
menu_create_main ( void * accel_group , int bar , int away , int toplevel ,
GtkWidget * * menu_widgets )
{
int i = 0 ;
GtkWidget * item ;
GtkWidget * menu = 0 ;
GtkWidget * menu_item = 0 ;
GtkWidget * menu_bar ;
GtkWidget * usermenu = 0 ;
GtkWidget * submenu = 0 ;
int close_mask = GDK_CONTROL_MASK ;
int away_mask = GDK_MOD1_MASK ;
char * key_theme = NULL ;
GtkSettings * settings ;
GSList * group = NULL ;
if ( bar )
menu_bar = gtk_menu_bar_new ( ) ;
else
menu_bar = gtk_menu_new ( ) ;
/* /MENU needs to know this later */
g_object_set_data ( G_OBJECT ( menu_bar ) , " accel " , accel_group ) ;
# if GTK_CHECK_VERSION(2,4,0)
g_signal_connect ( G_OBJECT ( menu_bar ) , " can-activate-accel " ,
G_CALLBACK ( menu_canacaccel ) , 0 ) ;
# endif
/* set the initial state of toggles */
mymenu [ MENUBAR_OFFSET ] . state = ! prefs . hidemenu ;
mymenu [ MENUBAR_OFFSET + 1 ] . state = prefs . topicbar ;
mymenu [ MENUBAR_OFFSET + 2 ] . state = ! prefs . hideuserlist ;
mymenu [ MENUBAR_OFFSET + 3 ] . state = prefs . userlistbuttons ;
mymenu [ MENUBAR_OFFSET + 4 ] . state = prefs . chanmodebuttons ;
mymenu [ AWAY_OFFSET ] . state = away ;
switch ( prefs . tab_layout )
{
case 0 :
mymenu [ TABS_OFFSET ] . state = 1 ;
mymenu [ TABS_OFFSET + 1 ] . state = 0 ;
break ;
default :
mymenu [ TABS_OFFSET ] . state = 0 ;
mymenu [ TABS_OFFSET + 1 ] . state = 1 ;
}
mymenu [ METRE_OFFSET ] . state = 0 ;
mymenu [ METRE_OFFSET + 1 ] . state = 0 ;
mymenu [ METRE_OFFSET + 2 ] . state = 0 ;
mymenu [ METRE_OFFSET + 3 ] . state = 0 ;
switch ( prefs . lagometer )
{
case 0 :
mymenu [ METRE_OFFSET ] . state = 1 ;
break ;
case 1 :
mymenu [ METRE_OFFSET + 1 ] . state = 1 ;
break ;
case 2 :
mymenu [ METRE_OFFSET + 2 ] . state = 1 ;
break ;
default :
mymenu [ METRE_OFFSET + 3 ] . state = 1 ;
}
/* change Close binding to ctrl-shift-w when using emacs keys */
settings = gtk_widget_get_settings ( menu_bar ) ;
if ( settings )
{
g_object_get ( settings , " gtk-key-theme-name " , & key_theme , NULL ) ;
if ( key_theme )
{
if ( ! strcasecmp ( key_theme , " Emacs " ) )
{
close_mask = GDK_SHIFT_MASK | GDK_CONTROL_MASK ;
mymenu [ SEARCH_OFFSET ] . key = 0 ;
}
g_free ( key_theme ) ;
}
}
/* Away binding to ctrl-alt-a if the _Help menu conflicts (FR/PT/IT) */
{
char * help = _ ( " _Help " ) ;
char * under = strchr ( help , ' _ ' ) ;
if ( under & & ( under [ 1 ] = = ' a ' | | under [ 1 ] = = ' A ' ) )
away_mask = GDK_MOD1_MASK | GDK_CONTROL_MASK ;
}
if ( ! toplevel )
{
mymenu [ DETACH_OFFSET ] . text = N_ ( " _Detach " ) ;
mymenu [ CLOSE_OFFSET ] . text = N_ ( " _Close " ) ;
}
else
{
mymenu [ DETACH_OFFSET ] . text = N_ ( " _Attach " ) ;
mymenu [ CLOSE_OFFSET ] . text = N_ ( " _Close " ) ;
}
while ( 1 )
{
item = NULL ;
if ( mymenu [ i ] . id = = MENU_ID_USERMENU & & ! prefs . gui_usermenu )
{
i + + ;
continue ;
}
switch ( mymenu [ i ] . type )
{
case M_NEWMENU :
if ( menu )
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( menu_item ) , menu ) ;
item = menu = gtk_menu_new ( ) ;
if ( mymenu [ i ] . id = = MENU_ID_USERMENU )
usermenu = menu ;
menu_item = gtk_menu_item_new_with_mnemonic ( _ ( mymenu [ i ] . text ) ) ;
/* record the English name for /menu */
g_object_set_data ( G_OBJECT ( menu_item ) , " name " , mymenu [ i ] . text ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu_bar ) , menu_item ) ;
gtk_widget_show ( menu_item ) ;
break ;
case M_MENUPIX :
item = create_icon_menu ( _ ( mymenu [ i ] . text ) , mymenu [ i ] . image , FALSE ) ;
goto normalitem ;
case M_MENUSTOCK :
item = create_icon_menu ( _ ( mymenu [ i ] . text ) , mymenu [ i ] . image , TRUE ) ;
goto normalitem ;
case M_MENUITEM :
item = gtk_menu_item_new_with_mnemonic ( _ ( mymenu [ i ] . text ) ) ;
normalitem :
if ( mymenu [ i ] . key ! = 0 )
gtk_widget_add_accelerator ( item , " activate " , accel_group ,
mymenu [ i ] . key ,
mymenu [ i ] . key = = GDK_F1 ? 0 :
mymenu [ i ] . key = = GDK_w ? close_mask :
2011-02-28 12:59:32 -05:00
( g_ascii_isupper ( mymenu [ i ] . key ) ) ?
GDK_SHIFT_MASK | GDK_CONTROL_MASK :
GDK_CONTROL_MASK ,
2011-02-23 22:14:30 -05:00
GTK_ACCEL_VISIBLE ) ;
if ( mymenu [ i ] . callback )
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( mymenu [ i ] . callback ) , 0 ) ;
if ( submenu )
gtk_menu_shell_append ( GTK_MENU_SHELL ( submenu ) , item ) ;
else
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
gtk_widget_show ( item ) ;
break ;
case M_MENUTOG :
item = gtk_check_menu_item_new_with_mnemonic ( _ ( mymenu [ i ] . text ) ) ;
togitem :
/* must avoid callback for Radio buttons */
GTK_CHECK_MENU_ITEM ( item ) - > active = mymenu [ i ] . state ;
/*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
mymenu [ i ] . state ) ; */
if ( mymenu [ i ] . key ! = 0 )
gtk_widget_add_accelerator ( item , " activate " , accel_group ,
mymenu [ i ] . key , mymenu [ i ] . id = = MENU_ID_AWAY ?
away_mask : GDK_CONTROL_MASK , GTK_ACCEL_VISIBLE ) ;
if ( mymenu [ i ] . callback )
g_signal_connect ( G_OBJECT ( item ) , " toggled " ,
G_CALLBACK ( mymenu [ i ] . callback ) , 0 ) ;
if ( submenu )
gtk_menu_shell_append ( GTK_MENU_SHELL ( submenu ) , item ) ;
else
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
gtk_widget_show ( item ) ;
gtk_widget_set_sensitive ( item , mymenu [ i ] . sensitive ) ;
break ;
case M_MENURADIO :
item = gtk_radio_menu_item_new_with_mnemonic ( group , _ ( mymenu [ i ] . text ) ) ;
group = gtk_radio_menu_item_get_group ( GTK_RADIO_MENU_ITEM ( item ) ) ;
goto togitem ;
case M_SEP :
item = gtk_menu_item_new ( ) ;
gtk_widget_set_sensitive ( item , FALSE ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
gtk_widget_show ( item ) ;
break ;
case M_MENUSUB :
group = NULL ;
submenu = gtk_menu_new ( ) ;
item = create_icon_menu ( _ ( mymenu [ i ] . text ) , mymenu [ i ] . image , TRUE ) ;
/* record the English name for /menu */
g_object_set_data ( G_OBJECT ( item ) , " name " , mymenu [ i ] . text ) ;
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( item ) , submenu ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
gtk_widget_show ( item ) ;
break ;
/*case M_END:*/ default :
if ( ! submenu )
{
if ( menu )
{
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( menu_item ) , menu ) ;
menu_add_plugin_mainmenu_items ( menu_bar ) ;
}
if ( usermenu )
usermenu_create ( usermenu ) ;
return ( menu_bar ) ;
}
submenu = NULL ;
}
/* record this GtkWidget * so it's state might be changed later */
if ( mymenu [ i ] . id ! = 0 & & menu_widgets )
/* this ends up in sess->gui->menu_item[MENU_ID_XXX] */
menu_widgets [ mymenu [ i ] . id ] = item ;
i + + ;
}
}