mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-11 09:20:19 +00:00
Merge pull request #287 from ZoiteChat/customize-all-keybinds
Customize all keybinds
This commit is contained in:
@@ -518,6 +518,7 @@ const struct prefs vars[] =
|
||||
{"irc_conf_mode", P_OFFINT (hex_irc_conf_mode), TYPE_BOOL},
|
||||
{"irc_extra_hilight", P_OFFSET (hex_irc_extra_hilight), TYPE_STR},
|
||||
{"irc_hide_nickchange", P_OFFINT (hex_irc_hide_nickchange), TYPE_BOOL},
|
||||
{"irc_hide_join_part_hostmask", P_OFFINT (hex_irc_hide_join_part_hostmask), TYPE_BOOL},
|
||||
{"irc_hide_version", P_OFFINT (hex_irc_hide_version), TYPE_BOOL},
|
||||
{"irc_hidehost", P_OFFINT (hex_irc_hidehost), TYPE_BOOL},
|
||||
{"irc_id_ntext", P_OFFSET (hex_irc_id_ntext), TYPE_STR},
|
||||
|
||||
@@ -1809,12 +1809,97 @@ format_event (session *sess, int index, char **args, char *o, gsize sizeofo, uns
|
||||
o[0] = 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
text_event_without_hostmask_format (const char *format, int host_arg)
|
||||
{
|
||||
char token[3];
|
||||
const char *arg;
|
||||
const char *open;
|
||||
const char *close;
|
||||
const char *start;
|
||||
char *out;
|
||||
gsize prefix_len;
|
||||
|
||||
g_snprintf (token, sizeof (token), "$%d", host_arg);
|
||||
arg = strstr (format, token);
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
open = arg;
|
||||
while (open > format && *open != '(' && *open != '\n')
|
||||
open--;
|
||||
|
||||
close = arg + strlen (token);
|
||||
while (*close && *close != ')' && *close != '\n')
|
||||
close++;
|
||||
|
||||
if (*open != '(' || *close != ')')
|
||||
return NULL;
|
||||
|
||||
start = open;
|
||||
if (start > format && start[-1] == ' ')
|
||||
start--;
|
||||
|
||||
prefix_len = start - format;
|
||||
out = g_malloc (prefix_len + strlen (close + 1) + 1);
|
||||
memcpy (out, format, prefix_len);
|
||||
strcpy (out + prefix_len, close + 1);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
display_event_string (session *sess, int event, char **args, char *format,
|
||||
unsigned int stripcolor_args, time_t timestamp)
|
||||
{
|
||||
char *compiled;
|
||||
char *saved;
|
||||
char o[4096];
|
||||
int max_arg;
|
||||
|
||||
if (pevt_build_string (format, &compiled, &max_arg) != 0)
|
||||
return;
|
||||
|
||||
saved = pntevts[event];
|
||||
pntevts[event] = compiled;
|
||||
format_event (sess, event, args, o, sizeof (o), stripcolor_args);
|
||||
pntevts[event] = saved;
|
||||
g_free (compiled);
|
||||
|
||||
if (o[0])
|
||||
PrintTextTimeStamp (sess, o, timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
display_event (session *sess, int event, char **args,
|
||||
unsigned int stripcolor_args, time_t timestamp)
|
||||
{
|
||||
char o[4096];
|
||||
format_event (sess, event, args, o, sizeof (o), stripcolor_args);
|
||||
char *format;
|
||||
char *host;
|
||||
int host_arg;
|
||||
|
||||
if (prefs.hex_irc_hide_join_part_hostmask &&
|
||||
(event == XP_TE_JOIN || event == XP_TE_PART || event == XP_TE_PARTREASON))
|
||||
{
|
||||
host_arg = event == XP_TE_JOIN ? 3 : 2;
|
||||
format = text_event_without_hostmask_format (pntevts_text[event], host_arg);
|
||||
if (format)
|
||||
{
|
||||
display_event_string (sess, event, args, format, stripcolor_args, timestamp);
|
||||
g_free (format);
|
||||
return;
|
||||
}
|
||||
|
||||
host = args[host_arg];
|
||||
args[host_arg] = "";
|
||||
format_event (sess, event, args, o, sizeof (o), stripcolor_args);
|
||||
args[host_arg] = host;
|
||||
}
|
||||
else
|
||||
{
|
||||
format_event (sess, event, args, o, sizeof (o), stripcolor_args);
|
||||
}
|
||||
|
||||
if (o[0])
|
||||
PrintTextTimeStamp (sess, o, timestamp);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,7 @@ struct zoitechatprefs
|
||||
unsigned int hex_irc_conf_mode;
|
||||
unsigned int hex_irc_hidehost;
|
||||
unsigned int hex_irc_hide_nickchange;
|
||||
unsigned int hex_irc_hide_join_part_hostmask;
|
||||
unsigned int hex_irc_hide_version;
|
||||
unsigned int hex_irc_invisible;
|
||||
unsigned int hex_irc_logging;
|
||||
|
||||
@@ -80,7 +80,7 @@ void key_action_tab_clean (void);
|
||||
*/
|
||||
|
||||
/* Remember that the *number* of actions is this *plus* 1 --AGL */
|
||||
#define KEY_MAX_ACTIONS 14
|
||||
#define KEY_MAX_ACTIONS 16
|
||||
|
||||
struct key_binding
|
||||
{
|
||||
@@ -142,6 +142,13 @@ static int key_action_move_tab_family_right (GtkWidget * wid, GdkEventKey * evt,
|
||||
static int key_action_put_history (GtkWidget * wid, GdkEventKey * evt,
|
||||
char *d1, char *d2,
|
||||
struct session *sess);
|
||||
static int key_action_menu_shortcut (GtkWidget * wid, GdkEventKey * evt,
|
||||
char *d1, char *d2,
|
||||
struct session *sess);
|
||||
static int key_action_reopen_closed_tab (GtkWidget * wid, GdkEventKey * evt,
|
||||
char *d1, char *d2,
|
||||
struct session *sess);
|
||||
|
||||
|
||||
static GSList *keybind_list = NULL;
|
||||
|
||||
@@ -287,6 +294,10 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
|
||||
N_("This command moves the current tab family to the right")},
|
||||
{key_action_put_history, "Push input line into history",
|
||||
N_("Push input line into history but doesn't send to server")},
|
||||
{key_action_menu_shortcut, "Menu Shortcut",
|
||||
N_("Runs one of the built-in menu shortcuts. Set Data 1 to: network-list, new-server-tab, new-server-window, close, quit, menu-toggle, user-list-toggle, fullscreen-toggle, away-toggle, reset-marker, move-marker, copy-selection, search-text, search-next, search-previous or contents.")},
|
||||
{key_action_reopen_closed_tab, "Reopen Closed Tab",
|
||||
N_("Reopens the most recently closed channel tab")},
|
||||
};
|
||||
|
||||
#define default_kb_cfg \
|
||||
@@ -329,7 +340,86 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
|
||||
"ACCEL=<Alt>Right\nMove front tab right\nD1!\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>Page_Up\nMove tab family left\nD1!\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>Page_Down\nMove tab family right\nD1!\nD2!\n\n"\
|
||||
"ACCEL=F9\nRun Command\nD1:/GUI MENU TOGGLE\nD2!\n\n"
|
||||
"ACCEL=<Primary>s\nMenu Shortcut\nD1:network-list\nD2!\n\n"\
|
||||
"ACCEL=<Primary>t\nMenu Shortcut\nD1:new-server-tab\nD2!\n\n"\
|
||||
"ACCEL=<Primary>n\nMenu Shortcut\nD1:new-server-window\nD2!\n\n"\
|
||||
"ACCEL=<Primary>w\nMenu Shortcut\nD1:close\nD2!\n\n"\
|
||||
"ACCEL=<Primary>q\nMenu Shortcut\nD1:quit\nD2!\n\n"\
|
||||
"ACCEL=<Primary>F9\nMenu Shortcut\nD1:menu-toggle\nD2!\n\n"\
|
||||
"ACCEL=F7\nMenu Shortcut\nD1:user-list-toggle\nD2!\n\n"\
|
||||
"ACCEL=F11\nMenu Shortcut\nD1:fullscreen-toggle\nD2!\n\n"\
|
||||
"ACCEL=<Alt>a\nMenu Shortcut\nD1:away-toggle\nD2!\n\n"\
|
||||
"ACCEL=<Primary>m\nMenu Shortcut\nD1:reset-marker\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>M\nMenu Shortcut\nD1:move-marker\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>C\nMenu Shortcut\nD1:copy-selection\nD2!\n\n"\
|
||||
"ACCEL=<Primary>f\nMenu Shortcut\nD1:search-text\nD2!\n\n"\
|
||||
"ACCEL=<Primary>g\nMenu Shortcut\nD1:search-next\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>G\nMenu Shortcut\nD1:search-previous\nD2!\n\n"\
|
||||
"ACCEL=F1\nMenu Shortcut\nD1:contents\nD2!\n\n"\
|
||||
"ACCEL=<Primary><Shift>T\nReopen Closed Tab\nD1!\nD2!\n\n"
|
||||
|
||||
static gboolean
|
||||
key_builtin_data_match (char *line, char *data)
|
||||
{
|
||||
if (line[2] == '!')
|
||||
return data == NULL || data[0] == 0;
|
||||
|
||||
if (line[2] == ':')
|
||||
return !strcmp (&line[3], data ? data : "");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
key_binding_is_builtin (struct key_binding *kb)
|
||||
{
|
||||
char *buf, *ibuf;
|
||||
char *action;
|
||||
int pnt = 0;
|
||||
int state = 0;
|
||||
gboolean match = FALSE;
|
||||
gboolean d1_match = FALSE;
|
||||
off_t size;
|
||||
|
||||
if (kb->action < 0 || kb->action > KEY_MAX_ACTIONS)
|
||||
return FALSE;
|
||||
|
||||
action = key_actions[kb->action].name;
|
||||
ibuf = g_strdup (default_kb_cfg);
|
||||
size = strlen (default_kb_cfg);
|
||||
|
||||
while (buf_get_line (ibuf, &buf, &pnt, size))
|
||||
{
|
||||
if (strlen (buf) == 0)
|
||||
continue;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
match = !strcmp (buf, action);
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
d1_match = match && key_builtin_data_match (buf, kb->data1);
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (d1_match && key_builtin_data_match (buf, kb->data2))
|
||||
{
|
||||
g_free (ibuf);
|
||||
return TRUE;
|
||||
}
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (ibuf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
key_init ()
|
||||
@@ -443,28 +533,6 @@ key_handle_key_press (GtkWidget *wid, GdkEventKey *evt, session *sess)
|
||||
if (!list)
|
||||
return FALSE;
|
||||
current_sess = sess;
|
||||
if ((evt->state & GDK_CONTROL_MASK) &&
|
||||
!(evt->state & (GDK_MOD1_MASK | GDK_META_MASK)))
|
||||
{
|
||||
if (!(evt->state & GDK_SHIFT_MASK) &&
|
||||
(evt->keyval == GDK_KEY_w || evt->keyval == GDK_KEY_W))
|
||||
{
|
||||
if (sess->type == SESS_CHANNEL)
|
||||
{
|
||||
fe_close_window (sess);
|
||||
g_signal_stop_emission_by_name (G_OBJECT (wid), "key-press-event");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((evt->state & GDK_SHIFT_MASK) &&
|
||||
(evt->keyval == GDK_KEY_t || evt->keyval == GDK_KEY_T))
|
||||
{
|
||||
mg_reopen_closed_channel_tab ();
|
||||
g_signal_stop_emission_by_name (G_OBJECT (wid), "key-press-event");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin_emit_keypress (sess, evt->state, evt->keyval, gdk_keyval_to_unicode (evt->keyval)))
|
||||
return 1;
|
||||
|
||||
@@ -508,6 +576,31 @@ key_handle_key_press (GtkWidget *wid, GdkEventKey *evt, session *sess)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
key_get_menu_accel (const char *name, guint *keyval, GdkModifierType *mod)
|
||||
{
|
||||
struct key_binding *kb;
|
||||
GSList *list;
|
||||
|
||||
if (!name)
|
||||
return FALSE;
|
||||
|
||||
list = keybind_list;
|
||||
while (list)
|
||||
{
|
||||
kb = (struct key_binding*)list->data;
|
||||
if (kb->action >= 0 && kb->action <= KEY_MAX_ACTIONS && kb->keyval != 0 && !strcmp (key_actions[kb->action].name, "Menu Shortcut") && kb->data1 && !strcmp (kb->data1, name))
|
||||
{
|
||||
*keyval = kb->keyval;
|
||||
*mod = kb->mod;
|
||||
return TRUE;
|
||||
}
|
||||
list = g_slist_next (list);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* ***** GUI code here ******************* */
|
||||
|
||||
@@ -518,6 +611,7 @@ enum
|
||||
ACTION_COLUMN,
|
||||
D1_COLUMN,
|
||||
D2_COLUMN,
|
||||
CUSTOM_COLUMN,
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
@@ -642,16 +736,32 @@ key_dialog_keypress (GtkWidget *wid, GdkEventKey *evt, gpointer userdata)
|
||||
|
||||
if (handled)
|
||||
{
|
||||
gboolean custom1, custom2;
|
||||
|
||||
sel = gtk_tree_view_get_selection (view);
|
||||
gtk_tree_selection_get_selected (sel, &store, &iter1);
|
||||
if (!gtk_tree_selection_get_selected (sel, &store, &iter1))
|
||||
return FALSE;
|
||||
|
||||
path = gtk_tree_model_get_path (store, &iter1);
|
||||
if (delta == 1)
|
||||
gtk_tree_path_next (path);
|
||||
else
|
||||
gtk_tree_path_prev (path);
|
||||
gtk_tree_model_get_iter (store, &iter2, path);
|
||||
else if (!gtk_tree_path_prev (path))
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gtk_tree_model_get_iter (store, &iter2, path))
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
gtk_list_store_swap (GTK_LIST_STORE (store), &iter1, &iter2);
|
||||
gtk_tree_model_get (store, &iter1, CUSTOM_COLUMN, &custom1, -1);
|
||||
gtk_tree_model_get (store, &iter2, CUSTOM_COLUMN, &custom2, -1);
|
||||
if (custom1 && custom2)
|
||||
gtk_list_store_swap (GTK_LIST_STORE (store), &iter1, &iter2);
|
||||
}
|
||||
|
||||
return handled;
|
||||
@@ -663,14 +773,23 @@ key_dialog_selection_changed (GtkTreeSelection *sel, gpointer userdata)
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GtkXText *xtext;
|
||||
GtkWidget *delete_button;
|
||||
char *actiontext;
|
||||
gboolean custom;
|
||||
int action;
|
||||
|
||||
delete_button = g_object_get_data (G_OBJECT (key_dialog), "delete_button");
|
||||
if (!gtk_tree_selection_get_selected (sel, &model, &iter) || model == NULL)
|
||||
{
|
||||
if (delete_button)
|
||||
gtk_widget_set_sensitive (delete_button, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
xtext = GTK_XTEXT (g_object_get_data (G_OBJECT (key_dialog), "xtext"));
|
||||
gtk_tree_model_get (model, &iter, ACTION_COLUMN, &actiontext, -1);
|
||||
gtk_tree_model_get (model, &iter, ACTION_COLUMN, &actiontext, CUSTOM_COLUMN, &custom, -1);
|
||||
if (delete_button)
|
||||
gtk_widget_set_sensitive (delete_button, custom);
|
||||
|
||||
if (actiontext)
|
||||
{
|
||||
@@ -745,7 +864,10 @@ key_dialog_save (GtkWidget *wid, gpointer userdata)
|
||||
}
|
||||
|
||||
if (key_save_kbs () == 0)
|
||||
{
|
||||
menu_update_quit_accel ();
|
||||
key_dialog_close (wid, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -758,6 +880,7 @@ key_dialog_add (GtkWidget *wid, gpointer userdata)
|
||||
GtkTreePath *path;
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, CUSTOM_COLUMN, TRUE, -1);
|
||||
|
||||
/* make sure the new row is visible and selected */
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
|
||||
@@ -774,9 +897,14 @@ key_dialog_delete (GtkWidget *wid, gpointer userdata)
|
||||
GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
gboolean custom;
|
||||
|
||||
if (gtkutil_treeview_get_selected (view, &iter, -1))
|
||||
{
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, CUSTOM_COLUMN, &custom, -1);
|
||||
if (!custom)
|
||||
return;
|
||||
|
||||
/* delete this row, select next one */
|
||||
if (gtk_list_store_remove (store, &iter))
|
||||
{
|
||||
@@ -803,13 +931,13 @@ key_dialog_treeview_new (GtkWidget *box)
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
|
||||
|
||||
store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_STRING);
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
|
||||
g_return_val_if_fail (store != NULL, NULL);
|
||||
|
||||
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
||||
gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);
|
||||
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
|
||||
gtk_tree_view_set_reorderable (GTK_TREE_VIEW (view), TRUE);
|
||||
gtk_tree_view_set_reorderable (GTK_TREE_VIEW (view), FALSE);
|
||||
|
||||
g_signal_connect (G_OBJECT (view), "key-press-event",
|
||||
G_CALLBACK (key_dialog_keypress), NULL);
|
||||
@@ -879,7 +1007,8 @@ key_dialog_treeview_new (GtkWidget *box)
|
||||
G_CALLBACK (key_dialog_combo_changed), combostore);
|
||||
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), ACTION_COLUMN,
|
||||
"Action", render,
|
||||
"text", ACTION_COLUMN,
|
||||
"text", ACTION_COLUMN,
|
||||
"editable", CUSTOM_COLUMN,
|
||||
NULL);
|
||||
|
||||
render = gtk_cell_renderer_text_new ();
|
||||
@@ -890,6 +1019,7 @@ key_dialog_treeview_new (GtkWidget *box)
|
||||
GTK_TREE_VIEW (view), D1_COLUMN,
|
||||
"Data1", render,
|
||||
"text", D1_COLUMN,
|
||||
"editable", CUSTOM_COLUMN,
|
||||
NULL);
|
||||
|
||||
render = gtk_cell_renderer_text_new ();
|
||||
@@ -900,6 +1030,7 @@ key_dialog_treeview_new (GtkWidget *box)
|
||||
GTK_TREE_VIEW (view), D2_COLUMN,
|
||||
"Data2", render,
|
||||
"text", D2_COLUMN,
|
||||
"editable", CUSTOM_COLUMN,
|
||||
NULL);
|
||||
|
||||
col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), KEY_COLUMN);
|
||||
@@ -945,7 +1076,8 @@ key_dialog_load (GtkListStore *store)
|
||||
ACCEL_COLUMN, accel_text,
|
||||
ACTION_COLUMN, key_actions[kb->action].name,
|
||||
D1_COLUMN, kb->data1,
|
||||
D2_COLUMN, kb->data2, -1);
|
||||
D2_COLUMN, kb->data2,
|
||||
CUSTOM_COLUMN, !key_binding_is_builtin (kb), -1);
|
||||
|
||||
g_free (accel_text);
|
||||
g_free (label_text);
|
||||
@@ -958,7 +1090,7 @@ void
|
||||
key_dialog_show ()
|
||||
{
|
||||
GtkWidget *vbox, *box;
|
||||
GtkWidget *view, *xtext;
|
||||
GtkWidget *view, *xtext, *delete_button;
|
||||
GtkListStore *store;
|
||||
XTextColor xtext_palette[XTEXT_COLS];
|
||||
char buf[128];
|
||||
@@ -992,8 +1124,10 @@ key_dialog_show ()
|
||||
|
||||
gtkutil_button (box, ICON_FKEYS_NEW, NULL, key_dialog_add,
|
||||
NULL, _("Add"));
|
||||
gtkutil_button (box, ICON_FKEYS_DELETE, NULL, key_dialog_delete,
|
||||
delete_button = gtkutil_button (box, ICON_FKEYS_DELETE, NULL, key_dialog_delete,
|
||||
NULL, _("Delete"));
|
||||
g_object_set_data (G_OBJECT (key_dialog), "delete_button", delete_button);
|
||||
gtk_widget_set_sensitive (delete_button, FALSE);
|
||||
gtkutil_button (box, ICON_FKEYS_CANCEL, NULL, key_dialog_close,
|
||||
NULL, _("Cancel"));
|
||||
gtkutil_button (box, ICON_FKEYS_SAVE, NULL, key_dialog_save,
|
||||
@@ -1289,6 +1423,24 @@ key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
key_action_menu_shortcut (GtkWidget * wid, GdkEventKey * evt, char *d1,
|
||||
char *d2, struct session *sess)
|
||||
{
|
||||
if (menu_key_action (d1, evt->keyval, evt->state))
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
key_action_reopen_closed_tab (GtkWidget * wid, GdkEventKey * evt, char *d1,
|
||||
char *d2, struct session *sess)
|
||||
{
|
||||
mg_reopen_closed_channel_tab ();
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the given session is inside the main window. This predicate
|
||||
* is passed to lastact_getfirst() as a way to filter out detached sessions.
|
||||
|
||||
@@ -35,5 +35,6 @@ int key_handle_key_press (GtkWidget * wid, GdkEventKey * evt, session *sess);
|
||||
int key_action_insert (GtkWidget * wid, GdkEventKey * evt, char *d1, char *d2,
|
||||
session *sess);
|
||||
void key_check_replace_on_change (GtkEditable *editable, gpointer data);
|
||||
gboolean key_get_menu_accel (const char *name, guint *keyval, GdkModifierType *mod);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1755,44 +1755,6 @@ menu_change_layout (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
menu_update_quit_accel (void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = sess_list;
|
||||
while (list)
|
||||
{
|
||||
session *sess = list->data;
|
||||
session_gui *gui = sess->gui;
|
||||
GtkWidget *item;
|
||||
GtkAccelGroup *accel_group;
|
||||
int enabled;
|
||||
|
||||
list = list->next;
|
||||
if (!gui)
|
||||
continue;
|
||||
|
||||
item = gui->menu_item[MENU_ID_QUIT];
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
enabled = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "zc-ctrlq-enabled"));
|
||||
if (enabled == (int)prefs.hex_gui_ctrlq_quit)
|
||||
continue;
|
||||
|
||||
accel_group = g_object_get_data (G_OBJECT (item), "zc-quit-accel-group");
|
||||
if (!accel_group)
|
||||
continue;
|
||||
|
||||
if (prefs.hex_gui_ctrlq_quit)
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group, GDK_KEY_q, STATE_CTRL, GTK_ACCEL_VISIBLE);
|
||||
else
|
||||
gtk_widget_remove_accelerator (item, accel_group, GDK_KEY_q, STATE_CTRL);
|
||||
g_object_set_data (G_OBJECT (item), "zc-ctrlq-enabled", GINT_TO_POINTER (prefs.hex_gui_ctrlq_quit));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_layout_cb (GtkWidget *item, gpointer none)
|
||||
{
|
||||
@@ -1939,13 +1901,13 @@ menu_about (GtkWidget *wid, gpointer sess)
|
||||
|
||||
static struct mymenu mymenu[] = {
|
||||
{N_("_ZoiteChat"), 0, 0, M_NEWMENU, MENU_ID_ZOITECHAT, 0, 1},
|
||||
{N_("Network Li_st"), menu_open_server_list, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_s},
|
||||
{N_("Network Li_st"), menu_open_server_list, 0, M_MENUITEM, 0, 0, 1},
|
||||
{0, 0, 0, M_SEP, 0, 0, 0},
|
||||
|
||||
{N_("_New"), 0, 0, M_MENUSUB, 0, 0, 1},
|
||||
{N_("Server Tab"), menu_newserver_tab, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_t},
|
||||
{N_("Server Tab"), menu_newserver_tab, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Channel Tab"), menu_newchannel_tab, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Server Window"), menu_newserver_window, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_n},
|
||||
{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},
|
||||
@@ -1957,13 +1919,13 @@ static struct mymenu mymenu[] = {
|
||||
#define CLOSE_OFFSET (13)
|
||||
{0, menu_close, 0, M_MENUITEM, 0, 0, 1},
|
||||
{0, 0, 0, M_SEP, 0, 0, 0},
|
||||
{N_("_Quit"), menu_quit, 0, M_MENUITEM, MENU_ID_QUIT, 0, 1, GDK_KEY_q}, /* 15 */
|
||||
{N_("_Quit"), menu_quit, 0, M_MENUITEM, MENU_ID_QUIT, 0, 1}, /* 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_KEY_F9},
|
||||
{N_("_Menu Bar"), menu_bar_toggle_cb, 0, M_MENUTOG, MENU_ID_MENUBAR, 0, 1},
|
||||
{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_KEY_F7},
|
||||
{N_("_User List"), menu_userlist_toggle, 0, M_MENUTOG, MENU_ID_USERLIST, 0, 1},
|
||||
{N_("U_ser List 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},
|
||||
@@ -1980,7 +1942,7 @@ static struct mymenu mymenu[] = {
|
||||
{N_("Both"), menu_metres_both, 0, M_MENURADIO, 0, 0, 1},
|
||||
{0, 0, 0, M_END, 0, 0, 0}, /* 32 */
|
||||
{ 0, 0, 0, M_SEP, 0, 0, 0 },
|
||||
{N_ ("_Fullscreen"), menu_fullscreen_toggle, 0, M_MENUTOG, MENU_ID_FULLSCREEN, 0, 1, GDK_KEY_F11},
|
||||
{N_ ("_Fullscreen"), menu_fullscreen_toggle, 0, M_MENUTOG, MENU_ID_FULLSCREEN, 0, 1},
|
||||
|
||||
{N_("_Server"), 0, 0, M_NEWMENU, 0, 0, 1},
|
||||
{N_("_Disconnect"), menu_disconnect, 0, M_MENUITEM, MENU_ID_DISCONNECT, 0, 1},
|
||||
@@ -1989,7 +1951,7 @@ static struct mymenu mymenu[] = {
|
||||
{N_("Channel _List"), menu_chanlist, 0, M_MENUITEM, 0, 0, 1},
|
||||
{0, 0, 0, M_SEP, 0, 0, 0},
|
||||
#define AWAY_OFFSET (41)
|
||||
{N_("Marked _Away"), menu_away_toggle, 0, M_MENUITEM, MENU_ID_AWAY, 0, 1, GDK_KEY_a},
|
||||
{N_("Marked _Away"), menu_away_toggle, 0, M_MENUITEM, MENU_ID_AWAY, 0, 1},
|
||||
|
||||
{N_("_Usermenu"), 0, 0, M_NEWMENU, MENU_ID_USERMENU, 0, 1}, /* 40 */
|
||||
|
||||
@@ -2017,25 +1979,191 @@ static struct mymenu mymenu[] = {
|
||||
{N_("_Raw Log"), menu_rawlog, 0, M_MENUITEM, 0, 0, 1}, /* 61 */
|
||||
{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_KEY_m},
|
||||
{N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_M},
|
||||
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C},
|
||||
{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("C_lear Text"), menu_flushbuffer, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Save Text" ELLIPSIS), menu_savebuffer, 0, M_MENUITEM, 0, 0, 1},
|
||||
#define SEARCH_OFFSET (70)
|
||||
{N_("Search"), 0, 0, M_MENUSUB, 0, 0, 1},
|
||||
{N_("Search Text" ELLIPSIS), menu_search, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_f},
|
||||
{N_("Search Next" ), menu_search_next, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_g},
|
||||
{N_("Search Previous" ), menu_search_prev, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_G},
|
||||
{N_("Search Text" ELLIPSIS), menu_search, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Search Next" ), menu_search_next, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("Search Previous" ), menu_search_prev, 0, M_MENUITEM, 0, 0, 1},
|
||||
{0, 0, 0, M_END, 0, 0, 0},
|
||||
|
||||
{N_("_Help"), 0, 0, M_NEWMENU, 0, 0, 1}, /* 74 */
|
||||
{N_("_Contents"), menu_docs, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_F1},
|
||||
{N_("_Contents"), menu_docs, 0, M_MENUITEM, 0, 0, 1},
|
||||
{N_("_About"), menu_about, 0, M_MENUITEM, 0, 0, 1},
|
||||
|
||||
{0, 0, 0, M_END, 0, 0, 0},
|
||||
};
|
||||
|
||||
static const char *
|
||||
menu_get_key_action_name (int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
return "network-list";
|
||||
case 4:
|
||||
return "new-server-tab";
|
||||
case 6:
|
||||
return "new-server-window";
|
||||
case CLOSE_OFFSET:
|
||||
return "close";
|
||||
case 15:
|
||||
return "quit";
|
||||
case MENUBAR_OFFSET:
|
||||
return "menu-toggle";
|
||||
case MENUBAR_OFFSET + 2:
|
||||
return "user-list-toggle";
|
||||
case 34:
|
||||
return "fullscreen-toggle";
|
||||
case AWAY_OFFSET:
|
||||
return "away-toggle";
|
||||
case 65:
|
||||
return "reset-marker";
|
||||
case 66:
|
||||
return "move-marker";
|
||||
case 67:
|
||||
return "copy-selection";
|
||||
case SEARCH_OFFSET + 1:
|
||||
return "search-text";
|
||||
case SEARCH_OFFSET + 2:
|
||||
return "search-next";
|
||||
case SEARCH_OFFSET + 3:
|
||||
return "search-previous";
|
||||
case 75:
|
||||
return "contents";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_add_keybinding_accel (GtkWidget *item, GtkAccelGroup *accel_group, const char *name)
|
||||
{
|
||||
guint keyval;
|
||||
GdkModifierType mod;
|
||||
|
||||
if (!accel_group || !key_get_menu_accel (name, &keyval, &mod))
|
||||
return;
|
||||
|
||||
if (!strcmp (name, "quit") && !prefs.hex_gui_ctrlq_quit && keyval == GDK_KEY_q && mod == STATE_CTRL)
|
||||
return;
|
||||
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group, keyval, mod, GTK_ACCEL_VISIBLE);
|
||||
g_object_set_data (G_OBJECT (item), "zc-key-accel-key", GUINT_TO_POINTER (keyval));
|
||||
g_object_set_data (G_OBJECT (item), "zc-key-accel-mod", GUINT_TO_POINTER (mod));
|
||||
}
|
||||
|
||||
static void
|
||||
menu_refresh_keybinding_accels (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkAccelGroup *accel_group = data;
|
||||
const char *name;
|
||||
guint keyval;
|
||||
GdkModifierType mod;
|
||||
GtkWidget *submenu;
|
||||
GList *children, *list;
|
||||
|
||||
if (GTK_IS_MENU_ITEM (widget))
|
||||
{
|
||||
keyval = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget), "zc-key-accel-key"));
|
||||
mod = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget), "zc-key-accel-mod"));
|
||||
if (keyval != 0)
|
||||
{
|
||||
gtk_widget_remove_accelerator (widget, accel_group, keyval, mod);
|
||||
g_object_set_data (G_OBJECT (widget), "zc-key-accel-key", NULL);
|
||||
g_object_set_data (G_OBJECT (widget), "zc-key-accel-mod", NULL);
|
||||
}
|
||||
|
||||
name = g_object_get_data (G_OBJECT (widget), "zc-key-action");
|
||||
menu_add_keybinding_accel (widget, accel_group, name);
|
||||
|
||||
submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
|
||||
if (submenu)
|
||||
menu_refresh_keybinding_accels (submenu, data);
|
||||
}
|
||||
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
{
|
||||
children = gtk_container_get_children (GTK_CONTAINER (widget));
|
||||
for (list = children; list; list = g_list_next (list))
|
||||
menu_refresh_keybinding_accels (list->data, data);
|
||||
g_list_free (children);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
menu_update_quit_accel (void)
|
||||
{
|
||||
session *sess;
|
||||
GSList *list;
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
list = sess_list;
|
||||
while (list)
|
||||
{
|
||||
sess = list->data;
|
||||
if (sess && sess->gui && sess->gui->menu)
|
||||
{
|
||||
accel_group = g_object_get_data (G_OBJECT (sess->gui->menu), "accel");
|
||||
if (accel_group)
|
||||
menu_refresh_keybinding_accels (sess->gui->menu, accel_group);
|
||||
}
|
||||
list = g_slist_next (list);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
menu_key_action (const char *name, guint keyval, GdkModifierType state)
|
||||
{
|
||||
if (!name)
|
||||
return FALSE;
|
||||
|
||||
if (!strcmp (name, "network-list"))
|
||||
menu_open_server_list (NULL, NULL);
|
||||
else if (!strcmp (name, "new-server-tab"))
|
||||
menu_newserver_tab (NULL, NULL);
|
||||
else if (!strcmp (name, "new-server-window"))
|
||||
menu_newserver_window (NULL, NULL);
|
||||
else if (!strcmp (name, "close"))
|
||||
menu_close (NULL, NULL);
|
||||
else if (!strcmp (name, "quit"))
|
||||
{
|
||||
if (!prefs.hex_gui_ctrlq_quit && keyval == GDK_KEY_q && (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == STATE_CTRL)
|
||||
return FALSE;
|
||||
menu_quit (NULL, NULL);
|
||||
}
|
||||
else if (!strcmp (name, "menu-toggle"))
|
||||
menu_bar_toggle_cb ();
|
||||
else if (!strcmp (name, "user-list-toggle"))
|
||||
menu_userlist_toggle (NULL, NULL);
|
||||
else if (!strcmp (name, "fullscreen-toggle"))
|
||||
menu_fullscreen_toggle (NULL, NULL);
|
||||
else if (!strcmp (name, "away-toggle"))
|
||||
menu_away_toggle (NULL, NULL);
|
||||
else if (!strcmp (name, "reset-marker"))
|
||||
menu_resetmarker (NULL, NULL);
|
||||
else if (!strcmp (name, "move-marker"))
|
||||
menu_movetomarker (NULL, NULL);
|
||||
else if (!strcmp (name, "copy-selection"))
|
||||
menu_copy_selection (NULL, NULL);
|
||||
else if (!strcmp (name, "search-text"))
|
||||
menu_search ();
|
||||
else if (!strcmp (name, "search-next"))
|
||||
menu_search_next (NULL);
|
||||
else if (!strcmp (name, "search-previous"))
|
||||
menu_search_prev (NULL);
|
||||
else if (!strcmp (name, "contents"))
|
||||
menu_docs (NULL, NULL);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
menu_set_away (session_gui *gui, int away)
|
||||
{
|
||||
@@ -2641,6 +2769,8 @@ menu_create_main (void *accel_group, int bar, int away, int toplevel,
|
||||
case M_MENUITEM:
|
||||
item = gtk_menu_item_new_with_mnemonic (_(mymenu[i].text));
|
||||
normalitem:
|
||||
g_object_set_data (G_OBJECT (item), "zc-key-action", (gpointer) menu_get_key_action_name (i));
|
||||
menu_add_keybinding_accel (item, accel_group, menu_get_key_action_name (i));
|
||||
if (mymenu[i].key != 0 && !(mymenu[i].id == MENU_ID_QUIT && !prefs.hex_gui_ctrlq_quit))
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
mymenu[i].key,
|
||||
@@ -2669,6 +2799,8 @@ normalitem:
|
||||
case M_MENUTOG:
|
||||
item = gtk_check_menu_item_new_with_mnemonic (_(mymenu[i].text));
|
||||
togitem:
|
||||
g_object_set_data (G_OBJECT (item), "zc-key-action", (gpointer) menu_get_key_action_name (i));
|
||||
menu_add_keybinding_accel (item, accel_group, menu_get_key_action_name (i));
|
||||
/* must avoid callback for Radio buttons */
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), mymenu[i].state);
|
||||
/*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
|
||||
|
||||
@@ -39,6 +39,7 @@ void menu_bar_toggle (void);
|
||||
void menu_add_plugin_items (GtkWidget *menu, char *root, char *target);
|
||||
void menu_change_layout (void);
|
||||
void menu_update_quit_accel (void);
|
||||
gboolean menu_key_action (const char *name, guint keyval, GdkModifierType state);
|
||||
|
||||
void menu_set_away (session_gui *gui, int away);
|
||||
void menu_set_fullscreen (session_gui *gui, int fullscreen);
|
||||
|
||||
@@ -546,6 +546,7 @@ static const setting general_settings[] =
|
||||
{ST_TOGGLE, N_("WHOIS on notify"), P_OFFINTNL(hex_notify_whois_online), N_("Sends a /WHOIS when a user comes online in your notify list."), 0, 0},
|
||||
{ST_TOGGLE, N_("Hide join and part messages"), P_OFFINTNL(hex_irc_conf_mode), N_("Hide channel join/part messages by default."), 0, 0},
|
||||
{ST_TOGGLE, N_("Hide nick change messages"), P_OFFINTNL(hex_irc_hide_nickchange), 0, 0, 0},
|
||||
{ST_TOGGLE, N_("Hide hostmasks in join and part messages"), P_OFFINTNL(hex_irc_hide_join_part_hostmask), 0, 0, 0},
|
||||
{ST_TOGGLE, N_("Enable Ctrl+Q to quit"), P_OFFINTNL(hex_gui_ctrlq_quit), 0, 0, 0},
|
||||
|
||||
{ST_END, 0, 0, 0, 0, 0}
|
||||
|
||||
Reference in New Issue
Block a user