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 /* The maximun number of notifications that could be shown in the
63 desktop. It's specified by the specs and limited by the screen
65 #define MAX_NOTIFICATIONS 6
67 static osso_context_t *osso_context = NULL;
70 on_modest_conf_update_interval_changed (ModestConf* self,
72 ModestConfEvent event,
73 ModestConfNotificationId id,
76 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
77 const guint update_interval_minutes =
78 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
79 modest_platform_set_update_interval (update_interval_minutes);
86 check_required_files (void)
88 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
90 g_printerr ("modest: check for mcc file failed\n");
95 if (access (MODEST_PROVIDERS_DATA_PATH, R_OK) != 0) {
96 g_printerr ("modest: cannot find providers data\n");
106 modest_platform_init (int argc, char *argv[])
108 osso_hw_state_t hw_state = { 0 };
111 if (!check_required_files ()) {
112 g_printerr ("modest: missing required files\n");
118 osso_initialize(PACKAGE,PACKAGE_VERSION,
121 g_printerr ("modest: failed to acquire osso context\n");
125 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
126 g_printerr ("modest: could not get dbus connection\n");
131 /* Add a D-Bus handler to be used when the main osso-rpc
132 * D-Bus handler has not handled something.
133 * We use this for D-Bus methods that need to use more complex types
134 * than osso-rpc supports.
136 if (!dbus_connection_add_filter (con,
137 modest_dbus_req_filter,
141 g_printerr ("modest: Could not add D-Bus filter\n");
145 /* Register our simple D-Bus callbacks, via the osso API: */
146 osso_return_t result = osso_rpc_set_cb_f(osso_context,
150 modest_dbus_req_handler, NULL /* user_data */);
151 if (result != OSSO_OK) {
152 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
156 /* Add handler for Exit D-BUS messages.
157 * Not used because osso_application_set_exit_cb() is deprecated and obsolete:
158 result = osso_application_set_exit_cb(osso_context,
159 modest_dbus_exit_event_handler,
161 if (result != OSSO_OK) {
162 g_print("Error setting exit callback (%d)\n", result);
167 /* Register hardware event dbus callback: */
168 hw_state.shutdown_ind = TRUE;
169 osso_hw_set_event_cb(osso_context, NULL,/*&hw_state*/ modest_osso_cb_hw_state_handler, NULL);
171 /* Register osso auto-save callbacks: */
172 result = osso_application_set_autosave_cb (osso_context,
173 modest_on_osso_application_autosave, NULL /* user_data */);
174 if (result != OSSO_OK) {
175 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
180 /* Make sure that the update interval is changed whenever its gconf key
182 /* CAUTION: we're not using here the
183 modest_conf_listen_to_namespace because we know that there
184 are other parts of Modest listening for this namespace, so
185 we'll receive the notifications anyway. We basically do not
186 use it because there is no easy way to do the
187 modest_conf_forget_namespace */
188 ModestConf *conf = modest_runtime_get_conf ();
189 g_signal_connect (G_OBJECT(conf),
191 G_CALLBACK (on_modest_conf_update_interval_changed),
194 /* Get the initial update interval from gconf: */
195 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
196 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
198 /* initialize the addressbook */
199 if (!osso_abook_init (&argc, &argv, osso_context)) {
200 g_printerr ("modest: failed to initialized addressbook\n");
208 modest_platform_get_new_device (void)
210 return TNY_DEVICE (tny_maemo_conic_device_new ());
214 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
215 gchar **effective_mime_type)
217 GString *mime_str = NULL;
218 gchar *icon_name = NULL;
219 gchar **icons, **cursor;
221 if (!mime_type || !g_ascii_strcasecmp (mime_type, "application/octet-stream"))
222 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
224 mime_str = g_string_new (mime_type);
225 g_string_ascii_down (mime_str);
228 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
229 for (cursor = icons; cursor; ++cursor) {
230 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
231 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
232 icon_name = g_strdup ("qgn_list_messagin");
234 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
235 icon_name = g_strdup (*cursor);
241 if (effective_mime_type)
242 *effective_mime_type = g_string_free (mime_str, FALSE);
244 g_string_free (mime_str, TRUE);
251 modest_platform_activate_uri (const gchar *uri)
253 HildonURIAction *action;
254 gboolean result = FALSE;
255 GSList *actions, *iter = NULL;
257 g_return_val_if_fail (uri, FALSE);
261 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
263 for (iter = actions; iter; iter = g_slist_next (iter)) {
264 action = (HildonURIAction*) iter->data;
265 if (action && strcmp (hildon_uri_action_get_service (action),
266 "com.nokia.modest") == 0) {
268 result = hildon_uri_open (uri, action, &err);
269 if (!result && err) {
270 g_printerr ("modest: modest_platform_activate_uri : %s",
271 err->message ? err->message : "unknown error");
278 /* if we could not open it with email, try something else */
280 result = hildon_uri_open (uri, NULL, NULL);
283 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
289 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
293 gchar *uri_path = NULL;
295 uri_path = g_strconcat ("file://", path, NULL);
296 con = osso_get_dbus_connection (osso_context);
299 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
301 result = hildon_mime_open_file (con, uri_path);
303 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"));
311 } ModestPlatformPopupInfo;
314 delete_uri_popup (GtkWidget *menu,
318 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
320 g_free (popup_info->uri);
321 hildon_uri_free_actions (popup_info->actions);
327 activate_uri_popup_item (GtkMenuItem *menu_item,
331 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
332 const gchar* action_name;
334 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
336 g_printerr ("modest: no action name defined\n");
340 /* special handling for the copy menu item -- copy the uri to the clipboard */
341 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
342 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
343 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
344 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
346 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
347 action_name += strlen ("mailto:");
349 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
350 return; /* we're done */
353 /* now, the real uri-actions... */
354 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
355 HildonURIAction *action = (HildonURIAction *) node->data;
356 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
357 hildon_uri_open (popup_info->uri, action, NULL);
364 modest_platform_show_uri_popup (const gchar *uri)
366 GSList *actions_list;
371 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
372 if (actions_list != NULL) {
374 GtkWidget *menu = gtk_menu_new ();
375 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
377 popup_info->actions = actions_list;
378 popup_info->uri = g_strdup (uri);
380 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
381 GtkWidget *menu_item;
382 const gchar *action_name;
383 const gchar *translation_domain;
384 HildonURIAction *action = (HildonURIAction *) node->data;
385 action_name = hildon_uri_action_get_name (action);
386 translation_domain = hildon_uri_action_get_translation_domain (action);
387 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
388 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
389 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
392 if (hildon_uri_is_default_action (action, NULL)) {
393 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
395 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
397 gtk_widget_show (menu_item);
400 /* always add the copy item */
401 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri", "uri_link_copy_link_location"));
402 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
403 g_strconcat (URI_ACTION_COPY, uri, NULL),
405 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
406 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
407 gtk_widget_show (menu_item);
410 /* and what to do when the link is deleted */
411 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
412 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
415 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
423 modest_platform_get_icon (const gchar *name)
426 GdkPixbuf* pixbuf = NULL;
427 GtkIconTheme *current_theme = NULL;
429 g_return_val_if_fail (name, NULL);
431 /* strlen == 0 is not really an error; it just
432 * means the icon is not available
434 if (!name || strlen(name) == 0)
437 #if 0 /* do we still need this? */
438 if (g_str_has_suffix (name, ".png")) { /*FIXME: hack*/
439 pixbuf = gdk_pixbuf_new_from_file (name, &err);
441 g_printerr ("modest: error loading icon '%s': %s\n",
449 current_theme = gtk_icon_theme_get_default ();
450 pixbuf = gtk_icon_theme_load_icon (current_theme, name, 26,
451 GTK_ICON_LOOKUP_NO_SVG,
454 g_printerr ("modest: error loading theme icon '%s': %s\n",
462 modest_platform_get_app_name (void)
464 return _("mcen_ap_name");
468 entry_insert_text (GtkEditable *editable,
477 chars = gtk_editable_get_chars (editable, 0, -1);
478 chars_length = g_utf8_strlen (chars, -1);
480 /* Show WID-INF036 */
481 if (chars_length >= 20) {
482 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
483 _CS("ckdg_ib_maximum_characters_reached"));
485 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
489 tmp = g_strndup (folder_name_forbidden_chars,
490 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
491 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
492 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
497 /* Write the text in the entry if it's valid */
498 g_signal_handlers_block_by_func (editable,
499 (gpointer) entry_insert_text, data);
500 gtk_editable_insert_text (editable, text, length, position);
501 g_signal_handlers_unblock_by_func (editable,
502 (gpointer) entry_insert_text, data);
505 /* Do not allow further processing */
506 g_signal_stop_emission_by_name (editable, "insert_text");
510 entry_changed (GtkEditable *editable,
514 GtkWidget *ok_button;
517 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
518 ok_button = GTK_WIDGET (buttons->next->data);
520 chars = gtk_editable_get_chars (editable, 0, -1);
521 g_return_if_fail (chars != NULL);
524 if (g_utf8_strlen (chars,-1) >= 21)
525 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
526 _CS("ckdg_ib_maximum_characters_reached"));
528 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
531 g_list_free (buttons);
536 launch_sort_headers_dialog (GtkWindow *parent_window,
537 HildonSortDialog *dialog)
539 ModestHeaderView *header_view = NULL;
541 GtkSortType sort_type;
543 gint default_key = 0;
545 gboolean outgoing = FALSE;
546 gint current_sort_colid = -1;
547 GtkSortType current_sort_type;
548 gint attachments_sort_id;
549 gint priority_sort_id;
550 GtkTreeSortable *sortable;
552 /* Get header window */
553 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
554 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
555 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
557 if (!header_view) return;
559 /* Add sorting keys */
560 cols = modest_header_view_get_columns (header_view);
561 if (cols == NULL) return;
562 int sort_model_ids[6];
566 outgoing = (GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cols->data), MODEST_HEADER_VIEW_COLUMN))==
567 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT);
569 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_sender_recipient"));
571 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
572 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
574 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
575 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
578 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_date"));
580 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
581 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE;
583 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
584 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE;
586 default_key = sort_key;
588 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_subject"));
589 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN;
591 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
593 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
595 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_attachment"));
596 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
597 sort_ids[sort_key] = TNY_HEADER_FLAG_ATTACHMENTS;
598 attachments_sort_id = sort_key;
600 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_size"));
601 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN;
602 sort_ids[sort_key] = 0;
604 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
605 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
606 sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
607 priority_sort_id = sort_key;
609 sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
611 if (!gtk_tree_sortable_get_sort_column_id (sortable,
612 ¤t_sort_colid, ¤t_sort_type)) {
613 hildon_sort_dialog_set_sort_key (dialog, default_key);
614 hildon_sort_dialog_set_sort_order (dialog, GTK_SORT_DESCENDING);
616 hildon_sort_dialog_set_sort_order (dialog, current_sort_type);
617 if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
618 gpointer flags_sort_type_pointer;
619 flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
620 if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
621 hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
623 hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
625 gint current_sort_keyid = 0;
626 while (current_sort_keyid < 6) {
627 if (sort_model_ids[current_sort_keyid] == current_sort_colid)
630 current_sort_keyid++;
632 hildon_sort_dialog_set_sort_key (dialog, current_sort_keyid);
636 result = gtk_dialog_run (GTK_DIALOG (dialog));
637 if (result == GTK_RESPONSE_OK) {
638 sort_key = hildon_sort_dialog_get_sort_key (dialog);
639 sort_type = hildon_sort_dialog_get_sort_order (dialog);
640 if (sort_model_ids[sort_key] == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
641 g_object_set_data (G_OBJECT(cols->data), MODEST_HEADER_VIEW_FLAG_SORT,
642 GINT_TO_POINTER (sort_ids[sort_key]));
643 /* This is a hack to make it resort rows always when flag fields are
644 * selected. If we do not do this, changing sort field from priority to
645 * attachments does not work */
646 modest_header_view_sort_by_column_id (header_view, 0, sort_type);
648 gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (cols->data),
649 sort_model_ids[sort_key]);
652 modest_header_view_sort_by_column_id (header_view, sort_model_ids[sort_key], sort_type);
653 gtk_tree_sortable_sort_column_changed (sortable);
656 modest_widget_memory_save (modest_runtime_get_conf (),
657 G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
659 /* while (gtk_events_pending ()) */
660 /* gtk_main_iteration (); */
669 on_response (GtkDialog *dialog,
673 GList *child_vbox, *child_hbox;
674 GtkWidget *hbox, *entry;
675 TnyFolderStore *parent;
677 if (response != GTK_RESPONSE_ACCEPT)
681 child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
682 hbox = child_vbox->data;
683 child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
684 entry = child_hbox->next->data;
686 parent = TNY_FOLDER_STORE (user_data);
688 /* Look for another folder with the same name */
689 if (modest_tny_folder_has_subfolder_with_name (parent,
690 gtk_entry_get_text (GTK_ENTRY (entry)))) {
692 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
693 NULL, _CS("ckdg_ib_folder_already_exists"));
694 /* Select the text */
695 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
696 gtk_widget_grab_focus (entry);
697 /* Do not close the dialog */
698 g_signal_stop_emission_by_name (dialog, "response");
705 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
706 TnyFolderStore *parent,
707 const gchar *dialog_title,
708 const gchar *label_text,
709 const gchar *suggested_name,
712 GtkWidget *accept_btn = NULL;
713 GtkWidget *dialog, *entry, *label, *hbox;
714 GList *buttons = NULL;
717 /* Ask the user for the folder name */
718 dialog = gtk_dialog_new_with_buttons (dialog_title,
720 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
721 _("mcen_bd_dialog_ok"),
723 _("mcen_bd_dialog_cancel"),
727 /* Add accept button (with unsensitive handler) */
728 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
729 accept_btn = GTK_WIDGET (buttons->next->data);
730 /* Create label and entry */
731 label = gtk_label_new (label_text);
732 /* TODO: check that the suggested name does not exist */
733 /* We set 21 as maximum because we want to show WID-INF036
734 when the user inputs more that 20 */
735 entry = gtk_entry_new_with_max_length (21);
737 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
739 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
740 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
742 /* Connect to the response method to avoid closing the dialog
743 when an invalid name is selected*/
744 g_signal_connect (dialog,
746 G_CALLBACK (on_response),
749 /* Track entry changes */
750 g_signal_connect (entry,
752 G_CALLBACK (entry_insert_text),
754 g_signal_connect (entry,
756 G_CALLBACK (entry_changed),
759 /* Create the hbox */
760 hbox = gtk_hbox_new (FALSE, 12);
761 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
762 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0);
764 /* Add hbox to dialog */
765 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
766 hbox, FALSE, FALSE, 0);
768 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
769 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
771 result = gtk_dialog_run (GTK_DIALOG(dialog));
772 if (result == GTK_RESPONSE_ACCEPT)
773 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
775 gtk_widget_destroy (dialog);
777 while (gtk_events_pending ())
778 gtk_main_iteration ();
784 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
785 TnyFolderStore *parent_folder,
786 gchar *suggested_name,
789 gchar *real_suggested_name = NULL;
792 if(suggested_name == NULL)
794 const gchar *default_name = _("mcen_ia_default_folder_name");
798 for(i = 0; i < 100; ++ i) {
799 gboolean exists = FALSE;
801 sprintf(num_str, "%.2u", i);
804 real_suggested_name = g_strdup (default_name);
806 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
809 exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
810 real_suggested_name);
815 g_free (real_suggested_name);
818 /* Didn't find a free number */
820 real_suggested_name = g_strdup (default_name);
822 real_suggested_name = suggested_name;
825 result = modest_platform_run_folder_name_dialog (parent_window,
827 _("mcen_ti_new_folder"),
828 _("mcen_fi_new_folder_name"),
831 if (suggested_name == NULL)
832 g_free(real_suggested_name);
838 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
839 TnyFolderStore *parent_folder,
840 const gchar *suggested_name,
843 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
845 return modest_platform_run_folder_name_dialog (parent_window,
847 _HL("ckdg_ti_rename_folder"),
848 _HL("ckdg_fi_rename_name"),
856 on_destroy_dialog (GtkDialog *dialog)
858 gtk_widget_destroy (GTK_WIDGET(dialog));
859 if (gtk_events_pending ())
860 gtk_main_iteration ();
864 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
865 const gchar *message)
870 dialog = hildon_note_new_confirmation (parent_window, message);
871 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
872 GTK_WINDOW (dialog));
874 response = gtk_dialog_run (GTK_DIALOG (dialog));
876 on_destroy_dialog (GTK_DIALOG(dialog));
878 while (gtk_events_pending ())
879 gtk_main_iteration ();
885 modest_platform_run_yes_no_dialog (GtkWindow *parent_window,
886 const gchar *message)
891 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
892 _("mcen_bd_yes"), GTK_RESPONSE_YES,
893 _("mcen_bd_no"), GTK_RESPONSE_NO,
895 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
896 response = gtk_dialog_run (GTK_DIALOG (dialog));
898 on_destroy_dialog (GTK_DIALOG(dialog));
900 while (gtk_events_pending ())
901 gtk_main_iteration ();
909 modest_platform_run_information_dialog (GtkWindow *parent_window,
910 const gchar *message)
914 note = hildon_note_new_information (parent_window, message);
915 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
918 g_signal_connect_swapped (note,
920 G_CALLBACK (on_destroy_dialog),
923 gtk_widget_show_all (note);
928 typedef struct _UtilIdleData {
936 on_connection_status_changed (TnyAccount *self,
937 TnyConnectionStatus status,
940 UtilIdleData *data = (UtilIdleData *) user_data;
941 TnyConnectionStatus conn_status;
943 conn_status = tny_account_get_connection_status (data->account);
944 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING)
947 /* Remove the handler and Exit loop */
948 g_signal_handler_disconnect (self, data->handler);
949 g_main_loop_quit (data->loop);
953 on_idle_connect_and_wait(gpointer user_data)
955 TnyDevice *device = NULL;
956 UtilIdleData *data = NULL;
957 gboolean connected, exit_loop;
960 device = modest_runtime_get_device();
961 data = (UtilIdleData*) user_data;
963 /* This is a GDK lock because we are an idle callback and
964 * tny_maemo_conic_device_connect can contain Gtk+ code */
966 connected = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
970 data->error = g_error_new (0, 0, "Error connecting");
975 TnyConnectionStatus conn_status;
976 gboolean tried_to_connect;
978 conn_status = tny_account_get_connection_status (data->account);
979 tried_to_connect = (conn_status == TNY_CONNECTION_STATUS_CONNECTED ||
980 conn_status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN);
982 if (!tried_to_connect) {
984 g_signal_connect (data->account, "connection-status-changed",
985 G_CALLBACK (on_connection_status_changed),
993 g_main_loop_quit (data->loop);
995 /* Remove the idle if we're connected */
1000 modest_platform_connect_and_wait (GtkWindow *parent_window,
1001 TnyAccount *account)
1003 UtilIdleData *data = NULL;
1006 if (!account && tny_device_is_online (modest_runtime_get_device()))
1010 tny_device_is_online (modest_runtime_get_device()) &&
1011 tny_account_get_connection_status (account) == TNY_CONNECTION_STATUS_CONNECTED)
1014 /* This blocks on the result: */
1015 data = g_slice_new0 (UtilIdleData);
1017 data->loop = g_main_loop_new (NULL, FALSE);
1018 data->account = (account) ? g_object_ref (account) : NULL;
1020 /* Cause the function to be run in an idle-handler, which is
1021 * always in the main thread
1023 g_idle_add (&on_idle_connect_and_wait, data);
1025 gdk_threads_leave ();
1026 g_main_loop_run (data->loop);
1027 gdk_threads_enter ();
1029 g_main_loop_unref (data->loop);
1032 g_error_free (data->error);
1038 g_object_unref (data->account);
1040 g_slice_free (UtilIdleData, data);
1046 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1048 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1049 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1050 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1051 /* This must be a maildir account, which does not require a connection: */
1056 return modest_platform_connect_and_wait (parent_window, account);
1060 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1063 return TRUE; /* Maybe it is something local. */
1065 gboolean result = TRUE;
1066 if (TNY_IS_FOLDER (folder_store)) {
1067 /* Get the folder's parent account: */
1068 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1069 if (account != NULL) {
1070 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1071 g_object_unref (account);
1073 } else if (TNY_IS_ACCOUNT (folder_store)) {
1074 /* Use the folder store as an account: */
1075 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1082 modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
1084 TnyAccount *account = NULL;
1085 gboolean result = TRUE;
1087 g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
1089 if (TNY_IS_FOLDER (folder_store)) {
1090 /* Get the folder's parent account: */
1091 account = tny_folder_get_account(TNY_FOLDER(folder_store));
1092 } else if (TNY_IS_ACCOUNT (folder_store)) {
1093 account = TNY_ACCOUNT(folder_store);
1094 g_object_ref(account);
1097 if (account != NULL) {
1098 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1099 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1100 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1101 /* This must be a maildir account, which does
1102 * not require a connection: */
1106 g_object_unref (account);
1115 modest_platform_run_sort_dialog (GtkWindow *parent_window,
1116 ModestSortDialogType type)
1118 GtkWidget *dialog = NULL;
1121 dialog = hildon_sort_dialog_new (parent_window);
1122 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1123 GTK_WINDOW (dialog));
1125 /* Fill sort keys */
1127 case MODEST_SORT_HEADERS:
1128 launch_sort_headers_dialog (parent_window,
1129 HILDON_SORT_DIALOG(dialog));
1134 on_destroy_dialog (GTK_DIALOG(dialog));
1139 modest_platform_set_update_interval (guint minutes)
1141 ModestConf *conf = modest_runtime_get_conf ();
1145 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1147 /* Delete any existing alarm,
1148 * because we will replace it: */
1150 /* TODO: What does the alarm_event_del() return value mean? */
1151 alarm_event_del(alarm_cookie);
1153 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1156 /* 0 means no updates: */
1161 /* Register alarm: */
1163 /* Set the interval in alarm_event_t structure: */
1164 alarm_event_t *event = g_new0(alarm_event_t, 1);
1165 event->alarm_time = minutes * 60; /* seconds */
1167 /* Set recurrence every few minutes: */
1168 event->recurrence = minutes;
1169 event->recurrence_count = -1; /* Means infinite */
1171 /* Specify what should happen when the alarm happens:
1172 * It should call this D-Bus method: */
1174 event->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1175 event->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1176 event->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1177 event->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1179 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1180 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1181 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1182 * This is why we want to use the Alarm API instead of just g_timeout_add().
1183 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1185 event->flags = ALARM_EVENT_NO_DIALOG | ALARM_EVENT_ACTIVATION;
1187 alarm_cookie = alarm_event_add (event);
1190 alarm_event_free (event);
1192 /* Store the alarm ID in GConf, so we can remove it later:
1193 * This is apparently valid between application instances. */
1194 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1196 if (!alarm_cookie) {
1198 const alarm_error_t alarm_error = alarmd_get_error ();
1199 g_debug ("Error setting alarm event. Error code: '%d'\n", alarm_error);
1201 /* Give people some clue: */
1202 /* The alarm API should have a function for this: */
1203 if (alarm_error == ALARMD_ERROR_DBUS) {
1204 g_debug (" ALARMD_ERROR_DBUS: An error with D-Bus occurred, probably coudn't get a D-Bus connection.\n");
1205 } else if (alarm_error == ALARMD_ERROR_CONNECTION) {
1206 g_debug (" ALARMD_ERROR_CONNECTION: Could not contact alarmd via D-Bus.\n");
1207 } else if (alarm_error == ALARMD_ERROR_INTERNAL) {
1208 g_debug (" ALARMD_ERROR_INTERNAL: Some alarmd or libalarm internal error, possibly a version mismatch.\n");
1209 } else if (alarm_error == ALARMD_ERROR_MEMORY) {
1210 g_debug (" ALARMD_ERROR_MEMORY: A memory allocation failed.\n");
1211 } else if (alarm_error == ALARMD_ERROR_ARGUMENT) {
1212 g_debug (" ALARMD_ERROR_ARGUMENT: An argument given by caller was invalid.\n");
1213 } else if (alarm_error == ALARMD_ERROR_NOT_RUNNING) {
1214 g_debug (" ALARMD_ERROR_NOT_RUNNING: alarmd is not running.\n");
1224 modest_platform_on_new_headers_received (TnyList *header_list)
1226 #ifdef MODEST_HAVE_HILDON_NOTIFY
1227 HildonNotification *notification;
1229 GSList *notifications_list = NULL;
1231 /* Get previous notifications ids */
1232 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1233 MODEST_CONF_NOTIFICATION_IDS,
1234 MODEST_CONF_VALUE_INT, NULL);
1236 iter = tny_list_create_iterator (header_list);
1237 while (!tny_iterator_is_done (iter)) {
1238 gchar *url = NULL, *display_address = NULL, *display_date = NULL, *summary = NULL;
1239 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1240 TnyFolder *folder = tny_header_get_folder (header);
1241 gboolean first_notification = TRUE;
1244 display_date = modest_text_utils_get_display_date (tny_header_get_date_received (header));
1245 display_address = modest_text_utils_get_display_address (tny_header_get_from (header));
1246 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1247 notification = hildon_notification_new (summary,
1248 tny_header_get_subject (header),
1249 "qgn_list_messagin",
1252 /* Create the message URL */
1253 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1254 tny_header_get_uid (header));
1256 hildon_notification_add_dbus_action(notification,
1259 MODEST_DBUS_SERVICE,
1262 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1266 /* Play sound if the user wants. Show the LED
1267 pattern. Show and play just one */
1268 if (G_UNLIKELY (first_notification)) {
1269 first_notification = FALSE;
1270 if (modest_conf_get_bool (modest_runtime_get_conf (),
1271 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE,
1273 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1274 "sound-file", "/usr/share/sounds/ui-new_email.wav");
1277 /* Set the led pattern */
1278 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1280 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1282 "PatternCommunicationEmail");
1285 /* Notify. We need to do this in an idle because this function
1286 could be called from a thread */
1287 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1289 /* Save id in the list */
1290 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1291 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1292 /* We don't listen for the "closed" signal, because we
1293 don't care about if the notification was removed or
1294 not to store the list in gconf */
1296 /* Free & carry on */
1297 g_free (display_date);
1298 g_free (display_address);
1301 g_object_unref (folder);
1302 g_object_unref (header);
1303 tny_iterator_next (iter);
1305 g_object_unref (iter);
1308 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1309 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1311 g_slist_free (notifications_list);
1313 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1317 modest_platform_remove_new_mail_notifications (void)
1319 #ifdef MODEST_HAVE_HILDON_NOTIFY
1320 GSList *notif_list = NULL;
1322 /* Get previous notifications ids */
1323 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1324 MODEST_CONF_NOTIFICATION_IDS,
1325 MODEST_CONF_VALUE_INT, NULL);
1327 while (notif_list) {
1329 NotifyNotification *notif;
1331 /* Nasty HACK to remove the notifications, set the id
1332 of the existing ones and then close them */
1333 notif_id = GPOINTER_TO_INT(notif_list->data);
1334 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1335 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1337 /* Close the notification, note that some ids could be
1338 already invalid, but we don't care because it does
1340 notify_notification_close(notif, NULL);
1341 g_object_unref(notif);
1343 /* Delete the link, it's like going to the next */
1344 notif_list = g_slist_delete_link (notif_list, notif_list);
1348 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1349 notif_list, MODEST_CONF_VALUE_INT, NULL);
1351 g_slist_free (notif_list);
1353 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1359 modest_platform_get_global_settings_dialog ()
1361 return modest_maemo_global_settings_dialog_new ();
1365 modest_platform_show_help (GtkWindow *parent_window,
1366 const gchar *help_id)
1368 osso_return_t result;
1370 g_return_if_fail (help_id);
1371 g_return_if_fail (osso_context);
1373 result = hildon_help_show (osso_context, help_id, HILDON_HELP_SHOW_DIALOG);
1375 if (result != OSSO_OK) {
1377 error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id);
1378 hildon_banner_show_information (GTK_WIDGET (parent_window),
1386 modest_platform_set_dialog_help (GtkDialog *parent_window,
1387 const gchar *help_id)
1390 g_return_if_fail (help_id);
1391 g_return_if_fail (osso_context);
1392 g_return_if_fail (GTK_IS_DIALOG (parent_window));
1394 result = hildon_help_dialog_help_enable (parent_window, help_id, osso_context);
1397 g_warning ("Help topic %s not found", help_id);
1402 modest_platform_show_search_messages (GtkWindow *parent_window)
1404 osso_return_t result = OSSO_ERROR;
1406 result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
1408 if (result != OSSO_OK) {
1409 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1414 modest_platform_show_addressbook (GtkWindow *parent_window)
1416 osso_return_t result = OSSO_ERROR;
1418 result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
1420 if (result != OSSO_OK) {
1421 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1426 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1428 GtkWidget *widget = modest_folder_view_new (query);
1430 /* Show one account by default */
1431 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1432 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1435 /* Restore settings */
1436 modest_widget_memory_restore (modest_runtime_get_conf(),
1438 MODEST_CONF_FOLDER_VIEW_KEY);
1444 modest_platform_information_banner (GtkWidget *parent,
1445 const gchar *icon_name,
1448 hildon_banner_show_information (parent, icon_name, text);
1452 modest_platform_animation_banner (GtkWidget *parent,
1453 const gchar *animation_name,
1456 GtkWidget *inf_note = NULL;
1458 g_return_val_if_fail (text != NULL, NULL);
1460 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1468 TnyAccount *account;
1471 } CheckAccountIdleData;
1473 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1476 on_timeout_check_account_is_online(gpointer user_data)
1478 printf ("DEBUG: %s:\n", __FUNCTION__);
1479 CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
1482 g_warning ("%s: data is NULL.\n", __FUNCTION__);
1485 if (!(data->account)) {
1486 g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
1489 if (data && data->account) {
1490 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));
1493 gboolean stop_trying = FALSE;
1494 if (data && data->account &&
1495 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1496 * after which the account is likely to be usable, or never likely to be usable soon: */
1497 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1499 data->is_online = TRUE;
1504 /* Give up if we have tried too many times: */
1505 if (data->count_tries >= NUMBER_OF_TRIES)
1510 /* Wait for another timeout: */
1511 ++(data->count_tries);
1516 /* Allow the function that requested this idle callback to continue: */
1518 g_main_loop_quit (data->loop);
1521 g_object_unref (data->account);
1523 return FALSE; /* Don't call this again. */
1525 return TRUE; /* Call this timeout callback again. */
1529 /* Return TRUE immediately if the account is already online,
1530 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1531 * soon as the account is online, or FALSE if the account does
1532 * not become online in the NUMBER_OF_TRIES seconds.
1533 * This is useful when the D-Bus method was run immediately after
1534 * the application was started (when using D-Bus activation),
1535 * because the account usually takes a short time to go online.
1536 * The return value is maybe not very useful.
1539 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1541 g_return_val_if_fail (account, FALSE);
1543 printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
1545 if (!tny_device_is_online (modest_runtime_get_device())) {
1546 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1550 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1551 * so we avoid wait unnecessarily: */
1552 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1553 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
1557 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n",
1558 __FUNCTION__, tny_account_get_connection_status (account));
1560 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1561 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1562 * we want to avoid. */
1563 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1566 /* This blocks on the result: */
1567 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1568 data->is_online = FALSE;
1569 data->account = account;
1570 g_object_ref (data->account);
1571 data->count_tries = 0;
1573 GMainContext *context = NULL; /* g_main_context_new (); */
1574 data->loop = g_main_loop_new (context, FALSE /* not running */);
1576 g_timeout_add (1000, &on_timeout_check_account_is_online, data);
1578 /* This main loop will run until the idle handler has stopped it: */
1579 g_main_loop_run (data->loop);
1581 g_main_loop_unref (data->loop);
1582 /* g_main_context_unref (context); */
1584 g_slice_free (CheckAccountIdleData, data);
1586 return data->is_online;
1592 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1594 /* GTK_RESPONSE_HELP means we need to show the certificate */
1595 if (response_id == GTK_RESPONSE_HELP) {
1599 /* Do not close the dialog */
1600 g_signal_stop_emission_by_name (dialog, "response");
1602 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1603 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1604 gtk_dialog_run (GTK_DIALOG(note));
1605 gtk_widget_destroy (note);
1611 modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
1612 const gchar *certificate)
1616 GtkWindow *main_win =
1617 (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
1619 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1622 note = hildon_note_new_confirmation_add_buttons (
1625 _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
1626 _("mcen_bd_view"), GTK_RESPONSE_HELP, /* abusing this... */
1627 _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
1630 g_signal_connect (G_OBJECT(note), "response",
1631 G_CALLBACK(on_cert_dialog_response),
1632 (gpointer) certificate);
1634 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1636 response = gtk_dialog_run(GTK_DIALOG(note));
1638 on_destroy_dialog (GTK_DIALOG(note));
1647 modest_platform_run_alert_dialog (const gchar* prompt,
1648 gboolean is_question)
1650 ModestWindow *main_window =
1651 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
1653 gboolean retval = TRUE;
1655 /* The Tinymail documentation says that we should show Yes and No buttons,
1656 * when it is a question.
1657 * Obviously, we need tinymail to use more specific error codes instead,
1658 * so we know what buttons to show. */
1659 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
1661 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1662 GTK_WINDOW (dialog));
1664 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1665 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1667 on_destroy_dialog (GTK_DIALOG(dialog));
1669 /* Just show the error text and use the default response: */
1670 modest_platform_run_information_dialog (GTK_WINDOW (main_window),