61e5d6035fa3b571a6be70a4724cdada6a4a0694
[tweakr] / modules / tweakr-profile.c
1 /*
2  * vim:ts=4:sw=4:et:cindent:cino=(0
3  */ 
4
5 #include <config.h>
6 #include <glib.h>
7 #include <glib/gi18n-lib.h>
8
9 #include <gtk/gtk.h>
10 #include <hildon/hildon-picker-button.h>
11 #include <hildon/hildon-touch-selector.h>
12 #include <hildon/hildon-entry.h>
13 #include <hildon/hildon-defines.h>
14 #include <hildon/hildon-banner.h>
15
16 #include <gconf/gconf-client.h>
17
18 #include <libprofile.h>
19
20 #include "libtweakr-section/tweakr-section.h"
21 #include "libtweakr-section/tweakr-module.h"
22
23
24 #define TWEAKR_TYPE_PROFILE_SECTION \
25         (tweakr_profile_section_type)
26 #define TWEAKR_PROFILE_SECTION(obj) \
27         (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
28         TWEAKR_TYPE_PROFILE_SECTION, \
29         TweakrProfileSection))
30 #define TWEAKR_PROFILE_SECTION_CLASS(k) \
31         (G_TYPE_CHECK_CLASS_CAST((k), \
32         TWEAKR_TYPE_PROFILE_SECTION, \
33         TweakrProfileSectionClass))
34 #define TWEAKR_IS_PROFILE_SECTION(obj) \
35         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
36         TWEAKR_TYPE_PROFILE_SECTION))
37
38 typedef struct _TweakrProfileSection TweakrProfileSection;
39 typedef struct _TweakrProfileSectionClass
40                TweakrProfileSectionClass;
41
42 struct _TweakrProfileSection
43 {
44     TweakrSection parent_instance;
45
46     GtkWidget *profile_button;
47     GHashTable *profile_map;
48     guint value_changed : 1;
49     gint previous_selected;
50 };
51
52 struct _TweakrProfileSectionClass
53 {
54     TweakrSectionClass parent_class;
55 };
56
57
58 static GType tweakr_profile_section_get_type (GTypeModule *module);
59 static void tweakr_profile_section_class_init
60     (TweakrProfileSectionClass *class);
61 static void tweakr_profile_section_init
62     (TweakrProfileSection *section);
63 static void tweakr_profile_section_dispose (GObject *obj);
64
65 static gboolean _save (TweakrSection *section,
66                        gboolean *requires_restart);
67
68 static GType tweakr_profile_section_type = 0;
69 static TweakrSectionClass *
70     tweakr_profile_section_parent_class = NULL;
71
72
73 G_MODULE_EXPORT void
74 tweakr_module_load (TweakrModule *module)
75 {
76     tweakr_profile_section_get_type (G_TYPE_MODULE (module));
77 }
78
79 G_MODULE_EXPORT void
80 tweakr_module_unload (TweakrModule *module)
81 {
82 }
83
84 static GType
85 tweakr_profile_section_get_type (GTypeModule *module)
86 {
87     if (!tweakr_profile_section_type)
88     {
89         static const GTypeInfo section_info =
90         {
91             sizeof (TweakrProfileSectionClass),
92             (GBaseInitFunc) NULL,
93             (GBaseFinalizeFunc) NULL,
94             (GClassInitFunc) tweakr_profile_section_class_init,
95             NULL,           /* class_finalize */
96             NULL,           /* class_data     */
97             sizeof (TweakrProfileSection),
98             0,              /* n_preallocs    */
99             (GInstanceInitFunc) tweakr_profile_section_init
100         };
101
102         tweakr_profile_section_type =
103             g_type_module_register_type (module, TWEAKR_TYPE_SECTION,
104                                          "TweakrProfileSection",
105                                          &section_info, 0);
106     }
107
108     return tweakr_profile_section_type;
109 }
110
111 static void
112 tweakr_profile_section_class_init
113     (TweakrProfileSectionClass *klass)
114 {
115     GObjectClass *object_class = G_OBJECT_CLASS (klass);
116     TweakrSectionClass *section_class =
117         TWEAKR_SECTION_CLASS (klass);
118
119     tweakr_profile_section_parent_class =
120         g_type_class_peek_parent (klass);
121
122     section_class->name   = "_Profile";
123     section_class->save = _save;
124
125     object_class->dispose = tweakr_profile_section_dispose;
126 }
127
128 static void
129 _value_changed (HildonPickerButton *button, TweakrProfileSection *section)
130 {
131     HildonTouchSelector *selector;
132     gint active;
133     GtkWindow *parent;
134
135     selector = hildon_picker_button_get_selector (button);
136     active = hildon_touch_selector_get_active (selector, 0);
137
138     parent = GTK_WINDOW (gtk_widget_get_ancestor (tweakr_section_get_widget
139                                                   (TWEAKR_SECTION (section)),
140                                                   GTK_TYPE_WINDOW));
141 #if 0
142     if (active == 0)
143     {
144         GtkWidget *dialog, *entry;
145         gint ret;
146         const gchar *text = NULL;
147
148         dialog = gtk_dialog_new_with_buttons
149             (_("Save current profile with new name"),
150              parent,
151              GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
152              GTK_STOCK_OK, GTK_RESPONSE_OK,
153              NULL);
154
155         entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT);
156         gtk_widget_show (entry);
157
158         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry,
159                             TRUE, TRUE, 0);
160         while (text == NULL || text [0] == '\0')
161         {
162             GtkTreeModel *model;
163             gint index;
164
165             ret = gtk_dialog_run (GTK_DIALOG (dialog));
166             if (ret == GTK_RESPONSE_OK)
167             {
168                 text = hildon_entry_get_text (HILDON_ENTRY (entry));
169                 if (text == NULL || text[0] == '\0')
170                 {
171                     GtkWidget *banner;
172
173                     banner = hildon_banner_show_information
174                         (dialog, NULL, _("Enter the name first."));
175
176                     continue;
177                 }
178
179                 hildon_touch_selector_append_text (selector, text);
180                 model = hildon_touch_selector_get_model (selector, 0);
181                 index = gtk_tree_model_iter_n_children (model, NULL);
182                 hildon_touch_selector_set_active (selector, 0, index);
183             }
184             else
185             {
186                 gtk_widget_destroy (dialog);
187                 hildon_touch_selector_set_active (selector, 0,
188                                                   section->previous_selected);
189                 break;
190             }
191             gtk_widget_destroy (dialog);
192         }
193     }
194 #endif
195     section->previous_selected = hildon_touch_selector_get_active (selector,
196                                                                    0);
197     section->value_changed = TRUE;
198 }
199
200 static GtkWidget *
201 _build_profile_select_button (TweakrProfileSection *section)
202 {
203     GtkWidget *button, *selector;
204     char **profiles;
205     gint i;
206     char *current_profile;
207
208     selector = hildon_touch_selector_new_text ();
209     /*
210     hildon_touch_selector_append_text
211         (HILDON_TOUCH_SELECTOR (selector),
212          _("Save current profile with new name"));
213     */
214
215     profiles = profile_get_profiles ();
216     for (i = 0; profiles && profiles[i] && profiles[i] != '\0'; i++)
217     {
218         /*
219          * Gotta make some l10n substitution here.
220          */
221         const gchar *p = profiles[i];
222
223         hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
224                                            _(p));
225         g_hash_table_insert (section->profile_map,
226                              GINT_TO_POINTER (i /*+ 1*/), g_strdup (p));
227
228     }
229
230     current_profile = profile_get_profile ();
231     for (i = 0; profiles[i] && profiles[i] != '\0'; i++)
232     {
233         if (g_strcmp0 (profiles[i], current_profile) == 0)
234         {
235             hildon_touch_selector_set_active
236                 (HILDON_TOUCH_SELECTOR (selector), 0, i/* + 1*/);
237             section->previous_selected = i/* + 1*/;
238         }
239     }
240     g_free (current_profile);
241     profile_free_profiles (profiles);
242
243     button = hildon_picker_button_new (HILDON_SIZE_AUTO |
244                                        HILDON_SIZE_FINGER_HEIGHT,
245                                        HILDON_BUTTON_ARRANGEMENT_VERTICAL);
246     hildon_button_set_title (HILDON_BUTTON (button),
247                              _("Use custom profile"));
248     gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f);
249     hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
250                                        HILDON_TOUCH_SELECTOR (selector));
251
252     g_signal_connect (G_OBJECT (button), "value-changed",
253                       G_CALLBACK (_value_changed), section);
254
255     gtk_widget_show (button);
256     return button;
257 }
258
259 static void
260 tweakr_profile_section_init (TweakrProfileSection *section)
261 {
262     TweakrSection *iface;
263
264     iface = TWEAKR_SECTION (section);
265     iface->name = _("Profiles");
266     iface->widget = gtk_vbox_new (FALSE, 0);
267
268     section->profile_map = g_hash_table_new_full (g_direct_hash,
269                                                   g_direct_equal,
270                                                   NULL, g_free);
271     section->profile_button = _build_profile_select_button (section);
272
273     gtk_box_pack_start (GTK_BOX (iface->widget), section->profile_button,
274                         FALSE, FALSE, 0);
275 }
276
277 static void
278 tweakr_profile_section_dispose (GObject *obj)
279 {
280     TweakrProfileSection *section = TWEAKR_PROFILE_SECTION (obj);
281
282     if (section->profile_map)
283     {
284         g_hash_table_destroy (section->profile_map);
285         section->profile_map = NULL;
286     }
287
288     G_OBJECT_CLASS (tweakr_profile_section_parent_class)->dispose (obj);
289 }
290
291 static gboolean _save (TweakrSection *section, gboolean *requires_restart)
292 {
293     if (TWEAKR_PROFILE_SECTION (section)->value_changed)
294     {
295         gint active;
296         const gchar *profile;
297
298         active =
299             hildon_picker_button_get_active (HILDON_PICKER_BUTTON
300                                              (TWEAKR_PROFILE_SECTION
301                                               (section)->profile_button));
302         profile = g_hash_table_lookup
303             (TWEAKR_PROFILE_SECTION (section)->profile_map,
304              GINT_TO_POINTER (active));
305
306         if (profile != NULL && profile[0] != '\0')
307         {
308             profile_set_profile (profile);
309         }
310     }
311
312     return TRUE;
313 }
314