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 "modest-hildon2-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 <modest-osso-autosave-callbacks.h>
43 #include <tny-maemo-conic-device.h>
44 #include <tny-simple-list.h>
45 #include <tny-folder.h>
46 #include <gtk/gtkicontheme.h>
47 #include <gtk/gtkmenuitem.h>
48 #include <gtk/gtkmain.h>
49 #include <modest-text-utils.h>
50 #include "modest-tny-folder.h"
51 #include "modest-tny-account.h"
53 #include <libgnomevfs/gnome-vfs-mime-utils.h>
54 #include <modest-account-settings-dialog.h>
55 #include <modest-easysetup-wizard-dialog.h>
56 #include "modest-hildon2-sort-dialog.h"
57 #include <hildon/hildon-sound.h>
59 #include "hildon2/modest-hildon2-details-dialog.h"
60 #include "hildon2/modest-hildon2-window-mgr.h"
61 #include <keys_nokia.h>
62 #include <libprofile.h>
64 #include <modest-datetime-formatter.h>
65 #include "modest-header-window.h"
66 #include <modest-folder-window.h>
67 #include <modest-account-mgr.h>
68 #include <modest-account-mgr-helpers.h>
69 #include <modest-ui-constants.h>
70 #include <modest-selector-picker.h>
71 #include <modest-icon-names.h>
73 #ifdef MODEST_HAVE_MCE
74 #include <mce/dbus-names.h>
75 #endif /*MODEST_HAVE_MCE*/
77 #ifdef MODEST_HAVE_ABOOK
78 #include <libosso-abook/osso-abook.h>
79 #endif /*MODEST_HAVE_ABOOK*/
81 #ifdef MODEST_HAVE_LIBALARM
82 #include <alarmd/libalarm.h> /* For alarm_event_add(), etc. */
83 #endif /*MODEST_HAVE_LIBALARM*/
86 #define HILDON_OSSO_URI_ACTION "uri-action"
87 #define URI_ACTION_COPY "copy:"
88 #define MODEST_NEW_MAIL_LIGHTING_PATTERN "PatternCommunicationEmail"
89 #define PROFILE_MAIL_TONE PROFILEKEY_EMAIL_ALERT_TONE
90 #define PROFILE_MAIL_VOLUME PROFILEKEY_EMAIL_ALERT_VOLUME
92 #define COMMON_FOLDER_DIALOG_ENTRY "entry"
93 #define COMMON_FOLDER_DIALOG_ACCOUNT_PICKER "account-picker"
94 #define FOLDER_PICKER_CURRENT_FOLDER "current-folder"
97 static void _modest_platform_play_email_tone (void);
101 on_modest_conf_update_interval_changed (ModestConf* self,
103 ModestConfEvent event,
104 ModestConfNotificationId id,
107 g_return_if_fail (key);
109 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
110 const guint update_interval_minutes =
111 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
112 modest_platform_set_update_interval (update_interval_minutes);
119 check_required_files (void)
121 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
123 g_printerr ("modest: check for mcc file failed\n");
128 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
129 access(MODEST_MAEMO_PROVIDER_DATA_FILE, R_OK) != 0) {
130 g_printerr ("modest: cannot find providers data\n");
138 /* the gpointer here is the osso_context. */
140 modest_platform_init (int argc, char *argv[])
142 osso_context_t *osso_context;
144 osso_hw_state_t hw_state = { 0 };
148 if (!check_required_files ()) {
149 g_printerr ("modest: missing required files\n");
153 osso_context = osso_initialize(PACKAGE,PACKAGE_VERSION,
156 g_printerr ("modest: failed to acquire osso context\n");
159 modest_maemo_utils_set_osso_context (osso_context);
161 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
162 g_printerr ("modest: could not get dbus connection\n");
166 /* Add a D-Bus handler to be used when the main osso-rpc
167 * D-Bus handler has not handled something.
168 * We use this for D-Bus methods that need to use more complex types
169 * than osso-rpc supports.
171 if (!dbus_connection_add_filter (con,
172 modest_dbus_req_filter,
176 g_printerr ("modest: Could not add D-Bus filter\n");
180 /* Register our simple D-Bus callbacks, via the osso API: */
181 osso_return_t result = osso_rpc_set_cb_f(osso_context,
185 modest_dbus_req_handler, NULL /* user_data */);
186 if (result != OSSO_OK) {
187 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
191 /* Register hardware event dbus callback: */
192 hw_state.shutdown_ind = TRUE;
193 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
195 /* Register osso auto-save callbacks: */
196 result = osso_application_set_autosave_cb (osso_context,
197 modest_on_osso_application_autosave, NULL /* user_data */);
198 if (result != OSSO_OK) {
199 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
204 /* Make sure that the update interval is changed whenever its gconf key
206 /* CAUTION: we're not using here the
207 modest_conf_listen_to_namespace because we know that there
208 are other parts of Modest listening for this namespace, so
209 we'll receive the notifications anyway. We basically do not
210 use it because there is no easy way to do the
211 modest_conf_forget_namespace */
212 ModestConf *conf = modest_runtime_get_conf ();
213 g_signal_connect (G_OBJECT(conf),
215 G_CALLBACK (on_modest_conf_update_interval_changed),
218 /* only force the setting of the default interval, if there are actually
220 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
222 /* Get the initial update interval from gconf: */
223 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
224 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
225 modest_account_mgr_free_account_names (acc_names);
229 #ifdef MODEST_HAVE_ABOOK
230 /* initialize the addressbook */
231 if (!osso_abook_init (&argc, &argv, osso_context)) {
232 g_printerr ("modest: failed to initialized addressbook\n");
235 #endif /*MODEST_HAVE_ABOOK*/
241 modest_platform_uninit (void)
243 osso_context_t *osso_context =
244 modest_maemo_utils_get_osso_context ();
246 osso_deinitialize (osso_context);
255 modest_platform_get_new_device (void)
257 return TNY_DEVICE (tny_maemo_conic_device_new ());
261 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
262 gchar **effective_mime_type)
264 GString *mime_str = NULL;
265 gchar *icon_name = NULL;
266 gchar **icons, **cursor;
268 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
269 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
271 mime_str = g_string_new (mime_type);
272 g_string_ascii_down (mime_str);
275 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
277 for (cursor = icons; cursor; ++cursor) {
278 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
279 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
280 icon_name = g_strdup ("qgn_list_messagin");
282 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
283 icon_name = g_strdup (*cursor);
289 if (effective_mime_type)
290 *effective_mime_type = g_string_free (mime_str, FALSE);
292 g_string_free (mime_str, TRUE);
299 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
304 g_return_val_if_fail (uri, FALSE);
306 result = hildon_uri_open (uri, action, &err);
308 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
309 uri, action, err && err->message ? err->message : "unknown error");
319 modest_platform_activate_uri (const gchar *uri)
321 HildonURIAction *action;
322 gboolean result = FALSE;
323 GSList *actions, *iter = NULL;
325 g_return_val_if_fail (uri, FALSE);
329 /* don't try to activate file: uri's -- they might confuse the user,
330 * and/or might have security implications */
331 if (!g_str_has_prefix (uri, "file:")) {
333 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
335 for (iter = actions; iter; iter = g_slist_next (iter)) {
336 action = (HildonURIAction*) iter->data;
337 if (action && strcmp (hildon_uri_action_get_service (action),
338 "com.nokia.modest") == 0) {
339 result = checked_hildon_uri_open (uri, action);
344 /* if we could not open it with email, try something else */
346 result = checked_hildon_uri_open (uri, NULL);
350 ModestWindow *parent =
351 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
352 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
353 _("mcen_ib_unsupported_link"));
354 g_warning ("%s: cannot open uri '%s'", __FUNCTION__,uri);
361 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
365 gchar *uri_path = NULL;
367 uri_path = gnome_vfs_get_uri_from_local_path (path);
368 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
371 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
373 result = hildon_mime_open_file (con, uri_path);
375 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
383 } ModestPlatformPopupInfo;
386 delete_uri_popup (GtkWidget *menu,
390 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
392 g_free (popup_info->uri);
393 hildon_uri_free_actions (popup_info->actions);
399 activate_uri_popup_item (GtkMenuItem *menu_item,
403 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
404 const gchar* action_name;
406 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
408 g_printerr ("modest: no action name defined\n");
412 /* special handling for the copy menu item -- copy the uri to the clipboard */
413 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
414 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
415 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
416 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
418 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
419 action_name += strlen ("mailto:");
421 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
422 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
423 return; /* we're done */
426 /* now, the real uri-actions... */
427 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
428 HildonURIAction *action = (HildonURIAction *) node->data;
429 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
430 if (!checked_hildon_uri_open (popup_info->uri, action)) {
431 ModestWindow *parent =
432 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
433 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
434 _("mcen_ib_unsupported_link"));
442 modest_platform_show_uri_popup (const gchar *uri)
444 GSList *actions_list;
449 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
452 GtkWidget *menu = gtk_menu_new ();
453 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
455 /* don't add actions for file: uri's -- they might confuse the user,
456 * and/or might have security implications
457 * we still allow to copy the url though
459 if (!g_str_has_prefix (uri, "file:")) {
462 popup_info->actions = actions_list;
463 popup_info->uri = g_strdup (uri);
465 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
466 GtkWidget *menu_item;
467 const gchar *action_name;
468 const gchar *translation_domain;
469 HildonURIAction *action = (HildonURIAction *) node->data;
470 action_name = hildon_uri_action_get_name (action);
471 translation_domain = hildon_uri_action_get_translation_domain (action);
472 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
473 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
474 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
477 if (hildon_uri_is_default_action (action, NULL)) {
478 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
480 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
482 gtk_widget_show (menu_item);
486 /* always add the copy item */
487 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri",
488 "uri_link_copy_link_location"));
489 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
490 g_strconcat (URI_ACTION_COPY, uri, NULL),
492 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
493 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
494 gtk_widget_show (menu_item);
497 /* and what to do when the link is deleted */
498 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
499 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
502 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
510 modest_platform_get_icon (const gchar *name, guint icon_size)
513 GdkPixbuf* pixbuf = NULL;
514 GtkIconTheme *current_theme = NULL;
516 g_return_val_if_fail (name, NULL);
518 /* strlen == 0 is not really an error; it just
519 * means the icon is not available
521 if (!name || strlen(name) == 0)
524 current_theme = gtk_icon_theme_get_default ();
525 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
526 GTK_ICON_LOOKUP_NO_SVG,
529 g_printerr ("modest: error loading theme icon '%s': %s\n",
537 modest_platform_get_app_name (void)
539 return _("mcen_ap_name");
543 entry_insert_text (GtkEditable *editable,
552 chars = gtk_editable_get_chars (editable, 0, -1);
553 chars_length = g_utf8_strlen (chars, -1);
556 /* Show WID-INF036 */
557 if (chars_length >= 20) {
558 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
559 _CS("ckdg_ib_maximum_characters_reached"));
561 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
565 tmp = g_strndup (folder_name_forbidden_chars,
566 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
567 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
568 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
573 /* Write the text in the entry if it's valid */
574 g_signal_handlers_block_by_func (editable,
575 (gpointer) entry_insert_text, data);
576 gtk_editable_insert_text (editable, text, length, position);
577 g_signal_handlers_unblock_by_func (editable,
578 (gpointer) entry_insert_text, data);
581 /* Do not allow further processing */
582 g_signal_stop_emission_by_name (editable, "insert_text");
586 entry_changed (GtkEditable *editable,
590 GtkWidget *ok_button;
593 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
594 ok_button = GTK_WIDGET (buttons->data);
596 chars = gtk_editable_get_chars (editable, 0, -1);
597 g_return_if_fail (chars != NULL);
600 if (g_utf8_strlen (chars,-1) >= 20)
601 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
602 _CS("ckdg_ib_maximum_characters_reached"));
604 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
607 g_list_free (buttons);
614 on_response (GtkDialog *dialog,
618 GtkWidget *entry, *picker;
619 TnyFolderStore *parent;
620 const gchar *new_name;
623 if (response != GTK_RESPONSE_ACCEPT)
627 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
628 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
630 parent = TNY_FOLDER_STORE (user_data);
631 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
634 if (picker != NULL) {
636 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
639 /* Look for another folder with the same name */
640 if (modest_tny_folder_has_subfolder_with_name (parent,
647 if (TNY_IS_ACCOUNT (parent) &&
648 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
649 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
658 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
659 NULL, _CS("ckdg_ib_folder_already_exists"));
660 /* Select the text */
661 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
662 gtk_widget_grab_focus (entry);
663 /* Do not close the dialog */
664 g_signal_stop_emission_by_name (dialog, "response");
669 typedef struct _FolderChooserData {
670 TnyFolderStore *store;
675 folder_chooser_activated (ModestFolderView *folder_view,
676 TnyFolderStore *folder,
677 FolderChooserData *userdata)
679 userdata->store = folder;
680 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
683 static TnyFolderStore *
684 folder_chooser_dialog_run (ModestFolderView *original)
686 GtkWidget *folder_view;
687 FolderChooserData userdata = {NULL, NULL};
689 const gchar *visible_id = NULL;
691 userdata.dialog = hildon_dialog_new ();
692 pannable = hildon_pannable_area_new ();
693 folder_view = modest_platform_create_folder_view (NULL);
694 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
695 MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS);
697 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original), MODEST_FOLDER_VIEW (folder_view));
700 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original));
701 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
704 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
705 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
706 gtk_widget_set_size_request (pannable, -1, 320);
708 gtk_widget_show (folder_view);
709 gtk_widget_show (pannable);
710 gtk_widget_show (userdata.dialog);
711 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
712 G_CALLBACK (folder_chooser_activated),
713 (gpointer) &userdata);
715 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
716 gtk_widget_destroy (userdata.dialog);
718 return userdata.store;
722 folder_store_get_display_name (TnyFolderStore *store)
724 if (TNY_IS_ACCOUNT (store)) {
725 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
728 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
730 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
731 type = tny_folder_get_folder_type (TNY_FOLDER (store));
732 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
733 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
734 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
735 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
737 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
740 /* Sometimes an special folder is reported by the server as
741 NORMAL, like some versions of Dovecot */
742 if (type == TNY_FOLDER_TYPE_NORMAL ||
743 type == TNY_FOLDER_TYPE_UNKNOWN) {
744 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
748 if (type == TNY_FOLDER_TYPE_INBOX) {
750 fname = g_strdup (_("mcen_me_folder_inbox"));
757 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
762 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
764 g_object_ref (store);
765 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
766 store, (GDestroyNotify) g_object_unref);
767 name = folder_store_get_display_name (store);
768 hildon_button_set_value (HILDON_BUTTON (button), name);
774 folder_picker_clicked (GtkButton *button,
775 ModestFolderView *folder_view)
777 TnyFolderStore *store;
779 store = folder_chooser_dialog_run (folder_view);
781 folder_picker_set_store (GTK_BUTTON (button), store);
786 folder_picker_new (ModestFolderView *folder_view, TnyFolderStore *suggested)
791 button = hildon_button_new (MODEST_EDITABLE_SIZE,
792 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
793 pixbuf = modest_platform_get_icon (MODEST_FOLDER_ICON_NORMAL,
794 MODEST_ICON_SIZE_SMALL);
796 hildon_button_set_image (HILDON_BUTTON (button),
797 gtk_image_new_from_pixbuf (pixbuf));
798 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
801 folder_picker_set_store (GTK_BUTTON (button), suggested);
804 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (folder_picker_clicked), folder_view);
811 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
812 TnyFolderStore *suggested_parent,
813 const gchar *dialog_title,
814 const gchar *label_text,
815 const gchar *suggested_name,
817 gboolean show_parent,
819 TnyFolderStore **parent)
821 GtkWidget *accept_btn = NULL;
822 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
823 GtkWidget *account_picker = NULL;
824 GList *buttons = NULL;
826 GtkSizeGroup *sizegroup;
827 ModestFolderView *folder_view;
828 ModestWindow *folder_window;
829 ModestHildon2WindowMgr *window_mgr;
831 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
832 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
833 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
835 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
837 /* Ask the user for the folder name */
838 dialog = gtk_dialog_new_with_buttons (dialog_title,
840 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
841 _FM("ckdg_bd_new_folder_dialog_ok"),
845 /* Add accept button (with unsensitive handler) */
846 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
847 accept_btn = GTK_WIDGET (buttons->data);
849 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
852 label_entry = gtk_label_new (label_text);
853 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
854 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
856 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
857 gtk_size_group_add_widget (sizegroup, label_entry);
860 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
862 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
863 gtk_entry_set_width_chars (GTK_ENTRY (entry),
864 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
865 g_utf8_strlen (_("mcen_ia_default_folder_name"), -1)));
866 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
871 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
873 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
874 gtk_size_group_add_widget (sizegroup, label_location);
876 account_picker = folder_picker_new (folder_view, suggested_parent);
879 g_object_unref (sizegroup);
881 /* Connect to the response method to avoid closing the dialog
882 when an invalid name is selected*/
883 g_signal_connect (dialog,
885 G_CALLBACK (on_response),
889 /* Track entry changes */
890 g_signal_connect (entry,
892 G_CALLBACK (entry_insert_text),
894 g_signal_connect (entry,
896 G_CALLBACK (entry_changed),
901 /* Some locales like pt_BR need this to get the full window
903 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
905 /* Create the hbox */
907 hbox = gtk_hbox_new (FALSE, 12);
908 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
909 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
911 /* Add hbox to dialog */
912 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
913 hbox, FALSE, FALSE, 0);
914 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
918 hbox = gtk_hbox_new (FALSE, 12);
919 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
920 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
922 /* Add hbox to dialog */
923 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
924 hbox, FALSE, FALSE, 0);
925 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
927 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
928 GTK_WINDOW (dialog), parent_window);
929 gtk_widget_show_all (GTK_WIDGET(dialog));
931 result = gtk_dialog_run (GTK_DIALOG(dialog));
932 if (result == GTK_RESPONSE_ACCEPT) {
934 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
936 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
938 g_object_ref (*parent);
942 gtk_widget_destroy (dialog);
944 while (gtk_events_pending ())
945 gtk_main_iteration ();
951 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
952 TnyFolderStore *suggested_folder,
953 gchar *suggested_name,
955 TnyFolderStore **parent_folder)
957 gchar *real_suggested_name = NULL, *tmp = NULL;
959 ModestTnyAccountStore *acc_store;
962 if(suggested_name == NULL)
964 const gchar *default_name = _("mcen_ia_default_folder_name");
968 for(i = 0; i < 100; ++ i) {
969 gboolean exists = FALSE;
971 sprintf(num_str, "%.2u", i);
974 real_suggested_name = g_strdup (default_name);
976 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
978 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
985 g_free (real_suggested_name);
988 /* Didn't find a free number */
990 real_suggested_name = g_strdup (default_name);
992 real_suggested_name = suggested_name;
995 /* In hildon 2.2 we always suggest the archive folder as parent */
996 acc_store = modest_runtime_get_account_store ();
997 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
999 suggested_folder = (TnyFolderStore *)
1000 modest_tny_account_get_special_folder (account,
1001 TNY_FOLDER_TYPE_ARCHIVE);
1002 g_object_unref (account);
1006 /* If there is not archive folder then fallback to local folders account */
1007 if (!suggested_folder)
1008 suggested_folder = (TnyFolderStore *)
1009 modest_tny_account_store_get_local_folders_account (acc_store);
1011 tmp = g_strconcat (_("mcen_fi_new_folder_name"), ":", NULL);
1012 result = modest_platform_run_folder_common_dialog (parent_window,
1014 _("mcen_ti_new_folder"),
1016 real_suggested_name,
1023 if (suggested_name == NULL)
1024 g_free(real_suggested_name);
1030 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1031 TnyFolderStore *parent_folder,
1032 const gchar *suggested_name,
1033 gchar **folder_name)
1035 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1037 return modest_platform_run_folder_common_dialog (parent_window,
1039 _HL("ckdg_ti_rename_folder"),
1040 _HL("ckdg_fi_rename_name"),
1051 on_destroy_dialog (GtkWidget *dialog)
1053 /* This could happen when the dialogs get programatically
1054 hidden or destroyed (for example when closing the
1055 application while a dialog is being shown) */
1056 if (!GTK_IS_WIDGET (dialog))
1059 gtk_widget_destroy (dialog);
1061 if (gtk_events_pending ())
1062 gtk_main_iteration ();
1066 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1067 const gchar *message)
1072 dialog = hildon_note_new_confirmation (parent_window, message);
1073 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1074 GTK_WINDOW (dialog), parent_window);
1076 response = gtk_dialog_run (GTK_DIALOG (dialog));
1078 on_destroy_dialog (dialog);
1084 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1085 const gchar *message,
1086 const gchar *button_accept,
1087 const gchar *button_cancel)
1092 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1093 button_accept, GTK_RESPONSE_ACCEPT,
1094 button_cancel, GTK_RESPONSE_CANCEL,
1097 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1098 GTK_WINDOW (dialog), parent_window);
1100 response = gtk_dialog_run (GTK_DIALOG (dialog));
1102 on_destroy_dialog (dialog);
1108 modest_platform_run_information_dialog (GtkWindow *parent_window,
1109 const gchar *message,
1114 note = hildon_note_new_information (parent_window, message);
1116 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1117 GTK_WINDOW (note), parent_window);
1120 gtk_dialog_run (GTK_DIALOG (note));
1122 on_destroy_dialog (note);
1124 g_signal_connect_swapped (note,
1126 G_CALLBACK (on_destroy_dialog),
1129 gtk_widget_show_all (note);
1133 typedef struct _ConnectAndWaitData {
1135 GMainLoop *wait_loop;
1136 gboolean has_callback;
1138 } ConnectAndWaitData;
1142 quit_wait_loop (TnyAccount *account,
1143 ConnectAndWaitData *data)
1145 /* Set the has_callback to TRUE (means that the callback was
1146 executed and wake up every code waiting for cond to be
1148 g_mutex_lock (data->mutex);
1149 data->has_callback = TRUE;
1150 if (data->wait_loop)
1151 g_main_loop_quit (data->wait_loop);
1152 g_mutex_unlock (data->mutex);
1156 on_connection_status_changed (TnyAccount *account,
1157 TnyConnectionStatus status,
1160 TnyConnectionStatus conn_status;
1161 ConnectAndWaitData *data;
1163 /* Ignore if reconnecting or disconnected */
1164 conn_status = tny_account_get_connection_status (account);
1165 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1166 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1169 /* Remove the handler */
1170 data = (ConnectAndWaitData *) user_data;
1171 g_signal_handler_disconnect (account, data->handler);
1173 /* Quit from wait loop */
1174 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1178 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1183 /* Quit from wait loop */
1184 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1188 modest_platform_connect_and_wait (GtkWindow *parent_window,
1189 TnyAccount *account)
1191 ConnectAndWaitData *data = NULL;
1192 gboolean device_online;
1194 TnyConnectionStatus conn_status;
1195 gboolean user_requested;
1197 device = modest_runtime_get_device();
1198 device_online = tny_device_is_online (device);
1200 /* Whether the connection is user requested or automatically
1201 requested, for example via D-Bus */
1202 user_requested = (parent_window) ? TRUE : FALSE;
1204 /* If there is no account check only the device status */
1209 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1210 NULL, user_requested);
1213 /* Return if the account is already connected */
1214 conn_status = tny_account_get_connection_status (account);
1215 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1218 /* Create the helper */
1219 data = g_slice_new0 (ConnectAndWaitData);
1220 data->mutex = g_mutex_new ();
1221 data->has_callback = FALSE;
1223 /* Connect the device */
1224 if (!device_online) {
1225 /* Track account connection status changes */
1226 data->handler = g_signal_connect (account, "connection-status-changed",
1227 G_CALLBACK (on_connection_status_changed),
1229 /* Try to connect the device */
1230 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1231 NULL, user_requested);
1233 /* If the device connection failed then exit */
1234 if (!device_online && data->handler)
1237 /* Force a reconnection of the account */
1238 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1239 on_tny_camel_account_set_online_cb, data);
1242 /* Wait until the callback is executed */
1243 g_mutex_lock (data->mutex);
1244 if (!data->has_callback) {
1245 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1246 gdk_threads_leave ();
1247 g_mutex_unlock (data->mutex);
1248 g_main_loop_run (data->wait_loop);
1249 g_mutex_lock (data->mutex);
1250 gdk_threads_enter ();
1252 g_mutex_unlock (data->mutex);
1256 if (g_signal_handler_is_connected (account, data->handler))
1257 g_signal_handler_disconnect (account, data->handler);
1258 g_mutex_free (data->mutex);
1259 g_main_loop_unref (data->wait_loop);
1260 g_slice_free (ConnectAndWaitData, data);
1263 conn_status = tny_account_get_connection_status (account);
1264 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1268 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1270 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1271 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1272 /* This must be a maildir account, which does not require a connection: */
1277 return modest_platform_connect_and_wait (parent_window, account);
1281 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1284 return TRUE; /* Maybe it is something local. */
1286 gboolean result = TRUE;
1287 if (TNY_IS_FOLDER (folder_store)) {
1288 /* Get the folder's parent account: */
1289 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1290 if (account != NULL) {
1291 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1292 g_object_unref (account);
1294 } else if (TNY_IS_ACCOUNT (folder_store)) {
1295 /* Use the folder store as an account: */
1296 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1303 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1307 dialog = modest_hildon2_sort_dialog_new (parent_window);
1314 modest_platform_set_update_interval (guint minutes)
1316 #ifdef MODEST_HAVE_LIBALARM
1318 ModestConf *conf = modest_runtime_get_conf ();
1322 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1324 /* Delete any existing alarm,
1325 * because we will replace it: */
1327 if (alarmd_event_del(alarm_cookie) != 1)
1328 g_warning ("%s: alarm %d was not on the queue", __FUNCTION__, (int)alarm_cookie);
1330 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1333 /* 0 means no updates: */
1338 /* Register alarm: */
1340 /* Set the interval in alarm_event_t structure: */
1341 alarm_event_t *event = alarm_event_create ();
1342 alarm_event_add_actions (event, 1);
1343 alarm_action_t *action = alarm_event_get_action (event, 0);
1344 event->alarm_time = minutes * 60; /* seconds */
1346 /* Set recurrence every few minutes: */
1347 event->recur_secs = minutes*60;
1348 event->recur_count = -1; /* Means infinite */
1350 /* Specify what should happen when the alarm happens:
1351 * It should call this D-Bus method: */
1353 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1354 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1355 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1356 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1357 action->flags = ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1359 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1360 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1361 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1362 * This is why we want to use the Alarm API instead of just g_timeout_add().
1363 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1364 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1366 event->flags = ALARM_EVENT_CONNECTED;
1368 alarm_cookie = alarmd_event_add (event);
1371 alarm_event_delete (event);
1373 /* Store the alarm ID in GConf, so we can remove it later:
1374 * This is apparently valid between application instances. */
1375 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1377 if (!alarm_cookie) {
1379 g_debug ("Error setting alarm event. \n");
1383 #endif /* MODEST_HAVE_LIBALARM */
1388 modest_platform_push_email_notification(void)
1390 gboolean screen_on, app_in_foreground;
1392 /* Get the window status */
1393 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1395 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1397 /* If the screen is on and the app is in the
1398 foreground we don't show anything */
1399 if (!(screen_on && app_in_foreground)) {
1401 _modest_platform_play_email_tone ();
1403 /* Activate LED. This must be deactivated by
1404 modest_platform_remove_new_mail_notifications */
1405 #ifdef MODEST_HAVE_MCE
1406 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1410 MCE_ACTIVATE_LED_PATTERN,
1412 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1419 modest_platform_on_new_headers_received (TnyList *header_list,
1420 gboolean show_visual)
1422 g_return_if_fail (TNY_IS_LIST(header_list));
1424 if (tny_list_get_length(header_list) == 0) {
1425 g_warning ("%s: header list is empty", __FUNCTION__);
1430 modest_platform_push_email_notification ();
1431 /* We do a return here to avoid indentation with an else */
1435 #ifdef MODEST_HAVE_HILDON_NOTIFY
1436 HildonNotification *notification;
1438 GSList *notifications_list = NULL;
1440 /* Get previous notifications ids */
1441 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1442 MODEST_CONF_NOTIFICATION_IDS,
1443 MODEST_CONF_VALUE_INT, NULL);
1445 iter = tny_list_create_iterator (header_list);
1446 while (!tny_iterator_is_done (iter)) {
1447 gchar *url = NULL, *display_address = NULL, *summary = NULL;
1448 const gchar *display_date;
1449 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1450 TnyFolder *folder = tny_header_get_folder (header);
1451 gboolean first_notification = TRUE;
1454 ModestDatetimeFormatter *datetime_formatter;
1456 /* constant string, don't free */
1457 datetime_formatter = modest_datetime_formatter_new ();
1458 display_date = modest_datetime_formatter_display_datetime (datetime_formatter,
1459 tny_header_get_date_received (header));
1460 g_object_unref (datetime_formatter);
1462 display_address = tny_header_dup_from (header);
1463 /* string is changed in-place */
1464 modest_text_utils_get_display_address (display_address);
1466 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1467 str = tny_header_dup_subject (header);
1468 notification = hildon_notification_new (summary,
1470 "qgn_list_messagin",
1473 /* Create the message URL */
1474 str = tny_header_dup_uid (header);
1475 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1479 hildon_notification_add_dbus_action(notification,
1482 MODEST_DBUS_SERVICE,
1485 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1489 /* Play sound if the user wants. Show the LED
1490 pattern. Show and play just one */
1491 if (G_UNLIKELY (first_notification)) {
1492 gchar *active_profile;
1495 gint mail_volume_int;
1497 first_notification = FALSE;
1499 active_profile = profile_get_profile ();
1500 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
1501 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
1502 mail_volume_int = profile_parse_int (mail_volume);
1504 if (mail_volume_int > 0)
1505 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1506 "sound-file", mail_tone);
1508 g_free (mail_volume);
1510 g_free (active_profile);
1512 /* Set the led pattern */
1513 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1515 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1517 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1520 /* Notify. We need to do this in an idle because this function
1521 could be called from a thread */
1522 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1524 /* Save id in the list */
1525 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1526 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1527 /* We don't listen for the "closed" signal, because we
1528 don't care about if the notification was removed or
1529 not to store the list in gconf */
1531 /* Free & carry on */
1532 g_free (display_address);
1535 g_object_unref (folder);
1536 g_object_unref (header);
1537 tny_iterator_next (iter);
1539 g_object_unref (iter);
1542 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1543 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1545 g_slist_free (notifications_list);
1547 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1551 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1554 #ifdef MODEST_HAVE_MCE
1555 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1559 MCE_DEACTIVATE_LED_PATTERN,
1561 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1567 #ifdef MODEST_HAVE_HILDON_NOTIFY
1568 GSList *notif_list = NULL;
1570 /* Get previous notifications ids */
1571 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1572 MODEST_CONF_NOTIFICATION_IDS,
1573 MODEST_CONF_VALUE_INT, NULL);
1575 while (notif_list) {
1577 NotifyNotification *notif;
1579 /* Nasty HACK to remove the notifications, set the id
1580 of the existing ones and then close them */
1581 notif_id = GPOINTER_TO_INT(notif_list->data);
1582 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1583 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1585 /* Close the notification, note that some ids could be
1586 already invalid, but we don't care because it does
1588 notify_notification_close(notif, NULL);
1589 g_object_unref(notif);
1591 /* Delete the link, it's like going to the next */
1592 notif_list = g_slist_delete_link (notif_list, notif_list);
1596 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1597 notif_list, MODEST_CONF_VALUE_INT, NULL);
1599 g_slist_free (notif_list);
1601 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1607 modest_platform_get_global_settings_dialog ()
1609 return modest_hildon2_global_settings_dialog_new ();
1613 modest_platform_show_help (GtkWindow *parent_window,
1614 const gchar *help_id)
1620 modest_platform_show_search_messages (GtkWindow *parent_window)
1622 osso_return_t result = OSSO_ERROR;
1624 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1625 "osso_global_search",
1626 "search_email", NULL, DBUS_TYPE_INVALID);
1628 if (result != OSSO_OK) {
1629 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1634 modest_platform_show_addressbook (GtkWindow *parent_window)
1636 osso_return_t result = OSSO_ERROR;
1638 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1640 "top_application", NULL, DBUS_TYPE_INVALID);
1642 if (result != OSSO_OK) {
1643 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1648 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1650 GtkWidget *widget = modest_folder_view_new (query);
1652 /* Show one account by default */
1653 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1654 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1656 /* Restore settings */
1657 modest_widget_memory_restore (modest_runtime_get_conf(),
1659 MODEST_CONF_FOLDER_VIEW_KEY);
1665 banner_finish (gpointer data, GObject *object)
1667 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1668 modest_window_mgr_unregister_banner (mgr);
1669 g_object_unref (mgr);
1673 modest_platform_information_banner (GtkWidget *parent,
1674 const gchar *icon_name,
1677 GtkWidget *banner, *banner_parent = NULL;
1678 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1680 if (modest_window_mgr_get_num_windows (mgr) == 0)
1683 if (parent && GTK_IS_WINDOW (parent)) {
1684 /* If the window is the active one then show the
1685 banner on top of this window */
1686 if (gtk_window_is_active (GTK_WINDOW (parent)))
1687 banner_parent = parent;
1688 /* If the window is not the topmost but it's visible
1689 (it's minimized for example) then show the banner
1691 else if (GTK_WIDGET_VISIBLE (parent))
1692 banner_parent = NULL;
1693 /* If the window is hidden (like the main window when
1694 running in the background) then do not show
1701 banner = hildon_banner_show_information (banner_parent, icon_name, text);
1703 modest_window_mgr_register_banner (mgr);
1705 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1709 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1710 const gchar *icon_name,
1716 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1719 banner = hildon_banner_show_information (parent, icon_name, text);
1720 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1724 modest_platform_animation_banner (GtkWidget *parent,
1725 const gchar *animation_name,
1728 GtkWidget *inf_note = NULL;
1730 g_return_val_if_fail (text != NULL, NULL);
1732 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1735 /* If the parent is not visible then do not show */
1736 if (parent && !GTK_WIDGET_VISIBLE (parent))
1739 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1747 TnyAccount *account;
1750 } CheckAccountIdleData;
1752 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1755 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1757 gboolean stop_trying = FALSE;
1758 g_return_val_if_fail (data && data->account, FALSE);
1760 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__,
1761 tny_account_get_connection_status (data->account));
1763 if (data && data->account &&
1764 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1765 * after which the account is likely to be usable, or never likely to be usable soon: */
1766 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1768 data->is_online = TRUE;
1772 /* Give up if we have tried too many times: */
1773 if (data->count_tries >= NUMBER_OF_TRIES) {
1776 /* Wait for another timeout: */
1777 ++(data->count_tries);
1782 /* Allow the function that requested this idle callback to continue: */
1784 g_main_loop_quit (data->loop);
1787 g_object_unref (data->account);
1789 return FALSE; /* Don't call this again. */
1791 return TRUE; /* Call this timeout callback again. */
1795 /* Return TRUE immediately if the account is already online,
1796 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1797 * soon as the account is online, or FALSE if the account does
1798 * not become online in the NUMBER_OF_TRIES seconds.
1799 * This is useful when the D-Bus method was run immediately after
1800 * the application was started (when using D-Bus activation),
1801 * because the account usually takes a short time to go online.
1802 * The return value is maybe not very useful.
1805 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1809 g_return_val_if_fail (account, FALSE);
1811 if (!tny_device_is_online (modest_runtime_get_device())) {
1812 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1816 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1817 * so we avoid wait unnecessarily: */
1818 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1821 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1822 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1823 * we want to avoid. */
1824 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1827 /* This blocks on the result: */
1828 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1829 data->is_online = FALSE;
1830 data->account = account;
1831 g_object_ref (data->account);
1832 data->count_tries = 0;
1834 GMainContext *context = NULL; /* g_main_context_new (); */
1835 data->loop = g_main_loop_new (context, FALSE /* not running */);
1837 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
1839 /* This main loop will run until the idle handler has stopped it: */
1840 g_main_loop_run (data->loop);
1842 g_main_loop_unref (data->loop);
1843 /* g_main_context_unref (context); */
1845 is_online = data->is_online;
1846 g_slice_free (CheckAccountIdleData, data);
1854 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1856 /* GTK_RESPONSE_HELP means we need to show the certificate */
1857 if (response_id == GTK_RESPONSE_APPLY) {
1861 /* Do not close the dialog */
1862 g_signal_stop_emission_by_name (dialog, "response");
1864 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1865 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1866 gtk_dialog_run (GTK_DIALOG(note));
1867 gtk_widget_destroy (note);
1873 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
1874 const gchar *certificate)
1879 HildonWindowStack *stack;
1881 stack = hildon_window_stack_get_default ();
1882 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1885 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1890 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1893 /* We use GTK_RESPONSE_APPLY because we want the button in the
1894 middle of OK and CANCEL the same as the browser does for
1895 example. With GTK_RESPONSE_HELP the view button is aligned
1896 to the left while the other two to the right */
1897 note = hildon_note_new_confirmation_add_buttons (
1900 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
1901 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
1902 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
1905 g_signal_connect (G_OBJECT(note), "response",
1906 G_CALLBACK(on_cert_dialog_response),
1907 (gpointer) certificate);
1909 response = gtk_dialog_run(GTK_DIALOG(note));
1911 on_destroy_dialog (note);
1914 return response == GTK_RESPONSE_OK;
1918 modest_platform_run_alert_dialog (const gchar* prompt,
1919 gboolean is_question)
1921 ModestWindow *top_win;
1922 HildonWindowStack *stack;
1924 stack = hildon_window_stack_get_default ();
1925 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1928 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1933 gboolean retval = TRUE;
1935 /* The Tinymail documentation says that we should show Yes and No buttons,
1936 * when it is a question.
1937 * Obviously, we need tinymail to use more specific error codes instead,
1938 * so we know what buttons to show. */
1939 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
1941 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1942 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
1944 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1945 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1947 on_destroy_dialog (dialog);
1949 /* Just show the error text and use the default response: */
1950 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
1958 GtkWindow *parent_window;
1959 ModestConnectedPerformer callback;
1960 TnyAccount *account;
1967 on_went_online_info_free (OnWentOnlineInfo *info)
1969 /* And if we cleanup, we DO cleanup :-) */
1972 g_object_unref (info->device);
1975 if (info->parent_window)
1976 g_object_unref (info->parent_window);
1978 g_object_unref (info->account);
1980 g_slice_free (OnWentOnlineInfo, info);
1982 /* We're done ... */
1988 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
1990 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
1992 /* Now it's really time to callback to the caller. If going online didn't succeed,
1993 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
1994 * canceled will be set. Etcetera etcetera. */
1996 if (info->callback) {
1997 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2000 /* This is our last call, we must cleanup here if we didn't yet do that */
2001 on_went_online_info_free (info);
2008 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2010 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2011 info->iap = g_strdup (iap_id);
2013 if (canceled || err || !info->account) {
2015 /* If there's a problem or if there's no account (then that's it for us, we callback
2016 * the caller's callback now. He'll have to handle err or canceled, of course.
2017 * We are not really online, as the account is not really online here ... */
2019 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2020 * this info. We don't cleanup err, Tinymail does that! */
2022 if (info->callback) {
2024 /* info->account can be NULL here, this means that the user did not
2025 * provide a nice account instance. We'll assume that the user knows
2026 * what he's doing and is happy with just the device going online.
2028 * We can't do magic, we don't know what account the user wants to
2029 * see going online. So just the device goes online, end of story */
2031 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2034 } else if (info->account) {
2036 /* If there's no problem and if we have an account, we'll put the account
2037 * online too. When done, the callback of bringing the account online
2038 * will callback the caller's callback. This is the most normal case. */
2040 info->device = TNY_DEVICE (g_object_ref (device));
2042 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2043 on_account_went_online, info);
2045 /* The on_account_went_online cb frees up the info, go look if you
2046 * don't believe me! (so we return here) */
2051 /* We cleanup if we are not bringing the account online too */
2052 on_went_online_info_free (info);
2058 modest_platform_connect_and_perform (GtkWindow *parent_window,
2060 TnyAccount *account,
2061 ModestConnectedPerformer callback,
2064 gboolean device_online;
2066 TnyConnectionStatus conn_status;
2067 OnWentOnlineInfo *info;
2069 device = modest_runtime_get_device();
2070 device_online = tny_device_is_online (device);
2072 /* If there is no account check only the device status */
2075 if (device_online) {
2077 /* We promise to instantly perform the callback, so ... */
2079 callback (FALSE, NULL, parent_window, account, user_data);
2084 info = g_slice_new0 (OnWentOnlineInfo);
2087 info->device = NULL;
2088 info->account = NULL;
2091 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2093 info->parent_window = NULL;
2094 info->user_data = user_data;
2095 info->callback = callback;
2097 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2098 force, on_conic_device_went_online,
2101 /* We'll cleanup in on_conic_device_went_online */
2104 /* The other code has no more reason to run. This is all that we can do for the
2105 * caller (he should have given us a nice and clean account instance!). We
2106 * can't do magic, we don't know what account he intends to bring online. So
2107 * we'll just bring the device online (and await his false bug report). */
2113 /* Return if the account is already connected */
2115 conn_status = tny_account_get_connection_status (account);
2116 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2118 /* We promise to instantly perform the callback, so ... */
2120 callback (FALSE, NULL, parent_window, account, user_data);
2126 /* Else, we are in a state that requires that we go online before we
2127 * call the caller's callback. */
2129 info = g_slice_new0 (OnWentOnlineInfo);
2131 info->device = NULL;
2133 info->account = TNY_ACCOUNT (g_object_ref (account));
2136 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2138 info->parent_window = NULL;
2140 /* So we'll put the callback away for later ... */
2142 info->user_data = user_data;
2143 info->callback = callback;
2145 if (!device_online) {
2147 /* If also the device is offline, then we connect both the device
2148 * and the account */
2150 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2151 force, on_conic_device_went_online,
2156 /* If the device is online, we'll just connect the account */
2158 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2159 on_account_went_online, info);
2162 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2163 * in both situations, go look if you don't believe me! */
2169 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2171 TnyFolderStore *folder_store,
2172 ModestConnectedPerformer callback,
2175 TnyAccount *account = NULL;
2177 if (!folder_store) {
2178 /* We promise to instantly perform the callback, so ... */
2180 callback (FALSE, NULL, parent_window, NULL, user_data);
2184 } else if (TNY_IS_FOLDER (folder_store)) {
2185 /* Get the folder's parent account: */
2186 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2187 } else if (TNY_IS_ACCOUNT (folder_store)) {
2188 /* Use the folder store as an account: */
2189 account = TNY_ACCOUNT (g_object_ref (folder_store));
2192 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
2193 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2194 /* No need to connect a local account */
2196 callback (FALSE, NULL, parent_window, account, user_data);
2201 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2205 g_object_unref (account);
2209 src_account_connect_performer (gboolean canceled,
2211 GtkWindow *parent_window,
2212 TnyAccount *src_account,
2215 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2217 if (canceled || err) {
2218 /* If there was any error call the user callback */
2219 info->callback (canceled, err, parent_window, src_account, info->data);
2221 /* Connect the destination account */
2222 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2223 TNY_FOLDER_STORE (info->dst_account),
2224 info->callback, info->data);
2227 /* Free the info object */
2228 g_object_unref (info->dst_account);
2229 g_slice_free (DoubleConnectionInfo, info);
2234 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2236 TnyFolderStore *folder_store,
2237 DoubleConnectionInfo *connect_info)
2239 modest_platform_connect_if_remote_and_perform(parent_window,
2242 src_account_connect_performer,
2247 modest_platform_get_account_settings_wizard (void)
2249 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2251 return GTK_WIDGET (dialog);
2255 modest_platform_get_current_connection (void)
2257 TnyDevice *device = NULL;
2258 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2260 device = modest_runtime_get_device ();
2262 if (!tny_device_is_online (device))
2263 return MODEST_CONNECTED_VIA_ANY;
2265 #ifdef MODEST_HAVE_CONIC
2267 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2269 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2270 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2271 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2273 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2274 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2275 !strcmp (bearer_type, "WIMAX")) {
2276 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2278 retval = MODEST_CONNECTED_VIA_ANY;
2281 g_object_unref (iap);
2284 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2285 #endif /* MODEST_HAVE_CONIC */
2292 modest_platform_check_memory_low (ModestWindow *win,
2297 /* are we in low memory state? */
2298 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2300 if (win && lowmem && visuals)
2301 modest_platform_run_information_dialog (
2303 dgettext("ke-recv","memr_ib_operation_disabled"),
2307 g_debug ("%s: low memory reached. disallowing some operations",
2314 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2320 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2323 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2324 GTK_WINDOW (dialog),
2326 gtk_widget_show_all (dialog);
2328 g_signal_connect_swapped (dialog, "response",
2329 G_CALLBACK (gtk_widget_destroy),
2334 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2340 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header);
2343 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2344 GTK_WINDOW (dialog),
2346 gtk_widget_show_all (dialog);
2348 g_signal_connect_swapped (dialog, "response",
2349 G_CALLBACK (gtk_widget_destroy),
2354 modest_platform_get_osso_context (void)
2356 return modest_maemo_utils_get_osso_context ();
2360 _modest_platform_play_email_tone (void)
2362 gchar *active_profile;
2365 gint mail_volume_int;
2367 ca_context *ca_con = NULL;
2368 ca_proplist *pl = NULL;
2370 active_profile = profile_get_profile ();
2371 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2372 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2373 mail_volume_int = profile_parse_int (mail_volume);
2375 if (mail_volume_int > 0) {
2377 if ((ret = ca_context_create(&ca_con)) != CA_SUCCESS) {
2378 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2382 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2383 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2384 ca_context_destroy(ca_con);
2388 ca_proplist_create(&pl);
2389 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2390 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", (gfloat) mail_volume_int);
2392 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2393 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2395 ca_proplist_destroy(pl);
2396 ca_context_destroy(ca_con);
2399 g_free (mail_volume);
2401 g_free (active_profile);
2405 on_move_to_dialog_folder_activated (GtkTreeView *tree_view,
2407 GtkTreeViewColumn *column,
2410 gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_OK);
2414 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
2415 GtkWidget **folder_view)
2417 GtkWidget *dialog, *folder_view_container;
2419 /* Create dialog. We cannot use a touch selector because we
2420 need to use here the folder view widget directly */
2421 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2422 GTK_WINDOW (parent_window),
2423 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
2424 GTK_DIALOG_DESTROY_WITH_PARENT,
2425 _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
2428 /* Create folder view */
2429 *folder_view = modest_platform_create_folder_view (NULL);
2431 /* Simulate the behaviour of a HildonPickerDialog by emitting
2432 a response when a folder is selected */
2433 g_signal_connect (*folder_view, "row-activated",
2434 G_CALLBACK (on_move_to_dialog_folder_activated),
2437 /* Create pannable and add it to the dialog */
2438 folder_view_container = hildon_pannable_area_new ();
2439 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
2440 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
2442 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
2444 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
2445 gtk_widget_show (folder_view_container);
2446 gtk_widget_show (*folder_view);
2452 modest_platform_get_list_to_move (ModestWindow *window)
2454 TnyList *list = NULL;
2456 if (MODEST_IS_HEADER_WINDOW (window)) {
2457 ModestHeaderView *header_view;
2459 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
2460 list = modest_header_view_get_selected_headers (header_view);
2461 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
2462 ModestFolderView *folder_view;
2463 TnyFolderStore *selected_folder;
2465 list = TNY_LIST (tny_simple_list_new ());
2466 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
2467 selected_folder = modest_folder_view_get_selected (folder_view);
2468 if (selected_folder) {
2469 tny_list_prepend (list, G_OBJECT (selected_folder));
2470 g_object_unref (selected_folder);
2473 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2476 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
2478 list = TNY_LIST (tny_simple_list_new ());
2479 tny_list_prepend (list, G_OBJECT (header));
2480 g_object_unref (header);
2483 g_return_val_if_reached (NULL);