Provide open_new_window and load_url methods with boolean fullscreen argument
[browser-switch] / config-ui / browser-switchboard-cp.c
1 /*
2  * browser-switchboard-cp.c -- a hildon-control-panel applet for
3  * selecting the default browser for Browser Switchboard
4  *
5  * Copyright (C) 2009-2010 Steven Luo
6  * Copyright (C) 2009-2010 Faheem Pervez
7  *
8  * Derived from services-cp.c from maemo-control-services
9  * Copyright (c) 2008 Janne Kataja <janne.kataja@iki.fi>
10  * Copyright (c) 2008 Nokia Corporation
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25  * USA.
26  */
27
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <glib.h>
35 #include <glib/gstdio.h>
36 #include <gtk/gtk.h>
37
38 #ifdef HILDON
39 #include <hildon/hildon-banner.h>
40 #include <hildon/hildon-program.h>
41
42 #ifdef FREMANTLE
43 #include <hildon/hildon-touch-selector.h>
44 #include <hildon/hildon-picker-button.h>
45 #include <hildon/hildon-caption.h>
46 #include <hildon/hildon-entry.h>
47 #endif /* FREMANTLE */
48
49 #ifdef HILDON_CP_APPLET
50 #include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
51 #endif /* HILDON_CP_APPLET */
52 #endif /* HILDON */
53
54 #include "config.h"
55 #include "save-config.h"
56 #include "browsers.h"
57
58 #define CONTINUOUS_MODE_DEFAULT 0
59
60 #if defined(HILDON) && defined(FREMANTLE)
61 #define _HILDON_SIZE_DEFAULT (HILDON_SIZE_AUTO_WIDTH|HILDON_SIZE_FINGER_HEIGHT)
62 #endif
63
64 struct swb_config orig_cfg;
65
66 struct config_widgets {
67 #if defined(HILDON) && defined(FREMANTLE)
68         GtkWidget *default_browser_selector;
69 #else
70         GtkWidget *continuous_mode_off_radio;
71         GtkWidget *continuous_mode_on_radio;
72         GtkWidget *default_browser_combo;
73 #endif
74         GtkWidget *other_browser_cmd_entry;
75         GtkWidget *other_browser_cmd_entry_label;
76 };
77 struct config_widgets cw;
78 GtkWidget *dialog;
79
80
81 struct browser_entry *installed_browsers;
82 void init_installed_browsers(void) {
83         struct browser_entry *cur = browsers;
84         unsigned int count = 0;
85
86         installed_browsers = calloc(sizeof browsers, 1);
87         if (!installed_browsers)
88                 exit(1);
89
90         count = 0;
91         for (; cur->config; ++cur)
92                 if (!cur->binary || !access(cur->binary, X_OK))
93                         installed_browsers[count++] = *cur;
94 }
95
96 /**********************************************************************
97  * Configuration routines
98  **********************************************************************/
99
100 #if defined(HILDON) && defined(FREMANTLE)
101
102 static inline char *get_default_browser(void) {
103         return installed_browsers[hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0)].config;
104 }
105
106 #else /* !defined(HILDON) || !defined(FREMANTLE) */
107
108 static inline int get_continuous_mode(void) {
109         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio));
110 }
111 static inline void set_continuous_mode(int state) {
112         if (state)
113                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio), TRUE);
114         else
115                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_off_radio), TRUE);
116 }
117
118 static inline char *get_default_browser(void) {
119         return installed_browsers[gtk_combo_box_get_active(GTK_COMBO_BOX(cw.default_browser_combo))].config;
120 }
121
122 #endif /* defined(HILDON) && defined(FREMANTLE) */
123
124 static void set_default_browser(char *browser) {
125         gint i;
126
127         /* Loop through browsers looking for a match */
128         for (i = 0;
129              installed_browsers[i].config && strcmp(installed_browsers[i].config, browser);
130              ++i);
131
132         if (!installed_browsers[i].config)
133                 /* No match found, set to the default browser */
134                 i = 0;
135
136 #if defined(HILDON) && defined(FREMANTLE)
137         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0, i);
138 #else
139         gtk_combo_box_set_active(GTK_COMBO_BOX(cw.default_browser_combo), i);
140 #endif
141 }
142
143 static inline char *get_other_browser_cmd(void) {
144         return (char *)gtk_entry_get_text(GTK_ENTRY(cw.other_browser_cmd_entry));
145 }
146 static inline void set_other_browser_cmd(char *cmd) {
147         gtk_entry_set_text(GTK_ENTRY(cw.other_browser_cmd_entry), cmd);
148 }
149
150 static void load_config(void) {
151         swb_config_init(&orig_cfg);
152
153         swb_config_load(&orig_cfg);
154
155 #ifndef FREMANTLE
156         set_continuous_mode(orig_cfg.continuous_mode);
157 #endif
158         set_default_browser(orig_cfg.default_browser);
159         if (orig_cfg.other_browser_cmd)
160                 set_other_browser_cmd(orig_cfg.other_browser_cmd);
161 }
162
163 static void save_config(void) {
164         struct swb_config new_cfg;
165
166         swb_config_copy(&new_cfg, &orig_cfg);
167
168 #ifndef FREMANTLE
169         if (get_continuous_mode() != orig_cfg.continuous_mode) {
170                 new_cfg.continuous_mode = get_continuous_mode();
171                 new_cfg.flags |= SWB_CONFIG_CONTINUOUS_MODE_SET;
172         }
173 #endif
174         if (strcmp(get_default_browser(), orig_cfg.default_browser)) {
175                 new_cfg.default_browser = get_default_browser();
176                 new_cfg.flags |= SWB_CONFIG_DEFAULT_BROWSER_SET;
177         }
178         if (strlen(get_other_browser_cmd()) == 0) {
179                 new_cfg.other_browser_cmd = NULL;
180                 new_cfg.flags &= ~SWB_CONFIG_OTHER_BROWSER_CMD_SET;
181         } else if (!(orig_cfg.other_browser_cmd &&
182                      !strcmp(get_other_browser_cmd(),
183                              orig_cfg.other_browser_cmd))) {
184                 new_cfg.other_browser_cmd = get_other_browser_cmd();
185                 new_cfg.flags |= SWB_CONFIG_OTHER_BROWSER_CMD_SET;
186         }
187
188         swb_config_save(&new_cfg);
189
190         /* Reconfigure a running browser-switchboard, if present */
191         swb_reconfig(&orig_cfg, &new_cfg);
192 }
193
194
195 /**********************************************************************
196  * Callbacks
197  **********************************************************************/
198
199 #if defined(HILDON) && defined(FREMANTLE)
200 static void default_browser_selector_callback(GtkWidget *widget,
201                 gint column, gpointer data) {
202 #else
203 static void default_browser_combo_callback(GtkWidget *widget, gpointer data) {
204 #endif
205         if (!strcmp(get_default_browser(), "other")) {
206                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), TRUE);
207                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, TRUE);
208                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, TRUE);
209         } else {
210                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), FALSE); /* FREMANTLE: give the text the greyed-out look */
211                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
212                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
213         }
214 }
215
216
217 /**********************************************************************
218  * Interface
219  **********************************************************************/
220
221 #if defined(HILDON) && defined(FREMANTLE)
222 /*
223  * Fremantle Hildon dialog
224  */
225 static GtkDialog *swb_config_dialog(gpointer cp_window) {
226         GtkWidget *dialog_vbox;
227
228         GtkWidget *default_browser_selector_button;
229         int i;
230         HildonGtkInputMode input_mode;
231
232         dialog = gtk_dialog_new_with_buttons(
233                 "Browser Switchboard",
234                 GTK_WINDOW(cp_window),
235                 GTK_DIALOG_MODAL,
236                 GTK_STOCK_OK,
237                 GTK_RESPONSE_OK,
238                 GTK_STOCK_CANCEL,
239                 GTK_RESPONSE_CANCEL,
240                 NULL);
241
242         dialog_vbox = GTK_DIALOG(dialog)->vbox;
243
244         /* Config options */
245         init_installed_browsers();
246         cw.default_browser_selector = hildon_touch_selector_new_text();
247         for (i = 0; installed_browsers[i].config; ++i)
248                 hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), installed_browsers[i].displayname);
249         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0, 0);
250         default_browser_selector_button = hildon_picker_button_new(_HILDON_SIZE_DEFAULT, HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
251         hildon_button_set_title(HILDON_BUTTON(default_browser_selector_button),
252                                 "Default browser:");
253         hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(default_browser_selector_button), HILDON_TOUCH_SELECTOR(cw.default_browser_selector));
254         hildon_button_set_alignment(HILDON_BUTTON(default_browser_selector_button),
255                                     0, 0.5, 0, 0);
256         g_signal_connect(G_OBJECT(cw.default_browser_selector), "changed",
257                          G_CALLBACK(default_browser_selector_callback), NULL);
258         gtk_box_pack_start(GTK_BOX(dialog_vbox),
259                            default_browser_selector_button, FALSE, FALSE, 0);
260
261         cw.other_browser_cmd_entry = hildon_entry_new(_HILDON_SIZE_DEFAULT);
262         /* Disable autocapitalization and dictionary features for the entry */
263         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
264         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
265                         HILDON_GTK_INPUT_MODE_DICTIONARY);
266         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
267
268         cw.other_browser_cmd_entry_label = hildon_caption_new(NULL,
269                         "Command (%s for URI):",
270                         cw.other_browser_cmd_entry,
271                         NULL, HILDON_CAPTION_OPTIONAL);
272         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
273         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
274         hildon_gtk_widget_set_theme_size(cw.other_browser_cmd_entry_label, _HILDON_SIZE_DEFAULT);
275         gtk_box_pack_start(GTK_BOX(dialog_vbox),
276                            cw.other_browser_cmd_entry_label, FALSE, FALSE, 0);
277
278         gtk_widget_show_all(dialog);
279         return GTK_DIALOG(dialog);
280 }
281
282 #else /* !defined(HILDON) || !defined(FREMANTLE) */
283 /*
284  * GTK+/Diablo Hildon dialog
285  */
286 static GtkDialog *swb_config_dialog(gpointer cp_window) {
287         GtkWidget *dialog_vbox;
288
289         GtkWidget *options_table;
290         GtkWidget *default_browser_combo_label;
291         GtkWidget *continuous_mode_label;
292         int i;
293 #ifdef HILDON
294         HildonGtkInputMode input_mode;
295 #endif
296
297         dialog = gtk_dialog_new_with_buttons(
298                 "Browser Switchboard",
299                 GTK_WINDOW(cp_window),
300                 GTK_DIALOG_MODAL,
301                 GTK_STOCK_OK,
302                 GTK_RESPONSE_OK,
303                 GTK_STOCK_CANCEL,
304                 GTK_RESPONSE_CANCEL,
305                 NULL);
306
307         dialog_vbox = GTK_DIALOG(dialog)->vbox;
308
309         /* Config options */
310         options_table = gtk_table_new(3, 2, FALSE);
311         gtk_table_set_row_spacings(GTK_TABLE(options_table), 5);
312         gtk_box_pack_start(GTK_BOX(dialog_vbox), options_table, FALSE, FALSE, 0);
313
314         init_installed_browsers();
315         cw.default_browser_combo = gtk_combo_box_new_text();
316         for (i = 0; installed_browsers[i].config; ++i)
317                 gtk_combo_box_append_text(GTK_COMBO_BOX(cw.default_browser_combo),
318                                           installed_browsers[i].displayname);
319         gtk_combo_box_set_active(GTK_COMBO_BOX(cw.default_browser_combo), 0);
320         default_browser_combo_label = gtk_label_new("Default browser:");
321         gtk_misc_set_alignment(GTK_MISC(default_browser_combo_label), 1, 0.5);
322         g_signal_connect(G_OBJECT(cw.default_browser_combo), "changed",
323                          G_CALLBACK(default_browser_combo_callback), NULL);
324         gtk_table_attach(GTK_TABLE(options_table),
325                         default_browser_combo_label,
326                         0, 1,
327                         0, 1,
328                         GTK_FILL, GTK_FILL|GTK_EXPAND,
329                         5, 0);
330         gtk_table_attach(GTK_TABLE(options_table),
331                         cw.default_browser_combo,
332                         1, 2,
333                         0, 1,
334                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
335                         5, 0);
336
337         cw.other_browser_cmd_entry = gtk_entry_new();
338 #ifdef HILDON
339         /* Disable autocapitalization and dictionary features for the entry */
340         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
341         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
342                         HILDON_GTK_INPUT_MODE_DICTIONARY);
343         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
344 #endif
345         cw.other_browser_cmd_entry_label = gtk_label_new("Command (%s for URI):");
346         gtk_misc_set_alignment(GTK_MISC(cw.other_browser_cmd_entry_label), 1, 0.5);
347         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
348         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
349         gtk_table_attach(GTK_TABLE(options_table),
350                         cw.other_browser_cmd_entry_label,
351                         0, 1,
352                         1, 2,
353                         GTK_FILL, GTK_FILL|GTK_EXPAND,
354                         5, 0);
355         gtk_table_attach(GTK_TABLE(options_table),
356                         cw.other_browser_cmd_entry,
357                         1, 2,
358                         1, 2,
359                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
360                         5, 0);
361         gtk_table_set_row_spacing(GTK_TABLE(options_table), 1, 15);
362
363         continuous_mode_label = gtk_label_new("Optimize Browser Switchboard for:");
364         gtk_misc_set_alignment(GTK_MISC(continuous_mode_label), 0, 0.5);
365         cw.continuous_mode_off_radio = gtk_radio_button_new_with_label(NULL,
366                         "Lower memory usage");
367         cw.continuous_mode_on_radio = gtk_radio_button_new_with_label_from_widget(
368                         GTK_RADIO_BUTTON(cw.continuous_mode_off_radio),
369                         "Faster browser startup time");
370         set_continuous_mode(CONTINUOUS_MODE_DEFAULT);
371         gtk_table_attach(GTK_TABLE(options_table),
372                         continuous_mode_label,
373                         0, 2,
374                         2, 3,
375                         GTK_FILL, GTK_FILL|GTK_EXPAND,
376                         5, 0);
377         gtk_table_attach(GTK_TABLE(options_table),
378                         cw.continuous_mode_off_radio,
379                         0, 2,
380                         3, 4,
381                         GTK_FILL, GTK_FILL|GTK_EXPAND,
382                         20, 0);
383         gtk_table_attach(GTK_TABLE(options_table),
384                         cw.continuous_mode_on_radio,
385                         0, 2,
386                         4, 5,
387                         GTK_FILL, GTK_FILL|GTK_EXPAND,
388                         20, 5);
389         gtk_table_set_row_spacing(GTK_TABLE(options_table), 3, 0);
390
391
392         gtk_widget_show_all(dialog);
393         return GTK_DIALOG(dialog);
394 }
395
396 #endif /* defined(HILDON) && defined(FREMANTLE) */
397
398
399 /**********************************************************************
400  * Entry
401  **********************************************************************/
402
403 #ifdef HILDON_CP_APPLET
404 /*
405  * Application was started from control panel.
406  */
407 osso_return_t execute(osso_context_t *osso,
408                       gpointer userdata, gboolean user_activated) {
409         GtkDialog *dialog;
410         gint response;
411
412         if (osso == NULL)
413                 return OSSO_ERROR;
414
415         dialog = GTK_DIALOG(swb_config_dialog(userdata));
416         load_config();
417
418         response = gtk_dialog_run(dialog);
419         if (response == GTK_RESPONSE_OK)
420                 save_config();
421
422         gtk_widget_destroy(GTK_WIDGET(dialog));
423
424         return OSSO_OK;
425 }
426 #else
427 /*
428  * Application was started from command line.
429  */
430 int main(int argc, char *argv[]) {
431         GtkDialog *dialog;
432         gint response;
433 #ifdef HILDON
434         HildonProgram *program = NULL;
435 #endif
436
437         gtk_init(&argc, &argv);
438 #ifdef HILDON
439         program = HILDON_PROGRAM(hildon_program_get_instance());
440 #endif
441
442         g_set_application_name("Browser Switchboard");
443
444         dialog = GTK_DIALOG(swb_config_dialog(NULL));
445         load_config();
446
447         response = gtk_dialog_run(dialog);
448         if (response == GTK_RESPONSE_OK)
449                 save_config();
450
451         gtk_widget_destroy(GTK_WIDGET(dialog));
452
453         exit(0);
454 }
455 #endif /* HILDON_CP_APPLET */