Change the profile concept to presets.
[tweakr] / modules / tweakr-profile-status-menu-widget.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.h>
11 #include <hildon/hildon-button.h>
12 #include <hildon/hildon-pannable-area.h>
13 #include <libhildondesktop/libhildondesktop.h>
14
15 #include <gconf/gconf-client.h>
16
17 #include <libprofile.h>
18
19 #define TYPE_TWEAKR_PROFILE_STATUS_PLUGIN \
20         (tweakr_profile_status_plugin_get_type ())
21 #define TWEAKR_PROFILE_STATUS_PLUGIN(obj) \
22         (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
23         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN, \
24         TweakrProfileStatusPlugin))
25 #define TWEAKR_PROFILE_STATUS_PLUGIN_CLASS(klass) \
26         (G_TYPE_CHECK_CLASS_CAST ((klass), \
27         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN, \
28         TweakrProfileStatusPluginClass))
29 #define IS_TWEAKR_PROFILE_STATUS_PLUGIN(obj) \
30         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
31         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN))
32 #define IS_TWEAKR_PROFILE_STATUS_PLUGIN_CLASS(klass) \
33         (G_TYPE_CHECK_CLASS_TYPE ((klass), \
34         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN))
35 #define TWEAKR_PROFILE_STATUS_PLUGIN_GET_CLASS(obj) \
36         (G_TYPE_INSTANCE_GET_CLASS ((obj), \
37         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN, \
38         TweakrProfileStatusPluginClass))
39
40 typedef struct _TweakrProfileStatusPlugin        TweakrProfileStatusPlugin;
41 typedef struct _TweakrProfileStatusPluginClass
42                TweakrProfileStatusPluginClass;
43 typedef struct _TweakrProfileStatusPluginPrivate
44                TweakrProfileStatusPluginPrivate; 
45
46 struct _TweakrProfileStatusPlugin
47 {
48     HDStatusMenuItem parent;
49
50     TweakrProfileStatusPluginPrivate *priv;
51 };
52
53 struct _TweakrProfileStatusPluginClass
54 {
55     HDStatusMenuItemClass parent;
56 };
57
58 GType tweakr_profile_status_plugin_get_type (void);
59
60 #define TWEAKR_PROFILE_STATUS_PLUGIN_GET_PRIVATE(obj) \
61         (G_TYPE_INSTANCE_GET_PRIVATE (obj, \
62         TYPE_TWEAKR_PROFILE_STATUS_PLUGIN, \
63         TweakrProfileStatusPluginPrivate))
64
65 #define GCONF_PATH "/system/tweakr"
66
67 struct _TweakrProfileStatusPluginPrivate
68 {
69     GtkWidget *button;
70     GtkWidget *dialog;
71     GtkWidget *box;
72     GConfClient *gconf;
73 };
74
75 HD_DEFINE_PLUGIN_MODULE (TweakrProfileStatusPlugin,
76                          tweakr_profile_status_plugin,
77                          HD_TYPE_STATUS_MENU_ITEM);
78
79 static void
80 _process_entry (GConfEntry *entry, TweakrProfileStatusPlugin *plugin)
81 {
82     gchar *basename;
83
84     basename = g_path_get_basename (entry->key);
85
86     profile_set_value ("general", basename,
87                          gconf_value_get_string (entry->value));
88
89     g_free (basename);
90     gconf_entry_free (entry);
91 }
92
93 static void
94 _preset_clicked (HildonButton *button, TweakrProfileStatusPlugin *plugin)
95 {
96     GSList *entries;
97     const gchar *path = g_object_get_data (G_OBJECT (button), "path");
98     gchar *basename;
99
100     entries = gconf_client_all_entries (plugin->priv->gconf, path, NULL);
101
102     g_slist_foreach (entries, (GFunc) _process_entry, plugin);
103     g_slist_free (entries);
104
105     profile_set_profile ("general");
106
107     basename = g_path_get_basename (path);
108     hildon_button_set_value (HILDON_BUTTON (plugin->priv->button), basename);
109     gconf_client_set_string (plugin->priv->gconf,
110                              "/system/tweakr/current-preset", basename, NULL);
111     g_free (basename);
112
113     gtk_dialog_response (GTK_DIALOG (plugin->priv->dialog), GTK_RESPONSE_OK);
114     hildon_banner_show_information (NULL, NULL,
115                                     _("Preset activated."));
116 }
117
118 static void
119 _add_preset (gchar *preset, TweakrProfileStatusPlugin *plugin)
120 {
121     GtkWidget *button;
122     gchar *basename;
123
124     basename = g_path_get_basename (preset);
125     button = hildon_button_new_with_text
126         (HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL,
127          basename, NULL);
128     gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f);
129     gtk_box_pack_start (GTK_BOX (plugin->priv->box), button, FALSE, FALSE, 0);
130     g_object_set_data_full (G_OBJECT (button), "path", preset,
131                             (GDestroyNotify) g_free);
132     g_signal_connect (button, "clicked", G_CALLBACK (_preset_clicked),
133                       plugin);
134 }
135
136 static void
137 _button_clicked (HildonButton *b, TweakrProfileStatusPlugin *plugin)
138 {
139     GtkWidget *panarea;
140     gint ret;
141     GSList *presets;
142     GtkWidget *parent;
143
144     parent = gtk_widget_get_ancestor (GTK_WIDGET (b), GTK_TYPE_WINDOW);
145     gtk_widget_hide (parent);
146
147     plugin->priv->dialog = gtk_dialog_new ();
148     gtk_window_set_modal (GTK_WINDOW (plugin->priv->dialog), TRUE);
149     gtk_window_set_title (GTK_WINDOW (plugin->priv->dialog),
150                           _("Select preset"));
151
152     panarea = hildon_pannable_area_new ();
153     plugin->priv->box = gtk_vbox_new (FALSE, 0);
154
155     hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (panarea),
156                                             plugin->priv->box);
157     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (plugin->priv->dialog)->vbox),
158                         panarea, TRUE, TRUE, 0);
159
160     presets = gconf_client_all_dirs (plugin->priv->gconf, GCONF_PATH, NULL);
161
162     g_object_set (G_OBJECT (panarea), "height-request",
163                   MIN (350, g_slist_length (presets) * 70), NULL);
164
165     g_slist_foreach (presets, (GFunc) _add_preset, plugin);
166
167     gtk_widget_show_all (GTK_DIALOG (plugin->priv->dialog)->vbox);
168     ret = gtk_dialog_run (GTK_DIALOG (plugin->priv->dialog));
169     gtk_widget_destroy (plugin->priv->dialog);
170
171     g_slist_free (presets);
172 }
173
174 static void
175 tweakr_profile_status_plugin_class_finalize
176     (TweakrProfileStatusPluginClass *klass)
177 {
178 }
179
180 static void
181 tweakr_profile_status_plugin_dispose (GObject *obj)
182 {
183     TweakrProfileStatusPlugin *plugin = TWEAKR_PROFILE_STATUS_PLUGIN (obj);
184
185     if (plugin->priv->gconf != NULL)
186     {
187         g_object_unref (plugin->priv->gconf);
188         plugin->priv->gconf = NULL;
189     }
190
191     G_OBJECT_CLASS (tweakr_profile_status_plugin_parent_class)->dispose (obj);
192 }
193
194 static void
195 tweakr_profile_status_plugin_class_init
196     (TweakrProfileStatusPluginClass *klass)
197 {
198     GObjectClass *object_class = G_OBJECT_CLASS (klass);
199
200     object_class->dispose = tweakr_profile_status_plugin_dispose;
201
202     g_type_class_add_private (klass,
203                               sizeof (TweakrProfileStatusPluginPrivate));
204 }
205
206 static void
207 tweakr_profile_status_plugin_init (TweakrProfileStatusPlugin *plugin)
208 {
209     gchar *current;
210     GtkWidget *image;
211
212     plugin->priv = TWEAKR_PROFILE_STATUS_PLUGIN_GET_PRIVATE (plugin);
213
214     plugin->priv->gconf = gconf_client_get_default ();
215     plugin->priv->button = hildon_button_new
216         (HILDON_SIZE_AUTO | HILDON_SIZE_FINGER_HEIGHT,
217          HILDON_BUTTON_ARRANGEMENT_VERTICAL);
218     hildon_button_set_title (HILDON_BUTTON (plugin->priv->button),
219                              _("Tweakr profile preset"));
220
221     current = gconf_client_get_string (plugin->priv->gconf,
222                                        "/system/tweakr/current-preset",
223                                        NULL);
224     hildon_button_set_value (HILDON_BUTTON (plugin->priv->button), current);
225     g_free (current);
226     gtk_button_set_alignment (GTK_BUTTON (plugin->priv->button), 0.0f, 0.5f);
227
228     image = gtk_image_new_from_icon_name ("control_tweakr",
229                                           GTK_ICON_SIZE_BUTTON);
230     hildon_button_set_image (HILDON_BUTTON (plugin->priv->button), image);
231
232     g_signal_connect (G_OBJECT (plugin->priv->button), "clicked",
233                       G_CALLBACK (_button_clicked), plugin);
234
235     gtk_container_add (GTK_CONTAINER (plugin), plugin->priv->button);
236     gtk_widget_show_all (plugin->priv->button);
237
238     gtk_widget_show (GTK_WIDGET (plugin));
239 }
240