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 <tny-account-store-view.h>
47 #include <gtk/gtkicontheme.h>
48 #include <gtk/gtkmenuitem.h>
49 #include <gtk/gtkmain.h>
50 #include <modest-text-utils.h>
51 #include "modest-tny-folder.h"
52 #include "modest-tny-account.h"
54 #include <libgnomevfs/gnome-vfs-mime-utils.h>
55 #include <modest-account-settings-dialog.h>
56 #include <modest-easysetup-wizard-dialog.h>
57 #include "modest-hildon2-sort-dialog.h"
58 #include <hildon/hildon-sound.h>
60 #include "hildon2/modest-hildon2-details-dialog.h"
61 #include "hildon2/modest-hildon2-window-mgr.h"
62 #include <keys_nokia.h>
63 #include <libprofile.h>
65 #include <modest-datetime-formatter.h>
66 #include "modest-header-window.h"
67 #include <modest-folder-window.h>
68 #include <modest-account-mgr.h>
69 #include <modest-account-mgr-helpers.h>
70 #include <modest-ui-constants.h>
71 #include <modest-selector-picker.h>
72 #include <modest-icon-names.h>
74 #ifdef MODEST_HAVE_MCE
75 #include <mce/dbus-names.h>
76 #endif /*MODEST_HAVE_MCE*/
78 #ifdef MODEST_HAVE_ABOOK
79 #include <libosso-abook/osso-abook.h>
80 #endif /*MODEST_HAVE_ABOOK*/
82 #ifdef MODEST_HAVE_LIBALARM
83 #include <alarmd/libalarm.h> /* For alarm_event_add(), etc. */
84 #endif /*MODEST_HAVE_LIBALARM*/
87 #define HILDON_OSSO_URI_ACTION "uri-action"
88 #define URI_ACTION_COPY "copy:"
89 #define MODEST_NEW_MAIL_LIGHTING_PATTERN "PatternCommunicationEmail"
90 #define PROFILE_MAIL_TONE PROFILEKEY_EMAIL_ALERT_TONE
91 #define PROFILE_MAIL_VOLUME PROFILEKEY_EMAIL_ALERT_VOLUME
93 #define COMMON_FOLDER_DIALOG_ENTRY "entry"
94 #define COMMON_FOLDER_DIALOG_ACCOUNT_PICKER "account-picker"
95 #define FOLDER_PICKER_CURRENT_FOLDER "current-folder"
96 #define MODEST_ALARMD_APPID PACKAGE_NAME
99 static void _modest_platform_play_email_tone (void);
103 on_modest_conf_update_interval_changed (ModestConf* self,
105 ModestConfEvent event,
106 ModestConfNotificationId id,
109 g_return_if_fail (key);
111 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
112 const guint update_interval_minutes =
113 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
114 modest_platform_set_update_interval (update_interval_minutes);
121 check_required_files (void)
123 FILE *mcc_file = modest_maemo_open_mcc_mapping_file ();
125 g_printerr ("modest: check for mcc file failed\n");
130 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
131 access(MODEST_MAEMO_PROVIDER_DATA_FILE, R_OK) != 0) {
132 g_printerr ("modest: cannot find providers data\n");
140 /* the gpointer here is the osso_context. */
142 modest_platform_init (int argc, char *argv[])
144 osso_context_t *osso_context;
146 osso_hw_state_t hw_state = { 0 };
150 if (!check_required_files ()) {
151 g_printerr ("modest: missing required files\n");
155 osso_context = osso_initialize(PACKAGE,PACKAGE_VERSION,
158 g_printerr ("modest: failed to acquire osso context\n");
161 modest_maemo_utils_set_osso_context (osso_context);
163 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
164 g_printerr ("modest: could not get dbus connection\n");
168 /* Add a D-Bus handler to be used when the main osso-rpc
169 * D-Bus handler has not handled something.
170 * We use this for D-Bus methods that need to use more complex types
171 * than osso-rpc supports.
173 if (!dbus_connection_add_filter (con,
174 modest_dbus_req_filter,
178 g_printerr ("modest: Could not add D-Bus filter\n");
182 /* Register our simple D-Bus callbacks, via the osso API: */
183 osso_return_t result = osso_rpc_set_cb_f(osso_context,
187 modest_dbus_req_handler, NULL /* user_data */);
188 if (result != OSSO_OK) {
189 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
193 /* Register hardware event dbus callback: */
194 hw_state.shutdown_ind = TRUE;
195 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
197 /* Register osso auto-save callbacks: */
198 result = osso_application_set_autosave_cb (osso_context,
199 modest_on_osso_application_autosave, NULL /* user_data */);
200 if (result != OSSO_OK) {
201 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
206 /* Make sure that the update interval is changed whenever its gconf key
208 /* CAUTION: we're not using here the
209 modest_conf_listen_to_namespace because we know that there
210 are other parts of Modest listening for this namespace, so
211 we'll receive the notifications anyway. We basically do not
212 use it because there is no easy way to do the
213 modest_conf_forget_namespace */
214 ModestConf *conf = modest_runtime_get_conf ();
215 g_signal_connect (G_OBJECT(conf),
217 G_CALLBACK (on_modest_conf_update_interval_changed),
220 /* only force the setting of the default interval, if there are actually
222 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
224 /* Get the initial update interval from gconf: */
225 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
226 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
227 modest_account_mgr_free_account_names (acc_names);
231 #ifdef MODEST_HAVE_ABOOK
232 /* initialize the addressbook */
233 if (!osso_abook_init (&argc, &argv, osso_context)) {
234 g_printerr ("modest: failed to initialized addressbook\n");
237 #endif /*MODEST_HAVE_ABOOK*/
243 modest_platform_uninit (void)
245 osso_context_t *osso_context =
246 modest_maemo_utils_get_osso_context ();
248 osso_deinitialize (osso_context);
257 modest_platform_get_new_device (void)
259 return TNY_DEVICE (tny_maemo_conic_device_new ());
263 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
264 gchar **effective_mime_type)
266 GString *mime_str = NULL;
267 gchar *icon_name = NULL;
268 gchar **icons, **cursor;
270 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
271 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
273 mime_str = g_string_new (mime_type);
274 g_string_ascii_down (mime_str);
277 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
279 for (cursor = icons; cursor; ++cursor) {
280 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
281 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
282 icon_name = g_strdup ("qgn_list_messagin");
284 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
285 icon_name = g_strdup (*cursor);
291 if (effective_mime_type)
292 *effective_mime_type = g_string_free (mime_str, FALSE);
294 g_string_free (mime_str, TRUE);
301 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
306 g_return_val_if_fail (uri, FALSE);
308 result = hildon_uri_open (uri, action, &err);
310 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
311 uri, action, err && err->message ? err->message : "unknown error");
321 modest_platform_activate_uri (const gchar *uri)
323 HildonURIAction *action;
324 gboolean result = FALSE;
325 GSList *actions, *iter = NULL;
327 g_return_val_if_fail (uri, FALSE);
331 /* don't try to activate file: uri's -- they might confuse the user,
332 * and/or might have security implications */
333 if (!g_str_has_prefix (uri, "file:")) {
335 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
337 for (iter = actions; iter; iter = g_slist_next (iter)) {
338 action = (HildonURIAction*) iter->data;
339 if (action && strcmp (hildon_uri_action_get_service (action),
340 "com.nokia.modest") == 0) {
341 result = checked_hildon_uri_open (uri, action);
346 /* if we could not open it with email, try something else */
348 result = checked_hildon_uri_open (uri, NULL);
352 ModestWindow *parent =
353 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
354 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
355 _("mcen_ib_unsupported_link"));
356 g_warning ("%s: cannot open uri '%s'", __FUNCTION__,uri);
363 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
367 gchar *uri_path = NULL;
369 uri_path = gnome_vfs_get_uri_from_local_path (path);
370 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
373 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
375 result = hildon_mime_open_file (con, uri_path);
377 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
385 } ModestPlatformPopupInfo;
388 delete_uri_popup (GtkWidget *menu,
392 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
394 g_free (popup_info->uri);
395 hildon_uri_free_actions (popup_info->actions);
401 activate_uri_popup_item (GtkMenuItem *menu_item,
405 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
406 const gchar* action_name;
408 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
410 g_printerr ("modest: no action name defined\n");
414 /* special handling for the copy menu item -- copy the uri to the clipboard */
415 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
416 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
417 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
418 action_name += strlen(URI_ACTION_COPY); /* jump past the prefix */
420 if (g_str_has_prefix (action_name, "mailto:")) /* ignore mailto: prefixes */
421 action_name += strlen ("mailto:");
423 gtk_clipboard_set_text (clipboard, action_name, strlen (action_name));
424 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
425 return; /* we're done */
428 /* now, the real uri-actions... */
429 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
430 HildonURIAction *action = (HildonURIAction *) node->data;
431 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
432 if (!checked_hildon_uri_open (popup_info->uri, action)) {
433 ModestWindow *parent =
434 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
435 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
436 _("mcen_ib_unsupported_link"));
444 modest_platform_show_uri_popup (const gchar *uri)
446 GSList *actions_list;
451 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
454 GtkWidget *menu = gtk_menu_new ();
455 ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1);
457 /* don't add actions for file: uri's -- they might confuse the user,
458 * and/or might have security implications
459 * we still allow to copy the url though
461 if (!g_str_has_prefix (uri, "file:")) {
464 popup_info->actions = actions_list;
465 popup_info->uri = g_strdup (uri);
467 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
468 GtkWidget *menu_item;
469 const gchar *action_name;
470 const gchar *translation_domain;
471 HildonURIAction *action = (HildonURIAction *) node->data;
472 action_name = hildon_uri_action_get_name (action);
473 translation_domain = hildon_uri_action_get_translation_domain (action);
474 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
475 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
476 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
479 if (hildon_uri_is_default_action (action, NULL)) {
480 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
482 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
484 gtk_widget_show (menu_item);
488 /* always add the copy item */
489 GtkWidget* menu_item = gtk_menu_item_new_with_label (dgettext("osso-uri",
490 "uri_link_copy_link_location"));
491 g_object_set_data_full (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION,
492 g_strconcat (URI_ACTION_COPY, uri, NULL),
494 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),NULL);
495 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
496 gtk_widget_show (menu_item);
499 /* and what to do when the link is deleted */
500 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
501 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
504 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link"));
512 modest_platform_get_icon (const gchar *name, guint icon_size)
515 GdkPixbuf* pixbuf = NULL;
516 GtkIconTheme *current_theme = NULL;
518 g_return_val_if_fail (name, NULL);
520 /* strlen == 0 is not really an error; it just
521 * means the icon is not available
523 if (!name || strlen(name) == 0)
526 current_theme = gtk_icon_theme_get_default ();
527 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
528 GTK_ICON_LOOKUP_NO_SVG,
531 g_printerr ("modest: error loading theme icon '%s': %s\n",
539 modest_platform_get_app_name (void)
541 return _("mcen_ap_name");
545 entry_insert_text (GtkEditable *editable,
554 chars = gtk_editable_get_chars (editable, 0, -1);
555 chars_length = g_utf8_strlen (chars, -1);
558 /* Show WID-INF036 */
559 if (chars_length >= 20) {
560 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
561 _CS("ckdg_ib_maximum_characters_reached"));
563 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
567 tmp = g_strndup (folder_name_forbidden_chars,
568 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
569 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
570 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
575 /* Write the text in the entry if it's valid */
576 g_signal_handlers_block_by_func (editable,
577 (gpointer) entry_insert_text, data);
578 gtk_editable_insert_text (editable, text, length, position);
579 g_signal_handlers_unblock_by_func (editable,
580 (gpointer) entry_insert_text, data);
583 /* Do not allow further processing */
584 g_signal_stop_emission_by_name (editable, "insert_text");
588 entry_changed (GtkEditable *editable,
592 GtkWidget *ok_button;
595 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
596 ok_button = GTK_WIDGET (buttons->data);
598 chars = gtk_editable_get_chars (editable, 0, -1);
599 g_return_if_fail (chars != NULL);
602 if (g_utf8_strlen (chars,-1) >= 20)
603 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
604 _CS("ckdg_ib_maximum_characters_reached"));
606 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
609 g_list_free (buttons);
616 on_response (GtkDialog *dialog,
620 GtkWidget *entry, *picker;
621 TnyFolderStore *parent;
622 const gchar *new_name;
625 if (response != GTK_RESPONSE_ACCEPT)
629 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
630 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
632 parent = TNY_FOLDER_STORE (user_data);
633 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
636 if (picker != NULL) {
638 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
641 /* Look for another folder with the same name */
642 if (modest_tny_folder_has_subfolder_with_name (parent,
649 if (TNY_IS_ACCOUNT (parent) &&
650 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
651 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
660 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
661 NULL, _CS("ckdg_ib_folder_already_exists"));
662 /* Select the text */
663 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
664 gtk_widget_grab_focus (entry);
665 /* Do not close the dialog */
666 g_signal_stop_emission_by_name (dialog, "response");
671 typedef struct _FolderChooserData {
672 TnyFolderStore *store;
677 folder_chooser_activated (ModestFolderView *folder_view,
678 TnyFolderStore *folder,
679 FolderChooserData *userdata)
681 userdata->store = folder;
682 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
685 static TnyFolderStore *
686 folder_chooser_dialog_run (ModestFolderView *original)
688 GtkWidget *folder_view;
689 FolderChooserData userdata = {NULL, NULL};
691 const gchar *visible_id = NULL;
693 userdata.dialog = hildon_dialog_new ();
694 pannable = hildon_pannable_area_new ();
695 folder_view = modest_platform_create_folder_view (NULL);
696 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
697 MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS);
699 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original),
700 MODEST_FOLDER_VIEW (folder_view));
703 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original));
704 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
707 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
708 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
709 gtk_widget_set_size_request (pannable, -1, 320);
711 gtk_widget_show (folder_view);
712 gtk_widget_show (pannable);
713 gtk_widget_show (userdata.dialog);
714 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
715 G_CALLBACK (folder_chooser_activated),
716 (gpointer) &userdata);
718 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
719 gtk_widget_destroy (userdata.dialog);
721 return userdata.store;
725 folder_store_get_display_name (TnyFolderStore *store)
727 if (TNY_IS_ACCOUNT (store)) {
728 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
731 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
733 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
734 type = tny_folder_get_folder_type (TNY_FOLDER (store));
735 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
736 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
737 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
738 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
740 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
743 /* Sometimes an special folder is reported by the server as
744 NORMAL, like some versions of Dovecot */
745 if (type == TNY_FOLDER_TYPE_NORMAL ||
746 type == TNY_FOLDER_TYPE_UNKNOWN) {
747 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
751 if (type == TNY_FOLDER_TYPE_INBOX) {
753 fname = g_strdup (_("mcen_me_folder_inbox"));
760 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
765 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
767 g_object_ref (store);
768 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
769 store, (GDestroyNotify) g_object_unref);
770 name = folder_store_get_display_name (store);
771 hildon_button_set_value (HILDON_BUTTON (button), name);
777 folder_picker_clicked (GtkButton *button,
778 ModestFolderView *folder_view)
780 TnyFolderStore *store;
782 store = folder_chooser_dialog_run (folder_view);
784 folder_picker_set_store (GTK_BUTTON (button), store);
789 folder_picker_new (ModestFolderView *folder_view, TnyFolderStore *suggested)
794 button = hildon_button_new (MODEST_EDITABLE_SIZE,
795 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
796 pixbuf = modest_platform_get_icon (MODEST_FOLDER_ICON_NORMAL,
797 MODEST_ICON_SIZE_SMALL);
799 hildon_button_set_image (HILDON_BUTTON (button),
800 gtk_image_new_from_pixbuf (pixbuf));
801 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
804 folder_picker_set_store (GTK_BUTTON (button), suggested);
807 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (folder_picker_clicked), folder_view);
814 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
815 TnyFolderStore *suggested_parent,
816 const gchar *dialog_title,
817 const gchar *label_text,
818 const gchar *suggested_name,
820 gboolean show_parent,
822 TnyFolderStore **parent)
824 GtkWidget *accept_btn = NULL;
825 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
826 GtkWidget *account_picker = NULL;
827 GList *buttons = NULL;
829 GtkSizeGroup *sizegroup;
830 ModestFolderView *folder_view;
831 ModestWindow *folder_window;
832 ModestHildon2WindowMgr *window_mgr;
834 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
835 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
836 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
838 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
840 /* Ask the user for the folder name */
841 dialog = gtk_dialog_new_with_buttons (dialog_title,
843 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
844 _FM("ckdg_bd_new_folder_dialog_ok"),
848 /* Add accept button (with unsensitive handler) */
849 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
850 accept_btn = GTK_WIDGET (buttons->data);
852 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
855 label_entry = gtk_label_new (label_text);
856 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
857 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
859 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
860 gtk_size_group_add_widget (sizegroup, label_entry);
863 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
865 gtk_entry_set_text (GTK_ENTRY (entry), _("mcen_ia_default_folder_name"));
866 gtk_entry_set_width_chars (GTK_ENTRY (entry),
867 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
868 g_utf8_strlen (_("mcen_ia_default_folder_name"), -1)));
869 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
874 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
876 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
877 gtk_size_group_add_widget (sizegroup, label_location);
879 account_picker = folder_picker_new (folder_view, suggested_parent);
882 g_object_unref (sizegroup);
884 /* Connect to the response method to avoid closing the dialog
885 when an invalid name is selected*/
886 g_signal_connect (dialog,
888 G_CALLBACK (on_response),
892 /* Track entry changes */
893 g_signal_connect (entry,
895 G_CALLBACK (entry_insert_text),
897 g_signal_connect (entry,
899 G_CALLBACK (entry_changed),
904 /* Some locales like pt_BR need this to get the full window
906 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
908 /* Create the hbox */
910 hbox = gtk_hbox_new (FALSE, 12);
911 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
912 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
914 /* Add hbox to dialog */
915 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
916 hbox, FALSE, FALSE, 0);
917 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
921 hbox = gtk_hbox_new (FALSE, 12);
922 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
923 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
925 /* Add hbox to dialog */
926 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
927 hbox, FALSE, FALSE, 0);
928 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
930 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
931 GTK_WINDOW (dialog), parent_window);
932 gtk_widget_show_all (GTK_WIDGET(dialog));
934 result = gtk_dialog_run (GTK_DIALOG(dialog));
935 if (result == GTK_RESPONSE_ACCEPT) {
937 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
939 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
941 g_object_ref (*parent);
945 gtk_widget_destroy (dialog);
947 while (gtk_events_pending ())
948 gtk_main_iteration ();
954 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
955 TnyFolderStore *suggested_folder,
956 gchar *suggested_name,
958 TnyFolderStore **parent_folder)
960 gchar *real_suggested_name = NULL, *tmp = NULL;
962 ModestTnyAccountStore *acc_store;
965 if(suggested_name == NULL)
967 const gchar *default_name = _("mcen_ia_default_folder_name");
971 for(i = 0; i < 100; ++ i) {
972 gboolean exists = FALSE;
974 sprintf(num_str, "%.2u", i);
977 real_suggested_name = g_strdup (default_name);
979 real_suggested_name = g_strdup_printf (_("mcen_ia_default_folder_name_s"),
981 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
988 g_free (real_suggested_name);
991 /* Didn't find a free number */
993 real_suggested_name = g_strdup (default_name);
995 real_suggested_name = suggested_name;
998 /* In hildon 2.2 we always suggest the archive folder as parent */
999 acc_store = modest_runtime_get_account_store ();
1000 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
1002 suggested_folder = (TnyFolderStore *)
1003 modest_tny_account_get_special_folder (account,
1004 TNY_FOLDER_TYPE_ARCHIVE);
1005 g_object_unref (account);
1009 /* If there is not archive folder then fallback to local folders account */
1010 if (!suggested_folder)
1011 suggested_folder = (TnyFolderStore *)
1012 modest_tny_account_store_get_local_folders_account (acc_store);
1014 tmp = g_strconcat (_("mcen_fi_new_folder_name"), ":", NULL);
1015 result = modest_platform_run_folder_common_dialog (parent_window,
1017 _("mcen_ti_new_folder"),
1019 real_suggested_name,
1026 if (suggested_name == NULL)
1027 g_free(real_suggested_name);
1033 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1034 TnyFolderStore *parent_folder,
1035 const gchar *suggested_name,
1036 gchar **folder_name)
1038 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1040 return modest_platform_run_folder_common_dialog (parent_window,
1042 _HL("ckdg_ti_rename_folder"),
1043 _HL("ckdg_fi_rename_name"),
1054 on_destroy_dialog (GtkWidget *dialog)
1056 /* This could happen when the dialogs get programatically
1057 hidden or destroyed (for example when closing the
1058 application while a dialog is being shown) */
1059 if (!GTK_IS_WIDGET (dialog))
1062 gtk_widget_destroy (dialog);
1064 if (gtk_events_pending ())
1065 gtk_main_iteration ();
1069 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1070 const gchar *message)
1075 dialog = hildon_note_new_confirmation (parent_window, message);
1076 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1077 GTK_WINDOW (dialog), parent_window);
1079 response = gtk_dialog_run (GTK_DIALOG (dialog));
1081 on_destroy_dialog (dialog);
1087 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1088 const gchar *message,
1089 const gchar *button_accept,
1090 const gchar *button_cancel)
1095 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1096 button_accept, GTK_RESPONSE_ACCEPT,
1097 button_cancel, GTK_RESPONSE_CANCEL,
1100 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1101 GTK_WINDOW (dialog), parent_window);
1103 response = gtk_dialog_run (GTK_DIALOG (dialog));
1105 on_destroy_dialog (dialog);
1111 modest_platform_run_information_dialog (GtkWindow *parent_window,
1112 const gchar *message,
1117 note = hildon_note_new_information (parent_window, message);
1119 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1120 GTK_WINDOW (note), parent_window);
1123 gtk_dialog_run (GTK_DIALOG (note));
1125 on_destroy_dialog (note);
1127 g_signal_connect_swapped (note,
1129 G_CALLBACK (on_destroy_dialog),
1132 gtk_widget_show_all (note);
1136 typedef struct _ConnectAndWaitData {
1138 GMainLoop *wait_loop;
1139 gboolean has_callback;
1141 } ConnectAndWaitData;
1145 quit_wait_loop (TnyAccount *account,
1146 ConnectAndWaitData *data)
1148 /* Set the has_callback to TRUE (means that the callback was
1149 executed and wake up every code waiting for cond to be
1151 g_mutex_lock (data->mutex);
1152 data->has_callback = TRUE;
1153 if (data->wait_loop)
1154 g_main_loop_quit (data->wait_loop);
1155 g_mutex_unlock (data->mutex);
1159 on_connection_status_changed (TnyAccount *account,
1160 TnyConnectionStatus status,
1163 TnyConnectionStatus conn_status;
1164 ConnectAndWaitData *data;
1166 /* Ignore if reconnecting or disconnected */
1167 conn_status = tny_account_get_connection_status (account);
1168 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1169 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1172 /* Remove the handler */
1173 data = (ConnectAndWaitData *) user_data;
1174 g_signal_handler_disconnect (account, data->handler);
1176 /* Quit from wait loop */
1177 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1181 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1186 /* Quit from wait loop */
1187 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1191 modest_platform_connect_and_wait (GtkWindow *parent_window,
1192 TnyAccount *account)
1194 ConnectAndWaitData *data = NULL;
1195 gboolean device_online;
1197 TnyConnectionStatus conn_status;
1198 gboolean user_requested;
1200 device = modest_runtime_get_device();
1201 device_online = tny_device_is_online (device);
1203 /* Whether the connection is user requested or automatically
1204 requested, for example via D-Bus */
1205 user_requested = (parent_window) ? TRUE : FALSE;
1207 /* If there is no account check only the device status */
1212 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1213 NULL, user_requested);
1216 /* Return if the account is already connected */
1217 conn_status = tny_account_get_connection_status (account);
1218 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1221 /* Create the helper */
1222 data = g_slice_new0 (ConnectAndWaitData);
1223 data->mutex = g_mutex_new ();
1224 data->has_callback = FALSE;
1226 /* Connect the device */
1227 if (!device_online) {
1228 /* Track account connection status changes */
1229 data->handler = g_signal_connect (account, "connection-status-changed",
1230 G_CALLBACK (on_connection_status_changed),
1232 /* Try to connect the device */
1233 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1234 NULL, user_requested);
1236 /* If the device connection failed then exit */
1237 if (!device_online && data->handler)
1240 /* Force a reconnection of the account */
1241 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1242 on_tny_camel_account_set_online_cb, data);
1245 /* Wait until the callback is executed */
1246 g_mutex_lock (data->mutex);
1247 if (!data->has_callback) {
1248 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1249 gdk_threads_leave ();
1250 g_mutex_unlock (data->mutex);
1251 g_main_loop_run (data->wait_loop);
1252 g_mutex_lock (data->mutex);
1253 gdk_threads_enter ();
1255 g_mutex_unlock (data->mutex);
1259 if (g_signal_handler_is_connected (account, data->handler))
1260 g_signal_handler_disconnect (account, data->handler);
1261 g_mutex_free (data->mutex);
1262 g_main_loop_unref (data->wait_loop);
1263 g_slice_free (ConnectAndWaitData, data);
1266 conn_status = tny_account_get_connection_status (account);
1267 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1271 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1273 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1274 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1275 /* This must be a maildir account, which does not require a connection: */
1280 return modest_platform_connect_and_wait (parent_window, account);
1284 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1287 return TRUE; /* Maybe it is something local. */
1289 gboolean result = TRUE;
1290 if (TNY_IS_FOLDER (folder_store)) {
1291 /* Get the folder's parent account: */
1292 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1293 if (account != NULL) {
1294 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1295 g_object_unref (account);
1297 } else if (TNY_IS_ACCOUNT (folder_store)) {
1298 /* Use the folder store as an account: */
1299 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1306 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1310 dialog = modest_hildon2_sort_dialog_new (parent_window);
1317 modest_platform_set_update_interval (guint minutes)
1319 #ifdef MODEST_HAVE_LIBALARM
1321 ModestConf *conf = modest_runtime_get_conf ();
1325 cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL);
1327 /* Delete any existing alarm,
1328 * because we will replace it: */
1330 if (alarmd_event_del(alarm_cookie) != 0)
1331 g_warning ("%s: alarm %d was not on the queue", __FUNCTION__, (int)alarm_cookie);
1333 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1336 /* 0 means no updates: */
1341 /* Register alarm: */
1343 /* Set the interval in alarm_event_t structure: */
1344 alarm_event_t *event = alarm_event_create ();
1345 alarm_event_add_actions (event, 1);
1346 alarm_action_t *action = alarm_event_get_action (event, 0);
1347 alarm_event_set_alarm_appid (event, MODEST_ALARMD_APPID);
1348 event->alarm_time = minutes * 60; /* seconds */
1350 /* Set recurrence every few minutes: */
1351 event->recur_secs = minutes*60;
1352 event->recur_count = -1; /* Means infinite */
1354 /* Specify what should happen when the alarm happens:
1355 * It should call this D-Bus method: */
1357 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1358 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1359 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1360 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1361 action->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1363 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1364 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1365 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1366 * This is why we want to use the Alarm API instead of just g_timeout_add().
1367 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1368 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1370 event->flags = ALARM_EVENT_CONNECTED;
1372 alarm_cookie = alarmd_event_add (event);
1375 alarm_event_delete (event);
1377 /* Store the alarm ID in GConf, so we can remove it later:
1378 * This is apparently valid between application instances. */
1379 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1381 if (!alarm_cookie) {
1383 g_debug ("Error setting alarm event. \n");
1387 #endif /* MODEST_HAVE_LIBALARM */
1392 modest_platform_push_email_notification(void)
1394 gboolean screen_on, app_in_foreground;
1396 /* Get the window status */
1397 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1399 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1401 /* If the screen is on and the app is in the
1402 foreground we don't show anything */
1403 if (!(screen_on && app_in_foreground)) {
1405 _modest_platform_play_email_tone ();
1407 /* Activate LED. This must be deactivated by
1408 modest_platform_remove_new_mail_notifications */
1409 #ifdef MODEST_HAVE_MCE
1410 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1414 MCE_ACTIVATE_LED_PATTERN,
1416 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1423 modest_platform_on_new_headers_received (TnyList *header_list,
1424 gboolean show_visual)
1426 g_return_if_fail (TNY_IS_LIST(header_list));
1428 if (tny_list_get_length(header_list) == 0) {
1429 g_warning ("%s: header list is empty", __FUNCTION__);
1434 modest_platform_push_email_notification ();
1435 /* We do a return here to avoid indentation with an else */
1439 #ifdef MODEST_HAVE_HILDON_NOTIFY
1440 HildonNotification *notification;
1442 GSList *notifications_list = NULL;
1444 /* Get previous notifications ids */
1445 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1446 MODEST_CONF_NOTIFICATION_IDS,
1447 MODEST_CONF_VALUE_INT, NULL);
1449 iter = tny_list_create_iterator (header_list);
1450 while (!tny_iterator_is_done (iter)) {
1451 gchar *url = NULL, *display_address = NULL, *summary = NULL;
1452 const gchar *display_date;
1453 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1454 TnyFolder *folder = tny_header_get_folder (header);
1455 gboolean first_notification = TRUE;
1458 ModestDatetimeFormatter *datetime_formatter;
1460 /* constant string, don't free */
1461 datetime_formatter = modest_datetime_formatter_new ();
1462 display_date = modest_datetime_formatter_display_datetime (datetime_formatter,
1463 tny_header_get_date_received (header));
1464 g_object_unref (datetime_formatter);
1466 display_address = tny_header_dup_from (header);
1467 /* string is changed in-place */
1468 modest_text_utils_get_display_address (display_address);
1470 summary = g_strdup_printf ("%s - %s", display_date, display_address);
1471 str = tny_header_dup_subject (header);
1472 notification = hildon_notification_new (summary,
1474 "qgn_list_messagin",
1477 /* Create the message URL */
1478 str = tny_header_dup_uid (header);
1479 url = g_strdup_printf ("%s/%s", tny_folder_get_url_string (folder),
1483 hildon_notification_add_dbus_action(notification,
1486 MODEST_DBUS_SERVICE,
1489 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1493 /* Play sound if the user wants. Show the LED
1494 pattern. Show and play just one */
1495 if (G_UNLIKELY (first_notification)) {
1496 gchar *active_profile;
1499 gint mail_volume_int;
1501 first_notification = FALSE;
1503 active_profile = profile_get_profile ();
1504 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
1505 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
1506 mail_volume_int = profile_parse_int (mail_volume);
1508 if (mail_volume_int > 0)
1509 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1510 "sound-file", mail_tone);
1512 g_free (mail_volume);
1514 g_free (active_profile);
1516 /* Set the led pattern */
1517 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1519 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1521 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1524 /* Notify. We need to do this in an idle because this function
1525 could be called from a thread */
1526 notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL);
1528 /* Save id in the list */
1529 g_object_get(G_OBJECT(notification), "id", ¬if_id, NULL);
1530 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1531 /* We don't listen for the "closed" signal, because we
1532 don't care about if the notification was removed or
1533 not to store the list in gconf */
1535 /* Free & carry on */
1536 g_free (display_address);
1539 g_object_unref (folder);
1540 g_object_unref (header);
1541 tny_iterator_next (iter);
1543 g_object_unref (iter);
1546 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1547 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1549 g_slist_free (notifications_list);
1551 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1555 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1558 #ifdef MODEST_HAVE_MCE
1559 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1563 MCE_DEACTIVATE_LED_PATTERN,
1565 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1571 #ifdef MODEST_HAVE_HILDON_NOTIFY
1572 GSList *notif_list = NULL;
1574 /* Get previous notifications ids */
1575 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1576 MODEST_CONF_NOTIFICATION_IDS,
1577 MODEST_CONF_VALUE_INT, NULL);
1579 while (notif_list) {
1581 NotifyNotification *notif;
1583 /* Nasty HACK to remove the notifications, set the id
1584 of the existing ones and then close them */
1585 notif_id = GPOINTER_TO_INT(notif_list->data);
1586 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1587 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1589 /* Close the notification, note that some ids could be
1590 already invalid, but we don't care because it does
1592 notify_notification_close(notif, NULL);
1593 g_object_unref(notif);
1595 /* Delete the link, it's like going to the next */
1596 notif_list = g_slist_delete_link (notif_list, notif_list);
1600 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1601 notif_list, MODEST_CONF_VALUE_INT, NULL);
1603 g_slist_free (notif_list);
1605 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1611 modest_platform_get_global_settings_dialog ()
1613 return modest_hildon2_global_settings_dialog_new ();
1617 modest_platform_show_help (GtkWindow *parent_window,
1618 const gchar *help_id)
1624 modest_platform_show_search_messages (GtkWindow *parent_window)
1626 osso_return_t result = OSSO_ERROR;
1628 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1629 "osso_global_search",
1630 "search_email", NULL, DBUS_TYPE_INVALID);
1632 if (result != OSSO_OK) {
1633 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1638 modest_platform_show_addressbook (GtkWindow *parent_window)
1640 osso_return_t result = OSSO_ERROR;
1642 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1644 "top_application", NULL, DBUS_TYPE_INVALID);
1646 if (result != OSSO_OK) {
1647 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1652 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1654 GtkWidget *widget = modest_folder_view_new (query);
1656 /* Show one account by default */
1657 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1658 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1660 /* Restore settings */
1661 modest_widget_memory_restore (modest_runtime_get_conf(),
1663 MODEST_CONF_FOLDER_VIEW_KEY);
1669 banner_finish (gpointer data, GObject *object)
1671 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1672 modest_window_mgr_unregister_banner (mgr);
1673 g_object_unref (mgr);
1677 modest_platform_information_banner (GtkWidget *parent,
1678 const gchar *icon_name,
1681 GtkWidget *banner, *banner_parent = NULL;
1682 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1684 if (modest_window_mgr_get_num_windows (mgr) == 0)
1687 if (parent && GTK_IS_WINDOW (parent)) {
1688 /* If the window is the active one then show the
1689 banner on top of this window */
1690 if (gtk_window_is_active (GTK_WINDOW (parent)))
1691 banner_parent = parent;
1692 /* If the window is not the topmost but it's visible
1693 (it's minimized for example) then show the banner
1695 else if (GTK_WIDGET_VISIBLE (parent))
1696 banner_parent = NULL;
1697 /* If the window is hidden (like the main window when
1698 running in the background) then do not show
1705 banner = hildon_banner_show_information (banner_parent, icon_name, text);
1707 modest_window_mgr_register_banner (mgr);
1709 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1713 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1714 const gchar *icon_name,
1720 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1723 banner = hildon_banner_show_information (parent, icon_name, text);
1724 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1728 modest_platform_animation_banner (GtkWidget *parent,
1729 const gchar *animation_name,
1732 GtkWidget *inf_note = NULL;
1734 g_return_val_if_fail (text != NULL, NULL);
1736 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1739 /* If the parent is not visible then do not show */
1740 if (parent && !GTK_WIDGET_VISIBLE (parent))
1743 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1751 TnyAccount *account;
1754 } CheckAccountIdleData;
1756 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1759 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1761 gboolean stop_trying = FALSE;
1762 g_return_val_if_fail (data && data->account, FALSE);
1764 printf ("DEBUG: %s: tny_account_get_connection_status()==%d\n", __FUNCTION__,
1765 tny_account_get_connection_status (data->account));
1767 if (data && data->account &&
1768 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1769 * after which the account is likely to be usable, or never likely to be usable soon: */
1770 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1772 data->is_online = TRUE;
1776 /* Give up if we have tried too many times: */
1777 if (data->count_tries >= NUMBER_OF_TRIES) {
1780 /* Wait for another timeout: */
1781 ++(data->count_tries);
1786 /* Allow the function that requested this idle callback to continue: */
1788 g_main_loop_quit (data->loop);
1791 g_object_unref (data->account);
1793 return FALSE; /* Don't call this again. */
1795 return TRUE; /* Call this timeout callback again. */
1799 /* Return TRUE immediately if the account is already online,
1800 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1801 * soon as the account is online, or FALSE if the account does
1802 * not become online in the NUMBER_OF_TRIES seconds.
1803 * This is useful when the D-Bus method was run immediately after
1804 * the application was started (when using D-Bus activation),
1805 * because the account usually takes a short time to go online.
1806 * The return value is maybe not very useful.
1809 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1813 g_return_val_if_fail (account, FALSE);
1815 if (!tny_device_is_online (modest_runtime_get_device())) {
1816 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1820 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1821 * so we avoid wait unnecessarily: */
1822 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1825 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1826 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1827 * we want to avoid. */
1828 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
1831 /* This blocks on the result: */
1832 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
1833 data->is_online = FALSE;
1834 data->account = account;
1835 g_object_ref (data->account);
1836 data->count_tries = 0;
1838 GMainContext *context = NULL; /* g_main_context_new (); */
1839 data->loop = g_main_loop_new (context, FALSE /* not running */);
1841 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
1843 /* This main loop will run until the idle handler has stopped it: */
1844 g_main_loop_run (data->loop);
1846 g_main_loop_unref (data->loop);
1847 /* g_main_context_unref (context); */
1849 is_online = data->is_online;
1850 g_slice_free (CheckAccountIdleData, data);
1858 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
1860 /* GTK_RESPONSE_HELP means we need to show the certificate */
1861 if (response_id == GTK_RESPONSE_APPLY) {
1865 /* Do not close the dialog */
1866 g_signal_stop_emission_by_name (dialog, "response");
1868 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
1869 note = hildon_note_new_information (GTK_WINDOW(dialog), msg);
1870 gtk_dialog_run (GTK_DIALOG(note));
1871 gtk_widget_destroy (note);
1877 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
1878 const gchar *certificate)
1883 HildonWindowStack *stack;
1885 stack = hildon_window_stack_get_default ();
1886 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1889 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1894 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
1897 /* We use GTK_RESPONSE_APPLY because we want the button in the
1898 middle of OK and CANCEL the same as the browser does for
1899 example. With GTK_RESPONSE_HELP the view button is aligned
1900 to the left while the other two to the right */
1901 note = hildon_note_new_confirmation_add_buttons (
1904 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
1905 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
1906 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
1909 g_signal_connect (G_OBJECT(note), "response",
1910 G_CALLBACK(on_cert_dialog_response),
1911 (gpointer) certificate);
1913 response = gtk_dialog_run(GTK_DIALOG(note));
1915 on_destroy_dialog (note);
1918 return response == GTK_RESPONSE_OK;
1922 modest_platform_run_alert_dialog (const gchar* prompt,
1923 gboolean is_question)
1925 ModestWindow *top_win;
1926 HildonWindowStack *stack;
1928 stack = hildon_window_stack_get_default ();
1929 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
1932 g_warning ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
1937 gboolean retval = TRUE;
1939 /* The Tinymail documentation says that we should show Yes and No buttons,
1940 * when it is a question.
1941 * Obviously, we need tinymail to use more specific error codes instead,
1942 * so we know what buttons to show. */
1943 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
1945 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1946 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
1948 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
1949 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
1951 on_destroy_dialog (dialog);
1953 /* Just show the error text and use the default response: */
1954 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
1962 GtkWindow *parent_window;
1963 ModestConnectedPerformer callback;
1964 TnyAccount *account;
1971 on_went_online_info_free (OnWentOnlineInfo *info)
1973 /* And if we cleanup, we DO cleanup :-) */
1976 g_object_unref (info->device);
1979 if (info->parent_window)
1980 g_object_unref (info->parent_window);
1982 g_object_unref (info->account);
1984 g_slice_free (OnWentOnlineInfo, info);
1986 /* We're done ... */
1992 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
1994 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
1996 /* Now it's really time to callback to the caller. If going online didn't succeed,
1997 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
1998 * canceled will be set. Etcetera etcetera. */
2000 if (info->callback) {
2001 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2004 /* This is our last call, we must cleanup here if we didn't yet do that */
2005 on_went_online_info_free (info);
2012 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2014 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2015 info->iap = g_strdup (iap_id);
2017 if (canceled || err || !info->account) {
2019 /* If there's a problem or if there's no account (then that's it for us, we callback
2020 * the caller's callback now. He'll have to handle err or canceled, of course.
2021 * We are not really online, as the account is not really online here ... */
2023 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2024 * this info. We don't cleanup err, Tinymail does that! */
2026 if (info->callback) {
2028 /* info->account can be NULL here, this means that the user did not
2029 * provide a nice account instance. We'll assume that the user knows
2030 * what he's doing and is happy with just the device going online.
2032 * We can't do magic, we don't know what account the user wants to
2033 * see going online. So just the device goes online, end of story */
2035 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2038 } else if (info->account) {
2040 /* If there's no problem and if we have an account, we'll put the account
2041 * online too. When done, the callback of bringing the account online
2042 * will callback the caller's callback. This is the most normal case. */
2044 info->device = TNY_DEVICE (g_object_ref (device));
2046 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2047 on_account_went_online, info);
2049 /* The on_account_went_online cb frees up the info, go look if you
2050 * don't believe me! (so we return here) */
2055 /* We cleanup if we are not bringing the account online too */
2056 on_went_online_info_free (info);
2062 modest_platform_connect_and_perform (GtkWindow *parent_window,
2064 TnyAccount *account,
2065 ModestConnectedPerformer callback,
2068 gboolean device_online;
2070 TnyConnectionStatus conn_status;
2071 OnWentOnlineInfo *info;
2073 device = modest_runtime_get_device();
2074 device_online = tny_device_is_online (device);
2076 /* If there is no account check only the device status */
2079 if (device_online) {
2081 /* We promise to instantly perform the callback, so ... */
2083 callback (FALSE, NULL, parent_window, account, user_data);
2088 info = g_slice_new0 (OnWentOnlineInfo);
2091 info->device = NULL;
2092 info->account = NULL;
2095 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2097 info->parent_window = NULL;
2098 info->user_data = user_data;
2099 info->callback = callback;
2101 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2102 force, on_conic_device_went_online,
2105 /* We'll cleanup in on_conic_device_went_online */
2108 /* The other code has no more reason to run. This is all that we can do for the
2109 * caller (he should have given us a nice and clean account instance!). We
2110 * can't do magic, we don't know what account he intends to bring online. So
2111 * we'll just bring the device online (and await his false bug report). */
2117 /* Return if the account is already connected */
2119 conn_status = tny_account_get_connection_status (account);
2120 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2122 /* We promise to instantly perform the callback, so ... */
2124 callback (FALSE, NULL, parent_window, account, user_data);
2130 /* Else, we are in a state that requires that we go online before we
2131 * call the caller's callback. */
2133 info = g_slice_new0 (OnWentOnlineInfo);
2135 info->device = NULL;
2137 info->account = TNY_ACCOUNT (g_object_ref (account));
2140 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2142 info->parent_window = NULL;
2144 /* So we'll put the callback away for later ... */
2146 info->user_data = user_data;
2147 info->callback = callback;
2149 if (!device_online) {
2151 /* If also the device is offline, then we connect both the device
2152 * and the account */
2154 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2155 force, on_conic_device_went_online,
2160 /* If the device is online, we'll just connect the account */
2162 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2163 on_account_went_online, info);
2166 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2167 * in both situations, go look if you don't believe me! */
2173 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2175 TnyFolderStore *folder_store,
2176 ModestConnectedPerformer callback,
2179 TnyAccount *account = NULL;
2181 if (!folder_store) {
2182 /* We promise to instantly perform the callback, so ... */
2184 callback (FALSE, NULL, parent_window, NULL, user_data);
2188 } else if (TNY_IS_FOLDER (folder_store)) {
2189 /* Get the folder's parent account: */
2190 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2191 } else if (TNY_IS_ACCOUNT (folder_store)) {
2192 /* Use the folder store as an account: */
2193 account = TNY_ACCOUNT (g_object_ref (folder_store));
2196 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
2197 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2198 /* No need to connect a local account */
2200 callback (FALSE, NULL, parent_window, account, user_data);
2205 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2209 g_object_unref (account);
2213 src_account_connect_performer (gboolean canceled,
2215 GtkWindow *parent_window,
2216 TnyAccount *src_account,
2219 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2221 if (canceled || err) {
2222 /* If there was any error call the user callback */
2223 info->callback (canceled, err, parent_window, src_account, info->data);
2225 /* Connect the destination account */
2226 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2227 TNY_FOLDER_STORE (info->dst_account),
2228 info->callback, info->data);
2231 /* Free the info object */
2232 g_object_unref (info->dst_account);
2233 g_slice_free (DoubleConnectionInfo, info);
2238 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2240 TnyFolderStore *folder_store,
2241 DoubleConnectionInfo *connect_info)
2243 modest_platform_connect_if_remote_and_perform(parent_window,
2246 src_account_connect_performer,
2251 modest_platform_get_account_settings_wizard (void)
2253 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2255 return GTK_WIDGET (dialog);
2259 modest_platform_get_current_connection (void)
2261 TnyDevice *device = NULL;
2262 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2264 device = modest_runtime_get_device ();
2266 if (!tny_device_is_online (device))
2267 return MODEST_CONNECTED_VIA_ANY;
2269 #ifdef MODEST_HAVE_CONIC
2271 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2273 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2274 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2275 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2277 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2278 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2279 !strcmp (bearer_type, "WIMAX")) {
2280 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2282 retval = MODEST_CONNECTED_VIA_ANY;
2285 g_object_unref (iap);
2288 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2289 #endif /* MODEST_HAVE_CONIC */
2296 modest_platform_check_memory_low (ModestWindow *win,
2301 /* are we in low memory state? */
2302 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2304 if (win && lowmem && visuals)
2305 modest_platform_run_information_dialog (
2307 dgettext("ke-recv","memr_ib_operation_disabled"),
2311 g_debug ("%s: low memory reached. disallowing some operations",
2318 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2324 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2327 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2328 GTK_WINDOW (dialog),
2330 gtk_widget_show_all (dialog);
2332 g_signal_connect_swapped (dialog, "response",
2333 G_CALLBACK (gtk_widget_destroy),
2338 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2344 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header);
2347 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2348 GTK_WINDOW (dialog),
2350 gtk_widget_show_all (dialog);
2352 g_signal_connect_swapped (dialog, "response",
2353 G_CALLBACK (gtk_widget_destroy),
2358 modest_platform_get_osso_context (void)
2360 return modest_maemo_utils_get_osso_context ();
2364 _modest_platform_play_email_tone (void)
2366 gchar *active_profile;
2369 gint mail_volume_int;
2371 ca_context *ca_con = NULL;
2372 ca_proplist *pl = NULL;
2374 active_profile = profile_get_profile ();
2375 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2376 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2377 mail_volume_int = profile_parse_int (mail_volume);
2379 if (mail_volume_int > 0) {
2381 if ((ret = ca_context_create(&ca_con)) != CA_SUCCESS) {
2382 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2386 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2387 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2388 ca_context_destroy(ca_con);
2392 ca_proplist_create(&pl);
2393 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2394 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", (gfloat) mail_volume_int);
2396 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2397 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2399 ca_proplist_destroy(pl);
2400 ca_context_destroy(ca_con);
2403 g_free (mail_volume);
2405 g_free (active_profile);
2409 on_move_to_dialog_folder_activated (GtkTreeView *tree_view,
2411 GtkTreeViewColumn *column,
2414 gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_OK);
2418 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
2419 GtkWidget **folder_view)
2421 GtkWidget *dialog, *folder_view_container;
2423 /* Create dialog. We cannot use a touch selector because we
2424 need to use here the folder view widget directly */
2425 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2426 GTK_WINDOW (parent_window),
2427 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
2428 GTK_DIALOG_DESTROY_WITH_PARENT,
2429 _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
2432 /* Create folder view */
2433 *folder_view = modest_platform_create_folder_view (NULL);
2435 /* Simulate the behaviour of a HildonPickerDialog by emitting
2436 a response when a folder is selected */
2437 g_signal_connect (*folder_view, "row-activated",
2438 G_CALLBACK (on_move_to_dialog_folder_activated),
2441 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (*folder_view),
2442 (TnyAccountStore *) modest_runtime_get_account_store ());
2444 /* Create pannable and add it to the dialog */
2445 folder_view_container = hildon_pannable_area_new ();
2446 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
2447 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
2449 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
2451 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
2452 gtk_widget_show (folder_view_container);
2453 gtk_widget_show (*folder_view);
2459 modest_platform_get_list_to_move (ModestWindow *window)
2461 TnyList *list = NULL;
2463 if (MODEST_IS_HEADER_WINDOW (window)) {
2464 ModestHeaderView *header_view;
2466 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
2467 list = modest_header_view_get_selected_headers (header_view);
2468 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
2469 ModestFolderView *folder_view;
2470 TnyFolderStore *selected_folder;
2472 list = TNY_LIST (tny_simple_list_new ());
2473 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
2474 selected_folder = modest_folder_view_get_selected (folder_view);
2475 if (selected_folder) {
2476 tny_list_prepend (list, G_OBJECT (selected_folder));
2477 g_object_unref (selected_folder);
2480 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2483 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
2485 list = TNY_LIST (tny_simple_list_new ());
2486 tny_list_prepend (list, G_OBJECT (header));
2487 g_object_unref (header);
2490 g_return_val_if_reached (NULL);