Moved shortcuts dialog into mooaccelprefs.*; modifying shortcuts using menu items does not work now.
parent
d48ba6b115
commit
6ccf23b775
File diff suppressed because it is too large
Load Diff
|
@ -11,43 +11,27 @@
|
|||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef __MOOACCEL_H__
|
||||
#define __MOOACCEL_H__
|
||||
#ifndef __MOO_ACCEL_H__
|
||||
#define __MOO_ACCEL_H__
|
||||
|
||||
#include <gtk/gtkactiongroup.h>
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void _moo_prefs_set_accel (const char *accel_path,
|
||||
const char *accel);
|
||||
const char *_moo_prefs_get_accel (const char *accel_path);
|
||||
void _moo_accel_register (const char *accel_path,
|
||||
const char *default_accel);
|
||||
|
||||
void _moo_set_accel (const char *accel_path,
|
||||
const char *accel);
|
||||
const char *_moo_get_accel (const char *accel_path);
|
||||
void _moo_set_default_accel (const char *accel_path,
|
||||
const char *accel);
|
||||
const char *_moo_get_default_accel (const char *accel_path);
|
||||
const char *_moo_get_accel (const char *accel_path);
|
||||
const char *_moo_get_default_accel (const char *accel_path);
|
||||
|
||||
char *_moo_get_accel_label (const char *accel);
|
||||
char *_moo_get_accel_label_by_path (const char *accel_path);
|
||||
void _moo_modify_acel (const char *accel_path,
|
||||
const char *new_accel);
|
||||
|
||||
gboolean _moo_accel_parse (const char *accel,
|
||||
guint *key,
|
||||
GdkModifierType *mods);
|
||||
char *_moo_accel_normalize (const char *accel);
|
||||
|
||||
void _moo_accel_label_set_action (GtkWidget *label,
|
||||
GtkAction *action);
|
||||
|
||||
|
||||
GtkWidget *_moo_accel_prefs_page_new (GtkActionGroup *group);
|
||||
GtkWidget *_moo_accel_prefs_dialog_new (GtkActionGroup *group);
|
||||
void _moo_accel_prefs_dialog_run (GtkActionGroup *group,
|
||||
GtkWidget *parent);
|
||||
char *_moo_accel_normalize (const char *accel);
|
||||
char *_moo_get_accel_label (const char *accel);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MOOACCEL_H__ */
|
||||
#endif /* __MOO_ACCEL_H__ */
|
||||
|
|
|
@ -38,26 +38,24 @@ enum {
|
|||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
||||
|
||||
static void moo_accel_button_class_init (MooAccelButtonClass *klass);
|
||||
static void moo_accel_button_init (MooAccelButton *button);
|
||||
static void moo_accel_button_finalize (GObject *object);
|
||||
static void moo_accel_button_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void moo_accel_button_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void moo_accel_button_finalize (GObject *object);
|
||||
static void moo_accel_button_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void moo_accel_button_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void moo_accel_button_clicked (MooAccelButton *button);
|
||||
static void moo_accel_button_clicked (GtkButton *button);
|
||||
|
||||
|
||||
G_DEFINE_TYPE(MooAccelButton, moo_accel_button, GTK_TYPE_BUTTON)
|
||||
G_DEFINE_TYPE (MooAccelButton, _moo_accel_button, GTK_TYPE_BUTTON)
|
||||
|
||||
|
||||
static void moo_accel_button_class_init (MooAccelButtonClass *klass)
|
||||
static void
|
||||
_moo_accel_button_class_init (MooAccelButtonClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
|
@ -65,6 +63,8 @@ static void moo_accel_button_class_init (MooAccelButtonClass *klass)
|
|||
gobject_class->set_property = moo_accel_button_set_property;
|
||||
gobject_class->finalize = moo_accel_button_finalize;
|
||||
|
||||
GTK_BUTTON_CLASS (klass)->clicked = moo_accel_button_clicked;
|
||||
|
||||
klass->accel_set = NULL;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
|
@ -96,41 +96,42 @@ static void moo_accel_button_class_init (MooAccelButtonClass *klass)
|
|||
}
|
||||
|
||||
|
||||
static void moo_accel_button_init (MooAccelButton *button)
|
||||
static void
|
||||
_moo_accel_button_init (MooAccelButton *button)
|
||||
{
|
||||
button->accel = NULL;
|
||||
button->title = NULL;
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (moo_accel_button_clicked), NULL);
|
||||
}
|
||||
|
||||
|
||||
static void moo_accel_button_finalize (GObject *object)
|
||||
static void
|
||||
moo_accel_button_finalize (GObject *object)
|
||||
{
|
||||
MooAccelButton *button = MOO_ACCEL_BUTTON (object);
|
||||
g_free (button->title);
|
||||
button->title = NULL;
|
||||
g_free (button->accel);
|
||||
button->accel = NULL;
|
||||
G_OBJECT_CLASS (moo_accel_button_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (_moo_accel_button_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void moo_accel_button_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
static void
|
||||
moo_accel_button_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MooAccelButton *button = MOO_ACCEL_BUTTON (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
moo_accel_button_set_title (button, g_value_get_string (value));
|
||||
_moo_accel_button_set_title (button, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_ACCEL:
|
||||
moo_accel_button_set_accel (button, g_value_get_string (value));
|
||||
_moo_accel_button_set_accel (button, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -140,21 +141,22 @@ static void moo_accel_button_set_property (GObject *object,
|
|||
}
|
||||
|
||||
|
||||
static void moo_accel_button_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
static void
|
||||
moo_accel_button_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MooAccelButton *button = MOO_ACCEL_BUTTON (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, moo_accel_button_get_title (button));
|
||||
g_value_set_string (value, _moo_accel_button_get_title (button));
|
||||
break;
|
||||
|
||||
case PROP_ACCEL:
|
||||
g_value_set_string (value, moo_accel_button_get_accel (button));
|
||||
g_value_set_string (value, _moo_accel_button_get_accel (button));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -164,22 +166,24 @@ static void moo_accel_button_get_property (GObject *object,
|
|||
}
|
||||
|
||||
|
||||
GtkWidget *moo_accel_button_new (const char *accel)
|
||||
GtkWidget *
|
||||
_moo_accel_button_new (const char *accel)
|
||||
{
|
||||
return GTK_WIDGET (g_object_new (MOO_TYPE_ACCEL_BUTTON,
|
||||
"accel", accel, NULL));
|
||||
return g_object_new (MOO_TYPE_ACCEL_BUTTON, "accel", accel, NULL);
|
||||
}
|
||||
|
||||
|
||||
const char *moo_accel_button_get_title (MooAccelButton *button)
|
||||
const char *
|
||||
_moo_accel_button_get_title (MooAccelButton *button)
|
||||
{
|
||||
g_return_val_if_fail (MOO_IS_ACCEL_BUTTON (button), NULL);
|
||||
return button->title;
|
||||
}
|
||||
|
||||
|
||||
void moo_accel_button_set_title (MooAccelButton *button,
|
||||
const char *title)
|
||||
void
|
||||
_moo_accel_button_set_title (MooAccelButton *button,
|
||||
const char *title)
|
||||
{
|
||||
g_return_if_fail (MOO_IS_ACCEL_BUTTON (button));
|
||||
g_free (button->title);
|
||||
|
@ -188,38 +192,42 @@ void moo_accel_button_set_title (MooAccelButton *button,
|
|||
}
|
||||
|
||||
|
||||
const char *moo_accel_button_get_accel (MooAccelButton *button)
|
||||
const char *
|
||||
_moo_accel_button_get_accel (MooAccelButton *button)
|
||||
{
|
||||
g_return_val_if_fail (MOO_IS_ACCEL_BUTTON (button), NULL);
|
||||
return button->accel;
|
||||
}
|
||||
|
||||
|
||||
gboolean moo_accel_button_set_accel (MooAccelButton *button,
|
||||
const char *accel)
|
||||
gboolean
|
||||
_moo_accel_button_set_accel (MooAccelButton *button,
|
||||
const char *accel)
|
||||
{
|
||||
guint accel_key;
|
||||
GdkModifierType accel_mods;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
|
||||
g_return_val_if_fail (MOO_IS_ACCEL_BUTTON (button), FALSE);
|
||||
|
||||
accel_key = 0;
|
||||
accel_mods = 0;
|
||||
if (accel && accel[0])
|
||||
{
|
||||
gtk_accelerator_parse (accel, &accel_key, &accel_mods);
|
||||
|
||||
if (!accel_key && !accel_mods)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (button->accel);
|
||||
if (accel_key || accel_mods) {
|
||||
|
||||
if (accel_key || accel_mods)
|
||||
{
|
||||
char *label = gtk_accelerator_get_label (accel_key, accel_mods);
|
||||
button->accel = gtk_accelerator_name (accel_key, accel_mods);
|
||||
gtk_button_set_label (GTK_BUTTON (button), label);
|
||||
g_free (label);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
button->accel = g_strdup ("");
|
||||
gtk_button_set_label (GTK_BUTTON (button), "");
|
||||
}
|
||||
|
@ -237,9 +245,10 @@ typedef struct {
|
|||
} Stuff;
|
||||
|
||||
|
||||
static gboolean key_event (G_GNUC_UNUSED GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
Stuff *s)
|
||||
static gboolean
|
||||
key_event (G_GNUC_UNUSED GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
Stuff *s)
|
||||
{
|
||||
if (gtk_accelerator_valid (event->keyval, event->state))
|
||||
{
|
||||
|
@ -255,8 +264,9 @@ static gboolean key_event (G_GNUC_UNUSED GtkWidget *widget,
|
|||
|
||||
|
||||
static void
|
||||
moo_accel_button_clicked (MooAccelButton *button)
|
||||
moo_accel_button_clicked (GtkButton *gtkbutton)
|
||||
{
|
||||
MooAccelButton *button = MOO_ACCEL_BUTTON (gtkbutton);
|
||||
MooGladeXML *xml;
|
||||
GtkWidget *dialog, *ok_button, *cancel_button, *eventbox, *label;
|
||||
Stuff s = {0, 0, NULL};
|
||||
|
@ -302,12 +312,12 @@ moo_accel_button_clicked (MooAccelButton *button)
|
|||
if (s.key || s.mods)
|
||||
{
|
||||
char *accel = gtk_accelerator_name (s.key, s.mods);
|
||||
moo_accel_button_set_accel (button, accel);
|
||||
_moo_accel_button_set_accel (button, accel);
|
||||
g_free (accel);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_accel_button_set_accel (button, "");
|
||||
_moo_accel_button_set_accel (button, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MOO_TYPE_ACCEL_BUTTON (moo_accel_button_get_type ())
|
||||
#define MOO_TYPE_ACCEL_BUTTON (_moo_accel_button_get_type ())
|
||||
#define MOO_ACCEL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOO_TYPE_ACCEL_BUTTON, MooAccelButton))
|
||||
#define MOO_ACCEL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_ACCEL_BUTTON, MooAccelButtonClass))
|
||||
#define MOO_IS_ACCEL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOO_TYPE_ACCEL_BUTTON))
|
||||
|
@ -44,15 +44,15 @@ struct _MooAccelButtonClass {
|
|||
};
|
||||
|
||||
|
||||
GType moo_accel_button_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *moo_accel_button_new (const char *accel);
|
||||
GType _moo_accel_button_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *_moo_accel_button_new (const char *accel);
|
||||
|
||||
const char *moo_accel_button_get_title (MooAccelButton *button);
|
||||
void moo_accel_button_set_title (MooAccelButton *button,
|
||||
const char *_moo_accel_button_get_title (MooAccelButton *button);
|
||||
void _moo_accel_button_set_title (MooAccelButton *button,
|
||||
const char *title);
|
||||
|
||||
const char *moo_accel_button_get_accel (MooAccelButton *button);
|
||||
gboolean moo_accel_button_set_accel (MooAccelButton *button,
|
||||
const char *_moo_accel_button_get_accel (MooAccelButton *button);
|
||||
gboolean _moo_accel_button_set_accel (MooAccelButton *button,
|
||||
const char *accel);
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,772 @@
|
|||
/*
|
||||
* mooaccelprefs.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#include "mooutils/mooaccelprefs.h"
|
||||
#include "mooutils/mooaccel.h"
|
||||
#include "mooutils/mooaccelprefs-glade.h"
|
||||
#include "mooutils/mooprefsdialog.h"
|
||||
#include "mooutils/mooaccelbutton.h"
|
||||
#include "mooutils/mooglade.h"
|
||||
#include "mooutils/moodialogs.h"
|
||||
#include "mooutils/mooi18n.h"
|
||||
#include "mooutils/moostock.h"
|
||||
#include "mooutils/mooaction-private.h"
|
||||
#include "mooutils/mooactiongroup.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
MooPrefsDialogPage base;
|
||||
|
||||
GtkAction *current_action;
|
||||
GtkTreeRowReference *current_row;
|
||||
|
||||
GtkWidget *shortcut_frame;
|
||||
GtkTreeView *treeview;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeStore *store;
|
||||
GtkToggleButton *shortcut_default;
|
||||
GtkToggleButton *shortcut_none;
|
||||
GtkToggleButton *shortcut_custom;
|
||||
MooAccelButton *shortcut;
|
||||
GtkLabel *default_label;
|
||||
|
||||
GHashTable *changed; /* Gtkction* -> Shortcut* */
|
||||
GPtrArray *actions; /* GtkActionGroup* */
|
||||
GHashTable *groups; /* char* -> GtkTreeRowReference* */
|
||||
} MooAccelPrefsPage;
|
||||
|
||||
typedef MooPrefsDialogPageClass MooAccelPrefsPageClass;
|
||||
|
||||
#define MOO_TYPE_ACCEL_PREFS_PAGE (_moo_accel_prefs_page_get_type ())
|
||||
#define MOO_ACCEL_PREFS_PAGE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_ACCEL_PREFS_PAGE, MooAccelPrefsPage))
|
||||
GType _moo_accel_prefs_page_get_type (void) G_GNUC_CONST;
|
||||
G_DEFINE_TYPE (MooAccelPrefsPage, _moo_accel_prefs_page, MOO_TYPE_PREFS_DIALOG_PAGE)
|
||||
|
||||
|
||||
typedef enum {
|
||||
NONE,
|
||||
DEFAULT,
|
||||
CUSTOM
|
||||
} ChoiceType;
|
||||
|
||||
typedef struct {
|
||||
char *accel;
|
||||
ChoiceType choice;
|
||||
} Shortcut;
|
||||
|
||||
|
||||
enum {
|
||||
COLUMN_ACTION_NAME,
|
||||
COLUMN_ACTION,
|
||||
COLUMN_ACCEL,
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
|
||||
static void moo_accel_prefs_page_init (MooPrefsDialogPage *page);
|
||||
static void moo_accel_prefs_page_apply (MooPrefsDialogPage *page);
|
||||
static void tree_selection_changed (MooAccelPrefsPage *page);
|
||||
static void accel_set (MooAccelPrefsPage *page);
|
||||
static void shortcut_none_toggled (MooAccelPrefsPage *page);
|
||||
static void shortcut_default_toggled (MooAccelPrefsPage *page);
|
||||
static void shortcut_custom_toggled (MooAccelPrefsPage *page);
|
||||
|
||||
|
||||
|
||||
|
||||
static Shortcut *
|
||||
shortcut_new (ChoiceType choice,
|
||||
const char *accel)
|
||||
{
|
||||
Shortcut *s = g_new (Shortcut, 1);
|
||||
s->choice = choice;
|
||||
s->accel = g_strdup (accel);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
shortcut_free (Shortcut *s)
|
||||
{
|
||||
g_free (s->accel);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_accel_prefs_page_finalize (GObject *object)
|
||||
{
|
||||
MooAccelPrefsPage *page = MOO_ACCEL_PREFS_PAGE (object);
|
||||
|
||||
g_hash_table_destroy (page->changed);
|
||||
g_hash_table_destroy (page->groups);
|
||||
g_ptr_array_free (page->actions, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (_moo_accel_prefs_page_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_accel_prefs_page_class_init (MooAccelPrefsPageClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS (klass)->finalize = _moo_accel_prefs_page_finalize;
|
||||
MOO_PREFS_DIALOG_PAGE_CLASS (klass)->init = moo_accel_prefs_page_init;
|
||||
MOO_PREFS_DIALOG_PAGE_CLASS (klass)->apply = moo_accel_prefs_page_apply;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
row_activated (MooAccelPrefsPage *page)
|
||||
{
|
||||
if (GTK_WIDGET_IS_SENSITIVE (page->shortcut))
|
||||
gtk_button_clicked (GTK_BUTTON (page->shortcut));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
block_accel_set (MooAccelPrefsPage *page)
|
||||
{
|
||||
g_signal_handlers_block_matched (page->shortcut, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) accel_set, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
unblock_accel_set (MooAccelPrefsPage *page)
|
||||
{
|
||||
g_signal_handlers_unblock_matched (page->shortcut, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) accel_set, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
block_radio (MooAccelPrefsPage *page)
|
||||
{
|
||||
g_signal_handlers_block_matched (page->shortcut_none, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_none_toggled, 0);
|
||||
g_signal_handlers_block_matched (page->shortcut_default, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_default_toggled, 0);
|
||||
g_signal_handlers_block_matched (page->shortcut_custom, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_custom_toggled, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
unblock_radio (MooAccelPrefsPage *page)
|
||||
{
|
||||
g_signal_handlers_unblock_matched (page->shortcut_none, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_none_toggled, 0);
|
||||
g_signal_handlers_unblock_matched (page->shortcut_default, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_default_toggled, 0);
|
||||
g_signal_handlers_unblock_matched (page->shortcut_custom, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, 0, (gpointer) shortcut_custom_toggled, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_accel_prefs_page_init (MooAccelPrefsPage *page)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
MooGladeXML *xml;
|
||||
|
||||
page->changed = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
|
||||
(GDestroyNotify) shortcut_free);
|
||||
page->actions = g_ptr_array_new ();
|
||||
page->groups = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) gtk_tree_row_reference_free);
|
||||
|
||||
xml = moo_glade_xml_new_empty (GETTEXT_PACKAGE);
|
||||
moo_glade_xml_map_class (xml, "GtkButton", MOO_TYPE_ACCEL_BUTTON);
|
||||
moo_glade_xml_fill_widget (xml, GTK_WIDGET (page),
|
||||
MOO_ACCEL_PREFS_GLADE_UI, -1,
|
||||
"page", NULL);
|
||||
g_object_set (page, "label", "Shortcuts", "icon-stock-id", MOO_STOCK_KEYBOARD, NULL);
|
||||
|
||||
page->treeview = moo_glade_xml_get_widget (xml, "treeview");
|
||||
gtk_tree_view_set_search_column (page->treeview, 0);
|
||||
|
||||
g_signal_connect_swapped (page->treeview, "row-activated",
|
||||
G_CALLBACK (row_activated),
|
||||
page);
|
||||
|
||||
page->shortcut_frame = moo_glade_xml_get_widget (xml, "shortcut_frame");
|
||||
page->shortcut_default = moo_glade_xml_get_widget (xml, "shortcut_default");
|
||||
page->shortcut_none = moo_glade_xml_get_widget (xml, "shortcut_none");
|
||||
page->shortcut_custom = moo_glade_xml_get_widget (xml, "shortcut_custom");
|
||||
page->shortcut = moo_glade_xml_get_widget (xml, "shortcut");
|
||||
page->default_label = moo_glade_xml_get_widget (xml, "default_label");
|
||||
|
||||
g_object_unref (xml);
|
||||
|
||||
page->store = gtk_tree_store_new (N_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
GTK_TYPE_ACTION,
|
||||
G_TYPE_STRING);
|
||||
gtk_tree_view_set_model (page->treeview, GTK_TREE_MODEL (page->store));
|
||||
g_object_unref (page->store);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Action", renderer,
|
||||
"text", COLUMN_ACTION_NAME,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (page->treeview, column);
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_ACTION_NAME);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Shortcut", renderer,
|
||||
"text", COLUMN_ACCEL,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (page->treeview, column);
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_ACCEL);
|
||||
|
||||
page->selection = gtk_tree_view_get_selection (page->treeview);
|
||||
gtk_tree_selection_set_mode (page->selection, GTK_SELECTION_SINGLE);
|
||||
|
||||
g_signal_connect_swapped (page->selection, "changed",
|
||||
G_CALLBACK (tree_selection_changed),
|
||||
page);
|
||||
|
||||
g_signal_connect_swapped (page->shortcut, "accel-set",
|
||||
G_CALLBACK (accel_set),
|
||||
page);
|
||||
g_signal_connect_swapped (page->shortcut_none, "toggled",
|
||||
G_CALLBACK (shortcut_none_toggled),
|
||||
page);
|
||||
g_signal_connect_swapped (page->shortcut_default, "toggled",
|
||||
G_CALLBACK (shortcut_default_toggled),
|
||||
page);
|
||||
g_signal_connect_swapped (page->shortcut_custom, "toggled",
|
||||
G_CALLBACK (shortcut_custom_toggled),
|
||||
page);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
get_action_accel (GtkAction *action)
|
||||
{
|
||||
const char *accel_path = _moo_action_get_accel_path (action);
|
||||
return _moo_get_accel (accel_path);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apply_one (GtkAction *action,
|
||||
Shortcut *shortcut)
|
||||
{
|
||||
const char *accel_path = _moo_action_get_accel_path (action);
|
||||
const char *default_accel = _moo_get_default_accel (accel_path);
|
||||
const char *new_accel = "";
|
||||
|
||||
switch (shortcut->choice)
|
||||
{
|
||||
case NONE:
|
||||
new_accel = "";
|
||||
break;
|
||||
case CUSTOM:
|
||||
new_accel = shortcut->accel;
|
||||
break;
|
||||
case DEFAULT:
|
||||
new_accel = default_accel;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
_moo_modify_acel (accel_path, new_accel);
|
||||
}
|
||||
|
||||
static void
|
||||
moo_accel_prefs_page_apply (MooPrefsDialogPage *prefs_page)
|
||||
{
|
||||
MooAccelPrefsPage *page = MOO_ACCEL_PREFS_PAGE (prefs_page);
|
||||
g_hash_table_foreach (page->changed, (GHFunc) apply_one, NULL);
|
||||
g_hash_table_foreach_remove (page->changed, (GHRFunc) gtk_true, NULL);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
get_accel_label_for_path (const char *accel_path)
|
||||
{
|
||||
g_return_val_if_fail (accel_path != NULL, g_strdup (""));
|
||||
return _moo_get_accel_label (_moo_get_accel (accel_path));
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
add_row (GtkActionGroup *group,
|
||||
GtkAction *action,
|
||||
MooAccelPrefsPage *page)
|
||||
{
|
||||
const char *group_name;
|
||||
char *accel;
|
||||
const char *name;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeRowReference *row;
|
||||
|
||||
if (_moo_action_get_no_accel (action))
|
||||
return FALSE;
|
||||
|
||||
group_name = _moo_action_group_get_display_name (MOO_ACTION_GROUP (group));
|
||||
|
||||
if (!group_name)
|
||||
group_name = "";
|
||||
|
||||
row = g_hash_table_lookup (page->groups, group_name);
|
||||
|
||||
if (row)
|
||||
{
|
||||
GtkTreeIter parent;
|
||||
GtkTreePath *path = gtk_tree_row_reference_get_path (row);
|
||||
if (!path || !gtk_tree_model_get_iter (GTK_TREE_MODEL (page->store), &parent, path))
|
||||
{
|
||||
g_critical ("%s: got invalid path for group %s",
|
||||
G_STRLOC, group_name);
|
||||
gtk_tree_path_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_tree_store_append (page->store, &iter, &parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTreeIter group;
|
||||
GtkTreePath *path;
|
||||
|
||||
gtk_tree_store_append (page->store, &group, NULL);
|
||||
gtk_tree_store_set (page->store, &group,
|
||||
COLUMN_ACTION_NAME, group_name,
|
||||
COLUMN_ACTION, NULL,
|
||||
COLUMN_ACCEL, NULL,
|
||||
-1);
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (page->store), &group);
|
||||
g_hash_table_insert (page->groups,
|
||||
g_strdup (group_name),
|
||||
gtk_tree_row_reference_new (GTK_TREE_MODEL (page->store), path));
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_tree_store_append (page->store, &iter, &group);
|
||||
}
|
||||
|
||||
accel = get_accel_label_for_path (_moo_action_get_accel_path (action));
|
||||
name = _moo_action_get_display_name (action);
|
||||
|
||||
gtk_tree_store_set (page->store, &iter,
|
||||
COLUMN_ACTION_NAME, name,
|
||||
COLUMN_ACTION, action,
|
||||
COLUMN_ACCEL, accel,
|
||||
-1);
|
||||
g_free (accel);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_accel_prefs_page_init (MooPrefsDialogPage *prefs_page)
|
||||
{
|
||||
guint i;
|
||||
MooAccelPrefsPage *page = MOO_ACCEL_PREFS_PAGE (prefs_page);
|
||||
|
||||
for (i = 0; i < page->actions->len; ++i)
|
||||
{
|
||||
GtkActionGroup *group = g_ptr_array_index (page->actions, i);
|
||||
GList *list = gtk_action_group_list_actions (group);
|
||||
|
||||
while (list)
|
||||
{
|
||||
add_row (group, list->data, page);
|
||||
list = g_list_delete_link (list, list);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (page->store),
|
||||
COLUMN_ACTION_NAME,
|
||||
GTK_SORT_ASCENDING);
|
||||
gtk_tree_view_expand_all (page->treeview);
|
||||
tree_selection_changed (page);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tree_selection_changed (MooAccelPrefsPage *page)
|
||||
{
|
||||
gboolean selected_action = FALSE;
|
||||
GtkTreeIter iter;
|
||||
GtkAction *action = NULL;
|
||||
GtkTreePath *path;
|
||||
char *default_label;
|
||||
const char *default_accel, *new_accel = "";
|
||||
GtkToggleButton *new_button = NULL;
|
||||
Shortcut *shortcut;
|
||||
|
||||
if (gtk_tree_selection_get_selected (page->selection, NULL, &iter))
|
||||
{
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (page->store), &iter,
|
||||
COLUMN_ACTION, &action, -1);
|
||||
if (action)
|
||||
selected_action = TRUE;
|
||||
}
|
||||
|
||||
page->current_action = action;
|
||||
gtk_tree_row_reference_free (page->current_row);
|
||||
page->current_row = NULL;
|
||||
|
||||
if (!selected_action)
|
||||
{
|
||||
gtk_label_set_text (page->default_label, "");
|
||||
gtk_widget_set_sensitive (page->shortcut_frame, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (page->store), &iter);
|
||||
page->current_row = gtk_tree_row_reference_new (GTK_TREE_MODEL (page->store), path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_widget_set_sensitive (page->shortcut_frame, TRUE);
|
||||
|
||||
default_accel = _moo_get_default_accel (_moo_action_get_accel_path (action));
|
||||
default_label = _moo_get_accel_label (default_accel);
|
||||
|
||||
if (!default_label || !default_label[0])
|
||||
gtk_label_set_text (page->default_label, "None");
|
||||
else
|
||||
gtk_label_set_text (page->default_label, default_label);
|
||||
|
||||
block_radio (page);
|
||||
block_accel_set (page);
|
||||
|
||||
shortcut = g_hash_table_lookup (page->changed, action);
|
||||
|
||||
if (shortcut)
|
||||
{
|
||||
switch (shortcut->choice)
|
||||
{
|
||||
case NONE:
|
||||
new_button = page->shortcut_none;
|
||||
new_accel = NULL;
|
||||
break;
|
||||
|
||||
case DEFAULT:
|
||||
new_button = page->shortcut_default;
|
||||
new_accel = default_accel;
|
||||
break;
|
||||
|
||||
case CUSTOM:
|
||||
new_button = page->shortcut_custom;
|
||||
new_accel = shortcut->accel;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *accel = get_action_accel (action);
|
||||
|
||||
if (!strcmp (accel, default_accel))
|
||||
{
|
||||
new_button = page->shortcut_default;
|
||||
new_accel = default_accel;
|
||||
}
|
||||
else if (!accel[0])
|
||||
{
|
||||
new_button = page->shortcut_none;
|
||||
new_accel = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_button = page->shortcut_custom;
|
||||
new_accel = accel;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_toggle_button_set_active (new_button, TRUE);
|
||||
_moo_accel_button_set_accel (page->shortcut, new_accel);
|
||||
|
||||
unblock_radio (page);
|
||||
unblock_accel_set (page);
|
||||
|
||||
g_free (default_label);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
accel_set (MooAccelPrefsPage *page)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
const char *accel;
|
||||
const char *label;
|
||||
|
||||
g_return_if_fail (page->current_row != NULL && page->current_action != NULL);
|
||||
|
||||
block_radio (page);
|
||||
gtk_toggle_button_set_active (page->shortcut_custom, TRUE);
|
||||
unblock_radio (page);
|
||||
|
||||
path = gtk_tree_row_reference_get_path (page->current_row);
|
||||
if (!path || !gtk_tree_model_get_iter (GTK_TREE_MODEL (page->store), &iter, path))
|
||||
{
|
||||
g_critical ("%s: got invalid path", G_STRLOC);
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
accel = _moo_accel_button_get_accel (page->shortcut);
|
||||
label = gtk_button_get_label (GTK_BUTTON (page->shortcut));
|
||||
gtk_tree_store_set (page->store, &iter, COLUMN_ACCEL, label, -1);
|
||||
|
||||
if (accel && accel[0])
|
||||
g_hash_table_insert (page->changed,
|
||||
page->current_action,
|
||||
shortcut_new (CUSTOM, accel));
|
||||
else
|
||||
g_hash_table_insert (page->changed,
|
||||
page->current_action,
|
||||
shortcut_new (NONE, ""));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shortcut_none_toggled (MooAccelPrefsPage *page)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
g_return_if_fail (page->current_row != NULL && page->current_action != NULL);
|
||||
|
||||
if (!gtk_toggle_button_get_active (page->shortcut_none))
|
||||
return;
|
||||
|
||||
path = gtk_tree_row_reference_get_path (page->current_row);
|
||||
if (!path || !gtk_tree_model_get_iter (GTK_TREE_MODEL (page->store), &iter, path))
|
||||
{
|
||||
g_critical ("%s: got invalid path", G_STRLOC);
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_tree_store_set (page->store, &iter, COLUMN_ACCEL, NULL, -1);
|
||||
g_hash_table_insert (page->changed,
|
||||
page->current_action,
|
||||
shortcut_new (NONE, ""));
|
||||
block_accel_set (page);
|
||||
_moo_accel_button_set_accel (page->shortcut, "");
|
||||
unblock_accel_set (page);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shortcut_default_toggled (MooAccelPrefsPage *page)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
Shortcut *current_shortcut;
|
||||
const char *default_accel;
|
||||
|
||||
g_return_if_fail (page->current_row != NULL && page->current_action != NULL);
|
||||
|
||||
if (!gtk_toggle_button_get_active (page->shortcut_default))
|
||||
return;
|
||||
|
||||
path = gtk_tree_row_reference_get_path (page->current_row);
|
||||
|
||||
if (!path || !gtk_tree_model_get_iter (GTK_TREE_MODEL (page->store), &iter, path))
|
||||
{
|
||||
g_critical ("%s: got invalid path", G_STRLOC);
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
current_shortcut = g_hash_table_lookup (page->changed, page->current_action);
|
||||
|
||||
if (!current_shortcut)
|
||||
{
|
||||
current_shortcut = shortcut_new (NONE, "");
|
||||
g_hash_table_insert (page->changed,
|
||||
page->current_action,
|
||||
current_shortcut);
|
||||
}
|
||||
|
||||
default_accel = _moo_action_get_default_accel (page->current_action);
|
||||
|
||||
if (default_accel[0])
|
||||
{
|
||||
char *label = _moo_get_accel_label (default_accel);
|
||||
gtk_tree_store_set (page->store, &iter, COLUMN_ACCEL, label, -1);
|
||||
g_free (label);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_tree_store_set (page->store, &iter, COLUMN_ACCEL, NULL, -1);
|
||||
}
|
||||
|
||||
current_shortcut->choice = DEFAULT;
|
||||
g_free (current_shortcut->accel);
|
||||
current_shortcut->accel = g_strdup (default_accel);
|
||||
|
||||
block_accel_set (page);
|
||||
_moo_accel_button_set_accel (page->shortcut, default_accel);
|
||||
unblock_accel_set (page);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shortcut_custom_toggled (MooAccelPrefsPage *page)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
Shortcut *shortcut;
|
||||
|
||||
g_return_if_fail (page->current_row != NULL && page->current_action != NULL);
|
||||
|
||||
if (!gtk_toggle_button_get_active (page->shortcut_custom))
|
||||
return;
|
||||
|
||||
path = gtk_tree_row_reference_get_path (page->current_row);
|
||||
|
||||
if (!path || !gtk_tree_model_get_iter (GTK_TREE_MODEL (page->store), &iter, path))
|
||||
{
|
||||
g_critical ("%s: got invalid path", G_STRLOC);
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
shortcut = g_hash_table_lookup (page->changed, page->current_action);
|
||||
|
||||
if (shortcut)
|
||||
{
|
||||
block_accel_set (page);
|
||||
_moo_accel_button_set_accel (page->shortcut, shortcut->accel);
|
||||
unblock_accel_set (page);
|
||||
|
||||
gtk_tree_store_set (page->store, &iter, COLUMN_ACCEL,
|
||||
gtk_button_get_label (GTK_BUTTON (page->shortcut)),
|
||||
-1);
|
||||
|
||||
shortcut->choice = CUSTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *accel = get_action_accel (page->current_action);
|
||||
g_hash_table_insert (page->changed,
|
||||
page->current_action,
|
||||
shortcut_new (CUSTOM, accel));
|
||||
|
||||
block_accel_set (page);
|
||||
_moo_accel_button_set_accel (page->shortcut, accel);
|
||||
unblock_accel_set (page);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dialog_response (GObject *page,
|
||||
int response)
|
||||
{
|
||||
switch (response)
|
||||
{
|
||||
case GTK_RESPONSE_OK:
|
||||
g_signal_emit_by_name (page, "apply", NULL);
|
||||
break;
|
||||
|
||||
case GTK_RESPONSE_REJECT:
|
||||
g_signal_emit_by_name (page, "set_defaults", NULL);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static MooAccelPrefsPage *
|
||||
_moo_accel_prefs_page_new (MooActionCollection *collection)
|
||||
{
|
||||
const GSList *groups;
|
||||
MooAccelPrefsPage *page;
|
||||
|
||||
page = g_object_new (MOO_TYPE_ACCEL_PREFS_PAGE, NULL);
|
||||
groups = moo_action_collection_get_groups (collection);
|
||||
|
||||
while (groups)
|
||||
{
|
||||
g_ptr_array_add (page->actions, groups->data);
|
||||
groups = groups->next;
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget*
|
||||
_moo_accel_prefs_dialog_new (MooActionCollection *collection)
|
||||
{
|
||||
MooAccelPrefsPage *page;
|
||||
GtkWidget *dialog, *page_holder;
|
||||
MooGladeXML *xml;
|
||||
|
||||
xml = moo_glade_xml_new_from_buf (MOO_ACCEL_PREFS_GLADE_UI, -1,
|
||||
"dialog", GETTEXT_PACKAGE, NULL);
|
||||
g_return_val_if_fail (xml != NULL, NULL);
|
||||
|
||||
dialog = moo_glade_xml_get_widget (xml, "dialog");
|
||||
|
||||
page = _moo_accel_prefs_page_new (collection);
|
||||
gtk_widget_show (GTK_WIDGET (page));
|
||||
page_holder = moo_glade_xml_get_widget (xml, "page_holder");
|
||||
gtk_container_add (GTK_CONTAINER (page_holder), GTK_WIDGET (page));
|
||||
|
||||
g_object_unref (xml);
|
||||
|
||||
#if GTK_MINOR_VERSION >= 6
|
||||
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
||||
GTK_RESPONSE_OK,
|
||||
GTK_RESPONSE_CANCEL,
|
||||
GTK_RESPONSE_REJECT,
|
||||
-1);
|
||||
#endif /* GTK_MINOR_VERSION >= 6 */
|
||||
|
||||
g_signal_connect_swapped (dialog, "response",
|
||||
G_CALLBACK (dialog_response), page);
|
||||
g_signal_emit_by_name (page, "init", NULL);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_accel_prefs_dialog_run (MooActionCollection *collection,
|
||||
GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *dialog = _moo_accel_prefs_dialog_new (collection);
|
||||
|
||||
moo_window_set_parent (dialog, parent);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
int response = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
|
||||
if (response != GTK_RESPONSE_REJECT)
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* mooaccelprefs.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef __MOO_ACCEL_PREFS_H__
|
||||
#define __MOO_ACCEL_PREFS_H__
|
||||
|
||||
#include <mooutils/mooactioncollection.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void _moo_accel_prefs_dialog_run (MooActionCollection *coll,
|
||||
GtkWidget *parent);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MOO_ACCEL_PREFS_H__ */
|
Loading…
Reference in New Issue