Diablo: disable autocap/predictive text for the other_browser_cmd entry
[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 Steven Luo
6  * 
7  * Derived from services-cp.c from maemo-control-services
8  * Copyright (c) 2008 Janne Kataja <janne.kataja@iki.fi>
9  * Copyright (c) 2008 Nokia Corporation
10  * 
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24  * USA.
25  */
26
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <glib.h>
34 #include <glib/gstdio.h>
35 #include <gtk/gtk.h>
36
37 #ifdef HILDON
38 #include <hildon/hildon-banner.h>
39 #include <hildon/hildon-program.h>
40
41 #ifdef FREMANTLE
42 #include <hildon/hildon-touch-selector.h>
43 #include <hildon/hildon-picker-button.h>
44 #include <hildon/hildon-caption.h>
45 #include <hildon/hildon-entry.h>
46 #endif /* FREMANTLE */
47
48 #ifdef HILDON_CP_APPLET
49 #include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
50 #endif /* HILDON_CP_APPLET */
51 #endif /* HILDON */
52
53 #include "configfile.h"
54
55 #define CONTINUOUS_MODE_DEFAULT 0
56
57 #if defined(HILDON) && defined(FREMANTLE)
58 #define _HILDON_SIZE_DEFAULT (HILDON_SIZE_AUTO_WIDTH|HILDON_SIZE_FINGER_HEIGHT)
59 #endif
60
61 struct browser_entry {
62         char *config;
63         char *displayname;
64 };
65 struct browser_entry browsers[] = {
66         { "microb", "MicroB" }, /* First entry is the default! */
67         { "tear", "Tear" },
68         { "fennec", "Mobile Firefox (Fennec)" },
69         { "midori", "Midori" },
70         { "other", "Other" },
71         { NULL, NULL },
72 };
73
74 struct config_widgets {
75 #if defined(HILDON) && defined(FREMANTLE)
76         GtkWidget *continuous_mode_selector;
77         GtkWidget *default_browser_selector;
78 #else
79         GtkWidget *continuous_mode_off_radio;
80         GtkWidget *continuous_mode_on_radio;
81         GtkWidget *default_browser_combo;
82 #endif
83         GtkWidget *other_browser_cmd_entry;
84         GtkWidget *other_browser_cmd_entry_label;
85 };
86 struct config_widgets cw;
87 GtkWidget *dialog;
88
89
90 /**********************************************************************
91  * Configuration routines
92  **********************************************************************/
93
94 #if defined(HILDON) && defined(FREMANTLE)
95
96 static inline int get_continuous_mode(void) {
97         return hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), 0);
98 }
99 static inline void set_continuous_mode(int state) {
100         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), 0, state);
101 }
102
103 static inline char *get_default_browser(void) {
104         return browsers[hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0)].config;
105 }
106
107 #else /* !defined(HILDON) || !defined(FREMANTLE) */
108
109 static inline int get_continuous_mode(void) {
110         return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio));
111 }
112 static inline void set_continuous_mode(int state) {
113         if (state)
114                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_on_radio), TRUE);
115         else
116                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.continuous_mode_off_radio), TRUE);
117 }
118
119 static inline char *get_default_browser(void) {
120         return browsers[gtk_combo_box_get_active(GTK_COMBO_BOX(cw.default_browser_combo))].config;
121 }
122
123 #endif /* defined(HILDON) && defined(FREMANTLE) */
124
125 static void set_default_browser(char *browser) {
126         gint i;
127
128         /* Loop through browsers looking for a match */
129         for (i = 0; browsers[i].config && strcmp(browsers[i].config, browser);
130                         ++i);
131
132         if (!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         FILE *fp;
152         int continuous_mode_seen = 0;
153         int default_browser_seen = 0;
154         int other_browser_cmd_seen = 0;
155         struct swb_config_line line;
156
157         if (!(fp = open_config_file()))
158                 return;
159
160         /* Parse the config file
161            TODO: should we handle errors differently than EOF? */
162         if (!parse_config_file_begin())
163                 goto out;
164         while (!parse_config_file_line(fp, &line)) {
165                 if (line.parsed) {
166                         if (!strcmp(line.key, "continuous_mode")) {
167                                 if (!continuous_mode_seen) {
168                                         set_continuous_mode(atoi(line.value));
169                                         continuous_mode_seen = 1;
170                                 }
171                         } else if (!strcmp(line.key, "default_browser")) {
172                                 if (!default_browser_seen) {
173                                         set_default_browser(line.value);
174                                         default_browser_seen = 1;
175                                 }
176                         } else if (!strcmp(line.key, "other_browser_cmd")) {
177                                 if (!other_browser_cmd_seen) {
178                                         set_other_browser_cmd(line.value);
179                                         other_browser_cmd_seen = 1;
180                                 }
181                         }
182                 }
183                 free(line.key);
184                 free(line.value);
185         }
186         parse_config_file_end();
187
188 out:
189         fclose(fp);
190         return;
191 }
192
193 static void save_config(void) {
194         FILE *fp = NULL, *tmpfp = NULL;
195         char *homedir, *tempfile, *newfile;
196         size_t len;
197         int continuous_mode_seen = 0;
198         int default_browser_seen = 0;
199         int other_browser_cmd_seen = 0;
200         struct swb_config_line line;
201
202         /* If CONFIGFILE_DIR doesn't exist already, try to create it */
203         if (!(homedir = getenv("HOME")))
204                 homedir = DEFAULT_HOMEDIR;
205         len = strlen(homedir) + strlen(CONFIGFILE_DIR) + 1;
206         if (!(newfile = calloc(len, sizeof(char))))
207                 return;
208         snprintf(newfile, len, "%s%s", homedir, CONFIGFILE_DIR);
209         if (access(newfile, F_OK) == -1 && errno == ENOENT) {
210                 mkdir(newfile, 0750);
211         }
212         free(newfile);
213
214         /* Put together the path to the new config file and the tempfile */
215         len = strlen(homedir) + strlen(CONFIGFILE_LOC) + 1;
216         if (!(newfile = calloc(len, sizeof(char))))
217                 return;
218         /* 4 = strlen(".tmp") */
219         if (!(tempfile = calloc(len+4, sizeof(char)))) {
220                 free(newfile);
221                 return;
222         }
223         snprintf(newfile, len, "%s%s", homedir, CONFIGFILE_LOC);
224         snprintf(tempfile, len+4, "%s%s", newfile, ".tmp");
225
226         /* Open the temporary file for writing */
227         if (!(tmpfp = fopen(tempfile, "w")))
228                 /* TODO: report the error somehow? */
229                 goto out;
230
231         /* Open the old config file, if it exists */
232         if ((fp = open_config_file()) && parse_config_file_begin()) {
233                 /* Copy the old config file over to the new one line by line,
234                    replacing old config values with new ones
235                    TODO: should we handle errors differently than EOF? */
236                 while (!parse_config_file_line(fp, &line)) {
237                         if (line.parsed) {
238                                 /* Is a config line, print the new value here */
239                                 if (!strcmp(line.key, "continuous_mode")) {
240                                         if (!continuous_mode_seen) {
241                                                 fprintf(tmpfp, "%s = %d\n",
242                                                         line.key,
243                                                         get_continuous_mode());
244                                                 continuous_mode_seen = 1;
245                                         }
246                                 } else if (!strcmp(line.key,
247                                                         "default_browser")) {
248                                         if (!default_browser_seen) {
249                                                 fprintf(tmpfp, "%s = \"%s\"\n",
250                                                         line.key,
251                                                         get_default_browser());
252                                                 default_browser_seen = 1;
253                                         }
254                                 } else if (!strcmp(line.key,
255                                                         "other_browser_cmd")) {
256                                         if (!other_browser_cmd_seen &&
257                                             strlen(get_other_browser_cmd())>0) {
258                                                 fprintf(tmpfp, "%s = \"%s\"\n",
259                                                         line.key,
260                                                         get_other_browser_cmd());
261                                                 other_browser_cmd_seen = 1;
262                                         }
263                                 }
264                         } else {
265                                 /* Just copy the old line over */
266                                 fprintf(tmpfp, "%s\n", line.key);
267                         }
268                         free(line.key);
269                         free(line.value);
270                 }
271                 parse_config_file_end();
272         }
273
274         /* If we haven't written them yet, write out the new config values */
275         if (!continuous_mode_seen)
276                 fprintf(tmpfp, "%s = %d\n",
277                         "continuous_mode", get_continuous_mode());
278         if (!default_browser_seen)
279                 fprintf(tmpfp, "%s = \"%s\"\n",
280                         "default_browser", get_default_browser());
281         if (!other_browser_cmd_seen && strlen(get_other_browser_cmd()) > 0)
282                 fprintf(tmpfp, "%s = \"%s\"\n",
283                         "other_browser_cmd", get_other_browser_cmd());
284
285         /* Replace the old config file with the new one */
286         fclose(tmpfp);
287         tmpfp = NULL;
288         rename(tempfile, newfile);
289
290 out:
291         free(newfile);
292         free(tempfile);
293         if (tmpfp)
294                 fclose(tmpfp);
295         if (fp)
296                 fclose(fp);
297         return;
298 }
299
300 static void do_reconfig(void) {
301         save_config();
302
303         /* Try to send SIGHUP to any running browser-switchboard process
304            This causes it to reread config files if in continuous_mode, and
305            die so that the config will be reloaded on next start otherwise */
306         system("kill -HUP `pidof browser-switchboard` > /dev/null 2>&1");
307 }
308
309
310 /**********************************************************************
311  * Callbacks
312  **********************************************************************/
313
314 #if defined(HILDON) && defined(FREMANTLE)
315 static void default_browser_selector_callback(GtkWidget *widget,
316                 gint column, gpointer data) {
317 #else
318 static void default_browser_combo_callback(GtkWidget *widget, gpointer data) {
319 #endif
320         if (!strcmp(get_default_browser(), "other")) {
321                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), TRUE);
322                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, TRUE);
323                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, TRUE);
324         } else {
325                 gtk_editable_set_editable(GTK_EDITABLE(cw.other_browser_cmd_entry), FALSE); /* FREMANTLE: give the text the greyed-out look */
326                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
327                 gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
328         }
329 }
330
331
332 /**********************************************************************
333  * Interface
334  **********************************************************************/
335
336 #if defined(HILDON) && defined(FREMANTLE)
337 /*
338  * Fremantle Hildon dialog
339  */
340 static GtkDialog *swb_config_dialog(gpointer cp_window) {
341         GtkWidget *dialog_vbox;
342
343         GtkWidget *default_browser_selector_button;
344         GtkWidget *continuous_mode_selector_button;
345         int i;
346         HildonGtkInputMode input_mode;
347
348         dialog = gtk_dialog_new_with_buttons(
349                 "Browser Switchboard",
350                 GTK_WINDOW(cp_window),
351                 GTK_DIALOG_MODAL,
352                 GTK_STOCK_OK,
353                 GTK_RESPONSE_OK,
354                 GTK_STOCK_CANCEL,
355                 GTK_RESPONSE_CANCEL,
356                 NULL);
357
358         dialog_vbox = GTK_DIALOG(dialog)->vbox;
359
360         /* Config options */
361         cw.default_browser_selector = hildon_touch_selector_new_text();
362         for (i = 0; browsers[i].config; ++i)
363                 hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), browsers[i].displayname);
364         hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(cw.default_browser_selector), 0, 0);
365         default_browser_selector_button = hildon_picker_button_new(_HILDON_SIZE_DEFAULT, HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
366         hildon_button_set_title(HILDON_BUTTON(default_browser_selector_button),
367                                 "Default browser:");
368         hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(default_browser_selector_button), HILDON_TOUCH_SELECTOR(cw.default_browser_selector));
369         hildon_button_set_alignment(HILDON_BUTTON(default_browser_selector_button),
370                                     0, 0.5, 0, 0);
371         g_signal_connect(G_OBJECT(cw.default_browser_selector), "changed",
372                          G_CALLBACK(default_browser_selector_callback), NULL);
373         gtk_box_pack_start(GTK_BOX(dialog_vbox),
374                            default_browser_selector_button, FALSE, FALSE, 0);
375
376         cw.other_browser_cmd_entry = hildon_entry_new(_HILDON_SIZE_DEFAULT);
377         /* Disable autocapitalization and dictionary features for the entry */
378         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
379         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
380                         HILDON_GTK_INPUT_MODE_DICTIONARY);
381         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
382
383         cw.other_browser_cmd_entry_label = hildon_caption_new(NULL,
384                         "Command (%s for URI):",
385                         cw.other_browser_cmd_entry,
386                         NULL, HILDON_CAPTION_OPTIONAL);
387         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
388         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
389         hildon_gtk_widget_set_theme_size(cw.other_browser_cmd_entry_label, _HILDON_SIZE_DEFAULT);
390         gtk_box_pack_start(GTK_BOX(dialog_vbox),
391                            cw.other_browser_cmd_entry_label, FALSE, FALSE, 0);
392
393         cw.continuous_mode_selector = hildon_touch_selector_new_text();
394         hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), "Lower memory usage");
395         hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector), "Faster browser startup time");
396
397         continuous_mode_selector_button = hildon_picker_button_new(_HILDON_SIZE_DEFAULT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
398         hildon_button_set_title(HILDON_BUTTON(continuous_mode_selector_button),
399                                 "Optimize Browser Switchboard for:");
400         hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(continuous_mode_selector_button), HILDON_TOUCH_SELECTOR(cw.continuous_mode_selector));
401         hildon_button_set_alignment(HILDON_BUTTON(continuous_mode_selector_button),
402                                     0, 0, 0, 0);
403         set_continuous_mode(CONTINUOUS_MODE_DEFAULT);
404         gtk_box_pack_start(GTK_BOX(dialog_vbox),
405                            continuous_mode_selector_button, FALSE, FALSE, 0);
406
407         gtk_widget_show_all(dialog);
408         return GTK_DIALOG(dialog);
409 }
410
411 #else /* !defined(HILDON) || !defined(FREMANTLE) */
412 /*
413  * GTK+/Diablo Hildon dialog
414  */
415 static GtkDialog *swb_config_dialog(gpointer cp_window) {
416         GtkWidget *dialog_vbox;
417
418         GtkWidget *options_table;
419         GtkWidget *default_browser_combo_label;
420         GtkWidget *continuous_mode_label;
421         int i;
422 #ifdef HILDON
423         HildonGtkInputMode input_mode;
424 #endif
425
426         dialog = gtk_dialog_new_with_buttons(
427                 "Browser Switchboard",
428                 GTK_WINDOW(cp_window),
429                 GTK_DIALOG_MODAL,
430                 GTK_STOCK_OK,
431                 GTK_RESPONSE_OK,
432                 GTK_STOCK_CANCEL,
433                 GTK_RESPONSE_CANCEL,
434                 NULL);
435
436         dialog_vbox = GTK_DIALOG(dialog)->vbox;
437
438         /* Config options */
439         options_table = gtk_table_new(3, 2, FALSE);
440         gtk_table_set_row_spacings(GTK_TABLE(options_table), 5);
441         gtk_box_pack_start(GTK_BOX(dialog_vbox), options_table, FALSE, FALSE, 0);
442
443         cw.default_browser_combo = gtk_combo_box_new_text();
444         for (i = 0; browsers[i].config; ++i)
445                 gtk_combo_box_append_text(GTK_COMBO_BOX(cw.default_browser_combo),
446                                           browsers[i].displayname);
447         gtk_combo_box_set_active(GTK_COMBO_BOX(cw.default_browser_combo), 0);
448         default_browser_combo_label = gtk_label_new("Default browser:");
449         gtk_misc_set_alignment(GTK_MISC(default_browser_combo_label), 1, 0.5);
450         g_signal_connect(G_OBJECT(cw.default_browser_combo), "changed",
451                          G_CALLBACK(default_browser_combo_callback), NULL);
452         gtk_table_attach(GTK_TABLE(options_table),
453                         default_browser_combo_label,
454                         0, 1,
455                         0, 1,
456                         GTK_FILL, GTK_FILL|GTK_EXPAND,
457                         5, 0);
458         gtk_table_attach(GTK_TABLE(options_table),
459                         cw.default_browser_combo,
460                         1, 2,
461                         0, 1,
462                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
463                         5, 0);
464
465         cw.other_browser_cmd_entry = gtk_entry_new();
466 #ifdef HILDON
467         /* Disable autocapitalization and dictionary features for the entry */
468         input_mode = hildon_gtk_entry_get_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry));
469         input_mode &= ~(HILDON_GTK_INPUT_MODE_AUTOCAP |
470                         HILDON_GTK_INPUT_MODE_DICTIONARY);
471         hildon_gtk_entry_set_input_mode(GTK_ENTRY(cw.other_browser_cmd_entry), input_mode);
472 #endif
473         cw.other_browser_cmd_entry_label = gtk_label_new("Command (%s for URI):");
474         gtk_misc_set_alignment(GTK_MISC(cw.other_browser_cmd_entry_label), 1, 0.5);
475         gtk_widget_set_sensitive(cw.other_browser_cmd_entry, FALSE);
476         gtk_widget_set_sensitive(cw.other_browser_cmd_entry_label, FALSE);
477         gtk_table_attach(GTK_TABLE(options_table),
478                         cw.other_browser_cmd_entry_label,
479                         0, 1,
480                         1, 2,
481                         GTK_FILL, GTK_FILL|GTK_EXPAND,
482                         5, 0);
483         gtk_table_attach(GTK_TABLE(options_table),
484                         cw.other_browser_cmd_entry,
485                         1, 2,
486                         1, 2,
487                         GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND,
488                         5, 0);
489         gtk_table_set_row_spacing(GTK_TABLE(options_table), 1, 15);
490
491         continuous_mode_label = gtk_label_new("Optimize Browser Switchboard for:");
492         gtk_misc_set_alignment(GTK_MISC(continuous_mode_label), 0, 0.5);
493         cw.continuous_mode_off_radio = gtk_radio_button_new_with_label(NULL,
494                         "Lower memory usage");
495         cw.continuous_mode_on_radio = gtk_radio_button_new_with_label_from_widget(
496                         GTK_RADIO_BUTTON(cw.continuous_mode_off_radio),
497                         "Faster browser startup time");
498         set_continuous_mode(CONTINUOUS_MODE_DEFAULT);
499         gtk_table_attach(GTK_TABLE(options_table),
500                         continuous_mode_label,
501                         0, 2,
502                         2, 3,
503                         GTK_FILL, GTK_FILL|GTK_EXPAND,
504                         5, 0);
505         gtk_table_attach(GTK_TABLE(options_table),
506                         cw.continuous_mode_off_radio,
507                         0, 2,
508                         3, 4,
509                         GTK_FILL, GTK_FILL|GTK_EXPAND,
510                         20, 0);
511         gtk_table_attach(GTK_TABLE(options_table),
512                         cw.continuous_mode_on_radio,
513                         0, 2,
514                         4, 5,
515                         GTK_FILL, GTK_FILL|GTK_EXPAND,
516                         20, 5);
517         gtk_table_set_row_spacing(GTK_TABLE(options_table), 3, 0);
518
519
520         gtk_widget_show_all(dialog);
521         return GTK_DIALOG(dialog);
522 }
523
524 #endif /* defined(HILDON) && defined(FREMANTLE) */
525
526
527 /**********************************************************************
528  * Entry
529  **********************************************************************/
530
531 #ifdef HILDON_CP_APPLET
532 /*
533  * Application was started from control panel.
534  */
535 osso_return_t execute(osso_context_t *osso,
536                       gpointer userdata, gboolean user_activated) {
537         GtkDialog *dialog;
538         gint response;
539
540         if (osso == NULL)
541                 return OSSO_ERROR;
542
543         dialog = GTK_DIALOG(swb_config_dialog(userdata));
544         load_config();
545
546         response = gtk_dialog_run(dialog);
547         if (response == GTK_RESPONSE_OK)
548                 do_reconfig();
549
550         gtk_widget_destroy(GTK_WIDGET(dialog));
551
552         return OSSO_OK;
553 }
554 #else
555 /*
556  * Application was started from command line.
557  */
558 int main(int argc, char *argv[]) {
559         GtkDialog *dialog;
560         gint response;
561 #ifdef HILDON
562         HildonProgram *program = NULL;
563 #endif
564
565         gtk_init(&argc, &argv);
566 #ifdef HILDON
567         program = HILDON_PROGRAM(hildon_program_get_instance());
568 #endif
569
570         g_set_application_name("Browser Switchboard");
571
572         dialog = GTK_DIALOG(swb_config_dialog(NULL));
573         load_config();
574
575         response = gtk_dialog_run(dialog);
576         if (response == GTK_RESPONSE_OK)
577                 do_reconfig();
578
579         gtk_widget_destroy(GTK_WIDGET(dialog));
580
581         exit(0);
582 }
583 #endif /* HILDON_CP_APPLET */