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>
33 #include <modest-platform.h>
34 #include <modest-defs.h>
35 #include <modest-runtime.h>
36 #include <modest-main-window.h>
37 #include <modest-header-view.h>
38 #include "modest-hildon2-global-settings-dialog.h"
39 #include "modest-widget-memory.h"
40 #include <modest-hildon-includes.h>
41 #include <modest-maemo-utils.h>
42 #include <modest-utils.h>
43 #include <dbus_api/modest-dbus-callbacks.h>
44 #include <modest-osso-autosave-callbacks.h>
46 #include <tny-maemo-conic-device.h>
47 #include <tny-camel-folder.h>
48 #include <tny-simple-list.h>
49 #include <tny-merge-folder.h>
50 #include <tny-error.h>
51 #include <tny-folder.h>
52 #include <tny-account-store-view.h>
53 #include <gtk/gtkicontheme.h>
54 #include <gtk/gtkmenuitem.h>
55 #include <gtk/gtkmain.h>
56 #include <modest-text-utils.h>
57 #include "modest-tny-folder.h"
58 #include "modest-tny-account.h"
60 #include <libgnomevfs/gnome-vfs-mime-utils.h>
61 #include <modest-account-settings-dialog.h>
62 #include <modest-easysetup-wizard-dialog.h>
63 #include "modest-hildon2-sort-dialog.h"
64 #include <hildon/hildon.h>
66 #include "hildon2/modest-hildon2-details-dialog.h"
67 #include "hildon2/modest-hildon2-window-mgr.h"
68 #ifdef MODEST_USE_PROFILE
69 #include <keys_nokia.h>
70 #include <libprofile.h>
73 #include <modest-datetime-formatter.h>
74 #include "modest-header-window.h"
75 #include <modest-folder-window.h>
76 #include <modest-account-mgr.h>
77 #include <modest-account-mgr-helpers.h>
78 #include <modest-ui-constants.h>
79 #include <modest-selector-picker.h>
80 #include <modest-icon-names.h>
81 #include <modest-count-stream.h>
83 #ifdef MODEST_HAVE_MCE
84 #include <mce/dbus-names.h>
85 #endif /*MODEST_HAVE_MCE*/
87 #ifdef MODEST_HAVE_ABOOK
88 #include <libosso-abook/osso-abook.h>
89 #endif /*MODEST_HAVE_ABOOK*/
91 #ifdef MODEST_HAVE_LIBALARM
92 #include <alarmd/libalarm.h> /* For alarm_event_add(), etc. */
93 #endif /*MODEST_HAVE_LIBALARM*/
96 #define HILDON_OSSO_URI_ACTION "uri-action"
97 #define URI_ACTION_COPY "copy:"
98 #define MODEST_NOTIFICATION_CATEGORY "email-message"
99 #define MODEST_NEW_MAIL_LIGHTING_PATTERN "PatternCommunicationEmail"
100 #ifdef MODEST_USE_PROFILE
101 #define PROFILE_MAIL_TONE PROFILEKEY_EMAIL_ALERT_TONE
102 #define PROFILE_MAIL_VOLUME PROFILEKEY_EMAIL_ALERT_VOLUME
104 #define MAIL_TONE "message-new-email"
107 #define COMMON_FOLDER_DIALOG_ENTRY "entry"
108 #define COMMON_FOLDER_DIALOG_ACCOUNT_PICKER "account-picker"
109 #define FOLDER_PICKER_CURRENT_FOLDER "current-folder"
110 #define MODEST_ALARMD_APPID PACKAGE_NAME
113 static void modest_platform_play_email_tone (void);
117 on_modest_conf_update_interval_changed (ModestConf* self,
119 ModestConfEvent event,
120 ModestConfNotificationId id,
123 g_return_if_fail (key);
125 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
126 const guint update_interval_minutes =
127 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
128 modest_platform_set_update_interval (update_interval_minutes);
135 check_required_files (void)
137 FILE *mcc_file = modest_utils_open_mcc_mapping_file (FALSE, NULL);
139 g_printerr ("modest: check for mcc file (for LANG) failed\n");
144 mcc_file = modest_utils_open_mcc_mapping_file (TRUE, NULL);
146 g_printerr ("modest: check for mcc file (for LC_MESSAGES) failed\n");
151 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
152 access(MODEST_FALLBACK_PROVIDER_DATA_FILE, R_OK) != 0) {
153 g_printerr ("modest: cannot find providers data\n");
161 /* the gpointer here is the osso_context. */
163 modest_platform_init (int argc, char *argv[])
165 osso_context_t *osso_context;
166 osso_hw_state_t hw_state = { 0 };
170 if (!check_required_files ()) {
171 g_printerr ("modest: missing required files\n");
175 osso_context = modest_maemo_utils_get_osso_context();
177 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
178 g_printerr ("modest: could not get dbus connection\n");
182 /* Add a D-Bus handler to be used when the main osso-rpc
183 * D-Bus handler has not handled something.
184 * We use this for D-Bus methods that need to use more complex types
185 * than osso-rpc supports.
187 if (!dbus_connection_add_filter (con,
188 modest_dbus_req_filter,
192 g_printerr ("modest: Could not add D-Bus filter\n");
196 /* Register our simple D-Bus callbacks, via the osso API: */
197 osso_return_t result = osso_rpc_set_cb_f(osso_context,
201 modest_dbus_req_handler, NULL /* user_data */);
202 if (result != OSSO_OK) {
203 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
207 /* Register hardware event dbus callback: */
208 hw_state.shutdown_ind = TRUE;
209 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
211 /* Register osso auto-save callbacks: */
212 result = osso_application_set_autosave_cb (osso_context,
213 modest_on_osso_application_autosave, NULL /* user_data */);
214 if (result != OSSO_OK) {
215 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
220 /* Make sure that the update interval is changed whenever its gconf key
222 /* CAUTION: we're not using here the
223 modest_conf_listen_to_namespace because we know that there
224 are other parts of Modest listening for this namespace, so
225 we'll receive the notifications anyway. We basically do not
226 use it because there is no easy way to do the
227 modest_conf_forget_namespace */
228 ModestConf *conf = modest_runtime_get_conf ();
229 g_signal_connect (G_OBJECT(conf),
231 G_CALLBACK (on_modest_conf_update_interval_changed),
234 /* only force the setting of the default interval, if there are actually
236 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
238 /* Get the initial update interval from gconf: */
239 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
240 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
241 modest_account_mgr_free_account_names (acc_names);
245 #ifdef MODEST_HAVE_ABOOK
246 /* initialize the addressbook */
247 if (!osso_abook_init (&argc, &argv, osso_context)) {
248 g_printerr ("modest: failed to initialized addressbook\n");
251 #endif /*MODEST_HAVE_ABOOK*/
257 modest_platform_uninit (void)
259 osso_context_t *osso_context =
260 modest_maemo_utils_get_osso_context ();
262 osso_deinitialize (osso_context);
271 modest_platform_get_new_device (void)
273 return TNY_DEVICE (tny_maemo_conic_device_new ());
277 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
278 gchar **effective_mime_type)
280 GString *mime_str = NULL;
281 gchar *icon_name = NULL;
282 gchar **icons, **cursor;
284 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
285 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
287 mime_str = g_string_new (mime_type);
288 g_string_ascii_down (mime_str);
291 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
293 for (cursor = icons; cursor; ++cursor) {
294 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
295 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
296 icon_name = g_strdup ("qgn_list_messagin");
298 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
299 icon_name = g_strdup (*cursor);
305 if (effective_mime_type)
306 *effective_mime_type = g_string_free (mime_str, FALSE);
308 g_string_free (mime_str, TRUE);
315 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
320 g_return_val_if_fail (uri, FALSE);
322 result = hildon_uri_open (uri, action, &err);
324 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
325 uri, action, err && err->message ? err->message : "unknown error");
335 modest_platform_activate_uri (const gchar *uri)
337 HildonURIAction *action;
338 gboolean result = FALSE;
339 GSList *actions, *iter = NULL;
341 g_return_val_if_fail (uri, FALSE);
345 /* don't try to activate file: uri's -- they might confuse the user,
346 * and/or might have security implications */
347 if (!g_str_has_prefix (uri, "file:")) {
349 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
351 for (iter = actions; iter; iter = g_slist_next (iter)) {
352 action = (HildonURIAction*) iter->data;
353 if (action && strcmp (hildon_uri_action_get_service (action),
354 "com.nokia.modest") == 0) {
355 result = checked_hildon_uri_open (uri, action);
360 /* if we could not open it with email, try something else */
362 result = checked_hildon_uri_open (uri, NULL);
366 ModestWindow *parent =
367 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
368 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
369 _("mcen_ib_unsupported_link"));
370 g_debug ("%s: cannot open uri '%s'", __FUNCTION__,uri);
377 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
381 gchar *uri_path = NULL;
383 uri_path = gnome_vfs_get_uri_from_local_path (path);
384 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
387 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
389 result = hildon_mime_open_file (con, uri_path);
391 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
399 } ModestPlatformPopupInfo;
402 delete_uri_popup (GtkWidget *menu,
406 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
408 g_free (popup_info->uri);
409 hildon_uri_free_actions (popup_info->actions);
415 activate_uri_popup_item (GtkMenuItem *menu_item,
419 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
420 const gchar* action_name;
422 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
424 g_printerr ("modest: no action name defined\n");
428 /* special handling for the copy menu item -- copy the uri to the clipboard */
429 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
430 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
431 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
432 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
434 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
435 action_name += strlen ("mailto:");
437 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
438 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
439 return; /* we're done */
442 /* now, the real uri-actions... */
443 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
444 HildonURIAction *action = (HildonURIAction *) node->data;
445 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
446 if (!checked_hildon_uri_open (popup_info->uri, action)) {
447 ModestWindow *parent =
448 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
449 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
450 _("mcen_ib_unsupported_link"));
458 modest_platform_show_uri_popup (const gchar *uri)
460 GSList *actions_list;
465 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
468 GtkWidget *menu = gtk_menu_new ();
469 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
471 /* don't add actions for file: uri's -- they might confuse the user,
472 * and/or might have security implications
473 * we still allow to copy the url though
475 if (!g_str_has_prefix (uri, "file:")) {
478 popup_info->actions = actions_list;
479 popup_info->uri = g_strdup (uri);
481 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
482 GtkWidget *menu_item;
483 const gchar *action_name;
484 const gchar *translation_domain;
485 HildonURIAction *action = (HildonURIAction *) node->data;
486 action_name = hildon_uri_action_get_name (action);
487 translation_domain = hildon_uri_action_get_translation_domain (action);
488 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
489 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
490 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
493 if (hildon_uri_is_default_action (action, NULL)) {
494 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
496 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
498 gtk_widget_show (menu_item);
503 /* and what to do when the link is deleted */
504 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
505 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
508 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
516 modest_platform_get_icon (const gchar *name, guint icon_size)
519 GdkPixbuf* pixbuf = NULL;
520 GtkIconTheme *current_theme = NULL;
522 g_return_val_if_fail (name, NULL);
524 /* strlen == 0 is not really an error; it just
525 * means the icon is not available
527 if (!name || strlen(name) == 0)
530 current_theme = gtk_icon_theme_get_default ();
531 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
532 GTK_ICON_LOOKUP_NO_SVG,
535 g_warning ("Error loading theme icon '%s': %s\n",
543 modest_platform_get_app_name (void)
545 return _("mcen_ap_name");
549 entry_insert_text (GtkEditable *editable,
558 chars = gtk_editable_get_chars (editable, 0, -1);
559 chars_length = g_utf8_strlen (chars, -1);
562 /* Show WID-INF036 */
563 if (chars_length >= 20) {
564 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
565 _CS("ckdg_ib_maximum_characters_reached"));
567 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
571 tmp = g_strndup (folder_name_forbidden_chars,
572 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
573 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
574 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
580 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
581 _CS("ckdg_ib_maximum_characters_reached"));
583 /* Write the text in the entry if it's valid */
584 g_signal_handlers_block_by_func (editable,
585 (gpointer) entry_insert_text, data);
586 gtk_editable_insert_text (editable, text, length, position);
587 g_signal_handlers_unblock_by_func (editable,
588 (gpointer) entry_insert_text, data);
591 /* Do not allow further processing */
592 g_signal_stop_emission_by_name (editable, "insert_text");
596 entry_changed (GtkEditable *editable,
600 GtkWidget *ok_button;
603 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
604 ok_button = GTK_WIDGET (buttons->data);
606 chars = gtk_editable_get_chars (editable, 0, -1);
607 g_return_if_fail (chars != NULL);
610 if (g_utf8_strlen (chars,-1) >= 20) {
611 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
612 _CS("ckdg_ib_maximum_characters_reached"));
614 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
617 g_list_free (buttons);
624 on_response (GtkDialog *dialog,
628 GtkWidget *entry, *picker;
629 TnyFolderStore *parent;
630 const gchar *new_name;
633 if (response != GTK_RESPONSE_ACCEPT)
637 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
638 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
640 parent = TNY_FOLDER_STORE (user_data);
641 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
645 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
647 /* Look for another folder with the same name */
648 if (!TNY_IS_MERGE_FOLDER (parent) &&
649 modest_tny_folder_has_subfolder_with_name (parent, new_name, TRUE))
653 if (TNY_IS_ACCOUNT (parent) &&
654 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
655 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
663 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
664 NULL, _CS("ckdg_ib_folder_already_exists"));
665 /* Select the text */
666 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
667 gtk_widget_grab_focus (entry);
668 /* Do not close the dialog */
669 g_signal_stop_emission_by_name (dialog, "response");
673 typedef struct _FolderChooserData {
674 TnyFolderStore *store;
679 folder_chooser_activated (ModestFolderView *folder_view,
680 TnyFolderStore *folder,
681 FolderChooserData *userdata)
683 userdata->store = folder;
684 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
687 static TnyFolderStore *
688 folder_chooser_dialog_run (ModestFolderView *original,
689 TnyFolderStore *current)
691 GtkWidget *folder_view;
692 FolderChooserData userdata = {NULL, NULL};
694 gchar *visible_id = NULL;
696 userdata.dialog = hildon_dialog_new ();
697 pannable = hildon_pannable_area_new ();
698 folder_view = modest_platform_create_folder_view (NULL);
700 gtk_window_set_title (GTK_WINDOW (userdata.dialog), _FM("ckdg_ti_change_folder"));
702 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original),
703 MODEST_FOLDER_VIEW (folder_view));
705 if (TNY_IS_ACCOUNT (current)) {
706 /* Local folders and MMC account are always shown
707 along with the currently visible server account */
708 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (current)) ||
709 modest_tny_account_is_memory_card_account (TNY_ACCOUNT (current)))
711 g_strdup (modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (original)));
713 visible_id = g_strdup (tny_account_get_id (TNY_ACCOUNT (current)));
714 } else if (TNY_IS_FOLDER (current) && !TNY_IS_MERGE_FOLDER (current)) {
716 account = tny_folder_get_account (TNY_FOLDER (current));
718 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (account)) ||
719 modest_tny_account_is_memory_card_account (TNY_ACCOUNT (account))) {
721 g_strdup (modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (original)));
723 visible_id = g_strdup (tny_account_get_id (account));
725 g_object_unref (account);
728 visible_id = g_strdup (
729 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original)));
732 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
736 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
737 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
738 gtk_widget_set_size_request (pannable, -1, 320);
740 gtk_widget_show (folder_view);
741 gtk_widget_show (pannable);
742 gtk_widget_show (userdata.dialog);
743 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
744 G_CALLBACK (folder_chooser_activated),
745 (gpointer) &userdata);
747 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
748 gtk_widget_destroy (userdata.dialog);
750 return userdata.store;
754 folder_store_get_display_name (TnyFolderStore *store)
756 if (TNY_IS_ACCOUNT (store)) {
757 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (store)))
758 return modest_conf_get_string (modest_runtime_get_conf(),
759 MODEST_CONF_DEVICE_NAME, NULL);
761 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
764 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
766 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
767 type = tny_folder_get_folder_type (TNY_FOLDER (store));
768 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
769 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
770 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
771 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
773 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
776 /* Sometimes an special folder is reported by the server as
777 NORMAL, like some versions of Dovecot */
778 if (type == TNY_FOLDER_TYPE_NORMAL ||
779 type == TNY_FOLDER_TYPE_UNKNOWN) {
780 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
784 if (type == TNY_FOLDER_TYPE_INBOX) {
786 fname = g_strdup (_("mcen_me_folder_inbox"));
793 get_image_for_folder_store (TnyFolderStore *store,
797 const gchar *icon_name = NULL;
798 GtkWidget *image = NULL;
800 if (TNY_IS_ACCOUNT (store)) {
801 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (store)))
802 icon_name = MODEST_FOLDER_ICON_LOCAL_FOLDERS;
803 else if (modest_tny_account_is_memory_card_account (TNY_ACCOUNT (store)))
804 icon_name = MODEST_FOLDER_ICON_MMC;
806 icon_name = MODEST_FOLDER_ICON_ACCOUNT;
808 TnyFolderType type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
809 if (modest_tny_folder_is_remote_folder (TNY_FOLDER (store))) {
811 case TNY_FOLDER_TYPE_INBOX:
812 icon_name = MODEST_FOLDER_ICON_INBOX;
815 icon_name = MODEST_FOLDER_ICON_REMOTE_FOLDER;
817 } else if (modest_tny_folder_is_local_folder (TNY_FOLDER (store))) {
819 case TNY_FOLDER_TYPE_OUTBOX:
820 icon_name = MODEST_FOLDER_ICON_OUTBOX;
822 case TNY_FOLDER_TYPE_DRAFTS:
823 icon_name = MODEST_FOLDER_ICON_DRAFTS;
825 case TNY_FOLDER_TYPE_SENT:
826 icon_name = MODEST_FOLDER_ICON_SENT;
829 icon_name = MODEST_FOLDER_ICON_NORMAL;
831 } else if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
832 icon_name = MODEST_FOLDER_ICON_MMC_FOLDER;
837 pixbuf = modest_platform_get_icon (icon_name, size);
840 image = gtk_image_new_from_pixbuf (pixbuf);
841 g_object_unref (pixbuf);
848 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
853 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
857 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
858 g_object_ref (store),
859 (GDestroyNotify) g_object_unref);
860 name = folder_store_get_display_name (store);
861 hildon_button_set_value (HILDON_BUTTON (button), name);
865 image = get_image_for_folder_store (store, MODEST_ICON_SIZE_SMALL);
867 hildon_button_set_image (HILDON_BUTTON (button), image);
871 /* Always returns DUPs so you must free the returned value */
873 get_next_folder_name (const gchar *suggested_name,
874 TnyFolderStore *suggested_folder)
876 const gchar *default_name = _FM("ckdg_va_new_folder_name_stub");
878 gchar *real_suggested_name;
880 if (suggested_name !=NULL) {
881 return g_strdup (suggested_name);
884 for(i = 0; i < 100; ++ i) {
885 gboolean exists = FALSE;
888 real_suggested_name = g_strdup (default_name);
890 real_suggested_name = g_strdup_printf ("%s(%d)",
891 _FM("ckdg_va_new_folder_name_stub"),
893 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
900 g_free (real_suggested_name);
903 /* Didn't find a free number */
905 real_suggested_name = g_strdup (default_name);
907 return real_suggested_name;
911 ModestFolderView *folder_view;
913 } FolderPickerHelper;
916 folder_picker_clicked (GtkButton *button,
917 FolderPickerHelper *helper)
919 TnyFolderStore *store, *current;
921 current = g_object_get_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER);
923 store = folder_chooser_dialog_run (helper->folder_view, current);
925 const gchar *current_name;
926 gboolean exists = FALSE;
928 folder_picker_set_store (GTK_BUTTON (button), store);
930 /* Update the name of the folder */
931 current_name = gtk_entry_get_text (helper->entry);
933 if (TNY_IS_FOLDER_STORE (store))
934 exists = modest_tny_folder_has_subfolder_with_name (store,
938 gchar *new_name = get_next_folder_name (NULL, store);
939 gtk_entry_set_text (helper->entry, new_name);
946 folder_picker_new (TnyFolderStore *suggested, FolderPickerHelper *helper)
950 button = hildon_button_new (MODEST_EDITABLE_SIZE,
951 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
953 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
956 folder_picker_set_store (GTK_BUTTON (button), suggested);
958 g_signal_connect (G_OBJECT (button), "clicked",
959 G_CALLBACK (folder_picker_clicked),
967 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
968 TnyFolderStore *suggested_parent,
969 const gchar *dialog_title,
970 const gchar *label_text,
971 const gchar *suggested_name,
973 gboolean show_parent,
975 TnyFolderStore **parent)
977 GtkWidget *accept_btn = NULL;
978 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
979 GtkWidget *account_picker = NULL;
980 GList *buttons = NULL;
982 GtkSizeGroup *sizegroup;
983 ModestFolderView *folder_view;
984 ModestWindow *folder_window;
985 ModestHildon2WindowMgr *window_mgr;
986 FolderPickerHelper *helper = NULL;
987 GtkWidget *top_vbox, *top_align;
989 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
990 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
991 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
993 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
995 top_vbox = gtk_vbox_new (FALSE, 0);
996 top_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
997 gtk_alignment_set_padding (GTK_ALIGNMENT (top_align), 0, 0, MODEST_MARGIN_DOUBLE, 0);
999 /* Ask the user for the folder name */
1000 dialog = gtk_dialog_new_with_buttons (dialog_title,
1002 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
1003 _FM("ckdg_bd_new_folder_dialog_ok"),
1004 GTK_RESPONSE_ACCEPT,
1007 /* Add accept button (with unsensitive handler) */
1008 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
1009 accept_btn = GTK_WIDGET (buttons->data);
1011 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
1014 label_entry = gtk_label_new (label_text);
1015 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1016 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
1018 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
1019 gtk_size_group_add_widget (sizegroup, label_entry);
1022 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
1024 gtk_entry_set_text (GTK_ENTRY (entry), _FM("ckdg_va_new_folder_name_stub"));
1025 gtk_entry_set_width_chars (GTK_ENTRY (entry),
1026 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
1027 g_utf8_strlen (_FM("ckdg_va_new_folder_name_stub"), -1)));
1028 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
1033 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
1035 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
1036 gtk_size_group_add_widget (sizegroup, label_location);
1038 helper = g_slice_new0 (FolderPickerHelper);
1039 helper->folder_view = folder_view;
1040 helper->entry = (GtkEntry *) entry;
1042 account_picker = folder_picker_new (suggested_parent, helper);
1045 g_object_unref (sizegroup);
1047 /* Connect to the response method to avoid closing the dialog
1048 when an invalid name is selected*/
1049 g_signal_connect (dialog,
1051 G_CALLBACK (on_response),
1055 /* Track entry changes */
1056 g_signal_connect (entry,
1058 G_CALLBACK (entry_insert_text),
1060 g_signal_connect (entry,
1062 G_CALLBACK (entry_changed),
1067 /* Some locales like pt_BR need this to get the full window
1069 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
1071 /* Create the hbox */
1073 hbox = gtk_hbox_new (FALSE, 12);
1074 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
1075 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
1077 /* Add hbox to dialog */
1078 gtk_box_pack_start (GTK_BOX (top_vbox),
1079 hbox, FALSE, FALSE, 0);
1080 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
1084 hbox = gtk_hbox_new (FALSE, 12);
1085 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
1086 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
1088 /* Add hbox to dialog */
1089 gtk_box_pack_start (GTK_BOX (top_vbox),
1090 hbox, FALSE, FALSE, 0);
1091 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
1093 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1094 GTK_WINDOW (dialog), parent_window);
1096 gtk_container_add (GTK_CONTAINER (top_align), top_vbox);
1097 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), top_align, TRUE, TRUE, 0);
1099 gtk_widget_show_all (GTK_WIDGET(dialog));
1101 result = gtk_dialog_run (GTK_DIALOG(dialog));
1102 if (result == GTK_RESPONSE_ACCEPT) {
1104 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1106 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
1108 g_object_ref (*parent);
1112 gtk_widget_destroy (dialog);
1115 g_slice_free (FolderPickerHelper, helper);
1117 while (gtk_events_pending ())
1118 gtk_main_iteration ();
1124 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
1125 TnyFolderStore *suggested_folder,
1126 gchar *suggested_name,
1127 gchar **folder_name,
1128 TnyFolderStore **parent_folder)
1130 gchar *real_suggested_name = NULL;
1132 ModestTnyAccountStore *acc_store;
1133 TnyAccount *account;
1134 gboolean do_free = FALSE;
1136 real_suggested_name = get_next_folder_name ((const gchar *) suggested_name,
1139 /* In hildon 2.2 we always suggest the archive folder as parent */
1140 if (!suggested_folder) {
1141 acc_store = modest_runtime_get_account_store ();
1142 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
1144 suggested_folder = (TnyFolderStore *)
1145 modest_tny_account_get_special_folder (account,
1146 TNY_FOLDER_TYPE_ARCHIVE);
1147 g_object_unref (account);
1152 /* If there is not archive folder then fallback to local folders account */
1153 if (!suggested_folder) {
1155 suggested_folder = (TnyFolderStore *)
1156 modest_tny_account_store_get_local_folders_account (acc_store);
1159 result = modest_platform_run_folder_common_dialog (parent_window,
1161 _HL("ckdg_ti_new_folder"),
1162 _FM("ckdg_fi_new_folder_name"),
1163 real_suggested_name,
1170 g_object_unref (suggested_folder);
1172 g_free(real_suggested_name);
1178 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1179 TnyFolderStore *parent_folder,
1180 const gchar *suggested_name,
1181 gchar **folder_name)
1183 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1185 return modest_platform_run_folder_common_dialog (parent_window,
1187 _HL("ckdg_ti_rename_folder"),
1188 _HL("ckdg_fi_rename_name"),
1199 on_destroy_dialog (GtkWidget *dialog)
1201 /* This could happen when the dialogs get programatically
1202 hidden or destroyed (for example when closing the
1203 application while a dialog is being shown) */
1204 if (!GTK_IS_WIDGET (dialog))
1207 gtk_widget_destroy (dialog);
1209 if (gtk_events_pending ())
1210 gtk_main_iteration ();
1214 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1215 const gchar *message)
1220 dialog = hildon_note_new_confirmation (parent_window, message);
1221 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1222 GTK_WINDOW (dialog), parent_window);
1224 response = gtk_dialog_run (GTK_DIALOG (dialog));
1226 on_destroy_dialog (dialog);
1232 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1233 const gchar *message,
1234 const gchar *button_accept,
1235 const gchar *button_cancel)
1240 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1241 button_accept, GTK_RESPONSE_ACCEPT,
1242 button_cancel, GTK_RESPONSE_CANCEL,
1245 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1246 GTK_WINDOW (dialog), parent_window);
1248 response = gtk_dialog_run (GTK_DIALOG (dialog));
1250 on_destroy_dialog (dialog);
1256 modest_platform_run_information_dialog (GtkWindow *parent_window,
1257 const gchar *message,
1262 note = hildon_note_new_information (parent_window, message);
1264 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1265 GTK_WINDOW (note), parent_window);
1268 gtk_dialog_run (GTK_DIALOG (note));
1270 on_destroy_dialog (note);
1272 g_signal_connect_swapped (note,
1274 G_CALLBACK (on_destroy_dialog),
1277 gtk_widget_show_all (note);
1281 typedef struct _ConnectAndWaitData {
1283 GMainLoop *wait_loop;
1284 gboolean has_callback;
1286 } ConnectAndWaitData;
1290 quit_wait_loop (TnyAccount *account,
1291 ConnectAndWaitData *data)
1293 /* Set the has_callback to TRUE (means that the callback was
1294 executed and wake up every code waiting for cond to be
1296 g_mutex_lock (data->mutex);
1297 data->has_callback = TRUE;
1298 if (data->wait_loop)
1299 g_main_loop_quit (data->wait_loop);
1300 g_mutex_unlock (data->mutex);
1304 on_connection_status_changed (TnyAccount *account,
1305 TnyConnectionStatus status,
1308 TnyConnectionStatus conn_status;
1309 ConnectAndWaitData *data;
1311 /* Ignore if reconnecting or disconnected */
1312 conn_status = tny_account_get_connection_status (account);
1313 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1314 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1317 /* Remove the handler */
1318 data = (ConnectAndWaitData *) user_data;
1319 g_signal_handler_disconnect (account, data->handler);
1321 /* Quit from wait loop */
1322 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1326 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1331 /* Quit from wait loop */
1332 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1336 modest_platform_connect_and_wait (GtkWindow *parent_window,
1337 TnyAccount *account)
1339 ConnectAndWaitData *data = NULL;
1340 gboolean device_online;
1342 TnyConnectionStatus conn_status;
1343 gboolean user_requested;
1345 device = modest_runtime_get_device();
1346 device_online = tny_device_is_online (device);
1348 /* Whether the connection is user requested or automatically
1349 requested, for example via D-Bus */
1350 user_requested = (parent_window) ? TRUE : FALSE;
1352 /* If there is no account check only the device status */
1357 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1358 NULL, user_requested);
1361 /* Return if the account is already connected */
1362 conn_status = tny_account_get_connection_status (account);
1363 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1366 /* Create the helper */
1367 data = g_slice_new0 (ConnectAndWaitData);
1368 data->mutex = g_mutex_new ();
1369 data->has_callback = FALSE;
1371 /* Connect the device */
1372 if (!device_online) {
1373 /* Track account connection status changes */
1374 data->handler = g_signal_connect (account, "connection-status-changed",
1375 G_CALLBACK (on_connection_status_changed),
1377 /* Try to connect the device */
1378 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1379 NULL, user_requested);
1381 /* If the device connection failed then exit */
1382 if (!device_online && data->handler)
1385 /* Force a reconnection of the account */
1386 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1387 on_tny_camel_account_set_online_cb, data);
1390 /* Wait until the callback is executed */
1391 g_mutex_lock (data->mutex);
1392 if (!data->has_callback) {
1393 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1394 gdk_threads_leave ();
1395 g_mutex_unlock (data->mutex);
1396 g_main_loop_run (data->wait_loop);
1397 g_mutex_lock (data->mutex);
1398 gdk_threads_enter ();
1400 g_mutex_unlock (data->mutex);
1403 if (g_signal_handler_is_connected (account, data->handler))
1404 g_signal_handler_disconnect (account, data->handler);
1405 g_mutex_free (data->mutex);
1406 g_main_loop_unref (data->wait_loop);
1407 g_slice_free (ConnectAndWaitData, data);
1409 conn_status = tny_account_get_connection_status (account);
1410 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1414 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1416 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1417 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1418 /* This must be a maildir account, which does not require a connection: */
1423 return modest_platform_connect_and_wait (parent_window, account);
1427 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1430 return TRUE; /* Maybe it is something local. */
1432 gboolean result = TRUE;
1433 if (TNY_IS_FOLDER (folder_store)) {
1434 /* Get the folder's parent account: */
1435 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1436 if (account != NULL) {
1437 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1438 g_object_unref (account);
1440 } else if (TNY_IS_ACCOUNT (folder_store)) {
1441 /* Use the folder store as an account: */
1442 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1449 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1453 dialog = modest_hildon2_sort_dialog_new (parent_window);
1460 modest_platform_set_update_interval (guint minutes)
1462 #ifdef MODEST_HAVE_LIBALARM
1464 ModestConf *conf = modest_runtime_get_conf ();
1468 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1470 /* Delete any existing alarm,
1471 * because we will replace it: */
1473 if (alarmd_event_del(alarm_cookie) != 0)
1474 g_debug ("%s: alarm %d was not on the queue", __FUNCTION__, (int)alarm_cookie);
1476 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1479 /* 0 means no updates: */
1484 /* Register alarm: */
1486 /* Set the interval in alarm_event_t structure: */
1487 alarm_event_t *event = alarm_event_create ();
1488 alarm_event_add_actions (event, 1);
1489 alarm_action_t *action = alarm_event_get_action (event, 0);
1490 alarm_event_set_alarm_appid (event, MODEST_ALARMD_APPID);
1491 event->alarm_time = minutes * 60; /* seconds */
1493 /* Set recurrence every few minutes: */
1494 event->recur_secs = minutes*60;
1495 event->recur_count = -1; /* Means infinite */
1497 /* Specify what should happen when the alarm happens:
1498 * It should call this D-Bus method: */
1500 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1501 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1502 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1503 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1504 action->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1506 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1507 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1508 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1509 * This is why we want to use the Alarm API instead of just g_timeout_add().
1510 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1511 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1513 event->flags = ALARM_EVENT_CONNECTED;
1515 alarm_cookie = alarmd_event_add (event);
1518 alarm_event_delete (event);
1520 /* Store the alarm ID in GConf, so we can remove it later:
1521 * This is apparently valid between application instances. */
1522 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1524 if (!alarm_cookie) {
1526 g_warning ("Error setting alarm event. \n");
1530 #endif /* MODEST_HAVE_LIBALARM */
1535 modest_platform_push_email_notification(void)
1537 gboolean screen_on, app_in_foreground;
1539 /* Get the window status */
1540 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1542 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1544 /* If the screen is on and the app is in the
1545 foreground we don't show anything */
1546 if (!(screen_on && app_in_foreground)) {
1548 modest_platform_play_email_tone ();
1550 /* Activate LED. This must be deactivated by
1551 modest_platform_remove_new_mail_notifications */
1552 #ifdef MODEST_HAVE_MCE
1553 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1557 MCE_ACTIVATE_LED_PATTERN,
1559 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1566 modest_platform_on_new_headers_received (GList *URI_list,
1567 gboolean show_visual)
1569 gboolean screen_on, app_in_foreground;
1571 /* Get the window status */
1572 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1573 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1575 /* If the screen is on and the app is in the
1576 foreground we don't show anything */
1577 if (screen_on && app_in_foreground)
1580 if (g_list_length (URI_list) == 0)
1583 #ifdef MODEST_HAVE_HILDON_NOTIFY
1584 /* For any other case issue a notification */
1585 HildonNotification *notification;
1586 ModestMsgNotificationData *data;
1589 TnyAccountStore *acc_store;
1590 TnyAccount *account;
1592 data = (ModestMsgNotificationData *) URI_list->data;
1594 /* String is changed in-place. There is no need to
1595 actually dup the data->from string but we just do
1596 it in order not to modify the original contents */
1597 from = g_strdup (data->from);
1598 modest_text_utils_get_display_address (from);
1600 /* Create notification */
1601 notification = hildon_notification_new (from,
1603 "qgn_list_messagin",
1604 MODEST_NOTIFICATION_CATEGORY);
1607 /* Add DBus action */
1608 hildon_notification_add_dbus_action(notification,
1611 MODEST_DBUS_SERVICE,
1614 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1615 G_TYPE_STRING, data->uri,
1618 /* Set the led pattern */
1619 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1621 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1623 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1625 /* Make the notification persistent */
1626 notify_notification_set_hint_byte (NOTIFY_NOTIFICATION (notification),
1627 "persistent", TRUE);
1629 /* Set the number of new notifications */
1630 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1631 "amount", g_list_length (URI_list));
1633 /* Set the account of the headers */
1634 acc_store = (TnyAccountStore *) modest_runtime_get_account_store ();
1635 account = tny_account_store_find_account (acc_store, data->uri);
1637 const gchar *acc_name;
1639 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
1640 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1643 g_object_unref (account);
1647 modest_platform_play_email_tone ();
1648 if (notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL)) {
1649 GSList *notifications_list = NULL;
1651 /* Get previous notifications ids */
1652 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1653 MODEST_CONF_NOTIFICATION_IDS,
1654 MODEST_CONF_VALUE_INT, NULL);
1656 /* Save id in the list */
1657 g_object_get(G_OBJECT (notification), "id", ¬if_id, NULL);
1658 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1660 /* We don't listen for the "closed" signal, because we
1661 don't care about if the notification was removed or
1662 not to store the list in gconf */
1665 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1666 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1668 g_slist_free (notifications_list);
1670 g_warning ("Failed to send notification");
1673 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1677 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1680 #ifdef MODEST_HAVE_MCE
1681 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1685 MCE_DEACTIVATE_LED_PATTERN,
1687 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1693 #ifdef MODEST_HAVE_HILDON_NOTIFY
1694 GSList *notif_list = NULL;
1696 /* Get previous notifications ids */
1697 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1698 MODEST_CONF_NOTIFICATION_IDS,
1699 MODEST_CONF_VALUE_INT, NULL);
1701 while (notif_list) {
1703 NotifyNotification *notif;
1705 /* Nasty HACK to remove the notifications, set the id
1706 of the existing ones and then close them */
1707 notif_id = GPOINTER_TO_INT(notif_list->data);
1708 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1709 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1711 /* Close the notification, note that some ids could be
1712 already invalid, but we don't care because it does
1714 notify_notification_close(notif, NULL);
1715 g_object_unref(notif);
1717 /* Delete the link, it's like going to the next */
1718 notif_list = g_slist_delete_link (notif_list, notif_list);
1722 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1723 notif_list, MODEST_CONF_VALUE_INT, NULL);
1725 g_slist_free (notif_list);
1727 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1733 modest_platform_get_global_settings_dialog ()
1735 return modest_hildon2_global_settings_dialog_new ();
1739 modest_platform_show_help (GtkWindow *parent_window,
1740 const gchar *help_id)
1746 modest_platform_show_search_messages (GtkWindow *parent_window)
1748 osso_return_t result = OSSO_ERROR;
1750 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1751 "osso_global_search",
1752 "search_email", NULL, DBUS_TYPE_INVALID);
1754 if (result != OSSO_OK) {
1755 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1760 modest_platform_show_addressbook (GtkWindow *parent_window)
1762 osso_return_t result = OSSO_ERROR;
1764 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1766 "top_application", NULL, DBUS_TYPE_INVALID);
1768 if (result != OSSO_OK) {
1769 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1774 modest_platform_create_folder_view_full (TnyFolderStoreQuery *query, gboolean do_refresh)
1776 GtkWidget *widget = modest_folder_view_new_full (query, do_refresh);
1778 /* Show one account by default */
1779 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1780 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1782 /* Restore settings */
1783 modest_widget_memory_restore (modest_runtime_get_conf(),
1785 MODEST_CONF_FOLDER_VIEW_KEY);
1791 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1793 return modest_platform_create_folder_view_full (query, TRUE);
1797 banner_finish (gpointer data, GObject *object)
1799 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1800 modest_window_mgr_unregister_banner (mgr);
1801 g_object_unref (mgr);
1805 modest_platform_information_banner (GtkWidget *parent,
1806 const gchar *icon_name,
1809 GtkWidget *banner_parent = NULL;
1810 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1812 if (modest_window_mgr_get_num_windows (mgr) == 0)
1815 if (parent && GTK_IS_WINDOW (parent)) {
1816 /* If the window is the active one then show the
1817 banner on top of this window */
1818 if (gtk_window_is_active (GTK_WINDOW (parent)))
1819 banner_parent = parent;
1820 /* If the window is not the topmost but it's visible
1821 (it's minimized for example) then show the banner
1823 else if (GTK_WIDGET_VISIBLE (parent))
1824 banner_parent = NULL;
1825 /* If the window is hidden (like the main window when
1826 running in the background) then do not show
1832 modest_platform_system_banner (banner_parent, icon_name, text);
1836 modest_platform_system_banner (GtkWidget *parent,
1837 const gchar *icon_name,
1840 GtkWidget *banner = NULL;
1841 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1843 if (parent && GTK_IS_WINDOW (parent)) {
1844 if (!gtk_window_is_active (GTK_WINDOW (parent)))
1848 banner = hildon_banner_show_information (parent, icon_name, text);
1850 modest_window_mgr_register_banner (mgr);
1852 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1856 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1857 const gchar *icon_name,
1863 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1866 banner = hildon_banner_show_information (parent, icon_name, text);
1867 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1871 modest_platform_animation_banner (GtkWidget *parent,
1872 const gchar *animation_name,
1875 GtkWidget *inf_note = NULL;
1877 g_return_val_if_fail (text != NULL, NULL);
1879 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1882 /* If the parent is not visible then do not show */
1883 if (parent && !GTK_WIDGET_VISIBLE (parent))
1886 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1894 TnyAccount *account;
1897 } CheckAccountIdleData;
1899 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1902 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1904 gboolean stop_trying = FALSE;
1905 g_return_val_if_fail (data && data->account, FALSE);
1907 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__,
1908 tny_account_get_connection_status (data->account));
1910 if (data && data->account &&
1911 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1912 * after which the account is likely to be usable, or never likely to be usable soon: */
1913 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1915 data->is_online = TRUE;
1919 /* Give up if we have tried too many times: */
1920 if (data->count_tries >= NUMBER_OF_TRIES) {
1923 /* Wait for another timeout: */
1924 ++(data->count_tries);
1929 /* Allow the function that requested this idle callback to continue: */
1931 g_main_loop_quit (data->loop);
1934 g_object_unref (data->account);
1936 return FALSE; /* Don't call this again. */
1938 return TRUE; /* Call this timeout callback again. */
1942 /* Return TRUE immediately if the account is already online,
1943 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1944 * soon as the account is online, or FALSE if the account does
1945 * not become online in the NUMBER_OF_TRIES seconds.
1946 * This is useful when the D-Bus method was run immediately after
1947 * the application was started (when using D-Bus activation),
1948 * because the account usually takes a short time to go online.
1949 * The return value is maybe not very useful.
1952 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1956 g_return_val_if_fail (account, FALSE);
1958 if (!tny_device_is_online (modest_runtime_get_device())) {
1959 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1963 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1964 * so we avoid wait unnecessarily: */
1965 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1968 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1969 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1970 * we want to avoid. */
1971 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1974 /* This blocks on the result: */
1975 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1976 data->is_online = FALSE;
1977 data->account = account;
1978 g_object_ref (data->account);
1979 data->count_tries = 0;
1981 GMainContext *context = NULL; /* g_main_context_new (); */
1982 data->loop = g_main_loop_new (context, FALSE /* not running */);
1984 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
1986 /* This main loop will run until the idle handler has stopped it: */
1987 g_main_loop_run (data->loop);
1989 g_main_loop_unref (data->loop);
1990 /* g_main_context_unref (context); */
1992 is_online = data->is_online;
1993 g_slice_free (CheckAccountIdleData, data);
2001 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
2003 /* GTK_RESPONSE_HELP means we need to show the certificate */
2004 if (response_id == GTK_RESPONSE_APPLY) {
2008 /* Do not close the dialog */
2009 g_signal_stop_emission_by_name (dialog, "response");
2011 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
2012 note = hildon_note_new_information (NULL, msg);
2013 gtk_dialog_run (GTK_DIALOG(note));
2014 gtk_widget_destroy (note);
2020 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
2021 const gchar *certificate)
2026 HildonWindowStack *stack;
2028 stack = hildon_window_stack_get_default ();
2029 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
2032 g_debug ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
2037 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
2040 /* We use GTK_RESPONSE_APPLY because we want the button in the
2041 middle of OK and CANCEL the same as the browser does for
2042 example. With GTK_RESPONSE_HELP the view button is aligned
2043 to the left while the other two to the right */
2044 note = hildon_note_new_confirmation_add_buttons (
2047 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
2048 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
2049 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
2052 g_signal_connect (G_OBJECT(note), "response",
2053 G_CALLBACK(on_cert_dialog_response),
2054 (gpointer) certificate);
2056 response = gtk_dialog_run(GTK_DIALOG(note));
2058 on_destroy_dialog (note);
2061 return response == GTK_RESPONSE_OK;
2065 modest_platform_run_alert_dialog (const gchar* prompt,
2066 gboolean is_question)
2068 ModestWindow *top_win;
2069 HildonWindowStack *stack;
2071 stack = hildon_window_stack_get_default ();
2072 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
2075 g_debug ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
2080 gboolean retval = TRUE;
2082 /* The Tinymail documentation says that we should show Yes and No buttons,
2083 * when it is a question.
2084 * Obviously, we need tinymail to use more specific error codes instead,
2085 * so we know what buttons to show. */
2086 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
2088 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2089 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
2091 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
2092 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
2094 on_destroy_dialog (dialog);
2096 /* Just show the error text and use the default response: */
2097 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
2105 GtkWindow *parent_window;
2106 ModestConnectedPerformer callback;
2107 TnyAccount *account;
2114 on_went_online_info_free (OnWentOnlineInfo *info)
2116 /* And if we cleanup, we DO cleanup :-) */
2119 g_object_unref (info->device);
2122 if (info->parent_window)
2123 g_object_unref (info->parent_window);
2125 g_object_unref (info->account);
2127 g_slice_free (OnWentOnlineInfo, info);
2129 /* We're done ... */
2135 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
2137 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2139 /* Now it's really time to callback to the caller. If going online didn't succeed,
2140 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
2141 * canceled will be set. Etcetera etcetera. */
2143 if (info->callback) {
2144 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2147 /* This is our last call, we must cleanup here if we didn't yet do that */
2148 on_went_online_info_free (info);
2155 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2157 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2158 info->iap = g_strdup (iap_id);
2160 if (canceled || err || !info->account) {
2162 /* If there's a problem or if there's no account (then that's it for us, we callback
2163 * the caller's callback now. He'll have to handle err or canceled, of course.
2164 * We are not really online, as the account is not really online here ... */
2166 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2167 * this info. We don't cleanup err, Tinymail does that! */
2169 if (info->callback) {
2171 /* info->account can be NULL here, this means that the user did not
2172 * provide a nice account instance. We'll assume that the user knows
2173 * what he's doing and is happy with just the device going online.
2175 * We can't do magic, we don't know what account the user wants to
2176 * see going online. So just the device goes online, end of story */
2178 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2181 } else if (info->account) {
2183 /* If there's no problem and if we have an account, we'll put the account
2184 * online too. When done, the callback of bringing the account online
2185 * will callback the caller's callback. This is the most normal case. */
2187 info->device = TNY_DEVICE (g_object_ref (device));
2189 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2190 on_account_went_online, info);
2192 /* The on_account_went_online cb frees up the info, go look if you
2193 * don't believe me! (so we return here) */
2198 /* We cleanup if we are not bringing the account online too */
2199 on_went_online_info_free (info);
2205 modest_platform_connect_and_perform (GtkWindow *parent_window,
2207 TnyAccount *account,
2208 ModestConnectedPerformer callback,
2211 gboolean device_online;
2213 TnyConnectionStatus conn_status;
2214 OnWentOnlineInfo *info;
2216 device = modest_runtime_get_device();
2217 device_online = tny_device_is_online (device);
2219 /* If there is no account check only the device status */
2222 if (device_online) {
2224 /* We promise to instantly perform the callback, so ... */
2226 callback (FALSE, NULL, parent_window, account, user_data);
2231 info = g_slice_new0 (OnWentOnlineInfo);
2234 info->device = NULL;
2235 info->account = NULL;
2238 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2240 info->parent_window = NULL;
2241 info->user_data = user_data;
2242 info->callback = callback;
2244 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2245 force, on_conic_device_went_online,
2248 /* We'll cleanup in on_conic_device_went_online */
2251 /* The other code has no more reason to run. This is all that we can do for the
2252 * caller (he should have given us a nice and clean account instance!). We
2253 * can't do magic, we don't know what account he intends to bring online. So
2254 * we'll just bring the device online (and await his false bug report). */
2260 /* Return if the account is already connected */
2262 conn_status = tny_account_get_connection_status (account);
2263 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2265 /* We promise to instantly perform the callback, so ... */
2267 callback (FALSE, NULL, parent_window, account, user_data);
2273 /* Else, we are in a state that requires that we go online before we
2274 * call the caller's callback. */
2276 info = g_slice_new0 (OnWentOnlineInfo);
2278 info->device = NULL;
2280 info->account = TNY_ACCOUNT (g_object_ref (account));
2283 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2285 info->parent_window = NULL;
2287 /* So we'll put the callback away for later ... */
2289 info->user_data = user_data;
2290 info->callback = callback;
2292 if (!device_online) {
2294 /* If also the device is offline, then we connect both the device
2295 * and the account */
2297 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2298 force, on_conic_device_went_online,
2303 /* If the device is online, we'll just connect the account */
2305 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2306 on_account_went_online, info);
2309 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2310 * in both situations, go look if you don't believe me! */
2316 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2318 TnyFolderStore *folder_store,
2319 ModestConnectedPerformer callback,
2322 TnyAccount *account = NULL;
2324 if (!folder_store ||
2325 (TNY_IS_MERGE_FOLDER (folder_store) &&
2326 (tny_folder_get_folder_type (TNY_FOLDER(folder_store)) == TNY_FOLDER_TYPE_OUTBOX))) {
2328 /* We promise to instantly perform the callback, so ... */
2330 GError *error = NULL;
2331 g_set_error (&error, TNY_ERROR_DOMAIN, TNY_SERVICE_ERROR_UNKNOWN,
2332 "Unable to move or not found folder");
2333 callback (FALSE, error, parent_window, NULL, user_data);
2334 g_error_free (error);
2338 } else if (TNY_IS_FOLDER (folder_store)) {
2339 /* Get the folder's parent account: */
2340 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2341 } else if (TNY_IS_ACCOUNT (folder_store)) {
2342 /* Use the folder store as an account: */
2343 account = TNY_ACCOUNT (g_object_ref (folder_store));
2346 if (account && (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE)) {
2347 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2348 /* No need to connect a local account */
2350 callback (FALSE, NULL, parent_window, account, user_data);
2355 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2359 g_object_unref (account);
2363 src_account_connect_performer (gboolean canceled,
2365 GtkWindow *parent_window,
2366 TnyAccount *src_account,
2369 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2371 if (canceled || err) {
2372 /* If there was any error call the user callback */
2373 info->callback (canceled, err, parent_window, src_account, info->data);
2375 /* Connect the destination account */
2376 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2377 TNY_FOLDER_STORE (info->dst_account),
2378 info->callback, info->data);
2381 /* Free the info object */
2382 g_object_unref (info->dst_account);
2383 g_slice_free (DoubleConnectionInfo, info);
2388 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2390 TnyFolderStore *folder_store,
2391 DoubleConnectionInfo *connect_info)
2393 modest_platform_connect_if_remote_and_perform(parent_window,
2396 src_account_connect_performer,
2401 modest_platform_get_account_settings_wizard (void)
2403 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2405 return GTK_WIDGET (dialog);
2409 modest_platform_get_current_connection (void)
2411 TnyDevice *device = NULL;
2412 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2414 device = modest_runtime_get_device ();
2416 if (!tny_device_is_online (device))
2417 return MODEST_CONNECTED_VIA_ANY;
2419 #ifdef MODEST_HAVE_CONIC
2421 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2423 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2424 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2425 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2427 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2428 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2429 !strcmp (bearer_type, "WIMAX")) {
2430 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2432 retval = MODEST_CONNECTED_VIA_ANY;
2435 g_object_unref (iap);
2438 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2439 #endif /* MODEST_HAVE_CONIC */
2446 modest_platform_check_memory_low (ModestWindow *win,
2451 /* are we in low memory state? */
2452 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2454 if (win && lowmem && visuals)
2455 modest_platform_run_information_dialog (
2457 _KR("memr_ib_operation_disabled"),
2461 g_debug ("%s: low memory reached. disallowing some operations",
2468 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2474 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2477 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2478 GTK_WINDOW (dialog),
2480 gtk_widget_show_all (dialog);
2482 g_signal_connect_swapped (dialog, "response",
2483 G_CALLBACK (gtk_widget_destroy),
2487 typedef struct _HeaderDetailsGetSizeInfo {
2491 } HeaderDetailsGetSizeInfo;
2494 header_details_dialog_destroy (gpointer userdata,
2497 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) userdata;
2499 info->dialog = NULL;
2503 idle_get_mime_part_size_cb (gpointer userdata)
2505 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) userdata;
2506 gdk_threads_enter ();
2508 if (info->dialog && GTK_WIDGET_VISIBLE (info->dialog)) {
2509 modest_details_dialog_set_message_size (MODEST_DETAILS_DIALOG (info->dialog),
2514 g_object_weak_unref (G_OBJECT (info->dialog), header_details_dialog_destroy, info);
2515 info->dialog = NULL;
2517 g_object_unref (info->part);
2518 g_slice_free (HeaderDetailsGetSizeInfo, info);
2520 gdk_threads_leave ();
2526 get_mime_part_size_thread (gpointer thr_user_data)
2528 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) thr_user_data;
2530 TnyStream *count_stream;
2532 count_stream = modest_count_stream_new ();
2533 result = tny_mime_part_decode_to_stream (info->part, count_stream, NULL);
2534 info->total = modest_count_stream_get_count(MODEST_COUNT_STREAM (count_stream));
2535 if (info->total == 0) {
2536 modest_count_stream_reset_count(MODEST_COUNT_STREAM (count_stream));
2537 result = tny_mime_part_write_to_stream (info->part, count_stream, NULL);
2538 info->total = modest_count_stream_get_count(MODEST_COUNT_STREAM (count_stream));
2541 /* if there was an error, don't set the size (this is pretty uncommon) */
2543 g_warning ("%s: error while writing mime part to stream\n", __FUNCTION__);
2545 g_idle_add (idle_get_mime_part_size_cb, info);
2551 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2553 gboolean async_get_size,
2559 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header, !async_get_size);
2561 if (async_get_size && msg && TNY_IS_MSG (msg)) {
2562 HeaderDetailsGetSizeInfo *info;
2563 info = g_slice_new (HeaderDetailsGetSizeInfo);
2564 info->dialog = dialog;
2566 info->part = TNY_MIME_PART (g_object_ref (msg));
2568 g_object_weak_ref (G_OBJECT (dialog), header_details_dialog_destroy, info);
2569 g_thread_create (get_mime_part_size_thread, info, FALSE, NULL);
2573 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2574 GTK_WINDOW (dialog),
2576 gtk_widget_show_all (dialog);
2578 g_signal_connect_swapped (dialog, "response",
2579 G_CALLBACK (gtk_widget_destroy),
2584 modest_platform_get_osso_context (void)
2586 return modest_maemo_utils_get_osso_context ();
2590 modest_platform_play_email_tone (void)
2593 gint mail_volume_int;
2595 ca_context *ca_con = NULL;
2596 ca_proplist *pl = NULL;
2598 #ifdef MODEST_USE_PROFILE
2599 gchar *active_profile;
2602 active_profile = profile_get_profile ();
2603 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2604 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2605 mail_volume_int = profile_parse_int (mail_volume);
2606 g_free (mail_volume);
2607 g_free (active_profile);
2609 mail_tone = MAIL_TONE;
2610 mail_volume_int = 100;
2613 if (mail_tone && !strstr (mail_tone, "/")) {
2616 tmp = g_strconcat ("/usr/share/sounds", mail_tone, NULL);
2621 if (mail_volume_int > 0) {
2623 if ((ret = ca_context_create(&ca_con)) != CA_SUCCESS) {
2624 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2628 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2629 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2630 ca_context_destroy(ca_con);
2634 ca_proplist_create(&pl);
2635 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2636 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", (gfloat) mail_volume_int);
2638 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2639 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2641 ca_proplist_destroy(pl);
2642 ca_context_destroy(ca_con);
2648 #define MOVE_TO_DIALOG_FOLDER_VIEW "folder-view"
2649 #define MOVE_TO_DIALOG_BACK_BUTTON "back-button"
2650 #define MOVE_TO_DIALOG_ACTION_BUTTON "action-button"
2651 #define MOVE_TO_DIALOG_SHOWING_FOLDERS "showing-folders"
2652 #define MOVE_TO_DIALOG_PANNABLE "pannable"
2653 #define MOVE_TO_FOLDER_SEPARATOR "/"
2656 translate_path (gchar **path)
2661 gboolean add_separator;
2663 parts = g_strsplit (*path, MOVE_TO_FOLDER_SEPARATOR, 0);
2667 output = g_string_new ("");
2668 add_separator = FALSE;
2670 while (*current != NULL) {
2671 TnyFolderType folder_type;
2674 if (add_separator) {
2675 output = g_string_append (output, MOVE_TO_FOLDER_SEPARATOR);
2677 add_separator = TRUE;
2680 downcase = g_ascii_strdown (*current, -1);
2681 folder_type = modest_local_folder_info_get_type (downcase);
2682 if (strcmp (downcase, "inbox") == 0) {
2683 output = g_string_append (output, _("mcen_me_folder_inbox"));
2684 } else if (folder_type == TNY_FOLDER_TYPE_ARCHIVE ||
2685 folder_type == TNY_FOLDER_TYPE_DRAFTS ||
2686 folder_type == TNY_FOLDER_TYPE_SENT ||
2687 folder_type == TNY_FOLDER_TYPE_OUTBOX) {
2688 output = g_string_append (output, modest_local_folder_info_get_type_display_name (folder_type));
2690 output = g_string_append (output, *current);
2698 *path = g_string_free (output, FALSE);
2702 move_to_dialog_set_selected_folder_store (GtkWidget *dialog,
2703 TnyFolderStore *folder_store)
2705 GtkWidget *action_button;
2706 GtkWidget *image = NULL;
2707 TnyAccount *account;
2708 gchar *account_name = NULL, *short_name = NULL;
2710 action_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2712 /* Get account name */
2713 if (TNY_IS_FOLDER (folder_store))
2714 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2716 account = g_object_ref (folder_store);
2718 if (modest_tny_account_is_virtual_local_folders (account))
2719 account_name = modest_conf_get_string (modest_runtime_get_conf(),
2720 MODEST_CONF_DEVICE_NAME, NULL);
2723 account_name = g_strdup (tny_account_get_name (account));
2725 g_object_unref (account);
2727 /* Set title of button: account or folder name */
2728 if (TNY_IS_FOLDER (folder_store))
2729 short_name = folder_store_get_display_name (folder_store);
2731 short_name = g_strdup (account_name);
2733 hildon_button_set_title (HILDON_BUTTON (action_button), short_name);
2735 /* Set value of button, folder full name */
2736 if (TNY_IS_CAMEL_FOLDER (folder_store)) {
2737 const gchar *camel_full_name;
2738 gchar *last_slash, *full_name;
2740 camel_full_name = tny_camel_folder_get_full_name (TNY_CAMEL_FOLDER (folder_store));
2741 last_slash = g_strrstr (camel_full_name, "/");
2743 gchar *prefix = g_strndup (camel_full_name, last_slash - camel_full_name + 1);
2744 full_name = g_strconcat (account_name, MOVE_TO_FOLDER_SEPARATOR, prefix, short_name, NULL);
2747 full_name = g_strconcat (account_name, MOVE_TO_FOLDER_SEPARATOR,
2751 translate_path (&full_name);
2752 hildon_button_set_value (HILDON_BUTTON (action_button), full_name);
2755 g_free (account_name);
2756 g_free (short_name);
2758 /* Set image for the button */
2759 image = get_image_for_folder_store (folder_store, MODEST_ICON_SIZE_BIG);
2761 hildon_button_set_image (HILDON_BUTTON (action_button), image);
2765 move_to_dialog_show_accounts (GtkWidget *dialog)
2767 GtkWidget *back_button;
2768 GtkWidget *folder_view;
2769 GtkWidget *pannable;
2770 GtkWidget *action_button;
2772 back_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON));
2773 action_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2774 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2775 pannable = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE));
2777 gtk_widget_set_sensitive (back_button, FALSE);
2778 gtk_widget_set_sensitive (action_button, FALSE);
2780 /* Need to set this here, otherwise callbacks called because
2781 of filtering won't perform correctly */
2782 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS, GINT_TO_POINTER (FALSE));
2784 /* Reset action button */
2785 hildon_button_set_title (HILDON_BUTTON (action_button), NULL);
2786 hildon_button_set_value (HILDON_BUTTON (action_button), NULL);
2787 hildon_button_set_image (HILDON_BUTTON (action_button), NULL);
2789 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (folder_view), NULL);
2790 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (folder_view), TRUE);
2791 modest_folder_view_set_style (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
2792 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2793 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2794 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2795 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2796 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2797 MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS);
2798 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2799 MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS);
2800 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
2804 move_to_dialog_show_folders (GtkWidget *dialog, TnyFolderStore *folder_store)
2806 GtkWidget *back_button;
2807 GtkWidget *folder_view;
2808 TnyAccount *account;
2809 const gchar *account_id;
2810 GtkWidget *pannable;
2811 GtkWidget *action_button;
2814 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON));
2816 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2818 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2820 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE));
2822 gtk_widget_set_sensitive (back_button, TRUE);
2823 gtk_widget_set_sensitive (action_button, TRUE);
2825 /* Need to set this here, otherwise callbacks called because
2826 of filtering won't perform correctly */
2827 g_object_set_data (G_OBJECT (dialog),
2828 MOVE_TO_DIALOG_SHOWING_FOLDERS,
2829 GINT_TO_POINTER (TRUE));
2831 account = TNY_ACCOUNT (folder_store);
2832 if (modest_tny_account_is_virtual_local_folders (account)) {
2833 account_id = tny_account_get_id (account);
2834 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2835 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2836 } else if (modest_tny_account_is_memory_card_account (account)) {
2837 account_id = tny_account_get_id (account);
2838 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2839 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2841 account_id = tny_account_get_id (account);
2842 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2843 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2844 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2845 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2848 move_to_dialog_set_selected_folder_store (dialog, folder_store);
2849 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (folder_view),
2852 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (folder_view), FALSE);
2853 modest_folder_view_set_style (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
2854 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS);
2855 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS);
2856 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
2860 on_move_to_dialog_back_clicked (GtkButton *button,
2863 GtkWidget *dialog = (GtkWidget *) userdata;
2865 /* Back to show accounts */
2866 move_to_dialog_show_accounts (dialog);
2870 on_move_to_dialog_row_activated (GtkTreeView *tree_view,
2872 GtkTreeViewColumn *column,
2875 TnyFolderStore *selected = NULL;
2877 GtkWidget *folder_view;
2878 gboolean showing_folders;
2880 dialog = (GtkWidget *) user_data;
2881 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog),
2882 MOVE_TO_DIALOG_SHOWING_FOLDERS));
2884 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
2885 MOVE_TO_DIALOG_FOLDER_VIEW));
2887 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2891 if (!showing_folders) {
2892 gboolean valid = TRUE;
2894 if (TNY_IS_ACCOUNT (selected) &&
2895 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (selected))) {
2896 ModestProtocolType protocol_type;
2898 protocol_type = modest_tny_account_get_protocol_type (TNY_ACCOUNT (selected));
2899 valid = !modest_protocol_registry_protocol_type_has_tag
2900 (modest_runtime_get_protocol_registry (),
2902 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
2905 move_to_dialog_show_folders (dialog, selected);
2907 move_to_dialog_set_selected_folder_store (dialog, selected);
2912 on_move_to_dialog_selection_changed (GtkTreeSelection *selection,
2915 gboolean showing_folders;
2918 dialog = (GtkWidget *) user_data;
2919 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS));
2920 if (showing_folders) {
2921 TnyFolderStore *selected;
2922 GtkWidget *folder_view;
2924 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2925 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2928 move_to_dialog_set_selected_folder_store (dialog, selected);
2929 g_object_unref (selected);
2935 on_move_to_dialog_action_clicked (GtkButton *selection,
2939 gboolean showing_folders;
2941 dialog = (GtkWidget *) user_data;
2942 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS));
2943 if (showing_folders) {
2944 TnyFolderStore *selected;
2945 GtkWidget *folder_view;
2947 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2948 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2951 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
2952 g_object_unref (selected);
2958 move_to_dialog_activity_changed (ModestFolderView *folder_view, gboolean activity, GtkDialog *dialog)
2960 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (dialog), activity?1:0);
2964 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
2965 GtkWidget **folder_view)
2967 GtkWidget *dialog, *folder_view_container;
2969 GtkWidget *buttons_hbox;
2970 GtkWidget *back_button;
2971 GdkPixbuf *back_pixbuf;
2972 GtkWidget *top_vbox;
2973 GtkWidget *action_button;
2974 GtkTreeSelection *selection;
2976 /* Create dialog. We cannot use a touch selector because we
2977 need to use here the folder view widget directly */
2978 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2979 GTK_WINDOW (parent_window),
2980 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
2981 GTK_DIALOG_DESTROY_WITH_PARENT,
2982 _HL("wdgt_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
2985 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
2986 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_NONE);
2987 top_vbox = gtk_vbox_new (FALSE, MODEST_MARGIN_HALF);
2989 /* Create folder view */
2990 *folder_view = modest_platform_create_folder_view_full (NULL, FALSE);
2991 g_signal_connect (G_OBJECT (*folder_view), "activity-changed", G_CALLBACK (move_to_dialog_activity_changed),
2994 modest_folder_view_set_cell_style (MODEST_FOLDER_VIEW (*folder_view),
2995 MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT);
2996 modest_folder_view_show_message_count (MODEST_FOLDER_VIEW (*folder_view),
2998 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (*folder_view),
2999 (TnyAccountStore *) modest_runtime_get_account_store ());
3001 buttons_hbox = gtk_hbox_new (FALSE, MODEST_MARGIN_HALF);
3002 back_button = gtk_button_new ();
3003 back_pixbuf = modest_platform_get_icon (_FM("filemanager_folder_up"), MODEST_ICON_SIZE_BIG);
3005 gtk_button_set_image (GTK_BUTTON (back_button), gtk_image_new_from_pixbuf (back_pixbuf));
3006 g_object_unref (back_pixbuf);
3009 action_button = hildon_button_new (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
3010 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
3011 gtk_button_set_alignment (GTK_BUTTON (action_button), 0.0, 0.5);
3013 gtk_box_pack_start (GTK_BOX (buttons_hbox), back_button, FALSE, FALSE, 0);
3014 gtk_box_pack_start (GTK_BOX (buttons_hbox), action_button, TRUE, TRUE, 0);
3015 gtk_widget_set_sensitive (GTK_WIDGET (back_button), FALSE);
3016 gtk_widget_set_sensitive (GTK_WIDGET (action_button), FALSE);
3017 gtk_box_pack_start (GTK_BOX (top_vbox), buttons_hbox, FALSE, FALSE, 0);
3019 /* Create pannable and add it to the dialog */
3020 folder_view_container = hildon_pannable_area_new ();
3021 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
3022 gtk_box_pack_start (GTK_BOX (top_vbox), folder_view_container, TRUE, TRUE, 0);
3024 gtk_container_add (GTK_CONTAINER (align), top_vbox);
3025 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 0);
3027 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3029 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
3030 gtk_widget_show (folder_view_container);
3031 gtk_widget_show (align);
3032 gtk_widget_show (top_vbox);
3033 gtk_widget_show (*folder_view);
3034 gtk_widget_show_all (back_button);
3035 gtk_widget_show (action_button);
3036 gtk_widget_show (buttons_hbox);
3037 gtk_widget_show (dialog);
3039 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW, *folder_view);
3040 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON, back_button);
3041 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON, action_button);
3042 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE, folder_view_container);
3044 /* Simulate the behaviour of a HildonPickerDialog by emitting
3045 a response when a folder is selected */
3046 g_signal_connect (*folder_view, "row-activated",
3047 G_CALLBACK (on_move_to_dialog_row_activated),
3050 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*folder_view));
3051 g_signal_connect (selection, "changed",
3052 G_CALLBACK (on_move_to_dialog_selection_changed),
3055 g_signal_connect (action_button, "clicked",
3056 G_CALLBACK (on_move_to_dialog_action_clicked),
3059 g_signal_connect (back_button, "clicked",
3060 G_CALLBACK (on_move_to_dialog_back_clicked),
3063 move_to_dialog_show_accounts (dialog);
3069 modest_platform_get_list_to_move (ModestWindow *window)
3071 TnyList *list = NULL;
3073 if (MODEST_IS_HEADER_WINDOW (window)) {
3074 ModestHeaderView *header_view;
3076 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
3077 list = modest_header_view_get_selected_headers (header_view);
3078 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3079 ModestFolderView *folder_view;
3080 TnyFolderStore *selected_folder;
3082 list = TNY_LIST (tny_simple_list_new ());
3083 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
3084 selected_folder = modest_folder_view_get_selected (folder_view);
3085 if (selected_folder) {
3086 tny_list_prepend (list, G_OBJECT (selected_folder));
3087 g_object_unref (selected_folder);
3090 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3093 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
3095 list = TNY_LIST (tny_simple_list_new ());
3096 tny_list_prepend (list, G_OBJECT (header));
3097 g_object_unref (header);
3100 g_return_val_if_reached (NULL);