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; /* urgh global */
65 on_modest_conf_update_interval_changed (ModestConf* self,
67 ModestConfEvent event,
68 ModestConfNotificationId id,
71 g_return_if_fail (key);
73 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
74 const guint update_interval_minutes =
75 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
76 modest_platform_set_update_interval (update_interval_minutes);
83 check_required_files (void)
85 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
87 g_printerr ("modest: check for mcc file failed\n");
92 if (access (MODEST_PROVIDERS_DATA_PATH, R_OK) != 0) {
93 g_printerr ("modest: cannot find providers data\n");
103 modest_platform_init (int argc, char *argv[])
105 osso_hw_state_t hw_state = { 0 };
109 if (!check_required_files ()) {
110 g_printerr ("modest: missing required files\n");
116 osso_initialize(PACKAGE,PACKAGE_VERSION,
119 g_printerr ("modest: failed to acquire osso context\n");
123 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
124 g_printerr ("modest: could not get dbus connection\n");
129 /* Add a D-Bus handler to be used when the main osso-rpc
130 * D-Bus handler has not handled something.
131 * We use this for D-Bus methods that need to use more complex types
132 * than osso-rpc supports.
134 if (!dbus_connection_add_filter (con,
135 modest_dbus_req_filter,
139 g_printerr ("modest: Could not add D-Bus filter\n");
143 /* Register our simple D-Bus callbacks, via the osso API: */
144 osso_return_t result = osso_rpc_set_cb_f(osso_context,
148 modest_dbus_req_handler, NULL /* user_data */);
149 if (result != OSSO_OK) {
150 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
154 /* Add handler for Exit D-BUS messages.
155 * Not used because osso_application_set_exit_cb() is deprecated and obsolete:
156 result = osso_application_set_exit_cb(osso_context,
157 modest_dbus_exit_event_handler,
159 if (result != OSSO_OK) {
160 g_print("Error setting exit callback (%d)\n", result);
165 /* Register hardware event dbus callback: */
166 hw_state.shutdown_ind = TRUE;
167 osso_hw_set_event_cb(osso_context, NULL,/*&hw_state*/ modest_osso_cb_hw_state_handler, NULL);
169 /* Register osso auto-save callbacks: */
170 result = osso_application_set_autosave_cb (osso_context,
171 modest_on_osso_application_autosave, NULL /* user_data */);
172 if (result != OSSO_OK) {
173 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
178 /* Make sure that the update interval is changed whenever its gconf key
180 /* CAUTION: we're not using here the
181 modest_conf_listen_to_namespace because we know that there
182 are other parts of Modest listening for this namespace, so
183 we'll receive the notifications anyway. We basically do not
184 use it because there is no easy way to do the
185 modest_conf_forget_namespace */
186 ModestConf *conf = modest_runtime_get_conf ();
187 g_signal_connect (G_OBJECT(conf),
189 G_CALLBACK (on_modest_conf_update_interval_changed),
192 /* only force the setting of the default interval, if there are actually
194 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
196 /* Get the initial update interval from gconf: */
197 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
198 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
199 modest_account_mgr_free_account_names (acc_names);
202 /* initialize the addressbook */
203 if (!osso_abook_init (&argc, &argv, osso_context)) {
204 g_printerr ("modest: failed to initialized addressbook\n");
212 modest_platform_get_new_device (void)
214 return TNY_DEVICE (tny_maemo_conic_device_new ());
218 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
219 gchar **effective_mime_type)
221 GString *mime_str = NULL;
222 gchar *icon_name = NULL;
223 gchar **icons, **cursor;
225 if (!mime_type || !g_ascii_strcasecmp (mime_type, "application/octet-stream"))
226 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
228 mime_str = g_string_new (mime_type);
229 g_string_ascii_down (mime_str);
232 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
233 for (cursor = icons; cursor; ++cursor) {
234 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
235 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
236 icon_name = g_strdup ("qgn_list_messagin");
238 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
239 icon_name = g_strdup (*cursor);
245 if (effective_mime_type)
246 *effective_mime_type = g_string_free (mime_str, FALSE);
248 g_string_free (mime_str, TRUE);
255 modest_platform_activate_uri (const gchar *uri)
257 HildonURIAction *action;
258 gboolean result = FALSE;
259 GSList *actions, *iter = NULL;
261 g_return_val_if_fail (uri, FALSE);
265 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
267 for (iter = actions; iter; iter = g_slist_next (iter)) {
268 action = (HildonURIAction*) iter->data;
269 if (action && strcmp (hildon_uri_action_get_service (action),
270 "com.nokia.modest") == 0) {
272 result = hildon_uri_open (uri, action, &err);
273 if (!result && err) {
274 g_printerr ("modest: modest_platform_activate_uri : %s",
275 err->message ? err->message : "unknown error");
282 /* if we could not open it with email, try something else */
284 result = hildon_uri_open (uri, NULL, NULL);
287 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
293 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
297 gchar *uri_path = NULL;
299 uri_path = g_strconcat ("file://", path, NULL);
300 con = osso_get_dbus_connection (osso_context);
303 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
305 result = hildon_mime_open_file (con, uri_path);
307 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"));
315 } ModestPlatformPopupInfo;
318 delete_uri_popup (GtkWidget *menu,
322 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
324 g_free (popup_info->uri);
325 hildon_uri_free_actions (popup_info->actions);
331 activate_uri_popup_item (GtkMenuItem *menu_item,
335 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
336 const gchar* action_name;
338 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
340 g_printerr ("modest: no action name defined\n");
344 /* special handling for the copy menu item -- copy the uri to the clipboard */
345 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
346 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
347 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
348 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
350 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
351 action_name += strlen ("mailto:");
353 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
354 return; /* we're done */
357 /* now, the real uri-actions... */
358 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
359 HildonURIAction *action = (HildonURIAction *) node->data;
360 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
361 hildon_uri_open (popup_info->uri, action, NULL);
368 modest_platform_show_uri_popup (const gchar *uri)
370 GSList *actions_list;
375 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
376 if (actions_list != NULL) {
378 GtkWidget *menu = gtk_menu_new ();
379 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
381 popup_info->actions = actions_list;
382 popup_info->uri = g_strdup (uri);
384 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
385 GtkWidget *menu_item;
386 const gchar *action_name;
387 const gchar *translation_domain;
388 HildonURIAction *action = (HildonURIAction *) node->data;
389 action_name = hildon_uri_action_get_name (action);
390 translation_domain = hildon_uri_action_get_translation_domain (action);
391 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
392 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
393 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
396 if (hildon_uri_is_default_action (action, NULL)) {
397 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
399 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
401 gtk_widget_show (menu_item);
404 /* always add the copy item */
405 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri", "uri_link_copy_link_location"));
406 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
407 g_strconcat (URI_ACTION_COPY, uri, NULL),
409 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
410 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
411 gtk_widget_show (menu_item);
414 /* and what to do when the link is deleted */
415 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
416 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
419 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
427 modest_platform_get_icon (const gchar *name)
430 GdkPixbuf* pixbuf = NULL;
431 GtkIconTheme *current_theme = NULL;
433 g_return_val_if_fail (name, NULL);
435 /* strlen == 0 is not really an error; it just
436 * means the icon is not available
438 if (!name || strlen(name) == 0)
441 #if 0 /* do we still need this? */
442 if (g_str_has_suffix (name, ".png")) { /*FIXME: hack*/
443 pixbuf = gdk_pixbuf_new_from_file (name, &err);
445 g_printerr ("modest: error loading icon '%s': %s\n",
453 current_theme = gtk_icon_theme_get_default ();
454 pixbuf = gtk_icon_theme_load_icon (current_theme, name, 26,
455 GTK_ICON_LOOKUP_NO_SVG,
458 g_printerr ("modest: error loading theme icon '%s': %s\n",
466 modest_platform_get_app_name (void)
468 return _("mcen_ap_name");
472 entry_insert_text (GtkEditable *editable,
481 chars = gtk_editable_get_chars (editable, 0, -1);
482 chars_length = g_utf8_strlen (chars, -1);
484 /* Show WID-INF036 */
485 if (chars_length >= 20) {
486 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
487 _CS("ckdg_ib_maximum_characters_reached"));
489 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
493 tmp = g_strndup (folder_name_forbidden_chars,
494 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
495 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
496 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
501 /* Write the text in the entry if it's valid */
502 g_signal_handlers_block_by_func (editable,
503 (gpointer) entry_insert_text, data);
504 gtk_editable_insert_text (editable, text, length, position);
505 g_signal_handlers_unblock_by_func (editable,
506 (gpointer) entry_insert_text, data);
509 /* Do not allow further processing */
510 g_signal_stop_emission_by_name (editable, "insert_text");
514 entry_changed (GtkEditable *editable,
518 GtkWidget *ok_button;
521 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
522 ok_button = GTK_WIDGET (buttons->next->data);
524 chars = gtk_editable_get_chars (editable, 0, -1);
525 g_return_if_fail (chars != NULL);
528 if (g_utf8_strlen (chars,-1) >= 21)
529 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
530 _CS("ckdg_ib_maximum_characters_reached"));
532 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
535 g_list_free (buttons);
540 launch_sort_headers_dialog (GtkWindow *parent_window,
541 HildonSortDialog *dialog)
543 ModestHeaderView *header_view = NULL;
545 GtkSortType sort_type;
547 gint default_key = 0;
549 gboolean outgoing = FALSE;
550 gint current_sort_colid = -1;
551 GtkSortType current_sort_type;
552 gint attachments_sort_id;
553 gint priority_sort_id;
554 GtkTreeSortable *sortable;
556 /* Get header window */
557 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
558 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_window),
559 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
561 if (!header_view) return;
563 /* Add sorting keys */
564 cols = modest_header_view_get_columns (header_view);
565 if (cols == NULL) return;
566 int sort_model_ids[6];
570 outgoing = (GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cols->data), MODEST_HEADER_VIEW_COLUMN))==
571 MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT);
573 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_sender_recipient"));
575 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
576 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
578 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
579 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
582 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_date"));
584 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
585 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE;
587 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
588 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE;
590 default_key = sort_key;
592 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_subject"));
593 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN;
595 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_OUT;
597 sort_ids[sort_key] = MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN;
599 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_attachment"));
600 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
601 sort_ids[sort_key] = TNY_HEADER_FLAG_ATTACHMENTS;
602 attachments_sort_id = sort_key;
604 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_size"));
605 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN;
606 sort_ids[sort_key] = 0;
608 sort_key = hildon_sort_dialog_add_sort_key (dialog, _("mcen_li_sort_priority"));
609 sort_model_ids[sort_key] = TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN;
610 sort_ids[sort_key] = TNY_HEADER_FLAG_PRIORITY;
611 priority_sort_id = sort_key;
613 sortable = GTK_TREE_SORTABLE (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)))));
615 if (!gtk_tree_sortable_get_sort_column_id (sortable,
616 ¤t_sort_colid, ¤t_sort_type)) {
617 hildon_sort_dialog_set_sort_key (dialog, default_key);
618 hildon_sort_dialog_set_sort_order (dialog, GTK_SORT_DESCENDING);
620 hildon_sort_dialog_set_sort_order (dialog, current_sort_type);
621 if (current_sort_colid == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
622 gpointer flags_sort_type_pointer;
623 flags_sort_type_pointer = g_object_get_data (G_OBJECT (cols->data), MODEST_HEADER_VIEW_FLAG_SORT);
624 if (GPOINTER_TO_INT (flags_sort_type_pointer) == TNY_HEADER_FLAG_PRIORITY)
625 hildon_sort_dialog_set_sort_key (dialog, priority_sort_id);
627 hildon_sort_dialog_set_sort_key (dialog, attachments_sort_id);
629 gint current_sort_keyid = 0;
630 while (current_sort_keyid < 6) {
631 if (sort_model_ids[current_sort_keyid] == current_sort_colid)
634 current_sort_keyid++;
636 hildon_sort_dialog_set_sort_key (dialog, current_sort_keyid);
640 result = gtk_dialog_run (GTK_DIALOG (dialog));
641 if (result == GTK_RESPONSE_OK) {
642 sort_key = hildon_sort_dialog_get_sort_key (dialog);
643 sort_type = hildon_sort_dialog_get_sort_order (dialog);
644 if (sort_model_ids[sort_key] == TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN) {
645 g_object_set_data (G_OBJECT(cols->data), MODEST_HEADER_VIEW_FLAG_SORT,
646 GINT_TO_POINTER (sort_ids[sort_key]));
647 /* This is a hack to make it resort rows always when flag fields are
648 * selected. If we do not do this, changing sort field from priority to
649 * attachments does not work */
650 modest_header_view_sort_by_column_id (header_view, 0, sort_type);
652 gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (cols->data),
653 sort_model_ids[sort_key]);
656 modest_header_view_sort_by_column_id (header_view, sort_model_ids[sort_key], sort_type);
657 gtk_tree_sortable_sort_column_changed (sortable);
660 modest_widget_memory_save (modest_runtime_get_conf (),
661 G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
663 /* while (gtk_events_pending ()) */
664 /* gtk_main_iteration (); */
673 on_response (GtkDialog *dialog,
677 GList *child_vbox, *child_hbox;
678 GtkWidget *hbox, *entry;
679 TnyFolderStore *parent;
681 if (response != GTK_RESPONSE_ACCEPT)
685 child_vbox = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
686 hbox = child_vbox->data;
687 child_hbox = gtk_container_get_children (GTK_CONTAINER (hbox));
688 entry = child_hbox->next->data;
690 parent = TNY_FOLDER_STORE (user_data);
692 /* Look for another folder with the same name */
693 if (modest_tny_folder_has_subfolder_with_name (parent,
694 gtk_entry_get_text (GTK_ENTRY (entry)))) {
696 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
697 NULL, _CS("ckdg_ib_folder_already_exists"));
698 /* Select the text */
699 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
700 gtk_widget_grab_focus (entry);
701 /* Do not close the dialog */
702 g_signal_stop_emission_by_name (dialog, "response");
709 modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
710 TnyFolderStore *parent,
711 const gchar *dialog_title,
712 const gchar *label_text,
713 const gchar *suggested_name,
716 GtkWidget *accept_btn = NULL;
717 GtkWidget *dialog, *entry, *label, *hbox;
718 GList *buttons = NULL;
721 /* Ask the user for the folder name */
722 dialog = gtk_dialog_new_with_buttons (dialog_title,
724 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
725 _("mcen_bd_dialog_ok"),
727 _("mcen_bd_dialog_cancel"),
731 /* Add accept button (with unsensitive handler) */
732 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
733 accept_btn = GTK_WIDGET (buttons->next->data);
734 /* Create label and entry */
735 label = gtk_label_new (label_text);
736 /* TODO: check that the suggested name does not exist */
737 /* We set 21 as maximum because we want to show WID-INF036
738 when the user inputs more that 20 */
739 entry = gtk_entry_new_with_max_length (21);
741 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
743 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
744 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
746 /* Connect to the response method to avoid closing the dialog
747 when an invalid name is selected*/
748 g_signal_connect (dialog,
750 G_CALLBACK (on_response),
753 /* Track entry changes */
754 g_signal_connect (entry,
756 G_CALLBACK (entry_insert_text),
758 g_signal_connect (entry,
760 G_CALLBACK (entry_changed),
763 /* Create the hbox */
764 hbox = gtk_hbox_new (FALSE, 12);
765 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
766 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0);
768 /* Add hbox to dialog */
769 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
770 hbox, FALSE, FALSE, 0);
772 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
773 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
775 result = gtk_dialog_run (GTK_DIALOG(dialog));
776 if (result == GTK_RESPONSE_ACCEPT)
777 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
779 gtk_widget_destroy (dialog);
781 while (gtk_events_pending ())
782 gtk_main_iteration ();
788 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
789 TnyFolderStore *parent_folder,
790 gchar *suggested_name,
793 gchar *real_suggested_name = NULL;
796 if(suggested_name == NULL)
798 const gchar *default_name = _("mcen_ia_default_folder_name");
802 for(i = 0; i < 100; ++ i) {
803 gboolean exists = FALSE;
805 sprintf(num_str, "%.2u", i);
808 real_suggested_name = g_strdup (default_name);
810 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
813 exists = modest_tny_folder_has_subfolder_with_name (parent_folder,
814 real_suggested_name);
819 g_free (real_suggested_name);
822 /* Didn't find a free number */
824 real_suggested_name = g_strdup (default_name);
826 real_suggested_name = suggested_name;
829 result = modest_platform_run_folder_name_dialog (parent_window,
831 _("mcen_ti_new_folder"),
832 _("mcen_fi_new_folder_name"),
835 if (suggested_name == NULL)
836 g_free(real_suggested_name);
842 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
843 TnyFolderStore *parent_folder,
844 const gchar *suggested_name,
847 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
849 return modest_platform_run_folder_name_dialog (parent_window,
851 _HL("ckdg_ti_rename_folder"),
852 _HL("ckdg_fi_rename_name"),
860 on_destroy_dialog (GtkDialog *dialog)
862 gtk_widget_destroy (GTK_WIDGET(dialog));
863 if (gtk_events_pending ())
864 gtk_main_iteration ();
868 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
869 const gchar *message)
874 dialog = hildon_note_new_confirmation (parent_window, message);
875 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
876 GTK_WINDOW (dialog));
878 response = gtk_dialog_run (GTK_DIALOG (dialog));
880 on_destroy_dialog (GTK_DIALOG(dialog));
882 while (gtk_events_pending ())
883 gtk_main_iteration ();
889 modest_platform_run_yes_no_dialog (GtkWindow *parent_window,
890 const gchar *message)
895 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
896 _("mcen_bd_yes"), GTK_RESPONSE_YES,
897 _("mcen_bd_no"), GTK_RESPONSE_NO,
899 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
900 response = gtk_dialog_run (GTK_DIALOG (dialog));
902 on_destroy_dialog (GTK_DIALOG(dialog));
904 while (gtk_events_pending ())
905 gtk_main_iteration ();
913 modest_platform_run_information_dialog (GtkWindow *parent_window,
914 const gchar *message)
918 note = hildon_note_new_information (parent_window, message);
919 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
922 g_signal_connect_swapped (note,
924 G_CALLBACK (on_destroy_dialog),
927 gtk_widget_show_all (note);
932 typedef struct _ConnectAndWaitData {
934 GMainLoop *wait_loop;
935 gboolean has_callback;
937 } ConnectAndWaitData;
941 quit_wait_loop (TnyAccount *account,
942 ConnectAndWaitData *data)
944 /* Set the has_callback to TRUE (means that the callback was
945 executed and wake up every code waiting for cond to be
947 g_mutex_lock (data->mutex);
948 data->has_callback = TRUE;
950 g_main_loop_quit (data->wait_loop);
951 g_mutex_unlock (data->mutex);
955 on_connection_status_changed (TnyAccount *account,
956 TnyConnectionStatus status,
959 TnyConnectionStatus conn_status;
960 ConnectAndWaitData *data;
962 /* Ignore if reconnecting or disconnected */
963 conn_status = tny_account_get_connection_status (account);
964 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
965 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
968 /* Remove the handler */
969 data = (ConnectAndWaitData *) user_data;
970 g_signal_handler_disconnect (account, data->handler);
972 /* Quit from wait loop */
973 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
977 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
982 /* Quit from wait loop */
983 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
987 modest_platform_connect_and_wait (GtkWindow *parent_window,
990 ConnectAndWaitData *data = NULL;
991 gboolean device_online;
993 TnyConnectionStatus conn_status;
995 device = modest_runtime_get_device();
996 device_online = tny_device_is_online (device);
998 /* If there is no account check only the device status */
1003 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
1006 /* Return if the account is already connected */
1007 conn_status = tny_account_get_connection_status (account);
1008 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1011 /* Create the helper */
1012 data = g_slice_new0 (ConnectAndWaitData);
1013 data->mutex = g_mutex_new ();
1014 data->has_callback = FALSE;
1016 /* Connect the device */
1017 if (!device_online) {
1018 /* Track account connection status changes */
1019 data->handler = g_signal_connect (account, "connection-status-changed",
1020 G_CALLBACK (on_connection_status_changed),
1022 /* Try to connect the device */
1023 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL);
1025 /* If the device connection failed then exit */
1026 if (!device_online && data->handler)
1029 /* Force a reconnection of the account */
1030 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1031 on_tny_camel_account_set_online_cb, data);
1034 /* Wait until the callback is executed */
1035 g_mutex_lock (data->mutex);
1036 if (!data->has_callback) {
1037 data->wait_loop = g_main_loop_new (NULL, FALSE);
1038 gdk_threads_leave ();
1039 g_mutex_unlock (data->mutex);
1040 g_main_loop_run (data->wait_loop);
1041 g_mutex_lock (data->mutex);
1042 gdk_threads_enter ();
1044 g_mutex_unlock (data->mutex);
1048 if (g_signal_handler_is_connected (account, data->handler))
1049 g_signal_handler_disconnect (account, data->handler);
1050 g_mutex_free (data->mutex);
1051 g_main_loop_unref (data->wait_loop);
1052 g_slice_free (ConnectAndWaitData, data);
1055 conn_status = tny_account_get_connection_status (account);
1056 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1060 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1062 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1063 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1064 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1065 /* This must be a maildir account, which does not require a connection: */
1070 return modest_platform_connect_and_wait (parent_window, account);
1074 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1077 return TRUE; /* Maybe it is something local. */
1079 gboolean result = TRUE;
1080 if (TNY_IS_FOLDER (folder_store)) {
1081 /* Get the folder's parent account: */
1082 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1083 if (account != NULL) {
1084 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1085 g_object_unref (account);
1087 } else if (TNY_IS_ACCOUNT (folder_store)) {
1088 /* Use the folder store as an account: */
1089 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1096 modest_platform_is_network_folderstore (TnyFolderStore *folder_store)
1098 TnyAccount *account = NULL;
1099 gboolean result = TRUE;
1101 g_return_val_if_fail(TNY_IS_FOLDER_STORE(folder_store), FALSE);
1103 if (TNY_IS_FOLDER (folder_store)) {
1104 /* Get the folder's parent account: */
1105 account = tny_folder_get_account(TNY_FOLDER(folder_store));
1106 } else if (TNY_IS_ACCOUNT (folder_store)) {
1107 account = TNY_ACCOUNT(folder_store);
1108 g_object_ref(account);
1111 if (account != NULL) {
1112 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1113 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1114 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
1115 /* This must be a maildir account, which does
1116 * not require a connection: */
1120 g_object_unref (account);
1129 modest_platform_run_sort_dialog (GtkWindow *parent_window,
1130 ModestSortDialogType type)
1132 GtkWidget *dialog = NULL;
1135 dialog = hildon_sort_dialog_new (parent_window);
1136 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1137 GTK_WINDOW (dialog));
1139 /* Fill sort keys */
1141 case MODEST_SORT_HEADERS:
1142 launch_sort_headers_dialog (parent_window,
1143 HILDON_SORT_DIALOG(dialog));
1148 on_destroy_dialog (GTK_DIALOG(dialog));
1153 modest_platform_set_update_interval (guint minutes)
1155 ModestConf *conf = modest_runtime_get_conf ();
1159 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1161 /* Delete any existing alarm,
1162 * because we will replace it: */
1164 /* TODO: What does the alarm_event_del() return value mean? */
1165 alarm_event_del(alarm_cookie);
1167 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1170 /* 0 means no updates: */
1175 /* Register alarm: */
1177 /* Set the interval in alarm_event_t structure: */
1178 alarm_event_t *event = g_new0(alarm_event_t, 1);
1179 event->alarm_time = minutes * 60; /* seconds */
1181 /* Set recurrence every few minutes: */
1182 event->recurrence = minutes;
1183 event->recurrence_count = -1; /* Means infinite */
1185 /* Specify what should happen when the alarm happens:
1186 * It should call this D-Bus method: */
1188 event->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1189 event->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1190 event->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1191 event->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1193 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1194 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1195 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1196 * This is why we want to use the Alarm API instead of just g_timeout_add().
1197 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1199 event->flags = ALARM_EVENT_NO_DIALOG | ALARM_EVENT_ACTIVATION;
1201 alarm_cookie = alarm_event_add (event);
1204 alarm_event_free (event);
1206 /* Store the alarm ID in GConf, so we can remove it later:
1207 * This is apparently valid between application instances. */
1208 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1210 if (!alarm_cookie) {
1212 const alarm_error_t alarm_error = alarmd_get_error ();
1213 g_debug ("Error setting alarm event. Error code: '%d'\n", alarm_error);
1215 /* Give people some clue: */
1216 /* The alarm API should have a function for this: */
1217 if (alarm_error == ALARMD_ERROR_DBUS) {
1218 g_debug (" ALARMD_ERROR_DBUS: An error with D-Bus occurred, probably coudn't get a D-Bus connection.\n");
1219 } else if (alarm_error == ALARMD_ERROR_CONNECTION) {
1220 g_debug (" ALARMD_ERROR_CONNECTION: Could not contact alarmd via D-Bus.\n");
1221 } else if (alarm_error == ALARMD_ERROR_INTERNAL) {
1222 g_debug (" ALARMD_ERROR_INTERNAL: Some alarmd or libalarm internal error, possibly a version mismatch.\n");
1223 } else if (alarm_error == ALARMD_ERROR_MEMORY) {
1224 g_debug (" ALARMD_ERROR_MEMORY: A memory allocation failed.\n");
1225 } else if (alarm_error == ALARMD_ERROR_ARGUMENT) {
1226 g_debug (" ALARMD_ERROR_ARGUMENT: An argument given by caller was invalid.\n");
1227 } else if (alarm_error == ALARMD_ERROR_NOT_RUNNING) {
1228 g_debug (" ALARMD_ERROR_NOT_RUNNING: alarmd is not running.\n");
1238 modest_platform_on_new_headers_received (TnyList *header_list)
1240 #ifdef MODEST_HAVE_HILDON_NOTIFY
1241 HildonNotification *notification;
1243 GSList *notifications_list = NULL;
1245 /* Get previous notifications ids */
1246 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1247 MODEST_CONF_NOTIFICATION_IDS,
1248 MODEST_CONF_VALUE_INT, NULL);
1250 iter = tny_list_create_iterator (header_list);
1251 while (!tny_iterator_is_done (iter)) {
1252 gchar *url = NULL, *display_address = NULL, *display_date = NULL, *summary = NULL;
1253 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1254 TnyFolder *folder = tny_header_get_folder (header);
1255 gboolean first_notification = TRUE;
1258 display_date = modest_text_utils_get_display_date (tny_header_get_date_received (header));
1260 display_address = g_strdup(tny_header_get_from (header));
1261 modest_text_utils_get_display_address (display_address); /* string is changed in-place */
1263 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1264 notification = hildon_notification_new (summary,
1265 tny_header_get_subject (header),
1266 "qgn_list_messagin",
1269 /* Create the message URL */
1270 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1271 tny_header_get_uid (header));
1273 hildon_notification_add_dbus_action(notification,
1276 MODEST_DBUS_SERVICE,
1279 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1283 /* Play sound if the user wants. Show the LED
1284 pattern. Show and play just one */
1285 if (G_UNLIKELY (first_notification)) {
1286 first_notification = FALSE;
1287 if (modest_conf_get_bool (modest_runtime_get_conf (),
1288 MODEST_CONF_PLAY_SOUND_MSG_ARRIVE,
1290 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1291 "sound-file", "/usr/share/sounds/ui-new_email.wav");
1294 /* Set the led pattern */
1295 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1297 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1299 "PatternCommunicationEmail");
1302 /* Notify. We need to do this in an idle because this function
1303 could be called from a thread */
1304 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1306 /* Save id in the list */
1307 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1308 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1309 /* We don't listen for the "closed" signal, because we
1310 don't care about if the notification was removed or
1311 not to store the list in gconf */
1313 /* Free & carry on */
1314 g_free (display_date);
1315 g_free (display_address);
1318 g_object_unref (folder);
1319 g_object_unref (header);
1320 tny_iterator_next (iter);
1322 g_object_unref (iter);
1325 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1326 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1328 g_slist_free (notifications_list);
1330 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1334 modest_platform_remove_new_mail_notifications (void)
1336 #ifdef MODEST_HAVE_HILDON_NOTIFY
1337 GSList *notif_list = NULL;
1339 /* Get previous notifications ids */
1340 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1341 MODEST_CONF_NOTIFICATION_IDS,
1342 MODEST_CONF_VALUE_INT, NULL);
1344 while (notif_list) {
1346 NotifyNotification *notif;
1348 /* Nasty HACK to remove the notifications, set the id
1349 of the existing ones and then close them */
1350 notif_id = GPOINTER_TO_INT(notif_list->data);
1351 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1352 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1354 /* Close the notification, note that some ids could be
1355 already invalid, but we don't care because it does
1357 notify_notification_close(notif, NULL);
1358 g_object_unref(notif);
1360 /* Delete the link, it's like going to the next */
1361 notif_list = g_slist_delete_link (notif_list, notif_list);
1365 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1366 notif_list, MODEST_CONF_VALUE_INT, NULL);
1368 g_slist_free (notif_list);
1370 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1376 modest_platform_get_global_settings_dialog ()
1378 return modest_maemo_global_settings_dialog_new ();
1382 modest_platform_show_help (GtkWindow *parent_window,
1383 const gchar *help_id)
1385 osso_return_t result;
1387 g_return_if_fail (help_id);
1388 g_return_if_fail (osso_context);
1390 result = hildon_help_show (osso_context, help_id, HILDON_HELP_SHOW_DIALOG);
1392 if (result != OSSO_OK) {
1394 error_msg = g_strdup_printf ("FIXME The help topic %s could not be found", help_id);
1395 hildon_banner_show_information (GTK_WIDGET (parent_window),
1403 modest_platform_set_dialog_help (GtkDialog *parent_window,
1404 const gchar *help_id)
1407 g_return_if_fail (help_id);
1408 g_return_if_fail (osso_context);
1409 g_return_if_fail (GTK_IS_DIALOG (parent_window));
1411 result = hildon_help_dialog_help_enable (parent_window, help_id, osso_context);
1414 g_warning ("Help topic %s not found", help_id);
1419 modest_platform_show_search_messages (GtkWindow *parent_window)
1421 osso_return_t result = OSSO_ERROR;
1423 result = osso_rpc_run_with_defaults (osso_context, "osso_global_search", "search_email", NULL, DBUS_TYPE_INVALID);
1425 if (result != OSSO_OK) {
1426 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1431 modest_platform_show_addressbook (GtkWindow *parent_window)
1433 osso_return_t result = OSSO_ERROR;
1435 result = osso_rpc_run_with_defaults (osso_context, "osso_addressbook", "top_application", NULL, DBUS_TYPE_INVALID);
1437 if (result != OSSO_OK) {
1438 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1443 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1445 GtkWidget *widget = modest_folder_view_new (query);
1447 /* Show one account by default */
1448 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1449 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1452 /* Restore settings */
1453 modest_widget_memory_restore (modest_runtime_get_conf(),
1455 MODEST_CONF_FOLDER_VIEW_KEY);
1461 modest_platform_information_banner (GtkWidget *parent,
1462 const gchar *icon_name,
1465 hildon_banner_show_information (parent, icon_name, text);
1469 modest_platform_animation_banner (GtkWidget *parent,
1470 const gchar *animation_name,
1473 GtkWidget *inf_note = NULL;
1475 g_return_val_if_fail (text != NULL, NULL);
1477 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1485 TnyAccount *account;
1488 } CheckAccountIdleData;
1490 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1493 on_timeout_check_account_is_online(gpointer user_data)
1495 printf ("DEBUG: %s:\n", __FUNCTION__);
1496 CheckAccountIdleData *data = (CheckAccountIdleData*)user_data;
1499 g_warning ("%s: data is NULL.\n", __FUNCTION__);
1502 if (!(data->account)) {
1503 g_warning ("%s: data->account is NULL.\n", __FUNCTION__);
1506 if (data && data->account) {
1507 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__, tny_account_get_connection_status (data->account));
1510 gboolean stop_trying = FALSE;
1511 if (data && data->account &&
1512 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1513 * after which the account is likely to be usable, or never likely to be usable soon: */
1514 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1516 data->is_online = TRUE;
1521 /* Give up if we have tried too many times: */
1522 if (data->count_tries >= NUMBER_OF_TRIES)
1527 /* Wait for another timeout: */
1528 ++(data->count_tries);
1533 /* Allow the function that requested this idle callback to continue: */
1535 g_main_loop_quit (data->loop);
1538 g_object_unref (data->account);
1540 return FALSE; /* Don't call this again. */
1542 return TRUE; /* Call this timeout callback again. */
1546 /* Return TRUE immediately if the account is already online,
1547 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1548 * soon as the account is online, or FALSE if the account does
1549 * not become online in the NUMBER_OF_TRIES seconds.
1550 * This is useful when the D-Bus method was run immediately after
1551 * the application was started (when using D-Bus activation),
1552 * because the account usually takes a short time to go online.
1553 * The return value is maybe not very useful.
1556 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1558 g_return_val_if_fail (account, FALSE);
1560 printf ("DEBUG: %s: account id=%s\n", __FUNCTION__, tny_account_get_id (account));
1562 if (!tny_device_is_online (modest_runtime_get_device())) {
1563 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1567 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1568 * so we avoid wait unnecessarily: */
1569 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
1570 !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account) ) {
1574 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n",
1575 __FUNCTION__, tny_account_get_connection_status (account));
1577 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1578 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1579 * we want to avoid. */
1580 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1583 /* This blocks on the result: */
1584 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1585 data->is_online = FALSE;
1586 data->account = account;
1587 g_object_ref (data->account);
1588 data->count_tries = 0;
1590 GMainContext *context = NULL; /* g_main_context_new (); */
1591 data->loop = g_main_loop_new (context, FALSE /* not running */);
1593 g_timeout_add (1000, on_timeout_check_account_is_online, data);
1595 /* This main loop will run until the idle handler has stopped it: */
1596 g_main_loop_run (data->loop);
1598 g_main_loop_unref (data->loop);
1599 /* g_main_context_unref (context); */
1601 g_slice_free (CheckAccountIdleData, data);
1603 return data->is_online;
1609 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1611 /* GTK_RESPONSE_HELP means we need to show the certificate */
1612 if (response_id == GTK_RESPONSE_HELP) {
1616 /* Do not close the dialog */
1617 g_signal_stop_emission_by_name (dialog, "response");
1619 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1620 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1621 gtk_dialog_run (GTK_DIALOG(note));
1622 gtk_widget_destroy (note);
1628 modest_platform_run_certificate_conformation_dialog (const gchar* server_name,
1629 const gchar *certificate)
1633 GtkWindow *main_win =
1634 (GtkWindow*)modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
1636 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1639 note = hildon_note_new_confirmation_add_buttons (
1642 _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
1643 _("mcen_bd_view"), GTK_RESPONSE_HELP, /* abusing this... */
1644 _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
1647 g_signal_connect (G_OBJECT(note), "response",
1648 G_CALLBACK(on_cert_dialog_response),
1649 (gpointer) certificate);
1651 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1653 response = gtk_dialog_run(GTK_DIALOG(note));
1655 on_destroy_dialog (GTK_DIALOG(note));
1664 modest_platform_run_alert_dialog (const gchar* prompt,
1665 gboolean is_question)
1667 ModestWindow *main_window =
1668 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
1670 gboolean retval = TRUE;
1672 /* The Tinymail documentation says that we should show Yes and No buttons,
1673 * when it is a question.
1674 * Obviously, we need tinymail to use more specific error codes instead,
1675 * so we know what buttons to show. */
1676 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
1678 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1679 GTK_WINDOW (dialog));
1681 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1682 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1684 on_destroy_dialog (GTK_DIALOG(dialog));
1686 /* Just show the error text and use the default response: */
1687 modest_platform_run_information_dialog (GTK_WINDOW (main_window),