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"
95 #define MODEST_ALARMD_APPID PACKAGE_NAME
98 static void _modest_platform_play_email_tone (void);
102 on_modest_conf_update_interval_changed (ModestConf* self,
104 ModestConfEvent event,
105 ModestConfNotificationId id,
108 g_return_if_fail (key);
110 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
111 const guint update_interval_minutes =
112 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
113 modest_platform_set_update_interval (update_interval_minutes);
120 check_required_files (void)
122 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
124 g_printerr ("modest: check for mcc file failed\n");
129 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
130 access(MODEST_MAEMO_PROVIDER_DATA_FILE, R_OK) != 0) {
131 g_printerr ("modest: cannot find providers data\n");
139 /* the gpointer here is the osso_context. */
141 modest_platform_init (int argc, char *argv[])
143 osso_context_t *osso_context;
145 osso_hw_state_t hw_state = { 0 };
149 if (!check_required_files ()) {
150 g_printerr ("modest: missing required files\n");
154 osso_context = osso_initialize(PACKAGE,PACKAGE_VERSION,
157 g_printerr ("modest: failed to acquire osso context\n");
160 modest_maemo_utils_set_osso_context (osso_context);
162 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
163 g_printerr ("modest: could not get dbus connection\n");
167 /* Add a D-Bus handler to be used when the main osso-rpc
168 * D-Bus handler has not handled something.
169 * We use this for D-Bus methods that need to use more complex types
170 * than osso-rpc supports.
172 if (!dbus_connection_add_filter (con,
173 modest_dbus_req_filter,
177 g_printerr ("modest: Could not add D-Bus filter\n");
181 /* Register our simple D-Bus callbacks, via the osso API: */
182 osso_return_t result = osso_rpc_set_cb_f(osso_context,
186 modest_dbus_req_handler, NULL /* user_data */);
187 if (result != OSSO_OK) {
188 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
192 /* Register hardware event dbus callback: */
193 hw_state.shutdown_ind = TRUE;
194 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
196 /* Register osso auto-save callbacks: */
197 result = osso_application_set_autosave_cb (osso_context,
198 modest_on_osso_application_autosave, NULL /* user_data */);
199 if (result != OSSO_OK) {
200 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
205 /* Make sure that the update interval is changed whenever its gconf key
207 /* CAUTION: we're not using here the
208 modest_conf_listen_to_namespace because we know that there
209 are other parts of Modest listening for this namespace, so
210 we'll receive the notifications anyway. We basically do not
211 use it because there is no easy way to do the
212 modest_conf_forget_namespace */
213 ModestConf *conf = modest_runtime_get_conf ();
214 g_signal_connect (G_OBJECT(conf),
216 G_CALLBACK (on_modest_conf_update_interval_changed),
219 /* only force the setting of the default interval, if there are actually
221 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
223 /* Get the initial update interval from gconf: */
224 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
225 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
226 modest_account_mgr_free_account_names (acc_names);
230 #ifdef MODEST_HAVE_ABOOK
231 /* initialize the addressbook */
232 if (!osso_abook_init (&argc, &argv, osso_context)) {
233 g_printerr ("modest: failed to initialized addressbook\n");
236 #endif /*MODEST_HAVE_ABOOK*/
242 modest_platform_uninit (void)
244 osso_context_t *osso_context =
245 modest_maemo_utils_get_osso_context ();
247 osso_deinitialize (osso_context);
256 modest_platform_get_new_device (void)
258 return TNY_DEVICE (tny_maemo_conic_device_new ());
262 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
263 gchar **effective_mime_type)
265 GString *mime_str = NULL;
266 gchar *icon_name = NULL;
267 gchar **icons, **cursor;
269 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
270 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
272 mime_str = g_string_new (mime_type);
273 g_string_ascii_down (mime_str);
276 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
278 for (cursor = icons; cursor; ++cursor) {
279 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
280 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
281 icon_name = g_strdup ("qgn_list_messagin");
283 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
284 icon_name = g_strdup (*cursor);
290 if (effective_mime_type)
291 *effective_mime_type = g_string_free (mime_str, FALSE);
293 g_string_free (mime_str, TRUE);
300 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
305 g_return_val_if_fail (uri, FALSE);
307 result = hildon_uri_open (uri, action, &err);
309 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
310 uri, action, err && err->message ? err->message : "unknown error");
320 modest_platform_activate_uri (const gchar *uri)
322 HildonURIAction *action;
323 gboolean result = FALSE;
324 GSList *actions, *iter = NULL;
326 g_return_val_if_fail (uri, FALSE);
330 /* don't try to activate file: uri's -- they might confuse the user,
331 * and/or might have security implications */
332 if (!g_str_has_prefix (uri, "file:")) {
334 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
336 for (iter = actions; iter; iter = g_slist_next (iter)) {
337 action = (HildonURIAction*) iter->data;
338 if (action && strcmp (hildon_uri_action_get_service (action),
339 "com.nokia.modest") == 0) {
340 result = checked_hildon_uri_open (uri, action);
345 /* if we could not open it with email, try something else */
347 result = checked_hildon_uri_open (uri, NULL);
351 ModestWindow *parent =
352 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
353 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
354 _("mcen_ib_unsupported_link"));
355 g_warning ("%s: cannot open uri '%s'", __FUNCTION__,uri);
362 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
366 gchar *uri_path = NULL;
368 uri_path = gnome_vfs_get_uri_from_local_path (path);
369 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
372 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
374 result = hildon_mime_open_file (con, uri_path);
376 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
384 } ModestPlatformPopupInfo;
387 delete_uri_popup (GtkWidget *menu,
391 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
393 g_free (popup_info->uri);
394 hildon_uri_free_actions (popup_info->actions);
400 activate_uri_popup_item (GtkMenuItem *menu_item,
404 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
405 const gchar* action_name;
407 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
409 g_printerr ("modest: no action name defined\n");
413 /* special handling for the copy menu item -- copy the uri to the clipboard */
414 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
415 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
416 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
417 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
419 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
420 action_name += strlen ("mailto:");
422 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
423 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
424 return; /* we're done */
427 /* now, the real uri-actions... */
428 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
429 HildonURIAction *action = (HildonURIAction *) node->data;
430 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
431 if (!checked_hildon_uri_open (popup_info->uri, action)) {
432 ModestWindow *parent =
433 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
434 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
435 _("mcen_ib_unsupported_link"));
443 modest_platform_show_uri_popup (const gchar *uri)
445 GSList *actions_list;
450 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
453 GtkWidget *menu = gtk_menu_new ();
454 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
456 /* don't add actions for file: uri's -- they might confuse the user,
457 * and/or might have security implications
458 * we still allow to copy the url though
460 if (!g_str_has_prefix (uri, "file:")) {
463 popup_info->actions = actions_list;
464 popup_info->uri = g_strdup (uri);
466 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
467 GtkWidget *menu_item;
468 const gchar *action_name;
469 const gchar *translation_domain;
470 HildonURIAction *action = (HildonURIAction *) node->data;
471 action_name = hildon_uri_action_get_name (action);
472 translation_domain = hildon_uri_action_get_translation_domain (action);
473 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
474 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
475 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
478 if (hildon_uri_is_default_action (action, NULL)) {
479 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
481 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
483 gtk_widget_show (menu_item);
487 /* always add the copy item */
488 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri",
489 "uri_link_copy_link_location"));
490 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
491 g_strconcat (URI_ACTION_COPY, uri, NULL),
493 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
494 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
495 gtk_widget_show (menu_item);
498 /* and what to do when the link is deleted */
499 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
500 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
503 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
511 modest_platform_get_icon (const gchar *name, guint icon_size)
514 GdkPixbuf* pixbuf = NULL;
515 GtkIconTheme *current_theme = NULL;
517 g_return_val_if_fail (name, NULL);
519 /* strlen == 0 is not really an error; it just
520 * means the icon is not available
522 if (!name || strlen(name) == 0)
525 current_theme = gtk_icon_theme_get_default ();
526 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
527 GTK_ICON_LOOKUP_NO_SVG,
530 g_printerr ("modest: error loading theme icon '%s': %s\n",
538 modest_platform_get_app_name (void)
540 return _("mcen_ap_name");
544 entry_insert_text (GtkEditable *editable,
553 chars = gtk_editable_get_chars (editable, 0, -1);
554 chars_length = g_utf8_strlen (chars, -1);
557 /* Show WID-INF036 */
558 if (chars_length >= 20) {
559 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
560 _CS("ckdg_ib_maximum_characters_reached"));
562 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
566 tmp = g_strndup (folder_name_forbidden_chars,
567 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
568 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
569 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
574 /* Write the text in the entry if it's valid */
575 g_signal_handlers_block_by_func (editable,
576 (gpointer) entry_insert_text, data);
577 gtk_editable_insert_text (editable, text, length, position);
578 g_signal_handlers_unblock_by_func (editable,
579 (gpointer) entry_insert_text, data);
582 /* Do not allow further processing */
583 g_signal_stop_emission_by_name (editable, "insert_text");
587 entry_changed (GtkEditable *editable,
591 GtkWidget *ok_button;
594 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
595 ok_button = GTK_WIDGET (buttons->data);
597 chars = gtk_editable_get_chars (editable, 0, -1);
598 g_return_if_fail (chars != NULL);
601 if (g_utf8_strlen (chars,-1) >= 20)
602 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
603 _CS("ckdg_ib_maximum_characters_reached"));
605 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
608 g_list_free (buttons);
615 on_response (GtkDialog *dialog,
619 GtkWidget *entry, *picker;
620 TnyFolderStore *parent;
621 const gchar *new_name;
624 if (response != GTK_RESPONSE_ACCEPT)
628 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
629 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
631 parent = TNY_FOLDER_STORE (user_data);
632 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
635 if (picker != NULL) {
637 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
640 /* Look for another folder with the same name */
641 if (modest_tny_folder_has_subfolder_with_name (parent,
648 if (TNY_IS_ACCOUNT (parent) &&
649 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
650 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
659 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
660 NULL, _CS("ckdg_ib_folder_already_exists"));
661 /* Select the text */
662 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
663 gtk_widget_grab_focus (entry);
664 /* Do not close the dialog */
665 g_signal_stop_emission_by_name (dialog, "response");
670 typedef struct _FolderChooserData {
671 TnyFolderStore *store;
676 folder_chooser_activated (ModestFolderView *folder_view,
677 TnyFolderStore *folder,
678 FolderChooserData *userdata)
680 userdata->store = folder;
681 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
684 static TnyFolderStore *
685 folder_chooser_dialog_run (ModestFolderView *original)
687 GtkWidget *folder_view;
688 FolderChooserData userdata = {NULL, NULL};
690 const gchar *visible_id = NULL;
692 userdata.dialog = hildon_dialog_new ();
693 pannable = hildon_pannable_area_new ();
694 folder_view = modest_platform_create_folder_view (NULL);
695 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
696 MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS);
698 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original), MODEST_FOLDER_VIEW (folder_view));
701 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original));
702 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
705 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
706 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
707 gtk_widget_set_size_request (pannable, -1, 320);
709 gtk_widget_show (folder_view);
710 gtk_widget_show (pannable);
711 gtk_widget_show (userdata.dialog);
712 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
713 G_CALLBACK (folder_chooser_activated),
714 (gpointer) &userdata);
716 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
717 gtk_widget_destroy (userdata.dialog);
719 return userdata.store;
723 folder_store_get_display_name (TnyFolderStore *store)
725 if (TNY_IS_ACCOUNT (store)) {
726 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
729 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
731 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
732 type = tny_folder_get_folder_type (TNY_FOLDER (store));
733 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
734 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
735 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
736 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
738 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
741 /* Sometimes an special folder is reported by the server as
742 NORMAL, like some versions of Dovecot */
743 if (type == TNY_FOLDER_TYPE_NORMAL ||
744 type == TNY_FOLDER_TYPE_UNKNOWN) {
745 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
749 if (type == TNY_FOLDER_TYPE_INBOX) {
751 fname = g_strdup (_("mcen_me_folder_inbox"));
758 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
763 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
765 g_object_ref (store);
766 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
767 store, (GDestroyNotify) g_object_unref);
768 name = folder_store_get_display_name (store);
769 hildon_button_set_value (HILDON_BUTTON (button), name);
775 folder_picker_clicked (GtkButton *button,
776 ModestFolderView *folder_view)
778 TnyFolderStore *store;
780 store = folder_chooser_dialog_run (folder_view);
782 folder_picker_set_store (GTK_BUTTON (button), store);
787 folder_picker_new (ModestFolderView *folder_view, TnyFolderStore *suggested)
792 button = hildon_button_new (MODEST_EDITABLE_SIZE,
793 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
794 pixbuf = modest_platform_get_icon (MODEST_FOLDER_ICON_NORMAL,
795 MODEST_ICON_SIZE_SMALL);
797 hildon_button_set_image (HILDON_BUTTON (button),
798 gtk_image_new_from_pixbuf (pixbuf));
799 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
802 folder_picker_set_store (GTK_BUTTON (button), suggested);
805 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (folder_picker_clicked), folder_view);
812 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
813 TnyFolderStore *suggested_parent,
814 const gchar *dialog_title,
815 const gchar *label_text,
816 const gchar *suggested_name,
818 gboolean show_parent,
820 TnyFolderStore **parent)
822 GtkWidget *accept_btn = NULL;
823 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
824 GtkWidget *account_picker = NULL;
825 GList *buttons = NULL;
827 GtkSizeGroup *sizegroup;
828 ModestFolderView *folder_view;
829 ModestWindow *folder_window;
830 ModestHildon2WindowMgr *window_mgr;
832 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
833 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
834 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
836 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
838 /* Ask the user for the folder name */
839 dialog = gtk_dialog_new_with_buttons (dialog_title,
841 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
842 _FM("ckdg_bd_new_folder_dialog_ok"),
846 /* Add accept button (with unsensitive handler) */
847 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
848 accept_btn = GTK_WIDGET (buttons->data);
850 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
853 label_entry = gtk_label_new (label_text);
854 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
855 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
857 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
858 gtk_size_group_add_widget (sizegroup, label_entry);
861 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
863 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
864 gtk_entry_set_width_chars (GTK_ENTRY (entry),
865 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
866 g_utf8_strlen (_("mcen_ia_default_folder_name"), -1)));
867 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
872 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
874 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
875 gtk_size_group_add_widget (sizegroup, label_location);
877 account_picker = folder_picker_new (folder_view, suggested_parent);
880 g_object_unref (sizegroup);
882 /* Connect to the response method to avoid closing the dialog
883 when an invalid name is selected*/
884 g_signal_connect (dialog,
886 G_CALLBACK (on_response),
890 /* Track entry changes */
891 g_signal_connect (entry,
893 G_CALLBACK (entry_insert_text),
895 g_signal_connect (entry,
897 G_CALLBACK (entry_changed),
902 /* Some locales like pt_BR need this to get the full window
904 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
906 /* Create the hbox */
908 hbox = gtk_hbox_new (FALSE, 12);
909 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
910 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
912 /* Add hbox to dialog */
913 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
914 hbox, FALSE, FALSE, 0);
915 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
919 hbox = gtk_hbox_new (FALSE, 12);
920 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
921 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
923 /* Add hbox to dialog */
924 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
925 hbox, FALSE, FALSE, 0);
926 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
928 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
929 GTK_WINDOW (dialog), parent_window);
930 gtk_widget_show_all (GTK_WIDGET(dialog));
932 result = gtk_dialog_run (GTK_DIALOG(dialog));
933 if (result == GTK_RESPONSE_ACCEPT) {
935 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
937 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
939 g_object_ref (*parent);
943 gtk_widget_destroy (dialog);
945 while (gtk_events_pending ())
946 gtk_main_iteration ();
952 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
953 TnyFolderStore *suggested_folder,
954 gchar *suggested_name,
956 TnyFolderStore **parent_folder)
958 gchar *real_suggested_name = NULL, *tmp = NULL;
960 ModestTnyAccountStore *acc_store;
963 if(suggested_name == NULL)
965 const gchar *default_name = _("mcen_ia_default_folder_name");
969 for(i = 0; i < 100; ++ i) {
970 gboolean exists = FALSE;
972 sprintf(num_str, "%.2u", i);
975 real_suggested_name = g_strdup (default_name);
977 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
979 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
986 g_free (real_suggested_name);
989 /* Didn't find a free number */
991 real_suggested_name = g_strdup (default_name);
993 real_suggested_name = suggested_name;
996 /* In hildon 2.2 we always suggest the archive folder as parent */
997 acc_store = modest_runtime_get_account_store ();
998 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
1000 suggested_folder = (TnyFolderStore *)
1001 modest_tny_account_get_special_folder (account,
1002 TNY_FOLDER_TYPE_ARCHIVE);
1003 g_object_unref (account);
1007 /* If there is not archive folder then fallback to local folders account */
1008 if (!suggested_folder)
1009 suggested_folder = (TnyFolderStore *)
1010 modest_tny_account_store_get_local_folders_account (acc_store);
1012 tmp = g_strconcat (_("mcen_fi_new_folder_name"), ":", NULL);
1013 result = modest_platform_run_folder_common_dialog (parent_window,
1015 _("mcen_ti_new_folder"),
1017 real_suggested_name,
1024 if (suggested_name == NULL)
1025 g_free(real_suggested_name);
1031 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1032 TnyFolderStore *parent_folder,
1033 const gchar *suggested_name,
1034 gchar **folder_name)
1036 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1038 return modest_platform_run_folder_common_dialog (parent_window,
1040 _HL("ckdg_ti_rename_folder"),
1041 _HL("ckdg_fi_rename_name"),
1052 on_destroy_dialog (GtkWidget *dialog)
1054 /* This could happen when the dialogs get programatically
1055 hidden or destroyed (for example when closing the
1056 application while a dialog is being shown) */
1057 if (!GTK_IS_WIDGET (dialog))
1060 gtk_widget_destroy (dialog);
1062 if (gtk_events_pending ())
1063 gtk_main_iteration ();
1067 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1068 const gchar *message)
1073 dialog = hildon_note_new_confirmation (parent_window, message);
1074 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1075 GTK_WINDOW (dialog), parent_window);
1077 response = gtk_dialog_run (GTK_DIALOG (dialog));
1079 on_destroy_dialog (dialog);
1085 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1086 const gchar *message,
1087 const gchar *button_accept,
1088 const gchar *button_cancel)
1093 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1094 button_accept, GTK_RESPONSE_ACCEPT,
1095 button_cancel, GTK_RESPONSE_CANCEL,
1098 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1099 GTK_WINDOW (dialog), parent_window);
1101 response = gtk_dialog_run (GTK_DIALOG (dialog));
1103 on_destroy_dialog (dialog);
1109 modest_platform_run_information_dialog (GtkWindow *parent_window,
1110 const gchar *message,
1115 note = hildon_note_new_information (parent_window, message);
1117 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1118 GTK_WINDOW (note), parent_window);
1121 gtk_dialog_run (GTK_DIALOG (note));
1123 on_destroy_dialog (note);
1125 g_signal_connect_swapped (note,
1127 G_CALLBACK (on_destroy_dialog),
1130 gtk_widget_show_all (note);
1134 typedef struct _ConnectAndWaitData {
1136 GMainLoop *wait_loop;
1137 gboolean has_callback;
1139 } ConnectAndWaitData;
1143 quit_wait_loop (TnyAccount *account,
1144 ConnectAndWaitData *data)
1146 /* Set the has_callback to TRUE (means that the callback was
1147 executed and wake up every code waiting for cond to be
1149 g_mutex_lock (data->mutex);
1150 data->has_callback = TRUE;
1151 if (data->wait_loop)
1152 g_main_loop_quit (data->wait_loop);
1153 g_mutex_unlock (data->mutex);
1157 on_connection_status_changed (TnyAccount *account,
1158 TnyConnectionStatus status,
1161 TnyConnectionStatus conn_status;
1162 ConnectAndWaitData *data;
1164 /* Ignore if reconnecting or disconnected */
1165 conn_status = tny_account_get_connection_status (account);
1166 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1167 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1170 /* Remove the handler */
1171 data = (ConnectAndWaitData *) user_data;
1172 g_signal_handler_disconnect (account, data->handler);
1174 /* Quit from wait loop */
1175 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1179 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1184 /* Quit from wait loop */
1185 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1189 modest_platform_connect_and_wait (GtkWindow *parent_window,
1190 TnyAccount *account)
1192 ConnectAndWaitData *data = NULL;
1193 gboolean device_online;
1195 TnyConnectionStatus conn_status;
1196 gboolean user_requested;
1198 device = modest_runtime_get_device();
1199 device_online = tny_device_is_online (device);
1201 /* Whether the connection is user requested or automatically
1202 requested, for example via D-Bus */
1203 user_requested = (parent_window) ? TRUE : FALSE;
1205 /* If there is no account check only the device status */
1210 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1211 NULL, user_requested);
1214 /* Return if the account is already connected */
1215 conn_status = tny_account_get_connection_status (account);
1216 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1219 /* Create the helper */
1220 data = g_slice_new0 (ConnectAndWaitData);
1221 data->mutex = g_mutex_new ();
1222 data->has_callback = FALSE;
1224 /* Connect the device */
1225 if (!device_online) {
1226 /* Track account connection status changes */
1227 data->handler = g_signal_connect (account, "connection-status-changed",
1228 G_CALLBACK (on_connection_status_changed),
1230 /* Try to connect the device */
1231 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1232 NULL, user_requested);
1234 /* If the device connection failed then exit */
1235 if (!device_online && data->handler)
1238 /* Force a reconnection of the account */
1239 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1240 on_tny_camel_account_set_online_cb, data);
1243 /* Wait until the callback is executed */
1244 g_mutex_lock (data->mutex);
1245 if (!data->has_callback) {
1246 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1247 gdk_threads_leave ();
1248 g_mutex_unlock (data->mutex);
1249 g_main_loop_run (data->wait_loop);
1250 g_mutex_lock (data->mutex);
1251 gdk_threads_enter ();
1253 g_mutex_unlock (data->mutex);
1257 if (g_signal_handler_is_connected (account, data->handler))
1258 g_signal_handler_disconnect (account, data->handler);
1259 g_mutex_free (data->mutex);
1260 g_main_loop_unref (data->wait_loop);
1261 g_slice_free (ConnectAndWaitData, data);
1264 conn_status = tny_account_get_connection_status (account);
1265 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1269 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1271 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1272 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1273 /* This must be a maildir account, which does not require a connection: */
1278 return modest_platform_connect_and_wait (parent_window, account);
1282 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1285 return TRUE; /* Maybe it is something local. */
1287 gboolean result = TRUE;
1288 if (TNY_IS_FOLDER (folder_store)) {
1289 /* Get the folder's parent account: */
1290 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1291 if (account != NULL) {
1292 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1293 g_object_unref (account);
1295 } else if (TNY_IS_ACCOUNT (folder_store)) {
1296 /* Use the folder store as an account: */
1297 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1304 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1308 dialog = modest_hildon2_sort_dialog_new (parent_window);
1315 modest_platform_set_update_interval (guint minutes)
1317 #ifdef MODEST_HAVE_LIBALARM
1319 ModestConf *conf = modest_runtime_get_conf ();
1323 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1325 /* Delete any existing alarm,
1326 * because we will replace it: */
1328 if (alarmd_event_del(alarm_cookie) != 0)
1329 g_warning ("%s: alarm %d was not on the queue", __FUNCTION__, (int)alarm_cookie);
1331 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1334 /* 0 means no updates: */
1339 /* Register alarm: */
1341 /* Set the interval in alarm_event_t structure: */
1342 alarm_event_t *event = alarm_event_create ();
1343 alarm_event_add_actions (event, 1);
1344 alarm_action_t *action = alarm_event_get_action (event, 0);
1345 alarm_event_set_alarm_appid (event, MODEST_ALARMD_APPID);
1346 event->alarm_time = minutes * 60; /* seconds */
1348 /* Set recurrence every few minutes: */
1349 event->recur_secs = minutes*60;
1350 event->recur_count = -1; /* Means infinite */
1352 /* Specify what should happen when the alarm happens:
1353 * It should call this D-Bus method: */
1355 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1356 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1357 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1358 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1359 action->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1361 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1362 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1363 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1364 * This is why we want to use the Alarm API instead of just g_timeout_add().
1365 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1366 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1368 event->flags = ALARM_EVENT_CONNECTED;
1370 alarm_cookie = alarmd_event_add (event);
1373 alarm_event_delete (event);
1375 /* Store the alarm ID in GConf, so we can remove it later:
1376 * This is apparently valid between application instances. */
1377 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1379 if (!alarm_cookie) {
1381 g_debug ("Error setting alarm event. \n");
1385 #endif /* MODEST_HAVE_LIBALARM */
1390 modest_platform_push_email_notification(void)
1392 gboolean screen_on, app_in_foreground;
1394 /* Get the window status */
1395 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1397 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1399 /* If the screen is on and the app is in the
1400 foreground we don't show anything */
1401 if (!(screen_on && app_in_foreground)) {
1403 _modest_platform_play_email_tone ();
1405 /* Activate LED. This must be deactivated by
1406 modest_platform_remove_new_mail_notifications */
1407 #ifdef MODEST_HAVE_MCE
1408 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1412 MCE_ACTIVATE_LED_PATTERN,
1414 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1421 modest_platform_on_new_headers_received (TnyList *header_list,
1422 gboolean show_visual)
1424 g_return_if_fail (TNY_IS_LIST(header_list));
1426 if (tny_list_get_length(header_list) == 0) {
1427 g_warning ("%s: header list is empty", __FUNCTION__);
1432 modest_platform_push_email_notification ();
1433 /* We do a return here to avoid indentation with an else */
1437 #ifdef MODEST_HAVE_HILDON_NOTIFY
1438 HildonNotification *notification;
1440 GSList *notifications_list = NULL;
1442 /* Get previous notifications ids */
1443 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1444 MODEST_CONF_NOTIFICATION_IDS,
1445 MODEST_CONF_VALUE_INT, NULL);
1447 iter = tny_list_create_iterator (header_list);
1448 while (!tny_iterator_is_done (iter)) {
1449 gchar *url = NULL, *display_address = NULL, *summary = NULL;
1450 const gchar *display_date;
1451 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1452 TnyFolder *folder = tny_header_get_folder (header);
1453 gboolean first_notification = TRUE;
1456 ModestDatetimeFormatter *datetime_formatter;
1458 /* constant string, don't free */
1459 datetime_formatter = modest_datetime_formatter_new ();
1460 display_date = modest_datetime_formatter_display_datetime (datetime_formatter,
1461 tny_header_get_date_received (header));
1462 g_object_unref (datetime_formatter);
1464 display_address = tny_header_dup_from (header);
1465 /* string is changed in-place */
1466 modest_text_utils_get_display_address (display_address);
1468 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1469 str = tny_header_dup_subject (header);
1470 notification = hildon_notification_new (summary,
1472 "qgn_list_messagin",
1475 /* Create the message URL */
1476 str = tny_header_dup_uid (header);
1477 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1481 hildon_notification_add_dbus_action(notification,
1484 MODEST_DBUS_SERVICE,
1487 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1491 /* Play sound if the user wants. Show the LED
1492 pattern. Show and play just one */
1493 if (G_UNLIKELY (first_notification)) {
1494 gchar *active_profile;
1497 gint mail_volume_int;
1499 first_notification = FALSE;
1501 active_profile = profile_get_profile ();
1502 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
1503 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
1504 mail_volume_int = profile_parse_int (mail_volume);
1506 if (mail_volume_int > 0)
1507 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1508 "sound-file", mail_tone);
1510 g_free (mail_volume);
1512 g_free (active_profile);
1514 /* Set the led pattern */
1515 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1517 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1519 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1522 /* Notify. We need to do this in an idle because this function
1523 could be called from a thread */
1524 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1526 /* Save id in the list */
1527 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1528 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1529 /* We don't listen for the "closed" signal, because we
1530 don't care about if the notification was removed or
1531 not to store the list in gconf */
1533 /* Free & carry on */
1534 g_free (display_address);
1537 g_object_unref (folder);
1538 g_object_unref (header);
1539 tny_iterator_next (iter);
1541 g_object_unref (iter);
1544 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1545 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1547 g_slist_free (notifications_list);
1549 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1553 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1556 #ifdef MODEST_HAVE_MCE
1557 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1561 MCE_DEACTIVATE_LED_PATTERN,
1563 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1569 #ifdef MODEST_HAVE_HILDON_NOTIFY
1570 GSList *notif_list = NULL;
1572 /* Get previous notifications ids */
1573 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1574 MODEST_CONF_NOTIFICATION_IDS,
1575 MODEST_CONF_VALUE_INT, NULL);
1577 while (notif_list) {
1579 NotifyNotification *notif;
1581 /* Nasty HACK to remove the notifications, set the id
1582 of the existing ones and then close them */
1583 notif_id = GPOINTER_TO_INT(notif_list->data);
1584 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1585 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1587 /* Close the notification, note that some ids could be
1588 already invalid, but we don't care because it does
1590 notify_notification_close(notif, NULL);
1591 g_object_unref(notif);
1593 /* Delete the link, it's like going to the next */
1594 notif_list = g_slist_delete_link (notif_list, notif_list);
1598 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1599 notif_list, MODEST_CONF_VALUE_INT, NULL);
1601 g_slist_free (notif_list);
1603 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1609 modest_platform_get_global_settings_dialog ()
1611 return modest_hildon2_global_settings_dialog_new ();
1615 modest_platform_show_help (GtkWindow *parent_window,
1616 const gchar *help_id)
1622 modest_platform_show_search_messages (GtkWindow *parent_window)
1624 osso_return_t result = OSSO_ERROR;
1626 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1627 "osso_global_search",
1628 "search_email", NULL, DBUS_TYPE_INVALID);
1630 if (result != OSSO_OK) {
1631 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1636 modest_platform_show_addressbook (GtkWindow *parent_window)
1638 osso_return_t result = OSSO_ERROR;
1640 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1642 "top_application", NULL, DBUS_TYPE_INVALID);
1644 if (result != OSSO_OK) {
1645 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1650 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1652 GtkWidget *widget = modest_folder_view_new (query);
1654 /* Show one account by default */
1655 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1656 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1658 /* Restore settings */
1659 modest_widget_memory_restore (modest_runtime_get_conf(),
1661 MODEST_CONF_FOLDER_VIEW_KEY);
1667 banner_finish (gpointer data, GObject *object)
1669 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1670 modest_window_mgr_unregister_banner (mgr);
1671 g_object_unref (mgr);
1675 modest_platform_information_banner (GtkWidget *parent,
1676 const gchar *icon_name,
1679 GtkWidget *banner, *banner_parent = NULL;
1680 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1682 if (modest_window_mgr_get_num_windows (mgr) == 0)
1685 if (parent && GTK_IS_WINDOW (parent)) {
1686 /* If the window is the active one then show the
1687 banner on top of this window */
1688 if (gtk_window_is_active (GTK_WINDOW (parent)))
1689 banner_parent = parent;
1690 /* If the window is not the topmost but it's visible
1691 (it's minimized for example) then show the banner
1693 else if (GTK_WIDGET_VISIBLE (parent))
1694 banner_parent = NULL;
1695 /* If the window is hidden (like the main window when
1696 running in the background) then do not show
1703 banner = hildon_banner_show_information (banner_parent, icon_name, text);
1705 modest_window_mgr_register_banner (mgr);
1707 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1711 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1712 const gchar *icon_name,
1718 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1721 banner = hildon_banner_show_information (parent, icon_name, text);
1722 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1726 modest_platform_animation_banner (GtkWidget *parent,
1727 const gchar *animation_name,
1730 GtkWidget *inf_note = NULL;
1732 g_return_val_if_fail (text != NULL, NULL);
1734 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1737 /* If the parent is not visible then do not show */
1738 if (parent && !GTK_WIDGET_VISIBLE (parent))
1741 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1749 TnyAccount *account;
1752 } CheckAccountIdleData;
1754 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1757 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1759 gboolean stop_trying = FALSE;
1760 g_return_val_if_fail (data && data->account, FALSE);
1762 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__,
1763 tny_account_get_connection_status (data->account));
1765 if (data && data->account &&
1766 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1767 * after which the account is likely to be usable, or never likely to be usable soon: */
1768 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1770 data->is_online = TRUE;
1774 /* Give up if we have tried too many times: */
1775 if (data->count_tries >= NUMBER_OF_TRIES) {
1778 /* Wait for another timeout: */
1779 ++(data->count_tries);
1784 /* Allow the function that requested this idle callback to continue: */
1786 g_main_loop_quit (data->loop);
1789 g_object_unref (data->account);
1791 return FALSE; /* Don't call this again. */
1793 return TRUE; /* Call this timeout callback again. */
1797 /* Return TRUE immediately if the account is already online,
1798 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1799 * soon as the account is online, or FALSE if the account does
1800 * not become online in the NUMBER_OF_TRIES seconds.
1801 * This is useful when the D-Bus method was run immediately after
1802 * the application was started (when using D-Bus activation),
1803 * because the account usually takes a short time to go online.
1804 * The return value is maybe not very useful.
1807 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1811 g_return_val_if_fail (account, FALSE);
1813 if (!tny_device_is_online (modest_runtime_get_device())) {
1814 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1818 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1819 * so we avoid wait unnecessarily: */
1820 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1823 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1824 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1825 * we want to avoid. */
1826 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1829 /* This blocks on the result: */
1830 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1831 data->is_online = FALSE;
1832 data->account = account;
1833 g_object_ref (data->account);
1834 data->count_tries = 0;
1836 GMainContext *context = NULL; /* g_main_context_new (); */
1837 data->loop = g_main_loop_new (context, FALSE /* not running */);
1839 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
1841 /* This main loop will run until the idle handler has stopped it: */
1842 g_main_loop_run (data->loop);
1844 g_main_loop_unref (data->loop);
1845 /* g_main_context_unref (context); */
1847 is_online = data->is_online;
1848 g_slice_free (CheckAccountIdleData, data);
1856 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1858 /* GTK_RESPONSE_HELP means we need to show the certificate */
1859 if (response_id == GTK_RESPONSE_APPLY) {
1863 /* Do not close the dialog */
1864 g_signal_stop_emission_by_name (dialog, "response");
1866 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1867 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1868 gtk_dialog_run (GTK_DIALOG(note));
1869 gtk_widget_destroy (note);
1875 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
1876 const gchar *certificate)
1881 HildonWindowStack *stack;
1883 stack = hildon_window_stack_get_default ();
1884 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1887 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1892 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1895 /* We use GTK_RESPONSE_APPLY because we want the button in the
1896 middle of OK and CANCEL the same as the browser does for
1897 example. With GTK_RESPONSE_HELP the view button is aligned
1898 to the left while the other two to the right */
1899 note = hildon_note_new_confirmation_add_buttons (
1902 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
1903 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
1904 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
1907 g_signal_connect (G_OBJECT(note), "response",
1908 G_CALLBACK(on_cert_dialog_response),
1909 (gpointer) certificate);
1911 response = gtk_dialog_run(GTK_DIALOG(note));
1913 on_destroy_dialog (note);
1916 return response == GTK_RESPONSE_OK;
1920 modest_platform_run_alert_dialog (const gchar* prompt,
1921 gboolean is_question)
1923 ModestWindow *top_win;
1924 HildonWindowStack *stack;
1926 stack = hildon_window_stack_get_default ();
1927 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1930 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1935 gboolean retval = TRUE;
1937 /* The Tinymail documentation says that we should show Yes and No buttons,
1938 * when it is a question.
1939 * Obviously, we need tinymail to use more specific error codes instead,
1940 * so we know what buttons to show. */
1941 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
1943 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1944 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
1946 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1947 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1949 on_destroy_dialog (dialog);
1951 /* Just show the error text and use the default response: */
1952 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
1960 GtkWindow *parent_window;
1961 ModestConnectedPerformer callback;
1962 TnyAccount *account;
1969 on_went_online_info_free (OnWentOnlineInfo *info)
1971 /* And if we cleanup, we DO cleanup :-) */
1974 g_object_unref (info->device);
1977 if (info->parent_window)
1978 g_object_unref (info->parent_window);
1980 g_object_unref (info->account);
1982 g_slice_free (OnWentOnlineInfo, info);
1984 /* We're done ... */
1990 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
1992 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
1994 /* Now it's really time to callback to the caller. If going online didn't succeed,
1995 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
1996 * canceled will be set. Etcetera etcetera. */
1998 if (info->callback) {
1999 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2002 /* This is our last call, we must cleanup here if we didn't yet do that */
2003 on_went_online_info_free (info);
2010 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2012 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2013 info->iap = g_strdup (iap_id);
2015 if (canceled || err || !info->account) {
2017 /* If there's a problem or if there's no account (then that's it for us, we callback
2018 * the caller's callback now. He'll have to handle err or canceled, of course.
2019 * We are not really online, as the account is not really online here ... */
2021 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2022 * this info. We don't cleanup err, Tinymail does that! */
2024 if (info->callback) {
2026 /* info->account can be NULL here, this means that the user did not
2027 * provide a nice account instance. We'll assume that the user knows
2028 * what he's doing and is happy with just the device going online.
2030 * We can't do magic, we don't know what account the user wants to
2031 * see going online. So just the device goes online, end of story */
2033 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2036 } else if (info->account) {
2038 /* If there's no problem and if we have an account, we'll put the account
2039 * online too. When done, the callback of bringing the account online
2040 * will callback the caller's callback. This is the most normal case. */
2042 info->device = TNY_DEVICE (g_object_ref (device));
2044 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2045 on_account_went_online, info);
2047 /* The on_account_went_online cb frees up the info, go look if you
2048 * don't believe me! (so we return here) */
2053 /* We cleanup if we are not bringing the account online too */
2054 on_went_online_info_free (info);
2060 modest_platform_connect_and_perform (GtkWindow *parent_window,
2062 TnyAccount *account,
2063 ModestConnectedPerformer callback,
2066 gboolean device_online;
2068 TnyConnectionStatus conn_status;
2069 OnWentOnlineInfo *info;
2071 device = modest_runtime_get_device();
2072 device_online = tny_device_is_online (device);
2074 /* If there is no account check only the device status */
2077 if (device_online) {
2079 /* We promise to instantly perform the callback, so ... */
2081 callback (FALSE, NULL, parent_window, account, user_data);
2086 info = g_slice_new0 (OnWentOnlineInfo);
2089 info->device = NULL;
2090 info->account = NULL;
2093 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2095 info->parent_window = NULL;
2096 info->user_data = user_data;
2097 info->callback = callback;
2099 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2100 force, on_conic_device_went_online,
2103 /* We'll cleanup in on_conic_device_went_online */
2106 /* The other code has no more reason to run. This is all that we can do for the
2107 * caller (he should have given us a nice and clean account instance!). We
2108 * can't do magic, we don't know what account he intends to bring online. So
2109 * we'll just bring the device online (and await his false bug report). */
2115 /* Return if the account is already connected */
2117 conn_status = tny_account_get_connection_status (account);
2118 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2120 /* We promise to instantly perform the callback, so ... */
2122 callback (FALSE, NULL, parent_window, account, user_data);
2128 /* Else, we are in a state that requires that we go online before we
2129 * call the caller's callback. */
2131 info = g_slice_new0 (OnWentOnlineInfo);
2133 info->device = NULL;
2135 info->account = TNY_ACCOUNT (g_object_ref (account));
2138 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2140 info->parent_window = NULL;
2142 /* So we'll put the callback away for later ... */
2144 info->user_data = user_data;
2145 info->callback = callback;
2147 if (!device_online) {
2149 /* If also the device is offline, then we connect both the device
2150 * and the account */
2152 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2153 force, on_conic_device_went_online,
2158 /* If the device is online, we'll just connect the account */
2160 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2161 on_account_went_online, info);
2164 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2165 * in both situations, go look if you don't believe me! */
2171 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2173 TnyFolderStore *folder_store,
2174 ModestConnectedPerformer callback,
2177 TnyAccount *account = NULL;
2179 if (!folder_store) {
2180 /* We promise to instantly perform the callback, so ... */
2182 callback (FALSE, NULL, parent_window, NULL, user_data);
2186 } else if (TNY_IS_FOLDER (folder_store)) {
2187 /* Get the folder's parent account: */
2188 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2189 } else if (TNY_IS_ACCOUNT (folder_store)) {
2190 /* Use the folder store as an account: */
2191 account = TNY_ACCOUNT (g_object_ref (folder_store));
2194 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
2195 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2196 /* No need to connect a local account */
2198 callback (FALSE, NULL, parent_window, account, user_data);
2203 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2207 g_object_unref (account);
2211 src_account_connect_performer (gboolean canceled,
2213 GtkWindow *parent_window,
2214 TnyAccount *src_account,
2217 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2219 if (canceled || err) {
2220 /* If there was any error call the user callback */
2221 info->callback (canceled, err, parent_window, src_account, info->data);
2223 /* Connect the destination account */
2224 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2225 TNY_FOLDER_STORE (info->dst_account),
2226 info->callback, info->data);
2229 /* Free the info object */
2230 g_object_unref (info->dst_account);
2231 g_slice_free (DoubleConnectionInfo, info);
2236 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2238 TnyFolderStore *folder_store,
2239 DoubleConnectionInfo *connect_info)
2241 modest_platform_connect_if_remote_and_perform(parent_window,
2244 src_account_connect_performer,
2249 modest_platform_get_account_settings_wizard (void)
2251 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2253 return GTK_WIDGET (dialog);
2257 modest_platform_get_current_connection (void)
2259 TnyDevice *device = NULL;
2260 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2262 device = modest_runtime_get_device ();
2264 if (!tny_device_is_online (device))
2265 return MODEST_CONNECTED_VIA_ANY;
2267 #ifdef MODEST_HAVE_CONIC
2269 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2271 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2272 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2273 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2275 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2276 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2277 !strcmp (bearer_type, "WIMAX")) {
2278 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2280 retval = MODEST_CONNECTED_VIA_ANY;
2283 g_object_unref (iap);
2286 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2287 #endif /* MODEST_HAVE_CONIC */
2294 modest_platform_check_memory_low (ModestWindow *win,
2299 /* are we in low memory state? */
2300 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2302 if (win && lowmem && visuals)
2303 modest_platform_run_information_dialog (
2305 dgettext("ke-recv","memr_ib_operation_disabled"),
2309 g_debug ("%s: low memory reached. disallowing some operations",
2316 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2322 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2325 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2326 GTK_WINDOW (dialog),
2328 gtk_widget_show_all (dialog);
2330 g_signal_connect_swapped (dialog, "response",
2331 G_CALLBACK (gtk_widget_destroy),
2336 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2342 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header);
2345 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2346 GTK_WINDOW (dialog),
2348 gtk_widget_show_all (dialog);
2350 g_signal_connect_swapped (dialog, "response",
2351 G_CALLBACK (gtk_widget_destroy),
2356 modest_platform_get_osso_context (void)
2358 return modest_maemo_utils_get_osso_context ();
2362 _modest_platform_play_email_tone (void)
2364 gchar *active_profile;
2367 gint mail_volume_int;
2369 ca_context *ca_con = NULL;
2370 ca_proplist *pl = NULL;
2372 active_profile = profile_get_profile ();
2373 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2374 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2375 mail_volume_int = profile_parse_int (mail_volume);
2377 if (mail_volume_int > 0) {
2379 if ((ret = ca_context_create(&ca_con)) != CA_SUCCESS) {
2380 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2384 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2385 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2386 ca_context_destroy(ca_con);
2390 ca_proplist_create(&pl);
2391 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2392 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", (gfloat) mail_volume_int);
2394 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2395 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2397 ca_proplist_destroy(pl);
2398 ca_context_destroy(ca_con);
2401 g_free (mail_volume);
2403 g_free (active_profile);
2407 on_move_to_dialog_folder_activated (GtkTreeView *tree_view,
2409 GtkTreeViewColumn *column,
2412 gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_OK);
2416 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
2417 GtkWidget **folder_view)
2419 GtkWidget *dialog, *folder_view_container;
2421 /* Create dialog. We cannot use a touch selector because we
2422 need to use here the folder view widget directly */
2423 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2424 GTK_WINDOW (parent_window),
2425 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
2426 GTK_DIALOG_DESTROY_WITH_PARENT,
2427 _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
2430 /* Create folder view */
2431 *folder_view = modest_platform_create_folder_view (NULL);
2433 /* Simulate the behaviour of a HildonPickerDialog by emitting
2434 a response when a folder is selected */
2435 g_signal_connect (*folder_view, "row-activated",
2436 G_CALLBACK (on_move_to_dialog_folder_activated),
2439 /* Create pannable and add it to the dialog */
2440 folder_view_container = hildon_pannable_area_new ();
2441 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
2442 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
2444 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
2446 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
2447 gtk_widget_show (folder_view_container);
2448 gtk_widget_show (*folder_view);
2454 modest_platform_get_list_to_move (ModestWindow *window)
2456 TnyList *list = NULL;
2458 if (MODEST_IS_HEADER_WINDOW (window)) {
2459 ModestHeaderView *header_view;
2461 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
2462 list = modest_header_view_get_selected_headers (header_view);
2463 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
2464 ModestFolderView *folder_view;
2465 TnyFolderStore *selected_folder;
2467 list = TNY_LIST (tny_simple_list_new ());
2468 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
2469 selected_folder = modest_folder_view_get_selected (folder_view);
2470 if (selected_folder) {
2471 tny_list_prepend (list, G_OBJECT (selected_folder));
2472 g_object_unref (selected_folder);
2475 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2478 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
2480 list = TNY_LIST (tny_simple_list_new ());
2481 tny_list_prepend (list, G_OBJECT (header));
2482 g_object_unref (header);
2485 g_return_val_if_reached (NULL);