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 <modest-maemo-utils.h>
40 #include <dbus_api/modest-dbus-callbacks.h>
41 #include <libosso-abook/osso-abook.h>
42 #include <maemo/modest-osso-autosave-callbacks.h>
44 #include <alarmd/alarm_event.h> /* For alarm_event_add(), etc. */
45 #include <tny-maemo-conic-device.h>
46 #include <tny-simple-list.h>
47 #include <tny-folder.h>
48 #include <tny-camel-imap-store-account.h>
49 #include <tny-camel-pop-store-account.h>
50 #include <gtk/gtkicontheme.h>
51 #include <gtk/gtkmenuitem.h>
52 #include <gtk/gtkmain.h>
53 #include <modest-text-utils.h>
54 #include "modest-tny-folder.h"
56 #include <libgnomevfs/gnome-vfs-mime-utils.h>
59 #define HILDON_OSSO_URI_ACTION "uri-action"
60 #define URI_ACTION_COPY "copy:"
62 static osso_context_t *osso_context = NULL;
65 on_modest_conf_update_interval_changed (ModestConf* self,
67 ModestConfEvent event,
68 ModestConfNotificationId id,
71 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
72 const guint update_interval_minutes =
73 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
74 modest_platform_set_update_interval (update_interval_minutes);
81 check_required_files (void)
83 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
85 g_printerr ("modest: check for mcc file failed\n");
90 if (access (MODEST_PROVIDERS_DATA_PATH, R_OK) != 0) {
91 g_printerr ("modest: cannot find providers data\n");
101 modest_platform_init (int argc, char *argv[])
103 osso_hw_state_t hw_state = { 0 };
106 if (!check_required_files ()) {
107 g_printerr ("modest: missing required files\n");
113 osso_initialize(PACKAGE,PACKAGE_VERSION,
116 g_printerr ("modest: failed to acquire osso context\n");
120 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
121 g_printerr ("modest: could not get dbus connection\n");
126 /* Add a D-Bus handler to be used when the main osso-rpc
127 * D-Bus handler has not handled something.
128 * We use this for D-Bus methods that need to use more complex types
129 * than osso-rpc supports.
131 if (!dbus_connection_add_filter (con,
132 modest_dbus_req_filter,
136 g_printerr ("modest: Could not add D-Bus filter\n");
140 /* Register our simple D-Bus callbacks, via the osso API: */
141 osso_return_t result = osso_rpc_set_cb_f(osso_context,
145 modest_dbus_req_handler, NULL /* user_data */);
146 if (result != OSSO_OK) {
147 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
151 /* Add handler for Exit D-BUS messages.
152 * Not used because osso_application_set_exit_cb() is deprecated and obsolete:
153 result = osso_application_set_exit_cb(osso_context,
154 modest_dbus_exit_event_handler,
156 if (result != OSSO_OK) {
157 g_print("Error setting exit callback (%d)\n", result);
162 /* Register hardware event dbus callback: */
163 hw_state.shutdown_ind = TRUE;
164 osso_hw_set_event_cb(osso_context, NULL,/*&hw_state*/ modest_osso_cb_hw_state_handler, NULL);
166 /* Register osso auto-save callbacks: */
167 result = osso_application_set_autosave_cb (osso_context,
168 modest_on_osso_application_autosave, NULL /* user_data */);
169 if (result != OSSO_OK) {
170 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
175 /* Make sure that the update interval is changed whenever its gconf key
177 /* CAUTION: we're not using here the
178 modest_conf_listen_to_namespace because we know that there
179 are other parts of Modest listening for this namespace, so
180 we'll receive the notifications anyway. We basically do not
181 use it because there is no easy way to do the
182 modest_conf_forget_namespace */
183 ModestConf *conf = modest_runtime_get_conf ();
184 g_signal_connect (G_OBJECT(conf),
186 G_CALLBACK (on_modest_conf_update_interval_changed),
189 /* Get the initial update interval from gconf: */
190 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
191 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
193 /* initialize the addressbook */
194 if (!osso_abook_init (&argc, &argv, osso_context)) {
195 g_printerr ("modest: failed to initialized addressbook\n");
203 modest_platform_get_new_device (void)
205 return TNY_DEVICE (tny_maemo_conic_device_new ());
209 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
210 gchar **effective_mime_type)
212 GString *mime_str = NULL;
213 gchar *icon_name = NULL;
214 gchar **icons, **cursor;
216 if (!mime_type || !g_ascii_strcasecmp (mime_type, "application/octet-stream"))
217 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
219 mime_str = g_string_new (mime_type);
220 g_string_ascii_down (mime_str);
223 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
224 for (cursor = icons; cursor; ++cursor) {
225 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
226 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
227 icon_name = g_strdup ("qgn_list_messagin");
229 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
230 icon_name = g_strdup (*cursor);
236 if (effective_mime_type)
237 *effective_mime_type = g_string_free (mime_str, FALSE);
239 g_string_free (mime_str, TRUE);
246 modest_platform_activate_uri (const gchar *uri)
248 HildonURIAction *action;
249 gboolean result = FALSE;
250 GSList *actions, *iter = NULL;
252 g_return_val_if_fail (uri, FALSE);
256 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
258 for (iter = actions; iter; iter = g_slist_next (iter)) {
259 action = (HildonURIAction*) iter->data;
260 if (action && strcmp (hildon_uri_action_get_service (action),
261 "com.nokia.modest") == 0) {
263 result = hildon_uri_open (uri, action, &err);
264 if (!result && err) {
265 g_printerr ("modest: modest_platform_activate_uri : %s",
266 err->message ? err->message : "unknown error");
273 /* if we could not open it with email, try something else */
275 result = hildon_uri_open (uri, NULL, NULL);
278 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
284 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
288 gchar *uri_path = NULL;
290 uri_path = g_strconcat ("file://", path, NULL);
291 con = osso_get_dbus_connection (osso_context);
294 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
296 result = hildon_mime_open_file (con, uri_path);
298 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"));
306 } ModestPlatformPopupInfo;
309 delete_uri_popup (GtkWidget *menu,
313 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
315 g_free (popup_info->uri);
316 hildon_uri_free_actions (popup_info->actions);
322 activate_uri_popup_item (GtkMenuItem *menu_item,
326 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
327 const gchar* action_name;
329 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
331 g_printerr ("modest: no action name defined\n");
335 /* special handling for the copy menu item -- copy the uri to the clipboard */
336 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
337 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
338 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
339 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
341 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
342 action_name += strlen ("mailto:");
344 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
345 return; /* we're done */
348 /* now, the real uri-actions... */
349 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
350 HildonURIAction *action = (HildonURIAction *) node->data;
351 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
352 hildon_uri_open (popup_info->uri, action, NULL);
359 modest_platform_show_uri_popup (const gchar *uri)
361 GSList *actions_list;
366 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
367 if (actions_list != NULL) {
369 GtkWidget *menu = gtk_menu_new ();
370 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
372 popup_info->actions = actions_list;
373 popup_info->uri = g_strdup (uri);
375 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
376 GtkWidget *menu_item;
377 const gchar *action_name;
378 const gchar *translation_domain;
379 HildonURIAction *action = (HildonURIAction *) node->data;
380 action_name = hildon_uri_action_get_name (action);
381 translation_domain = hildon_uri_action_get_translation_domain (action);
382 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
383 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
384 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
387 if (hildon_uri_is_default_action (action, NULL)) {
388 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
390 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
392 gtk_widget_show (menu_item);
395 /* always add the copy item */
396 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri", "uri_link_copy_link_location"));
397 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
398 g_strconcat (URI_ACTION_COPY, uri, NULL),
400 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
401 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
402 gtk_widget_show (menu_item);
405 /* and what to do when the link is deleted */
406 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
407 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
410 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
418 modest_platform_get_icon (const gchar *name)
421 GdkPixbuf* pixbuf = NULL;
422 GtkIconTheme *current_theme = NULL;
424 g_return_val_if_fail (name, NULL);
426 /* strlen == 0 is not really an error; it just
427 * means the icon is not available
429 if (!name || strlen(name) == 0)
432 #if 0 /* do we still need this? */
433 if (g_str_has_suffix (name, ".png")) { /*FIXME: hack*/
434 pixbuf = gdk_pixbuf_new_from_file (name, &err);
436 g_printerr ("modest: error loading icon '%s': %s\n",
444 current_theme = gtk_icon_theme_get_default ();
445 pixbuf = gtk_icon_theme_load_icon (current_theme, name, 26,
446 GTK_ICON_LOOKUP_NO_SVG,
449 g_printerr ("modest: error loading theme icon '%s': %s\n",
457 modest_platform_get_app_name (void)
459 return _("mcen_ap_name");
463 entry_insert_text (GtkEditable *editable,
472 chars = gtk_editable_get_chars (editable, 0, -1);
473 chars_length = g_utf8_strlen (chars, -1);
475 /* Show WID-INF036 */
476 if (chars_length >= 20) {
477 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
478 _CS("ckdg_ib_maximum_characters_reached"));
480 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
484 tmp = g_strndup (folder_name_forbidden_chars,
485 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
486 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
487 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
492 /* Write the text in the entry if it's valid */
493 g_signal_handlers_block_by_func (editable,
494 (gpointer) entry_insert_text, data);
495 gtk_editable_insert_text (editable, text, length, position);
496 g_signal_handlers_unblock_by_func (editable,
497 (gpointer) entry_insert_text, data);
500 /* Do not allow further processing */
501 g_signal_stop_emission_by_name (editable, "insert_text");
505 entry_changed (GtkEditable *editable,
509 GtkWidget *ok_button;
512 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
513 ok_button = GTK_WIDGET (buttons->next->data);
515 chars = gtk_editable_get_chars (editable, 0, -1);
516 g_return_if_fail (chars != NULL);
519 if (g_utf8_strlen (chars,-1) >= 21)
520 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
521 _CS("ckdg_ib_maximum_characters_reached"));
523 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
526 g_list_free (buttons);
531 launch_sort_headers_dialog (GtkWindow *parent_window,
532 HildonSortDialog *dialog)
534 ModestHeaderView *header_view = NULL;
536 GtkSortType sort_type;
538 gint default_key = 0;
540 gboolean outgoing = FALSE;
541 gint current_sort_colid = -1;
542 GtkSortType current_sort_type;
543 gint attachments_sort_id;
544 gint priority_sort_id;
545 GtkTreeSortable *sortable;
547 /* Get header window */
548 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
549 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
550 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
552 if (!header_view) return;
554 /* Add sorting keys */
555 cols = modest_header_view_get_columns (header_view);
556 if (cols == NULL) return;
557 int sort_model_ids[6];
561 outgoing = (GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cols->data), MODEST_HEADER_VIEW_COLUMN))==
562 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT);
564 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_sender_recipient"));
566 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
567 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
569 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
570 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
573 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_date"));
575 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
576 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE;
578 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
579 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE;
581 default_key = sort_key;
583 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_subject"));
584 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN;
586 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
588 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
590 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_attachment"));
591 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
592 sort_ids[sort_key] = TNY_HEADER_FLAG_ATTACHMENTS;
593 attachments_sort_id = sort_key;
595 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_size"));
596 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN;
597 sort_ids[sort_key] = 0;
599 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
600 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
601 sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
602 priority_sort_id = sort_key;
604 sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
606 if (!gtk_tree_sortable_get_sort_column_id (sortable,
607 ¤t_sort_colid, ¤t_sort_type)) {
608 hildon_sort_dialog_set_sort_key (dialog, default_key);
609 hildon_sort_dialog_set_sort_order (dialog, GTK_SORT_DESCENDING);
611 hildon_sort_dialog_set_sort_order (dialog, current_sort_type);
612 if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
613 gpointer flags_sort_type_pointer;
614 flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
615 if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
616 hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
618 hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
620 gint current_sort_keyid = 0;
621 while (current_sort_keyid < 6) {
622 if (sort_model_ids[current_sort_keyid] == current_sort_colid)
625 current_sort_keyid++;
627 hildon_sort_dialog_set_sort_key (dialog, current_sort_keyid);
631 result = gtk_dialog_run (GTK_DIALOG (dialog));
632 if (result == GTK_RESPONSE_OK) {
633 sort_key = hildon_sort_dialog_get_sort_key (dialog);
634 sort_type = hildon_sort_dialog_get_sort_order (dialog);
635 if (sort_model_ids[sort_key] == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
636 g_object_set_data (G_OBJECT(cols->data), MODEST_HEADER_VIEW_FLAG_SORT,
637 GINT_TO_POINTER (sort_ids[sort_key]));
638 /* This is a hack to make it resort rows always when flag fields are
639 * selected. If we do not do this, changing sort field from priority to
640 * attachments does not work */
641 modest_header_view_sort_by_column_id (header_view, 0, sort_type);
643 gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (cols->data),
644 sort_model_ids[sort_key]);
647 modest_header_view_sort_by_column_id (header_view, sort_model_ids[sort_key], sort_type);
648 gtk_tree_sortable_sort_column_changed (sortable);
651 modest_widget_memory_save (modest_runtime_get_conf (),
652 G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
654 /* while (gtk_events_pending ()) */
655 /* gtk_main_iteration (); */
664 on_response (GtkDialog *dialog,
668 GList *child_vbox, *child_hbox;
669 GtkWidget *hbox, *entry;
670 TnyFolderStore *parent;
672 if (response != GTK_RESPONSE_ACCEPT)
676 child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
677 hbox = child_vbox->data;
678 child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
679 entry = child_hbox->next->data;
681 parent = TNY_FOLDER_STORE (user_data);
683 /* Look for another folder with the same name */
684 if (modest_tny_folder_has_subfolder_with_name (parent,
685 gtk_entry_get_text (GTK_ENTRY (entry)))) {
687 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
688 NULL, _CS("ckdg_ib_folder_already_exists"));
689 /* Select the text */
690 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
691 gtk_widget_grab_focus (entry);
692 /* Do not close the dialog */
693 g_signal_stop_emission_by_name (dialog, "response");
700 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
701 TnyFolderStore *parent,
702 const gchar *dialog_title,
703 const gchar *label_text,
704 const gchar *suggested_name,
707 GtkWidget *accept_btn = NULL;
708 GtkWidget *dialog, *entry, *label, *hbox;
709 GList *buttons = NULL;
712 /* Ask the user for the folder name */
713 dialog = gtk_dialog_new_with_buttons (dialog_title,
715 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
716 _("mcen_bd_dialog_ok"),
718 _("mcen_bd_dialog_cancel"),
722 /* Add accept button (with unsensitive handler) */
723 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
724 accept_btn = GTK_WIDGET (buttons->next->data);
725 /* Create label and entry */
726 label = gtk_label_new (label_text);
727 /* TODO: check that the suggested name does not exist */
728 /* We set 21 as maximum because we want to show WID-INF036
729 when the user inputs more that 20 */
730 entry = gtk_entry_new_with_max_length (21);
732 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
734 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
735 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
737 /* Connect to the response method to avoid closing the dialog
738 when an invalid name is selected*/
739 g_signal_connect (dialog,
741 G_CALLBACK (on_response),
744 /* Track entry changes */
745 g_signal_connect (entry,
747 G_CALLBACK (entry_insert_text),
749 g_signal_connect (entry,
751 G_CALLBACK (entry_changed),
754 /* Create the hbox */
755 hbox = gtk_hbox_new (FALSE, 12);
756 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
757 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0);
759 /* Add hbox to dialog */
760 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
761 hbox, FALSE, FALSE, 0);
763 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
764 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
766 result = gtk_dialog_run (GTK_DIALOG(dialog));
767 if (result == GTK_RESPONSE_ACCEPT)
768 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
770 gtk_widget_destroy (dialog);
772 while (gtk_events_pending ())
773 gtk_main_iteration ();
779 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
780 TnyFolderStore *parent_folder,
781 gchar *suggested_name,
784 gchar *real_suggested_name = NULL;
787 if(suggested_name == NULL)
789 const gchar *default_name = _("mcen_ia_default_folder_name");
793 for(i = 0; i < 100; ++ i) {
794 gboolean exists = FALSE;
796 sprintf(num_str, "%.2u", i);
799 real_suggested_name = g_strdup (default_name);
801 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
804 exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
805 real_suggested_name);
810 g_free (real_suggested_name);
813 /* Didn't find a free number */
815 real_suggested_name = g_strdup (default_name);
817 real_suggested_name = suggested_name;
820 result = modest_platform_run_folder_name_dialog (parent_window,
822 _("mcen_ti_new_folder"),
823 _("mcen_fi_new_folder_name"),
826 if (suggested_name == NULL)
827 g_free(real_suggested_name);
833 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
834 TnyFolderStore *parent_folder,
835 const gchar *suggested_name,
838 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
840 return modest_platform_run_folder_name_dialog (parent_window,
842 _HL("ckdg_ti_rename_folder"),
843 _HL("ckdg_fi_rename_name"),
851 on_destroy_dialog (GtkDialog *dialog)
853 gtk_widget_destroy (GTK_WIDGET(dialog));
854 if (gtk_events_pending ())
855 gtk_main_iteration ();
859 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
860 const gchar *message)
865 dialog = hildon_note_new_confirmation (parent_window, message);
866 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
867 GTK_WINDOW (dialog));
869 response = gtk_dialog_run (GTK_DIALOG (dialog));
871 on_destroy_dialog (GTK_DIALOG(dialog));
873 while (gtk_events_pending ())
874 gtk_main_iteration ();
880 modest_platform_run_yes_no_dialog (GtkWindow *parent_window,
881 const gchar *message)
886 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
887 _("mcen_bd_yes"), GTK_RESPONSE_YES,
888 _("mcen_bd_no"), GTK_RESPONSE_NO,
890 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
891 response = gtk_dialog_run (GTK_DIALOG (dialog));
893 on_destroy_dialog (GTK_DIALOG(dialog));
895 while (gtk_events_pending ())
896 gtk_main_iteration ();
904 modest_platform_run_information_dialog (GtkWindow *parent_window,
905 const gchar *message)
909 note = hildon_note_new_information (parent_window, message);
910 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
913 g_signal_connect_swapped (note,
915 G_CALLBACK (on_destroy_dialog),
918 gtk_widget_show_all (note);
923 typedef struct _UtilIdleData {
931 on_connection_status_changed (TnyAccount *self,
932 TnyConnectionStatus status,
935 UtilIdleData *data = (UtilIdleData *) user_data;
936 TnyConnectionStatus conn_status;
938 conn_status = tny_account_get_connection_status (data->account);
939 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING)
942 /* Remove the handler and Exit loop */
943 g_signal_handler_disconnect (self, data->handler);
944 g_main_loop_quit (data->loop);
948 on_idle_connect_and_wait(gpointer user_data)
950 TnyDevice *device = NULL;
951 UtilIdleData *data = NULL;
952 gboolean connected, exit_loop;
955 device = modest_runtime_get_device();
956 data = (UtilIdleData*) user_data;
958 /* This is a GDK lock because we are an idle callback and
959 * tny_maemo_conic_device_connect can contain Gtk+ code */
961 connected = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
965 data->error = g_error_new (0, 0, "Error connecting");
970 TnyConnectionStatus conn_status;
971 gboolean tried_to_connect;
973 conn_status = tny_account_get_connection_status (data->account);
974 tried_to_connect = (conn_status == TNY_CONNECTION_STATUS_CONNECTED ||
975 conn_status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN);
977 if (!tried_to_connect) {
979 g_signal_connect (data->account, "connection-status-changed",
980 G_CALLBACK (on_connection_status_changed),
988 g_main_loop_quit (data->loop);
990 /* Remove the idle if we're connected */
995 modest_platform_connect_and_wait (GtkWindow *parent_window,
998 UtilIdleData *data = NULL;
1001 if (!account && tny_device_is_online (modest_runtime_get_device()))
1005 tny_device_is_online (modest_runtime_get_device()) &&
1006 tny_account_get_connection_status (account) == TNY_CONNECTION_STATUS_CONNECTED)
1009 /* This blocks on the result: */
1010 data = g_slice_new0 (UtilIdleData);
1012 data->loop = g_main_loop_new (NULL, FALSE);
1013 data->account = (account) ? g_object_ref (account) : NULL;
1015 /* Cause the function to be run in an idle-handler, which is
1016 * always in the main thread
1018 g_idle_add (&on_idle_connect_and_wait, data);
1020 gdk_threads_leave ();
1021 g_main_loop_run (data->loop);
1022 gdk_threads_enter ();
1024 g_main_loop_unref (data->loop);
1027 g_error_free (data->error);
1033 g_object_unref (data->account);
1035 g_slice_free (UtilIdleData, data);
1041 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1043 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1044 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1045 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1046 /* This must be a maildir account, which does not require a connection: */
1051 return modest_platform_connect_and_wait (parent_window, account);
1055 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1058 return TRUE; /* Maybe it is something local. */
1060 gboolean result = TRUE;
1061 if (TNY_IS_FOLDER (folder_store)) {
1062 /* Get the folder's parent account: */
1063 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1064 if (account != NULL) {
1065 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1066 g_object_unref (account);
1068 } else if (TNY_IS_ACCOUNT (folder_store)) {
1069 /* Use the folder store as an account: */
1070 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1077 modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
1079 TnyAccount *account = NULL;
1080 gboolean result = TRUE;
1082 g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
1084 if (TNY_IS_FOLDER (folder_store)) {
1085 /* Get the folder's parent account: */
1086 account = tny_folder_get_account(TNY_FOLDER(folder_store));
1087 } else if (TNY_IS_ACCOUNT (folder_store)) {
1088 account = TNY_ACCOUNT(folder_store);
1089 g_object_ref(account);
1092 if (account != NULL) {
1093 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1094 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1095 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1096 /* This must be a maildir account, which does
1097 * not require a connection: */
1101 g_object_unref (account);
1110 modest_platform_run_sort_dialog (GtkWindow *parent_window,
1111 ModestSortDialogType type)
1113 GtkWidget *dialog = NULL;
1116 dialog = hildon_sort_dialog_new (parent_window);
1117 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1118 GTK_WINDOW (dialog));
1120 /* Fill sort keys */
1122 case MODEST_SORT_HEADERS:
1123 launch_sort_headers_dialog (parent_window,
1124 HILDON_SORT_DIALOG(dialog));
1129 on_destroy_dialog (GTK_DIALOG(dialog));
1134 modest_platform_set_update_interval (guint minutes)
1136 ModestConf *conf = modest_runtime_get_conf ();
1140 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1142 /* Delete any existing alarm,
1143 * because we will replace it: */
1145 /* TODO: What does the alarm_event_del() return value mean? */
1146 alarm_event_del(alarm_cookie);
1148 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1151 /* 0 means no updates: */
1156 /* Register alarm: */
1158 /* Set the interval in alarm_event_t structure: */
1159 alarm_event_t *event = g_new0(alarm_event_t, 1);
1160 event->alarm_time = minutes * 60; /* seconds */
1162 /* Set recurrence every few minutes: */
1163 event->recurrence = minutes;
1164 event->recurrence_count = -1; /* Means infinite */
1166 /* Specify what should happen when the alarm happens:
1167 * It should call this D-Bus method: */
1169 event->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1170 event->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1171 event->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1172 event->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1174 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1175 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1176 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1177 * This is why we want to use the Alarm API instead of just g_timeout_add().
1178 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1180 event->flags = ALARM_EVENT_NO_DIALOG | ALARM_EVENT_ACTIVATION;
1182 alarm_cookie = alarm_event_add (event);
1185 alarm_event_free (event);
1187 /* Store the alarm ID in GConf, so we can remove it later:
1188 * This is apparently valid between application instances. */
1189 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1191 if (!alarm_cookie) {
1193 const alarm_error_t alarm_error = alarmd_get_error ();
1194 g_debug ("Error setting alarm event. Error code: '%d'\n", alarm_error);
1196 /* Give people some clue: */
1197 /* The alarm API should have a function for this: */
1198 if (alarm_error == ALARMD_ERROR_DBUS) {
1199 g_debug (" ALARMD_ERROR_DBUS: An error with D-Bus occurred, probably coudn't get a D-Bus connection.\n");
1200 } else if (alarm_error == ALARMD_ERROR_CONNECTION) {
1201 g_debug (" ALARMD_ERROR_CONNECTION: Could not contact alarmd via D-Bus.\n");
1202 } else if (alarm_error == ALARMD_ERROR_INTERNAL) {
1203 g_debug (" ALARMD_ERROR_INTERNAL: Some alarmd or libalarm internal error, possibly a version mismatch.\n");
1204 } else if (alarm_error == ALARMD_ERROR_MEMORY) {
1205 g_debug (" ALARMD_ERROR_MEMORY: A memory allocation failed.\n");
1206 } else if (alarm_error == ALARMD_ERROR_ARGUMENT) {
1207 g_debug (" ALARMD_ERROR_ARGUMENT: An argument given by caller was invalid.\n");
1208 } else if (alarm_error == ALARMD_ERROR_NOT_RUNNING) {
1209 g_debug (" ALARMD_ERROR_NOT_RUNNING: alarmd is not running.\n");
1219 modest_platform_get_global_settings_dialog ()
1221 return modest_maemo_global_settings_dialog_new ();
1225 modest_platform_on_new_header_received (TnyHeader *header)
1227 #ifdef MODEST_HAVE_HILDON_NOTIFY
1228 HildonNotification *notification;
1230 TnyFolder *folder = NULL;
1231 const gchar *subject;
1233 subject = tny_header_get_subject (header);
1234 if (!subject || strlen(subject) == 0)
1235 subject = _("mail_va_no_subject");
1237 notification = hildon_notification_new (tny_header_get_from (header),
1239 "qgn_list_messagin",
1242 folder = tny_header_get_folder (header);
1243 url = g_strdup_printf ("%s/%s",
1244 tny_folder_get_url_string (folder),
1245 tny_header_get_uid (header));
1246 g_object_unref (folder);
1248 hildon_notification_add_dbus_action(notification,
1251 MODEST_DBUS_SERVICE,
1254 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1259 /* Play sound if the user wants */
1260 if (modest_conf_get_bool (modest_runtime_get_conf (),
1261 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE,
1263 hildon_notification_set_sound (HILDON_NOTIFICATION(notification),
1264 "/usr/share/sounds/ui-new_email.wav");
1267 /* Set the led pattern */
1268 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION(notification),
1270 notify_notification_set_hint_string(NOTIFY_NOTIFICATION(notification),
1272 "PatternCommunicationEmail");
1274 /* Notify. We need to do this in an idle because this function
1275 could be called from a thread */
1276 if (!notify_notification_show (NOTIFY_NOTIFICATION(notification), NULL))
1277 g_error ("Failed to send notification");
1279 g_object_unref (notification);
1280 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1285 modest_platform_show_help (GtkWindow *parent_window,
1286 const gchar *help_id)
1288 osso_return_t result;
1290 g_return_if_fail (help_id);
1291 g_return_if_fail (osso_context);
1293 result = hildon_help_show (osso_context, help_id, HILDON_HELP_SHOW_DIALOG);
1295 if (result != OSSO_OK) {
1297 error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id);
1298 hildon_banner_show_information (GTK_WIDGET (parent_window),
1306 modest_platform_set_dialog_help (GtkDialog *parent_window,
1307 const gchar *help_id)
1310 g_return_if_fail (help_id);
1311 g_return_if_fail (osso_context);
1312 g_return_if_fail (GTK_IS_DIALOG (parent_window));
1314 result = hildon_help_dialog_help_enable (parent_window, help_id, osso_context);
1317 g_warning ("Help topic %s not found", help_id);
1322 modest_platform_show_search_messages (GtkWindow *parent_window)
1324 osso_return_t result = OSSO_ERROR;
1326 result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
1328 if (result != OSSO_OK) {
1329 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1334 modest_platform_show_addressbook (GtkWindow *parent_window)
1336 osso_return_t result = OSSO_ERROR;
1338 result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
1340 if (result != OSSO_OK) {
1341 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1346 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1348 GtkWidget *widget = modest_folder_view_new (query);
1350 /* Show one account by default */
1351 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1352 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1355 /* Restore settings */
1356 modest_widget_memory_restore (modest_runtime_get_conf(),
1358 MODEST_CONF_FOLDER_VIEW_KEY);
1364 modest_platform_information_banner (GtkWidget *parent,
1365 const gchar *icon_name,
1368 hildon_banner_show_information (parent, icon_name, text);
1372 modest_platform_animation_banner (GtkWidget *parent,
1373 const gchar *animation_name,
1376 GtkWidget *inf_note = NULL;
1378 g_return_val_if_fail (text != NULL, NULL);
1380 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1388 TnyAccount *account;
1391 } CheckAccountIdleData;
1393 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1396 on_timeout_check_account_is_online(gpointer user_data)
1398 printf ("DEBUG: %s:\n", __FUNCTION__);
1399 CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
1402 g_warning ("%s: data is NULL.\n", __FUNCTION__);
1405 if (!(data->account)) {
1406 g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
1409 if (data && data->account) {
1410 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));
1413 gboolean stop_trying = FALSE;
1414 if (data && data->account &&
1415 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1416 * after which the account is likely to be usable, or never likely to be usable soon: */
1417 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1419 data->is_online = TRUE;
1424 /* Give up if we have tried too many times: */
1425 if (data->count_tries >= NUMBER_OF_TRIES)
1430 /* Wait for another timeout: */
1431 ++(data->count_tries);
1436 /* Allow the function that requested this idle callback to continue: */
1438 g_main_loop_quit (data->loop);
1441 g_object_unref (data->account);
1443 return FALSE; /* Don't call this again. */
1445 return TRUE; /* Call this timeout callback again. */
1449 /* Return TRUE immediately if the account is already online,
1450 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1451 * soon as the account is online, or FALSE if the account does
1452 * not become online in the NUMBER_OF_TRIES seconds.
1453 * This is useful when the D-Bus method was run immediately after
1454 * the application was started (when using D-Bus activation),
1455 * because the account usually takes a short time to go online.
1456 * The return value is maybe not very useful.
1459 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1461 g_return_val_if_fail (account, FALSE);
1463 printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
1465 if (!tny_device_is_online (modest_runtime_get_device())) {
1466 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1470 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1471 * so we avoid wait unnecessarily: */
1472 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1473 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
1477 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n",
1478 __FUNCTION__, tny_account_get_connection_status (account));
1480 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1481 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1482 * we want to avoid. */
1483 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1486 /* This blocks on the result: */
1487 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1488 data->is_online = FALSE;
1489 data->account = account;
1490 g_object_ref (data->account);
1491 data->count_tries = 0;
1493 GMainContext *context = NULL; /* g_main_context_new (); */
1494 data->loop = g_main_loop_new (context, FALSE /* not running */);
1496 g_timeout_add (1000, &on_timeout_check_account_is_online, data);
1498 /* This main loop will run until the idle handler has stopped it: */
1499 g_main_loop_run (data->loop);
1501 g_main_loop_unref (data->loop);
1502 /* g_main_context_unref (context); */
1504 g_slice_free (CheckAccountIdleData, data);
1506 return data->is_online;
1512 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1514 /* GTK_RESPONSE_HELP means we need to show the certificate */
1515 if (response_id == GTK_RESPONSE_HELP) {
1519 /* Do not close the dialog */
1520 g_signal_stop_emission_by_name (dialog, "response");
1522 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1523 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1524 gtk_dialog_run (GTK_DIALOG(note));
1525 gtk_widget_destroy (note);
1531 modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
1532 const gchar *certificate)
1536 GtkWindow *main_win =
1537 (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
1539 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1542 note = hildon_note_new_confirmation_add_buttons (
1545 _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
1546 _("mcen_bd_view"), GTK_RESPONSE_HELP, /* abusing this... */
1547 _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
1550 g_signal_connect (G_OBJECT(note), "response",
1551 G_CALLBACK(on_cert_dialog_response),
1552 (gpointer) certificate);
1554 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1556 response = gtk_dialog_run(GTK_DIALOG(note));
1558 on_destroy_dialog (GTK_DIALOG(note));
1567 modest_platform_run_alert_dialog (const gchar* prompt,
1568 gboolean is_question)
1570 ModestWindow *main_window =
1571 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
1573 gboolean retval = TRUE;
1575 /* The Tinymail documentation says that we should show Yes and No buttons,
1576 * when it is a question.
1577 * Obviously, we need tinymail to use more specific error codes instead,
1578 * so we know what buttons to show. */
1579 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
1581 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1582 GTK_WINDOW (dialog));
1584 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1585 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1587 on_destroy_dialog (GTK_DIALOG(dialog));
1589 /* Just show the error text and use the default response: */
1590 modest_platform_run_information_dialog (GTK_WINDOW (main_window),