1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
32 #include <modest-platform.h>
33 #include <modest-runtime.h>
34 #include <modest-main-window.h>
35 #include <modest-header-view.h>
36 #include "maemo/modest-maemo-global-settings-dialog.h"
37 #include "modest-widget-memory.h"
38 #include <modest-hildon-includes.h>
39 #include <osso-helplib.h>
40 #include <modest-maemo-utils.h>
41 #include <dbus_api/modest-dbus-callbacks.h>
42 #include <libosso-abook/osso-abook.h>
43 #include <maemo/modest-osso-autosave-callbacks.h>
45 #include <alarmd/alarm_event.h> /* For alarm_event_add(), etc. */
46 #include <tny-maemo-conic-device.h>
47 #include <tny-simple-list.h>
48 #include <tny-folder.h>
49 #include <tny-camel-imap-store-account.h>
50 #include <tny-camel-pop-store-account.h>
51 #include <gtk/gtkicontheme.h>
52 #include <gtk/gtkmenuitem.h>
53 #include <gtk/gtkmain.h>
54 #include <modest-text-utils.h>
55 #include "modest-tny-folder.h"
57 #include <libgnomevfs/gnome-vfs-mime-utils.h>
60 #define HILDON_OSSO_URI_ACTION "uri-action"
61 #define URI_ACTION_COPY "copy:"
63 static osso_context_t *osso_context = NULL;
66 on_modest_conf_update_interval_changed (ModestConf* self,
68 ModestConfEvent event,
69 ModestConfNotificationId id,
72 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
73 const guint update_interval_minutes =
74 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
75 modest_platform_set_update_interval (update_interval_minutes);
80 modest_platform_init (int argc, char *argv[])
82 osso_hw_state_t hw_state = { 0 };
86 osso_initialize(PACKAGE,PACKAGE_VERSION,
89 g_printerr ("modest: failed to acquire osso context\n");
93 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
94 g_printerr ("modest: could not get dbus connection\n");
99 /* Add a D-Bus handler to be used when the main osso-rpc
100 * D-Bus handler has not handled something.
101 * We use this for D-Bus methods that need to use more complex types
102 * than osso-rpc supports.
104 if (!dbus_connection_add_filter (con,
105 modest_dbus_req_filter,
109 g_printerr ("modest: Could not add D-Bus filter\n");
113 /* Register our simple D-Bus callbacks, via the osso API: */
114 osso_return_t result = osso_rpc_set_cb_f(osso_context,
118 modest_dbus_req_handler, NULL /* user_data */);
119 if (result != OSSO_OK) {
120 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
124 /* Add handler for Exit D-BUS messages.
125 * Not used because osso_application_set_exit_cb() is deprecated and obsolete:
126 result = osso_application_set_exit_cb(osso_context,
127 modest_dbus_exit_event_handler,
129 if (result != OSSO_OK) {
130 g_print("Error setting exit callback (%d)\n", result);
135 /* Register hardware event dbus callback: */
136 hw_state.shutdown_ind = TRUE;
137 osso_hw_set_event_cb(osso_context, NULL,/*&hw_state*/ modest_osso_cb_hw_state_handler, NULL);
139 /* Register osso auto-save callbacks: */
140 result = osso_application_set_autosave_cb (osso_context,
141 modest_on_osso_application_autosave, NULL /* user_data */);
142 if (result != OSSO_OK) {
143 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
148 /* Make sure that the update interval is changed whenever its gconf key
150 /* CAUTION: we're not using here the
151 modest_conf_listen_to_namespace because we know that there
152 are other parts of Modest listening for this namespace, so
153 we'll receive the notifications anyway. We basically do not
154 use it because there is no easy way to do the
155 modest_conf_forget_namespace */
156 ModestConf *conf = modest_runtime_get_conf ();
157 g_signal_connect (G_OBJECT(conf),
159 G_CALLBACK (on_modest_conf_update_interval_changed),
162 /* Get the initial update interval from gconf: */
163 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
164 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
166 /* initialize the addressbook */
167 if (!osso_abook_init (&argc, &argv, osso_context)) {
168 g_printerr ("modest: failed to initialized addressbook\n");
176 modest_platform_get_new_device (void)
178 return TNY_DEVICE (tny_maemo_conic_device_new ());
182 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
183 gchar **effective_mime_type)
185 GString *mime_str = NULL;
186 gchar *icon_name = NULL;
187 gchar **icons, **cursor;
189 if (!mime_type || !g_ascii_strcasecmp (mime_type, "application/octet-stream"))
190 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
192 mime_str = g_string_new (mime_type);
193 g_string_ascii_down (mime_str);
196 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
197 for (cursor = icons; cursor; ++cursor) {
198 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
199 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
200 icon_name = g_strdup ("qgn_list_messagin");
202 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
203 icon_name = g_strdup (*cursor);
209 if (effective_mime_type)
210 *effective_mime_type = g_string_free (mime_str, FALSE);
212 g_string_free (mime_str, TRUE);
219 modest_platform_activate_uri (const gchar *uri)
221 HildonURIAction *action;
222 gboolean result = FALSE;
223 GSList *actions, *iter = NULL;
226 g_return_val_if_fail (uri, FALSE);
230 scheme = hildon_uri_get_scheme_from_uri (uri, NULL);
231 actions = hildon_uri_get_actions (scheme, NULL);
233 for (iter = actions; iter; iter = g_slist_next (iter)) {
234 action = (HildonURIAction*) iter->data;
235 if (action && strcmp (hildon_uri_action_get_service (action),
236 "com.nokia.modest") == 0) {
238 result = hildon_uri_open (uri, action, &err);
239 if (!result && err) {
240 g_printerr ("modest: modest_platform_activate_uri : %s",
241 err->message ? err->message : "unknown error");
248 /* if we could open it with email, try something else */
250 result = hildon_uri_open (uri, NULL, NULL);
253 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
259 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
263 gchar *uri_path = NULL;
265 uri_path = g_strconcat ("file://", path, NULL);
266 con = osso_get_dbus_connection (osso_context);
269 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
271 result = hildon_mime_open_file (con, uri_path);
273 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"));
281 } ModestPlatformPopupInfo;
284 delete_uri_popup (GtkWidget *menu,
288 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
290 g_free (popup_info->uri);
291 hildon_uri_free_actions (popup_info->actions);
297 activate_uri_popup_item (GtkMenuItem *menu_item,
301 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
302 const gchar* action_name;
304 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
306 g_printerr ("modest: no action name defined\n");
310 /* special handling for the copy menu item -- copy the uri to the clipboard */
311 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
312 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
313 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
314 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
316 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
317 action_name += strlen ("mailto:");
319 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
320 return; /* we're done */
323 /* now, the real uri-actions... */
324 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
325 HildonURIAction *action = (HildonURIAction *) node->data;
326 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
327 hildon_uri_open (popup_info->uri, action, NULL);
334 modest_platform_show_uri_popup (const gchar *uri)
337 GSList *actions_list;
342 scheme = hildon_uri_get_scheme_from_uri (uri, NULL);
343 actions_list = hildon_uri_get_actions (scheme, NULL);
344 if (actions_list != NULL) {
346 GtkWidget *menu = gtk_menu_new ();
347 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
349 popup_info->actions = actions_list;
350 popup_info->uri = g_strdup (uri);
352 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
353 GtkWidget *menu_item;
354 const gchar *action_name;
355 const gchar *translation_domain;
356 HildonURIAction *action = (HildonURIAction *) node->data;
357 action_name = hildon_uri_action_get_name (action);
358 translation_domain = hildon_uri_action_get_translation_domain (action);
359 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
360 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
361 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
364 if (hildon_uri_is_default_action (action, NULL)) {
365 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
367 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
369 gtk_widget_show (menu_item);
372 /* always add the copy item */
373 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri", "uri_link_copy_link_location"));
374 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
375 g_strconcat (URI_ACTION_COPY, uri, NULL),
377 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
378 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
379 gtk_widget_show (menu_item);
382 /* and what to do when the link is deleted */
383 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
384 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
387 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
396 modest_platform_get_icon (const gchar *name)
399 GdkPixbuf* pixbuf = NULL;
400 GtkIconTheme *current_theme = NULL;
402 g_return_val_if_fail (name, NULL);
404 /* strlen == 0 is not really an error; it just
405 * means the icon is not available
407 if (!name || strlen(name) == 0)
410 #if 0 /* do we still need this? */
411 if (g_str_has_suffix (name, ".png")) { /*FIXME: hack*/
412 pixbuf = gdk_pixbuf_new_from_file (name, &err);
414 g_printerr ("modest: error loading icon '%s': %s\n",
422 current_theme = gtk_icon_theme_get_default ();
423 pixbuf = gtk_icon_theme_load_icon (current_theme, name, 26,
424 GTK_ICON_LOOKUP_NO_SVG,
427 g_printerr ("modest: error loading theme icon '%s': %s\n",
435 modest_platform_get_app_name (void)
437 return _("mcen_ap_name");
441 entry_insert_text (GtkEditable *editable,
450 chars = gtk_editable_get_chars (editable, 0, -1);
451 chars_length = g_utf8_strlen (chars, -1);
453 /* Show WID-INF036 */
454 if (chars_length >= 20) {
455 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
456 _CS("ckdg_ib_maximum_characters_reached"));
458 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
462 tmp = g_strndup (folder_name_forbidden_chars,
463 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
464 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
465 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
470 /* Write the text in the entry if it's valid */
471 g_signal_handlers_block_by_func (editable,
472 (gpointer) entry_insert_text, data);
473 gtk_editable_insert_text (editable, text, length, position);
474 g_signal_handlers_unblock_by_func (editable,
475 (gpointer) entry_insert_text, data);
478 /* Do not allow further processing */
479 g_signal_stop_emission_by_name (editable, "insert_text");
483 entry_changed (GtkEditable *editable,
487 GtkWidget *ok_button;
490 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
491 ok_button = GTK_WIDGET (buttons->next->data);
493 chars = gtk_editable_get_chars (editable, 0, -1);
494 g_return_if_fail (chars != NULL);
497 if (g_utf8_strlen (chars,-1) >= 21)
498 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
499 _CS("ckdg_ib_maximum_characters_reached"));
501 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
504 g_list_free (buttons);
509 launch_sort_headers_dialog (GtkWindow *parent_window,
510 HildonSortDialog *dialog)
512 ModestHeaderView *header_view = NULL;
514 GtkSortType sort_type;
516 gint default_key = 0;
518 gboolean outgoing = FALSE;
519 gint current_sort_colid = -1;
520 GtkSortType current_sort_type;
521 gint attachments_sort_id;
522 gint priority_sort_id;
523 GtkTreeSortable *sortable;
525 /* Get header window */
526 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
527 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
528 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
530 if (!header_view) return;
532 /* Add sorting keys */
533 cols = modest_header_view_get_columns (header_view);
534 if (cols == NULL) return;
535 int sort_model_ids[6];
539 outgoing = (GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cols->data), MODEST_HEADER_VIEW_COLUMN))==
540 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT);
542 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_sender_recipient"));
544 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
545 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
547 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
548 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
551 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_date"));
553 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
554 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE;
556 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
557 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE;
559 default_key = sort_key;
561 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_subject"));
562 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN;
564 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
566 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
568 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_attachment"));
569 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
570 sort_ids[sort_key] = TNY_HEADER_FLAG_ATTACHMENTS;
571 attachments_sort_id = sort_key;
573 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_size"));
574 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN;
575 sort_ids[sort_key] = 0;
577 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
578 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
579 sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
580 priority_sort_id = sort_key;
582 sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
584 if (!gtk_tree_sortable_get_sort_column_id (sortable,
585 ¤t_sort_colid, ¤t_sort_type)) {
586 hildon_sort_dialog_set_sort_key (dialog, default_key);
587 hildon_sort_dialog_set_sort_order (dialog, GTK_SORT_DESCENDING);
589 hildon_sort_dialog_set_sort_order (dialog, current_sort_type);
590 if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
591 gpointer flags_sort_type_pointer;
592 flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
593 if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
594 hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
596 hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
598 gint current_sort_keyid = 0;
599 while (current_sort_keyid < 6) {
600 if (sort_model_ids[current_sort_keyid] == current_sort_colid)
603 current_sort_keyid++;
605 hildon_sort_dialog_set_sort_key (dialog, current_sort_keyid);
609 result = gtk_dialog_run (GTK_DIALOG (dialog));
610 if (result == GTK_RESPONSE_OK) {
611 sort_key = hildon_sort_dialog_get_sort_key (dialog);
612 sort_type = hildon_sort_dialog_get_sort_order (dialog);
613 if (sort_model_ids[sort_key] == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
614 g_object_set_data (G_OBJECT(cols->data), MODEST_HEADER_VIEW_FLAG_SORT,
615 GINT_TO_POINTER (sort_ids[sort_key]));
616 /* This is a hack to make it resort rows always when flag fields are
617 * selected. If we do not do this, changing sort field from priority to
618 * attachments does not work */
619 modest_header_view_sort_by_column_id (header_view, 0, sort_type);
621 gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (cols->data),
622 sort_model_ids[sort_key]);
625 modest_header_view_sort_by_column_id (header_view, sort_model_ids[sort_key], sort_type);
626 gtk_tree_sortable_sort_column_changed (sortable);
629 modest_widget_memory_save (modest_runtime_get_conf (),
630 G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
632 /* while (gtk_events_pending ()) */
633 /* gtk_main_iteration (); */
642 on_response (GtkDialog *dialog,
646 GList *child_vbox, *child_hbox;
647 GtkWidget *hbox, *entry;
648 TnyFolderStore *parent;
650 if (response != GTK_RESPONSE_ACCEPT)
654 child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
655 hbox = child_vbox->data;
656 child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
657 entry = child_hbox->next->data;
659 parent = TNY_FOLDER_STORE (user_data);
661 /* Look for another folder with the same name */
662 if (modest_tny_folder_has_subfolder_with_name (parent,
663 gtk_entry_get_text (GTK_ENTRY (entry)))) {
665 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
666 NULL, _CS("ckdg_ib_folder_already_exists"));
667 /* Select the text */
668 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
669 gtk_widget_grab_focus (entry);
670 /* Do not close the dialog */
671 g_signal_stop_emission_by_name (dialog, "response");
677 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
678 TnyFolderStore *parent,
679 const gchar *dialog_title,
680 const gchar *label_text,
681 const gchar *suggested_name,
684 GtkWidget *accept_btn = NULL;
685 GtkWidget *dialog, *entry, *label, *hbox;
686 GList *buttons = NULL;
689 /* Ask the user for the folder name */
690 dialog = gtk_dialog_new_with_buttons (dialog_title,
692 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
693 _("mcen_bd_dialog_ok"),
695 _("mcen_bd_dialog_cancel"),
699 /* Add accept button (with unsensitive handler) */
700 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
701 accept_btn = GTK_WIDGET (buttons->next->data);
702 /* Create label and entry */
703 label = gtk_label_new (label_text);
704 /* TODO: check that the suggested name does not exist */
705 /* We set 21 as maximum because we want to show WID-INF036
706 when the user inputs more that 20 */
707 entry = gtk_entry_new_with_max_length (21);
709 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
711 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
712 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
714 /* Connect to the response method to avoid closing the dialog
715 when an invalid name is selected*/
716 g_signal_connect (dialog,
718 G_CALLBACK (on_response),
721 /* Track entry changes */
722 g_signal_connect (entry,
724 G_CALLBACK (entry_insert_text),
726 g_signal_connect (entry,
728 G_CALLBACK (entry_changed),
731 /* Create the hbox */
732 hbox = gtk_hbox_new (FALSE, 12);
733 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
734 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0);
736 /* Add hbox to dialog */
737 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
738 hbox, FALSE, FALSE, 0);
740 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
742 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
746 result = gtk_dialog_run (GTK_DIALOG(dialog));
747 if (result == GTK_RESPONSE_ACCEPT)
748 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
750 gtk_widget_destroy (dialog);
752 while (gtk_events_pending ())
753 gtk_main_iteration ();
759 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
760 TnyFolderStore *parent_folder,
761 gchar *suggested_name,
764 gchar *real_suggested_name = NULL;
767 if(suggested_name == NULL)
769 const gchar *default_name = _("mcen_ia_default_folder_name");
773 for(i = 0; i < 100; ++ i) {
774 gboolean exists = FALSE;
776 sprintf(num_str, "%.2u", i);
779 real_suggested_name = g_strdup (default_name);
781 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
784 exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
785 real_suggested_name);
790 g_free (real_suggested_name);
793 /* Didn't find a free number */
795 real_suggested_name = g_strdup (default_name);
797 real_suggested_name = suggested_name;
800 result = modest_platform_run_folder_name_dialog (parent_window,
802 _("mcen_ti_new_folder"),
803 _("mcen_fi_new_folder_name"),
806 if (suggested_name == NULL)
807 g_free(real_suggested_name);
813 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
814 TnyFolderStore *parent_folder,
815 const gchar *suggested_name,
818 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
820 return modest_platform_run_folder_name_dialog (parent_window,
822 _HL("ckdg_ti_rename_folder"),
823 _HL("ckdg_fi_rename_name"),
829 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
830 const gchar *message)
835 dialog = hildon_note_new_confirmation (parent_window, message);
836 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
838 response = gtk_dialog_run (GTK_DIALOG (dialog));
840 gtk_widget_destroy (GTK_WIDGET (dialog));
842 while (gtk_events_pending ())
843 gtk_main_iteration ();
849 modest_platform_run_yes_no_dialog (GtkWindow *parent_window,
850 const gchar *message)
855 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
856 _("mcen_bd_yes"), GTK_RESPONSE_YES,
857 _("mcen_bd_no"), GTK_RESPONSE_NO,
859 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
861 response = gtk_dialog_run (GTK_DIALOG (dialog));
863 gtk_widget_destroy (GTK_WIDGET (dialog));
865 while (gtk_events_pending ())
866 gtk_main_iteration ();
872 modest_platform_run_information_dialog (GtkWindow *parent_window,
873 const gchar *message)
877 dialog = hildon_note_new_information (parent_window, message);
879 g_signal_connect_swapped (dialog,
881 G_CALLBACK (gtk_widget_destroy),
884 gtk_widget_show_all (dialog);
895 on_idle_connect_and_wait(gpointer user_data)
897 printf ("DEBUG: %s:\n", __FUNCTION__);
898 TnyDevice *device = modest_runtime_get_device();
899 if (!tny_device_is_online (device)) {
901 /* This is a GDK lock because we are an idle callback and
902 * tny_maemo_conic_device_connect can contain Gtk+ code */
904 gdk_threads_enter(); /* CHECKED */
905 tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
906 gdk_threads_leave(); /* CHECKED */
909 /* Allow the function that requested this idle callback to continue: */
910 UtilIdleData *data = (UtilIdleData*)user_data;
912 g_main_loop_quit (data->loop);
914 return FALSE; /* Don't call this again. */
917 static gboolean connect_request_in_progress = FALSE;
919 /* This callback is used when connect_and_wait() is already queued as an idle callback.
920 * This can happen because the gtk_dialog_run() for the connection dialog
921 * (at least in the fake scratchbox version) allows idle handlers to keep running.
924 on_idle_wait_for_previous_connect_to_finish(gpointer user_data)
926 gboolean result = FALSE;
927 TnyDevice *device = modest_runtime_get_device();
928 if (tny_device_is_online (device))
929 result = FALSE; /* Stop trying. */
931 /* Keep trying until connect_request_in_progress is FALSE. */
932 if (connect_request_in_progress)
933 result = TRUE; /* Keep trying */
935 printf ("DEBUG: %s: other idle has finished.\n", __FUNCTION__);
937 result = FALSE; /* Stop trying, now that a result should be available. */
941 if (result == FALSE) {
942 /* Allow the function that requested this idle callback to continue: */
943 UtilIdleData *data = (UtilIdleData*)user_data;
945 g_main_loop_quit (data->loop);
952 set_account_to_online (TnyAccount *account)
954 /* TODO: This is necessary to prevent a cancel of the password dialog
955 * from making a restart necessary to be asked the password again,
956 * but it causes a hang:
959 if (account && TNY_IS_CAMEL_STORE_ACCOUNT (account)) {
960 /* Make sure that store accounts are online too,
961 * because tinymail sets accounts to offline if
962 * a password dialog is ever cancelled.
963 * We don't do this for transport accounts because
964 * a) They fundamentally need network access, so they can't really be offline.
965 * b) That might cause a transport connection to happen too early.
968 /* The last argument is user_data, the NULL before that is the callback */
969 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE, NULL, NULL);
975 modest_platform_connect_and_wait (GtkWindow *parent_window, TnyAccount *account)
977 if (connect_request_in_progress)
980 printf ("DEBUG: %s:\n", __FUNCTION__);
981 TnyDevice *device = modest_runtime_get_device();
983 if (tny_device_is_online (device)) {
984 printf ("DEBUG: %s: Already online.\n", __FUNCTION__);
985 set_account_to_online (account);
989 printf ("DEBUG: %s: tny_device_is_online() returned FALSE\n", __FUNCTION__);
992 /* This blocks on the result: */
993 UtilIdleData *data = g_slice_new0 (UtilIdleData);
995 GMainContext *context = NULL; /* g_main_context_new (); */
996 data->loop = g_main_loop_new (context, FALSE /* not running */);
998 /* Cause the function to be run in an idle-handler, which is always
999 * in the main thread:
1001 if (!connect_request_in_progress) {
1002 printf ("DEBUG: %s: First request\n", __FUNCTION__);
1003 connect_request_in_progress = TRUE;
1004 g_idle_add (&on_idle_connect_and_wait, data);
1007 printf ("DEBUG: %s: nth request\n", __FUNCTION__);
1008 g_idle_add_full (G_PRIORITY_LOW, &on_idle_wait_for_previous_connect_to_finish, data, NULL);
1011 /* This main loop will run until the idle handler has stopped it: */
1012 printf ("DEBUG: %s: before g_main_loop_run()\n", __FUNCTION__);
1013 GDK_THREADS_LEAVE();
1014 g_main_loop_run (data->loop);
1015 GDK_THREADS_ENTER();
1016 printf ("DEBUG: %s: after g_main_loop_run()\n", __FUNCTION__);
1017 connect_request_in_progress = FALSE;
1018 printf ("DEBUG: %s: Finished\n", __FUNCTION__);
1019 g_main_loop_unref (data->loop);
1020 /* g_main_context_unref (context); */
1022 g_slice_free (UtilIdleData, data);
1024 const gboolean result = tny_device_is_online (device);
1027 set_account_to_online (account);
1034 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1036 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1037 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1038 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1039 /* This must be a maildir account, which does not require a connection: */
1044 return modest_platform_connect_and_wait (parent_window, account);
1048 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1051 return TRUE; /* Maybe it is something local. */
1053 gboolean result = TRUE;
1054 if (TNY_IS_FOLDER (folder_store)) {
1055 /* Get the folder's parent account: */
1056 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1057 if (account != NULL) {
1058 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1059 g_object_unref (account);
1061 } else if (TNY_IS_ACCOUNT (folder_store)) {
1062 /* Use the folder store as an account: */
1063 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1070 modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
1072 TnyAccount *account = NULL;
1073 gboolean result = TRUE;
1075 g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
1077 if (TNY_IS_FOLDER (folder_store)) {
1078 /* Get the folder's parent account: */
1079 account = tny_folder_get_account(TNY_FOLDER(folder_store));
1080 } else if (TNY_IS_ACCOUNT (folder_store)) {
1081 account = TNY_ACCOUNT(folder_store);
1082 g_object_ref(account);
1085 if (account != NULL) {
1086 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1087 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1088 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1089 /* This must be a maildir account, which does
1090 * not require a connection: */
1094 g_object_unref (account);
1103 modest_platform_run_sort_dialog (GtkWindow *parent_window,
1104 ModestSortDialogType type)
1106 GtkWidget *dialog = NULL;
1109 dialog = hildon_sort_dialog_new (parent_window);
1110 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
1112 /* Fill sort keys */
1114 case MODEST_SORT_HEADERS:
1115 launch_sort_headers_dialog (parent_window,
1116 HILDON_SORT_DIALOG(dialog));
1121 gtk_widget_destroy (GTK_WIDGET (dialog));
1126 modest_platform_set_update_interval (guint minutes)
1128 ModestConf *conf = modest_runtime_get_conf ();
1132 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1134 /* Delete any existing alarm,
1135 * because we will replace it: */
1137 /* TODO: What does the alarm_event_del() return value mean? */
1138 alarm_event_del(alarm_cookie);
1140 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1143 /* 0 means no updates: */
1148 /* Register alarm: */
1150 /* Set the interval in alarm_event_t structure: */
1151 alarm_event_t *event = g_new0(alarm_event_t, 1);
1152 event->alarm_time = minutes * 60; /* seconds */
1154 /* Set recurrence every few minutes: */
1155 event->recurrence = minutes;
1156 event->recurrence_count = -1; /* Means infinite */
1158 /* Specify what should happen when the alarm happens:
1159 * It should call this D-Bus method: */
1161 event->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1162 event->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1163 event->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1164 event->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1166 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1167 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1168 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1169 * This is why we want to use the Alarm API instead of just g_timeout_add().
1170 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1172 event->flags = ALARM_EVENT_NO_DIALOG | ALARM_EVENT_ACTIVATION;
1174 alarm_cookie = alarm_event_add (event);
1177 alarm_event_free (event);
1179 /* Store the alarm ID in GConf, so we can remove it later:
1180 * This is apparently valid between application instances. */
1181 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1183 if (!alarm_cookie) {
1185 const alarm_error_t alarm_error = alarmd_get_error ();
1186 g_debug ("Error setting alarm event. Error code: '%d'\n", alarm_error);
1188 /* Give people some clue: */
1189 /* The alarm API should have a function for this: */
1190 if (alarm_error == ALARMD_ERROR_DBUS) {
1191 g_debug (" ALARMD_ERROR_DBUS: An error with D-Bus occurred, probably coudn't get a D-Bus connection.\n");
1192 } else if (alarm_error == ALARMD_ERROR_CONNECTION) {
1193 g_debug (" ALARMD_ERROR_CONNECTION: Could not contact alarmd via D-Bus.\n");
1194 } else if (alarm_error == ALARMD_ERROR_INTERNAL) {
1195 g_debug (" ALARMD_ERROR_INTERNAL: Some alarmd or libalarm internal error, possibly a version mismatch.\n");
1196 } else if (alarm_error == ALARMD_ERROR_MEMORY) {
1197 g_debug (" ALARMD_ERROR_MEMORY: A memory allocation failed.\n");
1198 } else if (alarm_error == ALARMD_ERROR_ARGUMENT) {
1199 g_debug (" ALARMD_ERROR_ARGUMENT: An argument given by caller was invalid.\n");
1200 } else if (alarm_error == ALARMD_ERROR_NOT_RUNNING) {
1201 g_debug (" ALARMD_ERROR_NOT_RUNNING: alarmd is not running.\n");
1211 modest_platform_get_global_settings_dialog ()
1213 return modest_maemo_global_settings_dialog_new ();
1217 modest_platform_on_new_header_received (TnyHeader *header)
1219 #ifdef MODEST_HAVE_HILDON_NOTIFY
1220 HildonNotification *notification;
1222 TnyFolder *folder = NULL;
1223 const gchar *subject;
1225 subject = tny_header_get_subject (header);
1226 if (!subject || strlen(subject) == 0)
1227 subject = _("mail_va_no_subject");
1229 notification = hildon_notification_new (tny_header_get_from (header),
1231 "qgn_list_messagin",
1234 folder = tny_header_get_folder (header);
1235 url = g_strdup_printf ("%s/%s",
1236 tny_folder_get_url_string (folder),
1237 tny_header_get_uid (header));
1238 g_object_unref (folder);
1240 hildon_notification_add_dbus_action(notification,
1243 MODEST_DBUS_SERVICE,
1246 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1251 /* Play sound SR-SND-18 */
1252 hildon_notification_set_sound (HILDON_NOTIFICATION(notification),
1253 "/usr/share/sounds/ui-new_email.wav");
1254 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION(notification),
1257 /* Set the led pattern */
1258 notify_notification_set_hint_string(NOTIFY_NOTIFICATION(notification),
1260 "PatternCommunicationEmail");
1262 /* Notify. We need to do this in an idle because this function
1263 could be called from a thread */
1264 if (!notify_notification_show (NOTIFY_NOTIFICATION(notification), NULL))
1265 g_error ("Failed to send notification");
1267 g_object_unref (notification);
1268 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1273 modest_platform_show_help (GtkWindow *parent_window,
1274 const gchar *help_id)
1276 osso_return_t result;
1278 g_return_if_fail (help_id);
1279 g_return_if_fail (osso_context);
1282 #ifdef MODEST_HAVE_OSSO_HELP
1283 result = ossohelp_show (osso_context, help_id, OSSO_HELP_SHOW_DIALOG);
1285 result = hildon_help_show (osso_context, help_id, OSSO_HELP_SHOW_DIALOG);
1288 if (result != OSSO_OK) {
1290 error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id);
1291 hildon_banner_show_information (GTK_WIDGET (parent_window),
1299 modest_platform_show_search_messages (GtkWindow *parent_window)
1301 osso_return_t result = OSSO_ERROR;
1303 result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
1305 if (result != OSSO_OK) {
1306 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1311 modest_platform_show_addressbook (GtkWindow *parent_window)
1313 osso_return_t result = OSSO_ERROR;
1315 result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
1317 if (result != OSSO_OK) {
1318 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1323 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1325 GtkWidget *widget = modest_folder_view_new (query);
1327 /* Show one account by default */
1328 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1329 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1332 /* Restore settings */
1333 modest_widget_memory_restore (modest_runtime_get_conf(),
1335 MODEST_CONF_FOLDER_VIEW_KEY);
1341 modest_platform_information_banner (GtkWidget *parent,
1342 const gchar *icon_name,
1345 hildon_banner_show_information (parent, icon_name, text);
1349 modest_platform_animation_banner (GtkWidget *parent,
1350 const gchar *animation_name,
1353 GtkWidget *inf_note = NULL;
1355 g_return_val_if_fail (text != NULL, NULL);
1357 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1365 TnyAccount *account;
1368 } CheckAccountIdleData;
1370 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1373 on_timeout_check_account_is_online(gpointer user_data)
1375 printf ("DEBUG: %s:\n", __FUNCTION__);
1376 CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
1379 g_warning ("%s: data is NULL.\n", __FUNCTION__);
1382 if (!(data->account)) {
1383 g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
1386 if (data && data->account) {
1387 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));
1390 gboolean stop_trying = FALSE;
1391 if (data && data->account &&
1392 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1393 * after which the account is likely to be usable, or never likely to be usable soon: */
1394 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1396 data->is_online = TRUE;
1401 /* Give up if we have tried too many times: */
1402 if (data->count_tries >= NUMBER_OF_TRIES)
1407 /* Wait for another timeout: */
1408 ++(data->count_tries);
1413 /* Allow the function that requested this idle callback to continue: */
1415 g_main_loop_quit (data->loop);
1418 g_object_unref (data->account);
1420 return FALSE; /* Don't call this again. */
1422 return TRUE; /* Call this timeout callback again. */
1426 /* Return TRUE immediately if the account is already online,
1427 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1428 * soon as the account is online, or FALSE if the account does
1429 * not become online in the NUMBER_OF_TRIES seconds.
1430 * This is useful when the D-Bus method was run immediately after
1431 * the application was started (when using D-Bus activation),
1432 * because the account usually takes a short time to go online.
1433 * The return value is maybe not very useful.
1436 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1438 g_return_val_if_fail (account, FALSE);
1440 printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
1442 if (!tny_device_is_online (modest_runtime_get_device())) {
1443 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1447 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1448 * so we avoid wait unnecessarily: */
1449 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1450 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
1454 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n",
1455 __FUNCTION__, tny_account_get_connection_status (account));
1457 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1458 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1459 * we want to avoid. */
1460 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1463 /* This blocks on the result: */
1464 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1465 data->is_online = FALSE;
1466 data->account = account;
1467 g_object_ref (data->account);
1468 data->count_tries = 0;
1470 GMainContext *context = NULL; /* g_main_context_new (); */
1471 data->loop = g_main_loop_new (context, FALSE /* not running */);
1473 g_timeout_add (1000, &on_timeout_check_account_is_online, data);
1475 /* This main loop will run until the idle handler has stopped it: */
1476 g_main_loop_run (data->loop);
1478 g_main_loop_unref (data->loop);
1479 /* g_main_context_unref (context); */
1481 g_slice_free (CheckAccountIdleData, data);
1483 return data->is_online;
1489 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1491 /* GTK_RESPONSE_HELP means we need to show the certificate */
1492 if (response_id == GTK_RESPONSE_HELP) {
1496 /* Do not close the dialog */
1497 g_signal_stop_emission_by_name (dialog, "response");
1499 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1500 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1501 gtk_dialog_run (GTK_DIALOG(note));
1502 gtk_widget_destroy (note);
1508 modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
1509 const gchar *certificate)
1513 GtkWindow *main_win =
1514 (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
1516 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1519 note = hildon_note_new_confirmation_add_buttons (
1522 _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
1523 _("mcen_bd_view"), GTK_RESPONSE_HELP, /* abusing this... */
1524 _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
1527 g_signal_connect (G_OBJECT(note), "response",
1528 G_CALLBACK(on_cert_dialog_response),
1529 (gpointer) certificate);
1530 response = gtk_dialog_run(GTK_DIALOG(note));
1532 gtk_widget_destroy(GTK_WIDGET(note));
1541 modest_platform_run_alert_dialog (const gchar* prompt,
1542 gboolean is_question)
1544 ModestWindow *main_window =
1545 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
1547 gboolean retval = TRUE;
1549 /* The Tinymail documentation says that we should show Yes and No buttons,
1550 * when it is a question.
1551 * Obviously, we need tinymail to use more specific error codes instead,
1552 * so we know what buttons to show. */
1553 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
1555 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1556 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1558 gtk_widget_destroy (dialog);
1561 /* Just show the error text and use the default response: */
1562 modest_maemo_show_information_note_and_forget(GTK_WINDOW (main_window),