cc-input-options.c 6.4 KB
Newer Older
Matthias Clasen's avatar
Matthias Clasen committed
1
/*
2
 * Copyright (C) 2013, 2015 Red Hat, Inc.
Matthias Clasen's avatar
Matthias Clasen committed
3
4
5
6
7
8
9
10
11
12
13
14
 *
 * 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
15
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Matthias Clasen's avatar
Matthias Clasen committed
16
17
18
19
20
21
22
23
 *
 * Written by:
 *     Matthias Clasen
 */

#include <config.h>
#include <glib/gi18n.h>

24
25
26
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-xkb-info.h>

27
#include "cc-input-options.h"
Matthias Clasen's avatar
Matthias Clasen committed
28

29
30
struct _CcInputOptions {
        GtkDialog parent_instance;
Matthias Clasen's avatar
Matthias Clasen committed
31
32
33
        GtkWidget *same_source;
        GtkWidget *per_window_source;
        GtkWidget *previous_source;
34
        GtkWidget *previous_source_label;
Matthias Clasen's avatar
Matthias Clasen committed
35
        GtkWidget *next_source;
36
        GtkWidget *next_source_label;
Matthias Clasen's avatar
Matthias Clasen committed
37
        GtkWidget *alt_next_source;
38
        GtkWidget *alt_next_source_label;
Matthias Clasen's avatar
Matthias Clasen committed
39
        GSettings *settings;
40
};
Matthias Clasen's avatar
Matthias Clasen committed
41

42
G_DEFINE_TYPE (CcInputOptions, cc_input_options, GTK_TYPE_DIALOG);
Matthias Clasen's avatar
Matthias Clasen committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

static void
update_shortcut_label (GtkWidget   *widget,
                       const gchar *value)
{
        gchar *text;
        guint accel_key, *keycode;
        GdkModifierType mods;

        if (value == NULL || *value == '\0') {
                gtk_widget_hide (widget);
                return;
        }

        gtk_accelerator_parse_with_keycode (value, &accel_key, &keycode, &mods);
        if (accel_key == 0 && keycode == NULL && mods == 0) {
                g_warning ("Failed to parse keyboard shortcut: '%s'", value);
                gtk_widget_hide (widget);
                return;
        }

        text = gtk_accelerator_get_label_with_keycode (gtk_widget_get_display (widget), accel_key, *keycode, mods);
        g_free (keycode);
        gtk_label_set_text (GTK_LABEL (widget), text);
        g_free (text);
}

static void
71
update_shortcuts (CcInputOptions *self)
Matthias Clasen's avatar
Matthias Clasen committed
72
73
74
75
76
77
78
79
80
81
82
83
84
{
        gchar **previous;
        gchar **next;
        gchar *previous_shortcut;
        GSettings *settings;

        settings = g_settings_new ("org.gnome.desktop.wm.keybindings");

        previous = g_settings_get_strv (settings, "switch-input-source-backward");
        next = g_settings_get_strv (settings, "switch-input-source");

        previous_shortcut = g_strdup (previous[0]);

85
86
        update_shortcut_label (self->previous_source, previous_shortcut);
        update_shortcut_label (self->next_source, next[0]);
Matthias Clasen's avatar
Matthias Clasen committed
87
88
89
90
91
92
93

        g_free (previous_shortcut);

        g_strfreev (previous);
        g_strfreev (next);

        g_object_unref (settings);
94
95
96
}

static void
97
update_modifiers_shortcut (CcInputOptions *self)
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
{
        gchar **options, **p;
        GSettings *settings;
        GnomeXkbInfo *xkb_info;
        const gchar *text;

        xkb_info = gnome_xkb_info_new ();
        settings = g_settings_new ("org.gnome.desktop.input-sources");
        options = g_settings_get_strv (settings, "xkb-options");

        for (p = options; p && *p; ++p)
                if (g_str_has_prefix (*p, "grp:"))
                        break;

        if (p && *p) {
                text = gnome_xkb_info_description_for_option (xkb_info, "grp", *p);
114
                gtk_label_set_text (GTK_LABEL (self->alt_next_source), text);
115
        } else {
116
                gtk_widget_hide (self->alt_next_source);
117
        }
Matthias Clasen's avatar
Matthias Clasen committed
118

119
120
121
        g_strfreev (options);
        g_object_unref (settings);
        g_object_unref (xkb_info);
Matthias Clasen's avatar
Matthias Clasen committed
122
123
}

124
125
static void
cc_input_options_finalize (GObject *object)
Matthias Clasen's avatar
Matthias Clasen committed
126
{
127
        CcInputOptions *self = CC_INPUT_OPTIONS (object);
Matthias Clasen's avatar
Matthias Clasen committed
128

129
130
131
        g_object_unref (self->settings);
        G_OBJECT_CLASS (cc_input_options_parent_class)->finalize (object);
}
Matthias Clasen's avatar
Matthias Clasen committed
132

133
134
135
136
static void
cc_input_options_init (CcInputOptions *self)
{
        gtk_widget_init_template (GTK_WIDGET (self));
Matthias Clasen's avatar
Matthias Clasen committed
137

138
139
        g_object_bind_property (self->previous_source, "visible",
                                self->previous_source_label, "visible",
Matthias Clasen's avatar
Matthias Clasen committed
140
                                G_BINDING_DEFAULT);
141
142
        g_object_bind_property (self->next_source, "visible",
                                self->next_source_label, "visible",
Matthias Clasen's avatar
Matthias Clasen committed
143
                                G_BINDING_DEFAULT);
144
145
        g_object_bind_property (self->alt_next_source, "visible",
                                self->alt_next_source_label, "visible",
Matthias Clasen's avatar
Matthias Clasen committed
146
147
                                G_BINDING_DEFAULT);

148
149
150
        self->settings = g_settings_new ("org.gnome.desktop.input-sources");
        g_settings_bind (self->settings, "per-window",
                         self->per_window_source, "active",
Matthias Clasen's avatar
Matthias Clasen committed
151
                         G_SETTINGS_BIND_DEFAULT);
152
153
        g_settings_bind (self->settings, "per-window",
                         self->same_source, "active",
154
                         G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);
Matthias Clasen's avatar
Matthias Clasen committed
155

156
157
158
        update_shortcuts (self);
        update_modifiers_shortcut (self);
}
Matthias Clasen's avatar
Matthias Clasen committed
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
static void
cc_input_options_class_init (CcInputOptionsClass *klass)
{
        GObjectClass *object_klass = G_OBJECT_CLASS (klass);
        GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS (klass);

        object_klass->finalize = cc_input_options_finalize;

        gtk_widget_class_set_template_from_resource (widget_klass,
                                                     "/org/gnome/control-center/region/input-options.ui");
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, same_source);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, per_window_source);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, previous_source);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, previous_source_label);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, next_source);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, next_source_label);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, alt_next_source);
        gtk_widget_class_bind_template_child (widget_klass, CcInputOptions, alt_next_source_label);
}
Matthias Clasen's avatar
Matthias Clasen committed
179

180
181
182
GtkWidget *
cc_input_options_new (GtkWidget *parent)
{
183
        return g_object_new (CC_TYPE_INPUT_OPTIONS, "transient-for", parent, "use-header-bar", TRUE, NULL);
Matthias Clasen's avatar
Matthias Clasen committed
184
}