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;
225 g_return_val_if_fail (uri, FALSE);
229 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
231 for (iter = actions; iter; iter = g_slist_next (iter)) {
232 action = (HildonURIAction*) iter->data;
233 if (action && strcmp (hildon_uri_action_get_service (action),
234 "com.nokia.modest") == 0) {
236 result = hildon_uri_open (uri, action, &err);
237 if (!result && err) {
238 g_printerr ("modest: modest_platform_activate_uri : %s",
239 err->message ? err->message : "unknown error");
246 /* if we could not open it with email, try something else */
248 result = hildon_uri_open (uri, NULL, NULL);
251 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
257 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
261 gchar *uri_path = NULL;
263 uri_path = g_strconcat ("file://", path, NULL);
264 con = osso_get_dbus_connection (osso_context);
267 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
269 result = hildon_mime_open_file (con, uri_path);
271 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"));
279 } ModestPlatformPopupInfo;
282 delete_uri_popup (GtkWidget *menu,
286 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
288 g_free (popup_info->uri);
289 hildon_uri_free_actions (popup_info->actions);
295 activate_uri_popup_item (GtkMenuItem *menu_item,
299 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
300 const gchar* action_name;
302 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
304 g_printerr ("modest: no action name defined\n");
308 /* special handling for the copy menu item -- copy the uri to the clipboard */
309 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
310 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
311 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
312 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
314 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
315 action_name += strlen ("mailto:");
317 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
318 return; /* we're done */
321 /* now, the real uri-actions... */
322 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
323 HildonURIAction *action = (HildonURIAction *) node->data;
324 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
325 hildon_uri_open (popup_info->uri, action, NULL);
332 modest_platform_show_uri_popup (const gchar *uri)
334 GSList *actions_list;
339 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
340 if (actions_list != NULL) {
342 GtkWidget *menu = gtk_menu_new ();
343 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
345 popup_info->actions = actions_list;
346 popup_info->uri = g_strdup (uri);
348 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
349 GtkWidget *menu_item;
350 const gchar *action_name;
351 const gchar *translation_domain;
352 HildonURIAction *action = (HildonURIAction *) node->data;
353 action_name = hildon_uri_action_get_name (action);
354 translation_domain = hildon_uri_action_get_translation_domain (action);
355 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
356 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
357 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
360 if (hildon_uri_is_default_action (action, NULL)) {
361 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
363 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
365 gtk_widget_show (menu_item);
368 /* always add the copy item */
369 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri", "uri_link_copy_link_location"));
370 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
371 g_strconcat (URI_ACTION_COPY, uri, NULL),
373 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
374 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
375 gtk_widget_show (menu_item);
378 /* and what to do when the link is deleted */
379 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
380 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
383 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
391 modest_platform_get_icon (const gchar *name)
394 GdkPixbuf* pixbuf = NULL;
395 GtkIconTheme *current_theme = NULL;
397 g_return_val_if_fail (name, NULL);
399 /* strlen == 0 is not really an error; it just
400 * means the icon is not available
402 if (!name || strlen(name) == 0)
405 #if 0 /* do we still need this? */
406 if (g_str_has_suffix (name, ".png")) { /*FIXME: hack*/
407 pixbuf = gdk_pixbuf_new_from_file (name, &err);
409 g_printerr ("modest: error loading icon '%s': %s\n",
417 current_theme = gtk_icon_theme_get_default ();
418 pixbuf = gtk_icon_theme_load_icon (current_theme, name, 26,
419 GTK_ICON_LOOKUP_NO_SVG,
422 g_printerr ("modest: error loading theme icon '%s': %s\n",
430 modest_platform_get_app_name (void)
432 return _("mcen_ap_name");
436 entry_insert_text (GtkEditable *editable,
445 chars = gtk_editable_get_chars (editable, 0, -1);
446 chars_length = g_utf8_strlen (chars, -1);
448 /* Show WID-INF036 */
449 if (chars_length >= 20) {
450 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
451 _CS("ckdg_ib_maximum_characters_reached"));
453 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
457 tmp = g_strndup (folder_name_forbidden_chars,
458 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
459 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
460 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
465 /* Write the text in the entry if it's valid */
466 g_signal_handlers_block_by_func (editable,
467 (gpointer) entry_insert_text, data);
468 gtk_editable_insert_text (editable, text, length, position);
469 g_signal_handlers_unblock_by_func (editable,
470 (gpointer) entry_insert_text, data);
473 /* Do not allow further processing */
474 g_signal_stop_emission_by_name (editable, "insert_text");
478 entry_changed (GtkEditable *editable,
482 GtkWidget *ok_button;
485 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
486 ok_button = GTK_WIDGET (buttons->next->data);
488 chars = gtk_editable_get_chars (editable, 0, -1);
489 g_return_if_fail (chars != NULL);
492 if (g_utf8_strlen (chars,-1) >= 21)
493 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
494 _CS("ckdg_ib_maximum_characters_reached"));
496 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
499 g_list_free (buttons);
504 launch_sort_headers_dialog (GtkWindow *parent_window,
505 HildonSortDialog *dialog)
507 ModestHeaderView *header_view = NULL;
509 GtkSortType sort_type;
511 gint default_key = 0;
513 gboolean outgoing = FALSE;
514 gint current_sort_colid = -1;
515 GtkSortType current_sort_type;
516 gint attachments_sort_id;
517 gint priority_sort_id;
518 GtkTreeSortable *sortable;
520 /* Get header window */
521 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
522 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
523 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
525 if (!header_view) return;
527 /* Add sorting keys */
528 cols = modest_header_view_get_columns (header_view);
529 if (cols == NULL) return;
530 int sort_model_ids[6];
534 outgoing = (GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cols->data), MODEST_HEADER_VIEW_COLUMN))==
535 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT);
537 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_sender_recipient"));
539 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
540 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
542 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
543 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
546 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_date"));
548 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
549 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE;
551 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
552 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE;
554 default_key = sort_key;
556 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_subject"));
557 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN;
559 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
561 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
563 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_attachment"));
564 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
565 sort_ids[sort_key] = TNY_HEADER_FLAG_ATTACHMENTS;
566 attachments_sort_id = sort_key;
568 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_size"));
569 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN;
570 sort_ids[sort_key] = 0;
572 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
573 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
574 sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
575 priority_sort_id = sort_key;
577 sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
579 if (!gtk_tree_sortable_get_sort_column_id (sortable,
580 ¤t_sort_colid, ¤t_sort_type)) {
581 hildon_sort_dialog_set_sort_key (dialog, default_key);
582 hildon_sort_dialog_set_sort_order (dialog, GTK_SORT_DESCENDING);
584 hildon_sort_dialog_set_sort_order (dialog, current_sort_type);
585 if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
586 gpointer flags_sort_type_pointer;
587 flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
588 if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
589 hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
591 hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
593 gint current_sort_keyid = 0;
594 while (current_sort_keyid < 6) {
595 if (sort_model_ids[current_sort_keyid] == current_sort_colid)
598 current_sort_keyid++;
600 hildon_sort_dialog_set_sort_key (dialog, current_sort_keyid);
604 result = gtk_dialog_run (GTK_DIALOG (dialog));
605 if (result == GTK_RESPONSE_OK) {
606 sort_key = hildon_sort_dialog_get_sort_key (dialog);
607 sort_type = hildon_sort_dialog_get_sort_order (dialog);
608 if (sort_model_ids[sort_key] == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
609 g_object_set_data (G_OBJECT(cols->data), MODEST_HEADER_VIEW_FLAG_SORT,
610 GINT_TO_POINTER (sort_ids[sort_key]));
611 /* This is a hack to make it resort rows always when flag fields are
612 * selected. If we do not do this, changing sort field from priority to
613 * attachments does not work */
614 modest_header_view_sort_by_column_id (header_view, 0, sort_type);
616 gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (cols->data),
617 sort_model_ids[sort_key]);
620 modest_header_view_sort_by_column_id (header_view, sort_model_ids[sort_key], sort_type);
621 gtk_tree_sortable_sort_column_changed (sortable);
624 modest_widget_memory_save (modest_runtime_get_conf (),
625 G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
627 /* while (gtk_events_pending ()) */
628 /* gtk_main_iteration (); */
637 on_response (GtkDialog *dialog,
641 GList *child_vbox, *child_hbox;
642 GtkWidget *hbox, *entry;
643 TnyFolderStore *parent;
645 if (response != GTK_RESPONSE_ACCEPT)
649 child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
650 hbox = child_vbox->data;
651 child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
652 entry = child_hbox->next->data;
654 parent = TNY_FOLDER_STORE (user_data);
656 /* Look for another folder with the same name */
657 if (modest_tny_folder_has_subfolder_with_name (parent,
658 gtk_entry_get_text (GTK_ENTRY (entry)))) {
660 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
661 NULL, _CS("ckdg_ib_folder_already_exists"));
662 /* Select the text */
663 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
664 gtk_widget_grab_focus (entry);
665 /* Do not close the dialog */
666 g_signal_stop_emission_by_name (dialog, "response");
672 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
673 TnyFolderStore *parent,
674 const gchar *dialog_title,
675 const gchar *label_text,
676 const gchar *suggested_name,
679 GtkWidget *accept_btn = NULL;
680 GtkWidget *dialog, *entry, *label, *hbox;
681 GList *buttons = NULL;
684 /* Ask the user for the folder name */
685 dialog = gtk_dialog_new_with_buttons (dialog_title,
687 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
688 _("mcen_bd_dialog_ok"),
690 _("mcen_bd_dialog_cancel"),
694 /* Add accept button (with unsensitive handler) */
695 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
696 accept_btn = GTK_WIDGET (buttons->next->data);
697 /* Create label and entry */
698 label = gtk_label_new (label_text);
699 /* TODO: check that the suggested name does not exist */
700 /* We set 21 as maximum because we want to show WID-INF036
701 when the user inputs more that 20 */
702 entry = gtk_entry_new_with_max_length (21);
704 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
706 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
707 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
709 /* Connect to the response method to avoid closing the dialog
710 when an invalid name is selected*/
711 g_signal_connect (dialog,
713 G_CALLBACK (on_response),
716 /* Track entry changes */
717 g_signal_connect (entry,
719 G_CALLBACK (entry_insert_text),
721 g_signal_connect (entry,
723 G_CALLBACK (entry_changed),
726 /* Create the hbox */
727 hbox = gtk_hbox_new (FALSE, 12);
728 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
729 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0);
731 /* Add hbox to dialog */
732 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
733 hbox, FALSE, FALSE, 0);
735 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
737 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
741 result = gtk_dialog_run (GTK_DIALOG(dialog));
742 if (result == GTK_RESPONSE_ACCEPT)
743 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
745 gtk_widget_destroy (dialog);
747 while (gtk_events_pending ())
748 gtk_main_iteration ();
754 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
755 TnyFolderStore *parent_folder,
756 gchar *suggested_name,
759 gchar *real_suggested_name = NULL;
762 if(suggested_name == NULL)
764 const gchar *default_name = _("mcen_ia_default_folder_name");
768 for(i = 0; i < 100; ++ i) {
769 gboolean exists = FALSE;
771 sprintf(num_str, "%.2u", i);
774 real_suggested_name = g_strdup (default_name);
776 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
779 exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
780 real_suggested_name);
785 g_free (real_suggested_name);
788 /* Didn't find a free number */
790 real_suggested_name = g_strdup (default_name);
792 real_suggested_name = suggested_name;
795 result = modest_platform_run_folder_name_dialog (parent_window,
797 _("mcen_ti_new_folder"),
798 _("mcen_fi_new_folder_name"),
801 if (suggested_name == NULL)
802 g_free(real_suggested_name);
808 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
809 TnyFolderStore *parent_folder,
810 const gchar *suggested_name,
813 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
815 return modest_platform_run_folder_name_dialog (parent_window,
817 _HL("ckdg_ti_rename_folder"),
818 _HL("ckdg_fi_rename_name"),
824 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
825 const gchar *message)
830 dialog = hildon_note_new_confirmation (parent_window, message);
831 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
833 response = gtk_dialog_run (GTK_DIALOG (dialog));
835 gtk_widget_destroy (GTK_WIDGET (dialog));
837 while (gtk_events_pending ())
838 gtk_main_iteration ();
844 modest_platform_run_yes_no_dialog (GtkWindow *parent_window,
845 const gchar *message)
850 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
851 _("mcen_bd_yes"), GTK_RESPONSE_YES,
852 _("mcen_bd_no"), GTK_RESPONSE_NO,
854 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
856 response = gtk_dialog_run (GTK_DIALOG (dialog));
858 gtk_widget_destroy (GTK_WIDGET (dialog));
860 while (gtk_events_pending ())
861 gtk_main_iteration ();
867 modest_platform_run_information_dialog (GtkWindow *parent_window,
868 const gchar *message)
872 dialog = hildon_note_new_information (parent_window, message);
874 g_signal_connect_swapped (dialog,
876 G_CALLBACK (gtk_widget_destroy),
879 gtk_widget_show_all (dialog);
890 on_idle_connect_and_wait(gpointer user_data)
892 printf ("DEBUG: %s:\n", __FUNCTION__);
893 TnyDevice *device = modest_runtime_get_device();
894 if (!tny_device_is_online (device)) {
896 /* This is a GDK lock because we are an idle callback and
897 * tny_maemo_conic_device_connect can contain Gtk+ code */
899 gdk_threads_enter(); /* CHECKED */
900 tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
901 gdk_threads_leave(); /* CHECKED */
904 /* Allow the function that requested this idle callback to continue: */
905 UtilIdleData *data = (UtilIdleData*)user_data;
907 g_main_loop_quit (data->loop);
909 return FALSE; /* Don't call this again. */
912 static gboolean connect_request_in_progress = FALSE;
914 /* This callback is used when connect_and_wait() is already queued as an idle callback.
915 * This can happen because the gtk_dialog_run() for the connection dialog
916 * (at least in the fake scratchbox version) allows idle handlers to keep running.
919 on_idle_wait_for_previous_connect_to_finish(gpointer user_data)
921 gboolean result = FALSE;
922 TnyDevice *device = modest_runtime_get_device();
923 if (tny_device_is_online (device))
924 result = FALSE; /* Stop trying. */
926 /* Keep trying until connect_request_in_progress is FALSE. */
927 if (connect_request_in_progress)
928 result = TRUE; /* Keep trying */
930 printf ("DEBUG: %s: other idle has finished.\n", __FUNCTION__);
932 result = FALSE; /* Stop trying, now that a result should be available. */
936 if (result == FALSE) {
937 /* Allow the function that requested this idle callback to continue: */
938 UtilIdleData *data = (UtilIdleData*)user_data;
940 g_main_loop_quit (data->loop);
947 set_account_to_online (TnyAccount *account)
949 /* TODO: This is necessary to prevent a cancel of the password dialog
950 * from making a restart necessary to be asked the password again,
951 * but it causes a hang:
954 if (account && TNY_IS_CAMEL_STORE_ACCOUNT (account)) {
955 /* Make sure that store accounts are online too,
956 * because tinymail sets accounts to offline if
957 * a password dialog is ever cancelled.
958 * We don't do this for transport accounts because
959 * a) They fundamentally need network access, so they can't really be offline.
960 * b) That might cause a transport connection to happen too early.
963 /* The last argument is user_data, the NULL before that is the callback */
964 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE, NULL, NULL);
970 modest_platform_connect_and_wait (GtkWindow *parent_window, TnyAccount *account)
972 if (connect_request_in_progress)
975 printf ("DEBUG: %s:\n", __FUNCTION__);
976 TnyDevice *device = modest_runtime_get_device();
978 if (tny_device_is_online (device)) {
979 printf ("DEBUG: %s: Already online.\n", __FUNCTION__);
980 set_account_to_online (account);
984 printf ("DEBUG: %s: tny_device_is_online() returned FALSE\n", __FUNCTION__);
987 /* This blocks on the result: */
988 UtilIdleData *data = g_slice_new0 (UtilIdleData);
990 GMainContext *context = NULL; /* g_main_context_new (); */
991 data->loop = g_main_loop_new (context, FALSE /* not running */);
993 /* Cause the function to be run in an idle-handler, which is always
994 * in the main thread:
996 if (!connect_request_in_progress) {
997 printf ("DEBUG: %s: First request\n", __FUNCTION__);
998 connect_request_in_progress = TRUE;
999 g_idle_add (&on_idle_connect_and_wait, data);
1002 printf ("DEBUG: %s: nth request\n", __FUNCTION__);
1003 g_idle_add_full (G_PRIORITY_LOW, &on_idle_wait_for_previous_connect_to_finish, data, NULL);
1006 /* This main loop will run until the idle handler has stopped it: */
1007 printf ("DEBUG: %s: before g_main_loop_run()\n", __FUNCTION__);
1008 GDK_THREADS_LEAVE();
1009 g_main_loop_run (data->loop);
1010 GDK_THREADS_ENTER();
1011 printf ("DEBUG: %s: after g_main_loop_run()\n", __FUNCTION__);
1012 connect_request_in_progress = FALSE;
1013 printf ("DEBUG: %s: Finished\n", __FUNCTION__);
1014 g_main_loop_unref (data->loop);
1015 /* g_main_context_unref (context); */
1017 g_slice_free (UtilIdleData, data);
1019 const gboolean result = tny_device_is_online (device);
1022 set_account_to_online (account);
1029 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1031 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1032 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1033 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1034 /* This must be a maildir account, which does not require a connection: */
1039 return modest_platform_connect_and_wait (parent_window, account);
1043 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1046 return TRUE; /* Maybe it is something local. */
1048 gboolean result = TRUE;
1049 if (TNY_IS_FOLDER (folder_store)) {
1050 /* Get the folder's parent account: */
1051 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1052 if (account != NULL) {
1053 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1054 g_object_unref (account);
1056 } else if (TNY_IS_ACCOUNT (folder_store)) {
1057 /* Use the folder store as an account: */
1058 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1065 modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
1067 TnyAccount *account = NULL;
1068 gboolean result = TRUE;
1070 g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
1072 if (TNY_IS_FOLDER (folder_store)) {
1073 /* Get the folder's parent account: */
1074 account = tny_folder_get_account(TNY_FOLDER(folder_store));
1075 } else if (TNY_IS_ACCOUNT (folder_store)) {
1076 account = TNY_ACCOUNT(folder_store);
1077 g_object_ref(account);
1080 if (account != NULL) {
1081 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1082 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1083 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1084 /* This must be a maildir account, which does
1085 * not require a connection: */
1089 g_object_unref (account);
1098 modest_platform_run_sort_dialog (GtkWindow *parent_window,
1099 ModestSortDialogType type)
1101 GtkWidget *dialog = NULL;
1104 dialog = hildon_sort_dialog_new (parent_window);
1105 gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
1107 /* Fill sort keys */
1109 case MODEST_SORT_HEADERS:
1110 launch_sort_headers_dialog (parent_window,
1111 HILDON_SORT_DIALOG(dialog));
1116 gtk_widget_destroy (GTK_WIDGET (dialog));
1121 modest_platform_set_update_interval (guint minutes)
1123 ModestConf *conf = modest_runtime_get_conf ();
1127 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1129 /* Delete any existing alarm,
1130 * because we will replace it: */
1132 /* TODO: What does the alarm_event_del() return value mean? */
1133 alarm_event_del(alarm_cookie);
1135 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1138 /* 0 means no updates: */
1143 /* Register alarm: */
1145 /* Set the interval in alarm_event_t structure: */
1146 alarm_event_t *event = g_new0(alarm_event_t, 1);
1147 event->alarm_time = minutes * 60; /* seconds */
1149 /* Set recurrence every few minutes: */
1150 event->recurrence = minutes;
1151 event->recurrence_count = -1; /* Means infinite */
1153 /* Specify what should happen when the alarm happens:
1154 * It should call this D-Bus method: */
1156 event->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1157 event->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1158 event->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1159 event->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1161 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1162 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1163 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1164 * This is why we want to use the Alarm API instead of just g_timeout_add().
1165 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1167 event->flags = ALARM_EVENT_NO_DIALOG | ALARM_EVENT_ACTIVATION;
1169 alarm_cookie = alarm_event_add (event);
1172 alarm_event_free (event);
1174 /* Store the alarm ID in GConf, so we can remove it later:
1175 * This is apparently valid between application instances. */
1176 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1178 if (!alarm_cookie) {
1180 const alarm_error_t alarm_error = alarmd_get_error ();
1181 g_debug ("Error setting alarm event. Error code: '%d'\n", alarm_error);
1183 /* Give people some clue: */
1184 /* The alarm API should have a function for this: */
1185 if (alarm_error == ALARMD_ERROR_DBUS) {
1186 g_debug (" ALARMD_ERROR_DBUS: An error with D-Bus occurred, probably coudn't get a D-Bus connection.\n");
1187 } else if (alarm_error == ALARMD_ERROR_CONNECTION) {
1188 g_debug (" ALARMD_ERROR_CONNECTION: Could not contact alarmd via D-Bus.\n");
1189 } else if (alarm_error == ALARMD_ERROR_INTERNAL) {
1190 g_debug (" ALARMD_ERROR_INTERNAL: Some alarmd or libalarm internal error, possibly a version mismatch.\n");
1191 } else if (alarm_error == ALARMD_ERROR_MEMORY) {
1192 g_debug (" ALARMD_ERROR_MEMORY: A memory allocation failed.\n");
1193 } else if (alarm_error == ALARMD_ERROR_ARGUMENT) {
1194 g_debug (" ALARMD_ERROR_ARGUMENT: An argument given by caller was invalid.\n");
1195 } else if (alarm_error == ALARMD_ERROR_NOT_RUNNING) {
1196 g_debug (" ALARMD_ERROR_NOT_RUNNING: alarmd is not running.\n");
1206 modest_platform_get_global_settings_dialog ()
1208 return modest_maemo_global_settings_dialog_new ();
1212 modest_platform_on_new_header_received (TnyHeader *header)
1214 #ifdef MODEST_HAVE_HILDON_NOTIFY
1215 HildonNotification *notification;
1217 TnyFolder *folder = NULL;
1218 const gchar *subject;
1220 subject = tny_header_get_subject (header);
1221 if (!subject || strlen(subject) == 0)
1222 subject = _("mail_va_no_subject");
1224 notification = hildon_notification_new (tny_header_get_from (header),
1226 "qgn_list_messagin",
1229 folder = tny_header_get_folder (header);
1230 url = g_strdup_printf ("%s/%s",
1231 tny_folder_get_url_string (folder),
1232 tny_header_get_uid (header));
1233 g_object_unref (folder);
1235 hildon_notification_add_dbus_action(notification,
1238 MODEST_DBUS_SERVICE,
1241 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1246 /* Play sound if the user wants */
1247 if (modest_conf_get_bool (modest_runtime_get_conf (),
1248 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE,
1250 hildon_notification_set_sound (HILDON_NOTIFICATION(notification),
1251 "/usr/share/sounds/ui-new_email.wav");
1254 /* Set the led pattern */
1255 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION(notification),
1257 notify_notification_set_hint_string(NOTIFY_NOTIFICATION(notification),
1259 "PatternCommunicationEmail");
1261 /* Notify. We need to do this in an idle because this function
1262 could be called from a thread */
1263 if (!notify_notification_show (NOTIFY_NOTIFICATION(notification), NULL))
1264 g_error ("Failed to send notification");
1266 g_object_unref (notification);
1267 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1272 modest_platform_show_help (GtkWindow *parent_window,
1273 const gchar *help_id)
1275 osso_return_t result;
1277 g_return_if_fail (help_id);
1278 g_return_if_fail (osso_context);
1281 #ifdef MODEST_HAVE_OSSO_HELP
1282 result = ossohelp_show (osso_context, help_id, OSSO_HELP_SHOW_DIALOG);
1284 result = hildon_help_show (osso_context, help_id, OSSO_HELP_SHOW_DIALOG);
1287 if (result != OSSO_OK) {
1289 error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id);
1290 hildon_banner_show_information (GTK_WIDGET (parent_window),
1298 modest_platform_show_search_messages (GtkWindow *parent_window)
1300 osso_return_t result = OSSO_ERROR;
1302 result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
1304 if (result != OSSO_OK) {
1305 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1310 modest_platform_show_addressbook (GtkWindow *parent_window)
1312 osso_return_t result = OSSO_ERROR;
1314 result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
1316 if (result != OSSO_OK) {
1317 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1322 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1324 GtkWidget *widget = modest_folder_view_new (query);
1326 /* Show one account by default */
1327 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1328 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1331 /* Restore settings */
1332 modest_widget_memory_restore (modest_runtime_get_conf(),
1334 MODEST_CONF_FOLDER_VIEW_KEY);
1340 modest_platform_information_banner (GtkWidget *parent,
1341 const gchar *icon_name,
1344 hildon_banner_show_information (parent, icon_name, text);
1348 modest_platform_animation_banner (GtkWidget *parent,
1349 const gchar *animation_name,
1352 GtkWidget *inf_note = NULL;
1354 g_return_val_if_fail (text != NULL, NULL);
1356 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1364 TnyAccount *account;
1367 } CheckAccountIdleData;
1369 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1372 on_timeout_check_account_is_online(gpointer user_data)
1374 printf ("DEBUG: %s:\n", __FUNCTION__);
1375 CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
1378 g_warning ("%s: data is NULL.\n", __FUNCTION__);
1381 if (!(data->account)) {
1382 g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
1385 if (data && data->account) {
1386 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));
1389 gboolean stop_trying = FALSE;
1390 if (data && data->account &&
1391 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1392 * after which the account is likely to be usable, or never likely to be usable soon: */
1393 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1395 data->is_online = TRUE;
1400 /* Give up if we have tried too many times: */
1401 if (data->count_tries >= NUMBER_OF_TRIES)
1406 /* Wait for another timeout: */
1407 ++(data->count_tries);
1412 /* Allow the function that requested this idle callback to continue: */
1414 g_main_loop_quit (data->loop);
1417 g_object_unref (data->account);
1419 return FALSE; /* Don't call this again. */
1421 return TRUE; /* Call this timeout callback again. */
1425 /* Return TRUE immediately if the account is already online,
1426 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1427 * soon as the account is online, or FALSE if the account does
1428 * not become online in the NUMBER_OF_TRIES seconds.
1429 * This is useful when the D-Bus method was run immediately after
1430 * the application was started (when using D-Bus activation),
1431 * because the account usually takes a short time to go online.
1432 * The return value is maybe not very useful.
1435 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1437 g_return_val_if_fail (account, FALSE);
1439 printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
1441 if (!tny_device_is_online (modest_runtime_get_device())) {
1442 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1446 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1447 * so we avoid wait unnecessarily: */
1448 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1449 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
1453 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n",
1454 __FUNCTION__, tny_account_get_connection_status (account));
1456 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1457 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1458 * we want to avoid. */
1459 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1462 /* This blocks on the result: */
1463 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1464 data->is_online = FALSE;
1465 data->account = account;
1466 g_object_ref (data->account);
1467 data->count_tries = 0;
1469 GMainContext *context = NULL; /* g_main_context_new (); */
1470 data->loop = g_main_loop_new (context, FALSE /* not running */);
1472 g_timeout_add (1000, &on_timeout_check_account_is_online, data);
1474 /* This main loop will run until the idle handler has stopped it: */
1475 g_main_loop_run (data->loop);
1477 g_main_loop_unref (data->loop);
1478 /* g_main_context_unref (context); */
1480 g_slice_free (CheckAccountIdleData, data);
1482 return data->is_online;
1488 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1490 /* GTK_RESPONSE_HELP means we need to show the certificate */
1491 if (response_id == GTK_RESPONSE_HELP) {
1495 /* Do not close the dialog */
1496 g_signal_stop_emission_by_name (dialog, "response");
1498 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1499 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1500 gtk_dialog_run (GTK_DIALOG(note));
1501 gtk_widget_destroy (note);
1507 modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
1508 const gchar *certificate)
1512 GtkWindow *main_win =
1513 (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
1515 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1518 note = hildon_note_new_confirmation_add_buttons (
1521 _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
1522 _("mcen_bd_view"), GTK_RESPONSE_HELP, /* abusing this... */
1523 _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
1526 g_signal_connect (G_OBJECT(note), "response",
1527 G_CALLBACK(on_cert_dialog_response),
1528 (gpointer) certificate);
1529 response = gtk_dialog_run(GTK_DIALOG(note));
1531 gtk_widget_destroy(GTK_WIDGET(note));
1540 modest_platform_run_alert_dialog (const gchar* prompt,
1541 gboolean is_question)
1543 ModestWindow *main_window =
1544 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
1546 gboolean retval = TRUE;
1548 /* The Tinymail documentation says that we should show Yes and No buttons,
1549 * when it is a question.
1550 * Obviously, we need tinymail to use more specific error codes instead,
1551 * so we know what buttons to show. */
1552 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
1554 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1555 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1557 gtk_widget_destroy (dialog);
1560 /* Just show the error text and use the default response: */
1561 modest_platform_run_information_dialog (GTK_WINDOW (main_window),