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-merge-folder.h>
46 #include <tny-error.h>
47 #include <tny-folder.h>
48 #include <tny-account-store-view.h>
49 #include <gtk/gtkicontheme.h>
50 #include <gtk/gtkmenuitem.h>
51 #include <gtk/gtkmain.h>
52 #include <modest-text-utils.h>
53 #include "modest-tny-folder.h"
54 #include "modest-tny-account.h"
56 #include <libgnomevfs/gnome-vfs-mime-utils.h>
57 #include <modest-account-settings-dialog.h>
58 #include <modest-easysetup-wizard-dialog.h>
59 #include "modest-hildon2-sort-dialog.h"
60 #include <hildon/hildon-sound.h>
62 #include "hildon2/modest-hildon2-details-dialog.h"
63 #include "hildon2/modest-hildon2-window-mgr.h"
64 #include <keys_nokia.h>
65 #include <libprofile.h>
67 #include <modest-datetime-formatter.h>
68 #include "modest-header-window.h"
69 #include <modest-folder-window.h>
70 #include <modest-account-mgr.h>
71 #include <modest-account-mgr-helpers.h>
72 #include <modest-ui-constants.h>
73 #include <modest-selector-picker.h>
74 #include <modest-icon-names.h>
76 #ifdef MODEST_HAVE_MCE
77 #include <mce/dbus-names.h>
78 #endif /*MODEST_HAVE_MCE*/
80 #ifdef MODEST_HAVE_ABOOK
81 #include <libosso-abook/osso-abook.h>
82 #endif /*MODEST_HAVE_ABOOK*/
84 #ifdef MODEST_HAVE_LIBALARM
85 #include <alarmd/libalarm.h> /* For alarm_event_add(), etc. */
86 #endif /*MODEST_HAVE_LIBALARM*/
89 #define HILDON_OSSO_URI_ACTION "uri-action"
90 #define URI_ACTION_COPY "copy:"
91 #define MODEST_NEW_MAIL_LIGHTING_PATTERN "PatternCommunicationEmail"
92 #define PROFILE_MAIL_TONE PROFILEKEY_EMAIL_ALERT_TONE
93 #define PROFILE_MAIL_VOLUME PROFILEKEY_EMAIL_ALERT_VOLUME
95 #define COMMON_FOLDER_DIALOG_ENTRY "entry"
96 #define COMMON_FOLDER_DIALOG_ACCOUNT_PICKER "account-picker"
97 #define FOLDER_PICKER_CURRENT_FOLDER "current-folder"
98 #define MODEST_ALARMD_APPID PACKAGE_NAME
101 static void _modest_platform_play_email_tone (void);
105 on_modest_conf_update_interval_changed (ModestConf* self,
107 ModestConfEvent event,
108 ModestConfNotificationId id,
111 g_return_if_fail (key);
113 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
114 const guint update_interval_minutes =
115 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
116 modest_platform_set_update_interval (update_interval_minutes);
123 check_required_files (void)
125 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
127 g_printerr ("modest: check for mcc file failed\n");
132 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
133 access(MODEST_MAEMO_PROVIDER_DATA_FILE, R_OK) != 0) {
134 g_printerr ("modest: cannot find providers data\n");
142 /* the gpointer here is the osso_context. */
144 modest_platform_init (int argc, char *argv[])
146 osso_context_t *osso_context;
148 osso_hw_state_t hw_state = { 0 };
152 if (!check_required_files ()) {
153 g_printerr ("modest: missing required files\n");
157 osso_context = osso_initialize(PACKAGE,PACKAGE_VERSION,
160 g_printerr ("modest: failed to acquire osso context\n");
163 modest_maemo_utils_set_osso_context (osso_context);
165 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
166 g_printerr ("modest: could not get dbus connection\n");
170 /* Add a D-Bus handler to be used when the main osso-rpc
171 * D-Bus handler has not handled something.
172 * We use this for D-Bus methods that need to use more complex types
173 * than osso-rpc supports.
175 if (!dbus_connection_add_filter (con,
176 modest_dbus_req_filter,
180 g_printerr ("modest: Could not add D-Bus filter\n");
184 /* Register our simple D-Bus callbacks, via the osso API: */
185 osso_return_t result = osso_rpc_set_cb_f(osso_context,
189 modest_dbus_req_handler, NULL /* user_data */);
190 if (result != OSSO_OK) {
191 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
195 /* Register hardware event dbus callback: */
196 hw_state.shutdown_ind = TRUE;
197 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
199 /* Register osso auto-save callbacks: */
200 result = osso_application_set_autosave_cb (osso_context,
201 modest_on_osso_application_autosave, NULL /* user_data */);
202 if (result != OSSO_OK) {
203 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
208 /* Make sure that the update interval is changed whenever its gconf key
210 /* CAUTION: we're not using here the
211 modest_conf_listen_to_namespace because we know that there
212 are other parts of Modest listening for this namespace, so
213 we'll receive the notifications anyway. We basically do not
214 use it because there is no easy way to do the
215 modest_conf_forget_namespace */
216 ModestConf *conf = modest_runtime_get_conf ();
217 g_signal_connect (G_OBJECT(conf),
219 G_CALLBACK (on_modest_conf_update_interval_changed),
222 /* only force the setting of the default interval, if there are actually
224 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
226 /* Get the initial update interval from gconf: */
227 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
228 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
229 modest_account_mgr_free_account_names (acc_names);
233 #ifdef MODEST_HAVE_ABOOK
234 /* initialize the addressbook */
235 if (!osso_abook_init (&argc, &argv, osso_context)) {
236 g_printerr ("modest: failed to initialized addressbook\n");
239 #endif /*MODEST_HAVE_ABOOK*/
245 modest_platform_uninit (void)
247 osso_context_t *osso_context =
248 modest_maemo_utils_get_osso_context ();
250 osso_deinitialize (osso_context);
259 modest_platform_get_new_device (void)
261 return TNY_DEVICE (tny_maemo_conic_device_new ());
265 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
266 gchar **effective_mime_type)
268 GString *mime_str = NULL;
269 gchar *icon_name = NULL;
270 gchar **icons, **cursor;
272 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
273 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
275 mime_str = g_string_new (mime_type);
276 g_string_ascii_down (mime_str);
279 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
281 for (cursor = icons; cursor; ++cursor) {
282 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
283 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
284 icon_name = g_strdup ("qgn_list_messagin");
286 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
287 icon_name = g_strdup (*cursor);
293 if (effective_mime_type)
294 *effective_mime_type = g_string_free (mime_str, FALSE);
296 g_string_free (mime_str, TRUE);
303 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
308 g_return_val_if_fail (uri, FALSE);
310 result = hildon_uri_open (uri, action, &err);
312 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
313 uri, action, err && err->message ? err->message : "unknown error");
323 modest_platform_activate_uri (const gchar *uri)
325 HildonURIAction *action;
326 gboolean result = FALSE;
327 GSList *actions, *iter = NULL;
329 g_return_val_if_fail (uri, FALSE);
333 /* don't try to activate file: uri's -- they might confuse the user,
334 * and/or might have security implications */
335 if (!g_str_has_prefix (uri, "file:")) {
337 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
339 for (iter = actions; iter; iter = g_slist_next (iter)) {
340 action = (HildonURIAction*) iter->data;
341 if (action && strcmp (hildon_uri_action_get_service (action),
342 "com.nokia.modest") == 0) {
343 result = checked_hildon_uri_open (uri, action);
348 /* if we could not open it with email, try something else */
350 result = checked_hildon_uri_open (uri, NULL);
354 ModestWindow *parent =
355 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
356 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
357 _("mcen_ib_unsupported_link"));
358 g_warning ("%s: cannot open uri '%s'", __FUNCTION__,uri);
365 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
369 gchar *uri_path = NULL;
371 uri_path = gnome_vfs_get_uri_from_local_path (path);
372 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
375 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
377 result = hildon_mime_open_file (con, uri_path);
379 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
387 } ModestPlatformPopupInfo;
390 delete_uri_popup (GtkWidget *menu,
394 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
396 g_free (popup_info->uri);
397 hildon_uri_free_actions (popup_info->actions);
403 activate_uri_popup_item (GtkMenuItem *menu_item,
407 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
408 const gchar* action_name;
410 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
412 g_printerr ("modest: no action name defined\n");
416 /* special handling for the copy menu item -- copy the uri to the clipboard */
417 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
418 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
419 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
420 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
422 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
423 action_name += strlen ("mailto:");
425 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
426 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
427 return; /* we're done */
430 /* now, the real uri-actions... */
431 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
432 HildonURIAction *action = (HildonURIAction *) node->data;
433 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
434 if (!checked_hildon_uri_open (popup_info->uri, action)) {
435 ModestWindow *parent =
436 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
437 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
438 _("mcen_ib_unsupported_link"));
446 modest_platform_show_uri_popup (const gchar *uri)
448 GSList *actions_list;
453 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
456 GtkWidget *menu = gtk_menu_new ();
457 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
459 /* don't add actions for file: uri's -- they might confuse the user,
460 * and/or might have security implications
461 * we still allow to copy the url though
463 if (!g_str_has_prefix (uri, "file:")) {
466 popup_info->actions = actions_list;
467 popup_info->uri = g_strdup (uri);
469 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
470 GtkWidget *menu_item;
471 const gchar *action_name;
472 const gchar *translation_domain;
473 HildonURIAction *action = (HildonURIAction *) node->data;
474 action_name = hildon_uri_action_get_name (action);
475 translation_domain = hildon_uri_action_get_translation_domain (action);
476 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
477 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
478 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
481 if (hildon_uri_is_default_action (action, NULL)) {
482 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
484 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
486 gtk_widget_show (menu_item);
491 /* and what to do when the link is deleted */
492 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
493 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
496 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
504 modest_platform_get_icon (const gchar *name, guint icon_size)
507 GdkPixbuf* pixbuf = NULL;
508 GtkIconTheme *current_theme = NULL;
510 g_return_val_if_fail (name, NULL);
512 /* strlen == 0 is not really an error; it just
513 * means the icon is not available
515 if (!name || strlen(name) == 0)
518 current_theme = gtk_icon_theme_get_default ();
519 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
520 GTK_ICON_LOOKUP_NO_SVG,
523 g_printerr ("modest: error loading theme icon '%s': %s\n",
531 modest_platform_get_app_name (void)
533 return _("mcen_ap_name");
537 entry_insert_text (GtkEditable *editable,
546 chars = gtk_editable_get_chars (editable, 0, -1);
547 chars_length = g_utf8_strlen (chars, -1);
550 /* Show WID-INF036 */
551 if (chars_length >= 20) {
552 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
553 _CS("ckdg_ib_maximum_characters_reached"));
555 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
559 tmp = g_strndup (folder_name_forbidden_chars,
560 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
561 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
562 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
567 /* Write the text in the entry if it's valid */
568 g_signal_handlers_block_by_func (editable,
569 (gpointer) entry_insert_text, data);
570 gtk_editable_insert_text (editable, text, length, position);
571 g_signal_handlers_unblock_by_func (editable,
572 (gpointer) entry_insert_text, data);
575 /* Do not allow further processing */
576 g_signal_stop_emission_by_name (editable, "insert_text");
580 entry_changed (GtkEditable *editable,
584 GtkWidget *ok_button;
587 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
588 ok_button = GTK_WIDGET (buttons->data);
590 chars = gtk_editable_get_chars (editable, 0, -1);
591 g_return_if_fail (chars != NULL);
594 if (g_utf8_strlen (chars,-1) >= 20)
595 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
596 _CS("ckdg_ib_maximum_characters_reached"));
598 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
601 g_list_free (buttons);
608 on_response (GtkDialog *dialog,
612 GtkWidget *entry, *picker;
613 TnyFolderStore *parent;
614 const gchar *new_name;
617 if (response != GTK_RESPONSE_ACCEPT)
621 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
622 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
624 parent = TNY_FOLDER_STORE (user_data);
625 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
628 if (picker != NULL) {
630 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
633 /* Look for another folder with the same name */
634 if (modest_tny_folder_has_subfolder_with_name (parent,
641 if (TNY_IS_ACCOUNT (parent) &&
642 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
643 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
652 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
653 NULL, _CS("ckdg_ib_folder_already_exists"));
654 /* Select the text */
655 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
656 gtk_widget_grab_focus (entry);
657 /* Do not close the dialog */
658 g_signal_stop_emission_by_name (dialog, "response");
663 typedef struct _FolderChooserData {
664 TnyFolderStore *store;
669 folder_chooser_activated (ModestFolderView *folder_view,
670 TnyFolderStore *folder,
671 FolderChooserData *userdata)
673 userdata->store = folder;
674 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
677 static TnyFolderStore *
678 folder_chooser_dialog_run (ModestFolderView *original)
680 GtkWidget *folder_view;
681 FolderChooserData userdata = {NULL, NULL};
683 const gchar *visible_id = NULL;
685 userdata.dialog = hildon_dialog_new ();
686 pannable = hildon_pannable_area_new ();
687 folder_view = modest_platform_create_folder_view (NULL);
688 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
689 MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS);
691 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original),
692 MODEST_FOLDER_VIEW (folder_view));
695 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original));
696 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
699 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
700 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
701 gtk_widget_set_size_request (pannable, -1, 320);
703 gtk_widget_show (folder_view);
704 gtk_widget_show (pannable);
705 gtk_widget_show (userdata.dialog);
706 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
707 G_CALLBACK (folder_chooser_activated),
708 (gpointer) &userdata);
710 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
711 gtk_widget_destroy (userdata.dialog);
713 return userdata.store;
717 folder_store_get_display_name (TnyFolderStore *store)
719 if (TNY_IS_ACCOUNT (store)) {
720 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
723 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
725 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
726 type = tny_folder_get_folder_type (TNY_FOLDER (store));
727 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
728 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
729 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
730 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
732 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
735 /* Sometimes an special folder is reported by the server as
736 NORMAL, like some versions of Dovecot */
737 if (type == TNY_FOLDER_TYPE_NORMAL ||
738 type == TNY_FOLDER_TYPE_UNKNOWN) {
739 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
743 if (type == TNY_FOLDER_TYPE_INBOX) {
745 fname = g_strdup (_("mcen_me_folder_inbox"));
752 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
757 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
760 const gchar *icon_name = NULL;
762 g_object_ref (store);
763 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
764 store, (GDestroyNotify) g_object_unref);
765 name = folder_store_get_display_name (store);
766 hildon_button_set_value (HILDON_BUTTON (button), name);
770 if (TNY_IS_ACCOUNT (store)) {
771 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (store)))
772 icon_name = MODEST_FOLDER_ICON_LOCAL_FOLDERS;
773 else if (modest_tny_account_is_memory_card_account (TNY_ACCOUNT (store)))
774 icon_name = MODEST_FOLDER_ICON_MMC;
776 icon_name = MODEST_FOLDER_ICON_ACCOUNT;
778 if (modest_tny_folder_is_remote_folder (TNY_FOLDER (store))) {
779 TnyFolderType type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
781 case TNY_FOLDER_TYPE_INBOX:
782 icon_name = MODEST_FOLDER_ICON_INBOX;
785 icon_name = MODEST_FOLDER_ICON_ACCOUNT;
787 } else if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)))
788 icon_name = MODEST_FOLDER_ICON_NORMAL;
789 else if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store)))
790 icon_name = MODEST_FOLDER_ICON_MMC_FOLDER;
794 pixbuf = modest_platform_get_icon (icon_name, MODEST_ICON_SIZE_SMALL);
797 hildon_button_set_image (HILDON_BUTTON (button),
798 gtk_image_new_from_pixbuf (pixbuf));
799 g_object_unref (pixbuf);
805 folder_picker_clicked (GtkButton *button,
806 ModestFolderView *folder_view)
808 TnyFolderStore *store;
810 store = folder_chooser_dialog_run (folder_view);
812 folder_picker_set_store (GTK_BUTTON (button), store);
817 folder_picker_new (ModestFolderView *folder_view, TnyFolderStore *suggested)
821 button = hildon_button_new (MODEST_EDITABLE_SIZE,
822 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
824 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
827 folder_picker_set_store (GTK_BUTTON (button), suggested);
830 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (folder_picker_clicked), folder_view);
837 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
838 TnyFolderStore *suggested_parent,
839 const gchar *dialog_title,
840 const gchar *label_text,
841 const gchar *suggested_name,
843 gboolean show_parent,
845 TnyFolderStore **parent)
847 GtkWidget *accept_btn = NULL;
848 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
849 GtkWidget *account_picker = NULL;
850 GList *buttons = NULL;
852 GtkSizeGroup *sizegroup;
853 ModestFolderView *folder_view;
854 ModestWindow *folder_window;
855 ModestHildon2WindowMgr *window_mgr;
857 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
858 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
859 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
861 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
863 /* Ask the user for the folder name */
864 dialog = gtk_dialog_new_with_buttons (dialog_title,
866 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
867 _FM("ckdg_bd_new_folder_dialog_ok"),
871 /* Add accept button (with unsensitive handler) */
872 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
873 accept_btn = GTK_WIDGET (buttons->data);
875 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
878 label_entry = gtk_label_new (label_text);
879 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
880 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
882 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
883 gtk_size_group_add_widget (sizegroup, label_entry);
886 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
888 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
889 gtk_entry_set_width_chars (GTK_ENTRY (entry),
890 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
891 g_utf8_strlen (_("mcen_ia_default_folder_name"), -1)));
892 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
897 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
899 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
900 gtk_size_group_add_widget (sizegroup, label_location);
902 account_picker = folder_picker_new (folder_view, suggested_parent);
905 g_object_unref (sizegroup);
907 /* Connect to the response method to avoid closing the dialog
908 when an invalid name is selected*/
909 g_signal_connect (dialog,
911 G_CALLBACK (on_response),
915 /* Track entry changes */
916 g_signal_connect (entry,
918 G_CALLBACK (entry_insert_text),
920 g_signal_connect (entry,
922 G_CALLBACK (entry_changed),
927 /* Some locales like pt_BR need this to get the full window
929 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
931 /* Create the hbox */
933 hbox = gtk_hbox_new (FALSE, 12);
934 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
935 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
937 /* Add hbox to dialog */
938 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
939 hbox, FALSE, FALSE, 0);
940 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
944 hbox = gtk_hbox_new (FALSE, 12);
945 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
946 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
948 /* Add hbox to dialog */
949 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
950 hbox, FALSE, FALSE, 0);
951 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
953 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
954 GTK_WINDOW (dialog), parent_window);
955 gtk_widget_show_all (GTK_WIDGET(dialog));
957 result = gtk_dialog_run (GTK_DIALOG(dialog));
958 if (result == GTK_RESPONSE_ACCEPT) {
960 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
962 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
964 g_object_ref (*parent);
968 gtk_widget_destroy (dialog);
970 while (gtk_events_pending ())
971 gtk_main_iteration ();
977 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
978 TnyFolderStore *suggested_folder,
979 gchar *suggested_name,
981 TnyFolderStore **parent_folder)
983 gchar *real_suggested_name = NULL, *tmp = NULL;
985 ModestTnyAccountStore *acc_store;
988 if(suggested_name == NULL)
990 const gchar *default_name = _("mcen_ia_default_folder_name");
994 for(i = 0; i < 100; ++ i) {
995 gboolean exists = FALSE;
997 sprintf(num_str, "%.2u", i);
1000 real_suggested_name = g_strdup (default_name);
1002 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
1004 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
1005 real_suggested_name,
1011 g_free (real_suggested_name);
1014 /* Didn't find a free number */
1016 real_suggested_name = g_strdup (default_name);
1018 real_suggested_name = suggested_name;
1021 /* In hildon 2.2 we always suggest the archive folder as parent */
1022 acc_store = modest_runtime_get_account_store ();
1023 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
1025 suggested_folder = (TnyFolderStore *)
1026 modest_tny_account_get_special_folder (account,
1027 TNY_FOLDER_TYPE_ARCHIVE);
1028 g_object_unref (account);
1032 /* If there is not archive folder then fallback to local folders account */
1033 if (!suggested_folder)
1034 suggested_folder = (TnyFolderStore *)
1035 modest_tny_account_store_get_local_folders_account (acc_store);
1037 tmp = g_strconcat (_("mcen_fi_new_folder_name"), ":", NULL);
1038 result = modest_platform_run_folder_common_dialog (parent_window,
1040 _("mcen_ti_new_folder"),
1042 real_suggested_name,
1049 if (suggested_name == NULL)
1050 g_free(real_suggested_name);
1056 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1057 TnyFolderStore *parent_folder,
1058 const gchar *suggested_name,
1059 gchar **folder_name)
1061 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1063 return modest_platform_run_folder_common_dialog (parent_window,
1065 _HL("ckdg_ti_rename_folder"),
1066 _HL("ckdg_fi_rename_name"),
1077 on_destroy_dialog (GtkWidget *dialog)
1079 /* This could happen when the dialogs get programatically
1080 hidden or destroyed (for example when closing the
1081 application while a dialog is being shown) */
1082 if (!GTK_IS_WIDGET (dialog))
1085 gtk_widget_destroy (dialog);
1087 if (gtk_events_pending ())
1088 gtk_main_iteration ();
1092 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1093 const gchar *message)
1098 dialog = hildon_note_new_confirmation (parent_window, message);
1099 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1100 GTK_WINDOW (dialog), parent_window);
1102 response = gtk_dialog_run (GTK_DIALOG (dialog));
1104 on_destroy_dialog (dialog);
1110 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1111 const gchar *message,
1112 const gchar *button_accept,
1113 const gchar *button_cancel)
1118 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1119 button_accept, GTK_RESPONSE_ACCEPT,
1120 button_cancel, GTK_RESPONSE_CANCEL,
1123 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1124 GTK_WINDOW (dialog), parent_window);
1126 response = gtk_dialog_run (GTK_DIALOG (dialog));
1128 on_destroy_dialog (dialog);
1134 modest_platform_run_information_dialog (GtkWindow *parent_window,
1135 const gchar *message,
1140 note = hildon_note_new_information (parent_window, message);
1142 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1143 GTK_WINDOW (note), parent_window);
1146 gtk_dialog_run (GTK_DIALOG (note));
1148 on_destroy_dialog (note);
1150 g_signal_connect_swapped (note,
1152 G_CALLBACK (on_destroy_dialog),
1155 gtk_widget_show_all (note);
1159 typedef struct _ConnectAndWaitData {
1161 GMainLoop *wait_loop;
1162 gboolean has_callback;
1164 } ConnectAndWaitData;
1168 quit_wait_loop (TnyAccount *account,
1169 ConnectAndWaitData *data)
1171 /* Set the has_callback to TRUE (means that the callback was
1172 executed and wake up every code waiting for cond to be
1174 g_mutex_lock (data->mutex);
1175 data->has_callback = TRUE;
1176 if (data->wait_loop)
1177 g_main_loop_quit (data->wait_loop);
1178 g_mutex_unlock (data->mutex);
1182 on_connection_status_changed (TnyAccount *account,
1183 TnyConnectionStatus status,
1186 TnyConnectionStatus conn_status;
1187 ConnectAndWaitData *data;
1189 /* Ignore if reconnecting or disconnected */
1190 conn_status = tny_account_get_connection_status (account);
1191 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1192 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1195 /* Remove the handler */
1196 data = (ConnectAndWaitData *) user_data;
1197 g_signal_handler_disconnect (account, data->handler);
1199 /* Quit from wait loop */
1200 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1204 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1209 /* Quit from wait loop */
1210 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1214 modest_platform_connect_and_wait (GtkWindow *parent_window,
1215 TnyAccount *account)
1217 ConnectAndWaitData *data = NULL;
1218 gboolean device_online;
1220 TnyConnectionStatus conn_status;
1221 gboolean user_requested;
1223 device = modest_runtime_get_device();
1224 device_online = tny_device_is_online (device);
1226 /* Whether the connection is user requested or automatically
1227 requested, for example via D-Bus */
1228 user_requested = (parent_window) ? TRUE : FALSE;
1230 /* If there is no account check only the device status */
1235 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1236 NULL, user_requested);
1239 /* Return if the account is already connected */
1240 conn_status = tny_account_get_connection_status (account);
1241 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1244 /* Create the helper */
1245 data = g_slice_new0 (ConnectAndWaitData);
1246 data->mutex = g_mutex_new ();
1247 data->has_callback = FALSE;
1249 /* Connect the device */
1250 if (!device_online) {
1251 /* Track account connection status changes */
1252 data->handler = g_signal_connect (account, "connection-status-changed",
1253 G_CALLBACK (on_connection_status_changed),
1255 /* Try to connect the device */
1256 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1257 NULL, user_requested);
1259 /* If the device connection failed then exit */
1260 if (!device_online && data->handler)
1263 /* Force a reconnection of the account */
1264 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1265 on_tny_camel_account_set_online_cb, data);
1268 /* Wait until the callback is executed */
1269 g_mutex_lock (data->mutex);
1270 if (!data->has_callback) {
1271 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1272 gdk_threads_leave ();
1273 g_mutex_unlock (data->mutex);
1274 g_main_loop_run (data->wait_loop);
1275 g_mutex_lock (data->mutex);
1276 gdk_threads_enter ();
1278 g_mutex_unlock (data->mutex);
1282 if (g_signal_handler_is_connected (account, data->handler))
1283 g_signal_handler_disconnect (account, data->handler);
1284 g_mutex_free (data->mutex);
1285 g_main_loop_unref (data->wait_loop);
1286 g_slice_free (ConnectAndWaitData, data);
1289 conn_status = tny_account_get_connection_status (account);
1290 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1294 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1296 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1297 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1298 /* This must be a maildir account, which does not require a connection: */
1303 return modest_platform_connect_and_wait (parent_window, account);
1307 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1310 return TRUE; /* Maybe it is something local. */
1312 gboolean result = TRUE;
1313 if (TNY_IS_FOLDER (folder_store)) {
1314 /* Get the folder's parent account: */
1315 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1316 if (account != NULL) {
1317 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1318 g_object_unref (account);
1320 } else if (TNY_IS_ACCOUNT (folder_store)) {
1321 /* Use the folder store as an account: */
1322 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1329 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1333 dialog = modest_hildon2_sort_dialog_new (parent_window);
1340 modest_platform_set_update_interval (guint minutes)
1342 #ifdef MODEST_HAVE_LIBALARM
1344 ModestConf *conf = modest_runtime_get_conf ();
1348 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1350 /* Delete any existing alarm,
1351 * because we will replace it: */
1353 if (alarmd_event_del(alarm_cookie) != 0)
1354 g_warning ("%s: alarm %d was not on the queue", __FUNCTION__, (int)alarm_cookie);
1356 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1359 /* 0 means no updates: */
1364 /* Register alarm: */
1366 /* Set the interval in alarm_event_t structure: */
1367 alarm_event_t *event = alarm_event_create ();
1368 alarm_event_add_actions (event, 1);
1369 alarm_action_t *action = alarm_event_get_action (event, 0);
1370 alarm_event_set_alarm_appid (event, MODEST_ALARMD_APPID);
1371 event->alarm_time = minutes * 60; /* seconds */
1373 /* Set recurrence every few minutes: */
1374 event->recur_secs = minutes*60;
1375 event->recur_count = -1; /* Means infinite */
1377 /* Specify what should happen when the alarm happens:
1378 * It should call this D-Bus method: */
1380 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1381 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1382 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1383 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1384 action->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1386 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1387 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1388 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1389 * This is why we want to use the Alarm API instead of just g_timeout_add().
1390 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1391 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1393 event->flags = ALARM_EVENT_CONNECTED;
1395 alarm_cookie = alarmd_event_add (event);
1398 alarm_event_delete (event);
1400 /* Store the alarm ID in GConf, so we can remove it later:
1401 * This is apparently valid between application instances. */
1402 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1404 if (!alarm_cookie) {
1406 g_debug ("Error setting alarm event. \n");
1410 #endif /* MODEST_HAVE_LIBALARM */
1415 modest_platform_push_email_notification(void)
1417 gboolean screen_on, app_in_foreground;
1419 /* Get the window status */
1420 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1422 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1424 /* If the screen is on and the app is in the
1425 foreground we don't show anything */
1426 if (!(screen_on && app_in_foreground)) {
1428 _modest_platform_play_email_tone ();
1430 /* Activate LED. This must be deactivated by
1431 modest_platform_remove_new_mail_notifications */
1432 #ifdef MODEST_HAVE_MCE
1433 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1437 MCE_ACTIVATE_LED_PATTERN,
1439 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1446 modest_platform_on_new_headers_received (TnyList *header_list,
1447 gboolean show_visual)
1449 g_return_if_fail (TNY_IS_LIST(header_list));
1451 if (tny_list_get_length(header_list) == 0) {
1452 g_warning ("%s: header list is empty", __FUNCTION__);
1457 modest_platform_push_email_notification ();
1458 /* We do a return here to avoid indentation with an else */
1462 #ifdef MODEST_HAVE_HILDON_NOTIFY
1463 HildonNotification *notification;
1465 GSList *notifications_list = NULL;
1467 /* Get previous notifications ids */
1468 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1469 MODEST_CONF_NOTIFICATION_IDS,
1470 MODEST_CONF_VALUE_INT, NULL);
1472 iter = tny_list_create_iterator (header_list);
1473 while (!tny_iterator_is_done (iter)) {
1474 gchar *url = NULL, *display_address = NULL, *summary = NULL;
1475 const gchar *display_date;
1476 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1477 TnyFolder *folder = tny_header_get_folder (header);
1478 gboolean first_notification = TRUE;
1481 ModestDatetimeFormatter *datetime_formatter;
1483 /* constant string, don't free */
1484 datetime_formatter = modest_datetime_formatter_new ();
1485 display_date = modest_datetime_formatter_display_datetime (datetime_formatter,
1486 tny_header_get_date_received (header));
1487 g_object_unref (datetime_formatter);
1489 display_address = tny_header_dup_from (header);
1490 /* string is changed in-place */
1491 modest_text_utils_get_display_address (display_address);
1493 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1494 str = tny_header_dup_subject (header);
1495 notification = hildon_notification_new (summary,
1497 "qgn_list_messagin",
1500 /* Create the message URL */
1501 str = tny_header_dup_uid (header);
1502 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1506 hildon_notification_add_dbus_action(notification,
1509 MODEST_DBUS_SERVICE,
1512 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1516 /* Play sound if the user wants. Show the LED
1517 pattern. Show and play just one */
1518 if (G_UNLIKELY (first_notification)) {
1519 gchar *active_profile;
1522 gint mail_volume_int;
1524 first_notification = FALSE;
1526 active_profile = profile_get_profile ();
1527 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
1528 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
1529 mail_volume_int = profile_parse_int (mail_volume);
1531 if (mail_volume_int > 0)
1532 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1533 "sound-file", mail_tone);
1535 g_free (mail_volume);
1537 g_free (active_profile);
1539 /* Set the led pattern */
1540 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1542 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1544 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1547 /* Notify. We need to do this in an idle because this function
1548 could be called from a thread */
1549 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1551 /* Save id in the list */
1552 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1553 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1554 /* We don't listen for the "closed" signal, because we
1555 don't care about if the notification was removed or
1556 not to store the list in gconf */
1558 /* Free & carry on */
1559 g_free (display_address);
1562 g_object_unref (folder);
1563 g_object_unref (header);
1564 tny_iterator_next (iter);
1566 g_object_unref (iter);
1569 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1570 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1572 g_slist_free (notifications_list);
1574 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1578 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1581 #ifdef MODEST_HAVE_MCE
1582 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1586 MCE_DEACTIVATE_LED_PATTERN,
1588 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1594 #ifdef MODEST_HAVE_HILDON_NOTIFY
1595 GSList *notif_list = NULL;
1597 /* Get previous notifications ids */
1598 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1599 MODEST_CONF_NOTIFICATION_IDS,
1600 MODEST_CONF_VALUE_INT, NULL);
1602 while (notif_list) {
1604 NotifyNotification *notif;
1606 /* Nasty HACK to remove the notifications, set the id
1607 of the existing ones and then close them */
1608 notif_id = GPOINTER_TO_INT(notif_list->data);
1609 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1610 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1612 /* Close the notification, note that some ids could be
1613 already invalid, but we don't care because it does
1615 notify_notification_close(notif, NULL);
1616 g_object_unref(notif);
1618 /* Delete the link, it's like going to the next */
1619 notif_list = g_slist_delete_link (notif_list, notif_list);
1623 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1624 notif_list, MODEST_CONF_VALUE_INT, NULL);
1626 g_slist_free (notif_list);
1628 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1634 modest_platform_get_global_settings_dialog ()
1636 return modest_hildon2_global_settings_dialog_new ();
1640 modest_platform_show_help (GtkWindow *parent_window,
1641 const gchar *help_id)
1647 modest_platform_show_search_messages (GtkWindow *parent_window)
1649 osso_return_t result = OSSO_ERROR;
1651 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1652 "osso_global_search",
1653 "search_email", NULL, DBUS_TYPE_INVALID);
1655 if (result != OSSO_OK) {
1656 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1661 modest_platform_show_addressbook (GtkWindow *parent_window)
1663 osso_return_t result = OSSO_ERROR;
1665 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1667 "top_application", NULL, DBUS_TYPE_INVALID);
1669 if (result != OSSO_OK) {
1670 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1675 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1677 GtkWidget *widget = modest_folder_view_new (query);
1679 /* Show one account by default */
1680 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1681 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1683 /* Restore settings */
1684 modest_widget_memory_restore (modest_runtime_get_conf(),
1686 MODEST_CONF_FOLDER_VIEW_KEY);
1692 banner_finish (gpointer data, GObject *object)
1694 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1695 modest_window_mgr_unregister_banner (mgr);
1696 g_object_unref (mgr);
1700 modest_platform_information_banner (GtkWidget *parent,
1701 const gchar *icon_name,
1704 GtkWidget *banner, *banner_parent = NULL;
1705 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1707 if (modest_window_mgr_get_num_windows (mgr) == 0)
1710 if (parent && GTK_IS_WINDOW (parent)) {
1711 /* If the window is the active one then show the
1712 banner on top of this window */
1713 if (gtk_window_is_active (GTK_WINDOW (parent)))
1714 banner_parent = parent;
1715 /* If the window is not the topmost but it's visible
1716 (it's minimized for example) then show the banner
1718 else if (GTK_WIDGET_VISIBLE (parent))
1719 banner_parent = NULL;
1720 /* If the window is hidden (like the main window when
1721 running in the background) then do not show
1728 banner = hildon_banner_show_information (banner_parent, icon_name, text);
1730 modest_window_mgr_register_banner (mgr);
1732 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1736 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1737 const gchar *icon_name,
1743 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1746 banner = hildon_banner_show_information (parent, icon_name, text);
1747 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1751 modest_platform_animation_banner (GtkWidget *parent,
1752 const gchar *animation_name,
1755 GtkWidget *inf_note = NULL;
1757 g_return_val_if_fail (text != NULL, NULL);
1759 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1762 /* If the parent is not visible then do not show */
1763 if (parent && !GTK_WIDGET_VISIBLE (parent))
1766 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1774 TnyAccount *account;
1777 } CheckAccountIdleData;
1779 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1782 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1784 gboolean stop_trying = FALSE;
1785 g_return_val_if_fail (data && data->account, FALSE);
1787 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__,
1788 tny_account_get_connection_status (data->account));
1790 if (data && data->account &&
1791 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1792 * after which the account is likely to be usable, or never likely to be usable soon: */
1793 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1795 data->is_online = TRUE;
1799 /* Give up if we have tried too many times: */
1800 if (data->count_tries >= NUMBER_OF_TRIES) {
1803 /* Wait for another timeout: */
1804 ++(data->count_tries);
1809 /* Allow the function that requested this idle callback to continue: */
1811 g_main_loop_quit (data->loop);
1814 g_object_unref (data->account);
1816 return FALSE; /* Don't call this again. */
1818 return TRUE; /* Call this timeout callback again. */
1822 /* Return TRUE immediately if the account is already online,
1823 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1824 * soon as the account is online, or FALSE if the account does
1825 * not become online in the NUMBER_OF_TRIES seconds.
1826 * This is useful when the D-Bus method was run immediately after
1827 * the application was started (when using D-Bus activation),
1828 * because the account usually takes a short time to go online.
1829 * The return value is maybe not very useful.
1832 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1836 g_return_val_if_fail (account, FALSE);
1838 if (!tny_device_is_online (modest_runtime_get_device())) {
1839 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1843 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1844 * so we avoid wait unnecessarily: */
1845 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1848 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1849 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1850 * we want to avoid. */
1851 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1854 /* This blocks on the result: */
1855 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1856 data->is_online = FALSE;
1857 data->account = account;
1858 g_object_ref (data->account);
1859 data->count_tries = 0;
1861 GMainContext *context = NULL; /* g_main_context_new (); */
1862 data->loop = g_main_loop_new (context, FALSE /* not running */);
1864 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
1866 /* This main loop will run until the idle handler has stopped it: */
1867 g_main_loop_run (data->loop);
1869 g_main_loop_unref (data->loop);
1870 /* g_main_context_unref (context); */
1872 is_online = data->is_online;
1873 g_slice_free (CheckAccountIdleData, data);
1881 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1883 /* GTK_RESPONSE_HELP means we need to show the certificate */
1884 if (response_id == GTK_RESPONSE_APPLY) {
1888 /* Do not close the dialog */
1889 g_signal_stop_emission_by_name (dialog, "response");
1891 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1892 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1893 gtk_dialog_run (GTK_DIALOG(note));
1894 gtk_widget_destroy (note);
1900 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
1901 const gchar *certificate)
1906 HildonWindowStack *stack;
1908 stack = hildon_window_stack_get_default ();
1909 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1912 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1917 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1920 /* We use GTK_RESPONSE_APPLY because we want the button in the
1921 middle of OK and CANCEL the same as the browser does for
1922 example. With GTK_RESPONSE_HELP the view button is aligned
1923 to the left while the other two to the right */
1924 note = hildon_note_new_confirmation_add_buttons (
1927 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
1928 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
1929 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
1932 g_signal_connect (G_OBJECT(note), "response",
1933 G_CALLBACK(on_cert_dialog_response),
1934 (gpointer) certificate);
1936 response = gtk_dialog_run(GTK_DIALOG(note));
1938 on_destroy_dialog (note);
1941 return response == GTK_RESPONSE_OK;
1945 modest_platform_run_alert_dialog (const gchar* prompt,
1946 gboolean is_question)
1948 ModestWindow *top_win;
1949 HildonWindowStack *stack;
1951 stack = hildon_window_stack_get_default ();
1952 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1955 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1960 gboolean retval = TRUE;
1962 /* The Tinymail documentation says that we should show Yes and No buttons,
1963 * when it is a question.
1964 * Obviously, we need tinymail to use more specific error codes instead,
1965 * so we know what buttons to show. */
1966 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
1968 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1969 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
1971 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1972 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1974 on_destroy_dialog (dialog);
1976 /* Just show the error text and use the default response: */
1977 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
1985 GtkWindow *parent_window;
1986 ModestConnectedPerformer callback;
1987 TnyAccount *account;
1994 on_went_online_info_free (OnWentOnlineInfo *info)
1996 /* And if we cleanup, we DO cleanup :-) */
1999 g_object_unref (info->device);
2002 if (info->parent_window)
2003 g_object_unref (info->parent_window);
2005 g_object_unref (info->account);
2007 g_slice_free (OnWentOnlineInfo, info);
2009 /* We're done ... */
2015 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
2017 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2019 /* Now it's really time to callback to the caller. If going online didn't succeed,
2020 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
2021 * canceled will be set. Etcetera etcetera. */
2023 if (info->callback) {
2024 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2027 /* This is our last call, we must cleanup here if we didn't yet do that */
2028 on_went_online_info_free (info);
2035 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2037 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2038 info->iap = g_strdup (iap_id);
2040 if (canceled || err || !info->account) {
2042 /* If there's a problem or if there's no account (then that's it for us, we callback
2043 * the caller's callback now. He'll have to handle err or canceled, of course.
2044 * We are not really online, as the account is not really online here ... */
2046 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2047 * this info. We don't cleanup err, Tinymail does that! */
2049 if (info->callback) {
2051 /* info->account can be NULL here, this means that the user did not
2052 * provide a nice account instance. We'll assume that the user knows
2053 * what he's doing and is happy with just the device going online.
2055 * We can't do magic, we don't know what account the user wants to
2056 * see going online. So just the device goes online, end of story */
2058 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2061 } else if (info->account) {
2063 /* If there's no problem and if we have an account, we'll put the account
2064 * online too. When done, the callback of bringing the account online
2065 * will callback the caller's callback. This is the most normal case. */
2067 info->device = TNY_DEVICE (g_object_ref (device));
2069 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2070 on_account_went_online, info);
2072 /* The on_account_went_online cb frees up the info, go look if you
2073 * don't believe me! (so we return here) */
2078 /* We cleanup if we are not bringing the account online too */
2079 on_went_online_info_free (info);
2085 modest_platform_connect_and_perform (GtkWindow *parent_window,
2087 TnyAccount *account,
2088 ModestConnectedPerformer callback,
2091 gboolean device_online;
2093 TnyConnectionStatus conn_status;
2094 OnWentOnlineInfo *info;
2096 device = modest_runtime_get_device();
2097 device_online = tny_device_is_online (device);
2099 /* If there is no account check only the device status */
2102 if (device_online) {
2104 /* We promise to instantly perform the callback, so ... */
2106 callback (FALSE, NULL, parent_window, account, user_data);
2111 info = g_slice_new0 (OnWentOnlineInfo);
2114 info->device = NULL;
2115 info->account = NULL;
2118 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2120 info->parent_window = NULL;
2121 info->user_data = user_data;
2122 info->callback = callback;
2124 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2125 force, on_conic_device_went_online,
2128 /* We'll cleanup in on_conic_device_went_online */
2131 /* The other code has no more reason to run. This is all that we can do for the
2132 * caller (he should have given us a nice and clean account instance!). We
2133 * can't do magic, we don't know what account he intends to bring online. So
2134 * we'll just bring the device online (and await his false bug report). */
2140 /* Return if the account is already connected */
2142 conn_status = tny_account_get_connection_status (account);
2143 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2145 /* We promise to instantly perform the callback, so ... */
2147 callback (FALSE, NULL, parent_window, account, user_data);
2153 /* Else, we are in a state that requires that we go online before we
2154 * call the caller's callback. */
2156 info = g_slice_new0 (OnWentOnlineInfo);
2158 info->device = NULL;
2160 info->account = TNY_ACCOUNT (g_object_ref (account));
2163 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2165 info->parent_window = NULL;
2167 /* So we'll put the callback away for later ... */
2169 info->user_data = user_data;
2170 info->callback = callback;
2172 if (!device_online) {
2174 /* If also the device is offline, then we connect both the device
2175 * and the account */
2177 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2178 force, on_conic_device_went_online,
2183 /* If the device is online, we'll just connect the account */
2185 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2186 on_account_went_online, info);
2189 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2190 * in both situations, go look if you don't believe me! */
2196 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2198 TnyFolderStore *folder_store,
2199 ModestConnectedPerformer callback,
2202 TnyAccount *account = NULL;
2204 if (!folder_store ||
2205 (TNY_IS_MERGE_FOLDER (folder_store) &&
2206 (tny_folder_get_folder_type (TNY_FOLDER(folder_store)) == TNY_FOLDER_TYPE_OUTBOX))) {
2208 /* We promise to instantly perform the callback, so ... */
2210 GError *error = NULL;
2211 g_set_error (&error, TNY_ERROR_DOMAIN, TNY_SERVICE_ERROR_UNKNOWN,
2212 "Unable to move or not found folder");
2213 callback (FALSE, error, parent_window, NULL, user_data);
2214 g_error_free (error);
2218 } else if (TNY_IS_FOLDER (folder_store)) {
2219 /* Get the folder's parent account: */
2220 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2221 } else if (TNY_IS_ACCOUNT (folder_store)) {
2222 /* Use the folder store as an account: */
2223 account = TNY_ACCOUNT (g_object_ref (folder_store));
2226 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
2227 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2228 /* No need to connect a local account */
2230 callback (FALSE, NULL, parent_window, account, user_data);
2235 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2239 g_object_unref (account);
2243 src_account_connect_performer (gboolean canceled,
2245 GtkWindow *parent_window,
2246 TnyAccount *src_account,
2249 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2251 if (canceled || err) {
2252 /* If there was any error call the user callback */
2253 info->callback (canceled, err, parent_window, src_account, info->data);
2255 /* Connect the destination account */
2256 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2257 TNY_FOLDER_STORE (info->dst_account),
2258 info->callback, info->data);
2261 /* Free the info object */
2262 g_object_unref (info->dst_account);
2263 g_slice_free (DoubleConnectionInfo, info);
2268 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2270 TnyFolderStore *folder_store,
2271 DoubleConnectionInfo *connect_info)
2273 modest_platform_connect_if_remote_and_perform(parent_window,
2276 src_account_connect_performer,
2281 modest_platform_get_account_settings_wizard (void)
2283 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2285 return GTK_WIDGET (dialog);
2289 modest_platform_get_current_connection (void)
2291 TnyDevice *device = NULL;
2292 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2294 device = modest_runtime_get_device ();
2296 if (!tny_device_is_online (device))
2297 return MODEST_CONNECTED_VIA_ANY;
2299 #ifdef MODEST_HAVE_CONIC
2301 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2303 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2304 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2305 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2307 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2308 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2309 !strcmp (bearer_type, "WIMAX")) {
2310 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2312 retval = MODEST_CONNECTED_VIA_ANY;
2315 g_object_unref (iap);
2318 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2319 #endif /* MODEST_HAVE_CONIC */
2326 modest_platform_check_memory_low (ModestWindow *win,
2331 /* are we in low memory state? */
2332 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2334 if (win && lowmem && visuals)
2335 modest_platform_run_information_dialog (
2337 dgettext("ke-recv","memr_ib_operation_disabled"),
2341 g_debug ("%s: low memory reached. disallowing some operations",
2348 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2354 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2357 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2358 GTK_WINDOW (dialog),
2360 gtk_widget_show_all (dialog);
2362 g_signal_connect_swapped (dialog, "response",
2363 G_CALLBACK (gtk_widget_destroy),
2368 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2374 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header);
2377 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2378 GTK_WINDOW (dialog),
2380 gtk_widget_show_all (dialog);
2382 g_signal_connect_swapped (dialog, "response",
2383 G_CALLBACK (gtk_widget_destroy),
2388 modest_platform_get_osso_context (void)
2390 return modest_maemo_utils_get_osso_context ();
2394 _modest_platform_play_email_tone (void)
2396 gchar *active_profile;
2399 gint mail_volume_int;
2401 ca_context *ca_con = NULL;
2402 ca_proplist *pl = NULL;
2404 active_profile = profile_get_profile ();
2405 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2406 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2407 mail_volume_int = profile_parse_int (mail_volume);
2409 if (mail_volume_int > 0) {
2411 if ((ret = ca_context_create(&ca_con)) != CA_SUCCESS) {
2412 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2416 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2417 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2418 ca_context_destroy(ca_con);
2422 ca_proplist_create(&pl);
2423 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2424 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", (gfloat) mail_volume_int);
2426 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2427 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2429 ca_proplist_destroy(pl);
2430 ca_context_destroy(ca_con);
2433 g_free (mail_volume);
2435 g_free (active_profile);
2439 on_move_to_dialog_folder_activated (GtkTreeView *tree_view,
2441 GtkTreeViewColumn *column,
2444 gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_OK);
2448 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
2449 GtkWidget **folder_view)
2451 GtkWidget *dialog, *folder_view_container;
2453 /* Create dialog. We cannot use a touch selector because we
2454 need to use here the folder view widget directly */
2455 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2456 GTK_WINDOW (parent_window),
2457 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
2458 GTK_DIALOG_DESTROY_WITH_PARENT,
2459 _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
2462 /* Create folder view */
2463 *folder_view = modest_platform_create_folder_view (NULL);
2465 /* Simulate the behaviour of a HildonPickerDialog by emitting
2466 a response when a folder is selected */
2467 g_signal_connect (*folder_view, "row-activated",
2468 G_CALLBACK (on_move_to_dialog_folder_activated),
2471 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (*folder_view),
2472 (TnyAccountStore *) modest_runtime_get_account_store ());
2474 /* Create pannable and add it to the dialog */
2475 folder_view_container = hildon_pannable_area_new ();
2476 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
2477 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
2479 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
2481 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
2482 gtk_widget_show (folder_view_container);
2483 gtk_widget_show (*folder_view);
2489 modest_platform_get_list_to_move (ModestWindow *window)
2491 TnyList *list = NULL;
2493 if (MODEST_IS_HEADER_WINDOW (window)) {
2494 ModestHeaderView *header_view;
2496 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
2497 list = modest_header_view_get_selected_headers (header_view);
2498 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
2499 ModestFolderView *folder_view;
2500 TnyFolderStore *selected_folder;
2502 list = TNY_LIST (tny_simple_list_new ());
2503 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
2504 selected_folder = modest_folder_view_get_selected (folder_view);
2505 if (selected_folder) {
2506 tny_list_prepend (list, G_OBJECT (selected_folder));
2507 g_object_unref (selected_folder);
2510 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2513 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
2515 list = TNY_LIST (tny_simple_list_new ());
2516 tny_list_prepend (list, G_OBJECT (header));
2517 g_object_unref (header);
2520 g_return_val_if_reached (NULL);