1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <modest-platform.h>
34 #include <modest-defs.h>
35 #include <modest-runtime.h>
36 #include <modest-main-window.h>
37 #include <modest-header-view.h>
38 #include "modest-hildon2-global-settings-dialog.h"
39 #include "modest-widget-memory.h"
40 #include <modest-hildon-includes.h>
41 #include <modest-maemo-utils.h>
42 #include <modest-utils.h>
43 #include <dbus_api/modest-dbus-callbacks.h>
44 #include <modest-osso-autosave-callbacks.h>
46 #include <tny-maemo-conic-device.h>
47 #include <tny-camel-folder.h>
48 #include <tny-simple-list.h>
49 #include <tny-merge-folder.h>
50 #include <tny-error.h>
51 #include <tny-folder.h>
52 #include <tny-account-store-view.h>
53 #include <gtk/gtkicontheme.h>
54 #include <gtk/gtkmenuitem.h>
55 #include <gtk/gtkmain.h>
56 #include <modest-text-utils.h>
57 #include "modest-tny-folder.h"
58 #include "modest-tny-account.h"
60 #include <libgnomevfs/gnome-vfs-mime-utils.h>
61 #include <modest-account-settings-dialog.h>
62 #include <modest-easysetup-wizard-dialog.h>
63 #include "modest-hildon2-sort-dialog.h"
64 #include <hildon/hildon.h>
66 #include "hildon2/modest-hildon2-details-dialog.h"
67 #include "hildon2/modest-hildon2-window-mgr.h"
68 #ifdef MODEST_USE_PROFILE
69 #include <keys_nokia.h>
70 #include <libprofile.h>
73 #include <modest-datetime-formatter.h>
74 #include "modest-header-window.h"
75 #include <modest-folder-window.h>
76 #include <modest-account-mgr.h>
77 #include <modest-account-mgr-helpers.h>
78 #include <modest-ui-constants.h>
79 #include <modest-selector-picker.h>
80 #include <modest-icon-names.h>
81 #include <modest-count-stream.h>
84 #ifdef MODEST_HAVE_MCE
85 #include <mce/dbus-names.h>
86 #endif /*MODEST_HAVE_MCE*/
88 #ifdef MODEST_HAVE_ABOOK
89 #include <libosso-abook/osso-abook.h>
90 #endif /*MODEST_HAVE_ABOOK*/
92 #ifdef MODEST_HAVE_LIBALARM
93 #include <alarmd/libalarm.h> /* For alarm_event_add(), etc. */
94 #endif /*MODEST_HAVE_LIBALARM*/
97 #define HILDON_OSSO_URI_ACTION "uri-action"
98 #define URI_ACTION_COPY "copy:"
99 #define MODEST_NOTIFICATION_CATEGORY "email-message"
100 #define MODEST_NEW_MAIL_LIGHTING_PATTERN "PatternCommunicationEmail"
101 #ifdef MODEST_USE_PROFILE
102 #define PROFILE_MAIL_TONE PROFILEKEY_EMAIL_ALERT_TONE
103 #define PROFILE_MAIL_VOLUME PROFILEKEY_EMAIL_ALERT_VOLUME
105 #define MAIL_TONE "message-new-email"
108 #define COMMON_FOLDER_DIALOG_ENTRY "entry"
109 #define COMMON_FOLDER_DIALOG_ACCOUNT_PICKER "account-picker"
110 #define FOLDER_PICKER_CURRENT_FOLDER "current-folder"
111 #define FOLDER_PICKER_ORIGINAL_ACCOUNT "original-account"
112 #define MODEST_ALARMD_APPID PACKAGE_NAME
114 static ca_context *ca_con = NULL;
115 static gboolean ca_con_opened = FALSE;
118 static void modest_platform_play_email_tone (void);
122 on_modest_conf_update_interval_changed (ModestConf* self,
124 ModestConfEvent event,
125 ModestConfNotificationId id,
128 g_return_if_fail (key);
130 if (strcmp (key, MODEST_CONF_UPDATE_INTERVAL) == 0) {
131 const guint update_interval_minutes =
132 modest_conf_get_int (self, MODEST_CONF_UPDATE_INTERVAL, NULL);
133 modest_platform_set_update_interval (update_interval_minutes);
140 check_required_files (void)
142 FILE *mcc_file = modest_utils_open_mcc_mapping_file (FALSE, NULL);
144 g_printerr ("modest: check for mcc file (for LANG) failed\n");
149 mcc_file = modest_utils_open_mcc_mapping_file (TRUE, NULL);
151 g_printerr ("modest: check for mcc file (for LC_MESSAGES) failed\n");
156 if (access(MODEST_PROVIDER_DATA_FILE, R_OK) != 0 &&
157 access(MODEST_FALLBACK_PROVIDER_DATA_FILE, R_OK) != 0) {
158 g_printerr ("modest: cannot find providers data\n");
166 /* the gpointer here is the osso_context. */
168 modest_platform_init (int argc, char *argv[])
170 osso_context_t *osso_context;
171 osso_hw_state_t hw_state = { 0 };
175 if (!check_required_files ()) {
176 g_printerr ("modest: missing required files\n");
180 osso_context = modest_maemo_utils_get_osso_context();
182 if ((con = osso_get_dbus_connection (osso_context)) == NULL) {
183 g_printerr ("modest: could not get dbus connection\n");
187 /* Add a D-Bus handler to be used when the main osso-rpc
188 * D-Bus handler has not handled something.
189 * We use this for D-Bus methods that need to use more complex types
190 * than osso-rpc supports.
192 if (!dbus_connection_add_filter (con,
193 modest_dbus_req_filter,
197 g_printerr ("modest: Could not add D-Bus filter\n");
201 /* Register our simple D-Bus callbacks, via the osso API: */
202 osso_return_t result = osso_rpc_set_cb_f(osso_context,
206 modest_dbus_req_handler, NULL /* user_data */);
207 if (result != OSSO_OK) {
208 g_printerr ("modest: Error setting D-BUS callback (%d)\n", result);
212 /* Register hardware event dbus callback: */
213 hw_state.shutdown_ind = TRUE;
214 osso_hw_set_event_cb(osso_context, NULL, NULL, NULL);
216 /* Register osso auto-save callbacks: */
217 result = osso_application_set_autosave_cb (osso_context,
218 modest_on_osso_application_autosave, NULL /* user_data */);
219 if (result != OSSO_OK) {
220 g_printerr ("modest: osso_application_set_autosave_cb() failed.\n");
225 /* Make sure that the update interval is changed whenever its gconf key
227 /* CAUTION: we're not using here the
228 modest_conf_listen_to_namespace because we know that there
229 are other parts of Modest listening for this namespace, so
230 we'll receive the notifications anyway. We basically do not
231 use it because there is no easy way to do the
232 modest_conf_forget_namespace */
233 ModestConf *conf = modest_runtime_get_conf ();
234 g_signal_connect (G_OBJECT(conf),
236 G_CALLBACK (on_modest_conf_update_interval_changed),
239 /* only force the setting of the default interval, if there are actually
241 acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), TRUE);
243 /* Get the initial update interval from gconf: */
244 on_modest_conf_update_interval_changed(conf, MODEST_CONF_UPDATE_INTERVAL,
245 MODEST_CONF_EVENT_KEY_CHANGED, 0, NULL);
246 modest_account_mgr_free_account_names (acc_names);
250 #ifdef MODEST_HAVE_ABOOK
251 /* initialize the addressbook */
252 if (!osso_abook_init (&argc, &argv, osso_context)) {
253 g_printerr ("modest: failed to initialized addressbook\n");
256 #endif /*MODEST_HAVE_ABOOK*/
262 modest_platform_uninit (void)
264 osso_context_t *osso_context =
265 modest_maemo_utils_get_osso_context ();
267 osso_deinitialize (osso_context);
276 modest_platform_get_new_device (void)
278 return TNY_DEVICE (tny_maemo_conic_device_new ());
282 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
283 gchar **effective_mime_type)
285 GString *mime_str = NULL;
286 gchar *icon_name = NULL;
287 gchar **icons, **cursor;
289 if (!mime_type || g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0)
290 mime_str = g_string_new (gnome_vfs_get_mime_type_for_name (name));
292 mime_str = g_string_new (mime_type);
293 g_string_ascii_down (mime_str);
296 icons = hildon_mime_get_icon_names (mime_str->str, NULL);
298 for (cursor = icons; cursor; ++cursor) {
299 if (!g_ascii_strcasecmp (*cursor, "gnome-mime-message") ||
300 !g_ascii_strcasecmp (*cursor, "gnome-mime-message-rfc822")) {
301 icon_name = g_strdup ("qgn_list_messagin");
303 } else if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default(), *cursor)) {
304 icon_name = g_strdup (*cursor);
310 if (effective_mime_type)
311 *effective_mime_type = g_string_free (mime_str, FALSE);
313 g_string_free (mime_str, TRUE);
320 checked_hildon_uri_open (const gchar *uri, HildonURIAction *action)
325 g_return_val_if_fail (uri, FALSE);
327 result = hildon_uri_open (uri, action, &err);
329 g_printerr ("modest: hildon_uri_open ('%s', %p) failed: %s",
330 uri, action, err && err->message ? err->message : "unknown error");
340 modest_platform_activate_uri (const gchar *uri)
342 HildonURIAction *action;
343 gboolean result = FALSE;
344 GSList *actions, *iter = NULL;
346 g_return_val_if_fail (uri, FALSE);
350 /* don't try to activate file: uri's -- they might confuse the user,
351 * and/or might have security implications */
352 if (!g_str_has_prefix (uri, "file:")) {
354 actions = hildon_uri_get_actions_by_uri (uri, -1, NULL);
356 for (iter = actions; iter; iter = g_slist_next (iter)) {
357 action = (HildonURIAction*) iter->data;
358 if (action && strcmp (hildon_uri_action_get_service (action),
359 "com.nokia.modest") == 0) {
360 result = checked_hildon_uri_open (uri, action);
365 /* if we could not open it with email, try something else */
367 result = checked_hildon_uri_open (uri, NULL);
371 ModestWindow *parent =
372 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
373 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
374 _("mcen_ib_unsupported_link"));
375 g_debug ("%s: cannot open uri '%s'", __FUNCTION__,uri);
382 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
386 gchar *uri_path = NULL;
388 uri_path = gnome_vfs_get_uri_from_local_path (path);
389 con = osso_get_dbus_connection (modest_maemo_utils_get_osso_context());
392 result = hildon_mime_open_file_with_mime_type (con, uri_path, mime_type);
394 result = hildon_mime_open_file (con, uri_path);
396 modest_platform_run_information_dialog (NULL, _("mcen_ni_noregistered_viewer"), FALSE);
404 } ModestPlatformPopupInfo;
407 delete_uri_popup (GtkWidget *menu,
411 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
413 g_free (popup_info->uri);
414 hildon_uri_free_actions (popup_info->actions);
420 activate_uri_popup_item (GtkMenuItem *menu_item,
424 ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata;
425 const gchar* action_name;
427 action_name = g_object_get_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION);
429 g_printerr ("modest: no action name defined\n");
433 /* special handling for the copy menu item -- copy the uri to the clipboard */
434 /* if it's a copy thingy, the uri will look like 'copy:http://slashdot.org' */
435 if (g_str_has_prefix (action_name, URI_ACTION_COPY)) {
436 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
437 const gchar *uri = (const gchar *) popup_info->uri;
439 /* Special case: ignore "mailto:" prefixes */
440 if (g_str_has_prefix (uri, "mailto:"))
441 uri = popup_info->uri + strlen ("mailto:");
443 gtk_clipboard_set_text (clipboard, uri, strlen (uri));
444 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
445 return; /* we're done */
448 /* now, the real uri-actions... */
449 for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) {
450 HildonURIAction *action = (HildonURIAction *) node->data;
451 if (strcmp (action_name, hildon_uri_action_get_name (action))==0) {
452 if (!checked_hildon_uri_open (popup_info->uri, action)) {
453 ModestWindow *parent =
454 modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE);
455 hildon_banner_show_information (parent ? GTK_WIDGET(parent): NULL, NULL,
456 _("mcen_ib_unsupported_link"));
464 modest_platform_show_uri_popup (const gchar *uri)
466 GSList *actions_list, *node;
468 ModestPlatformPopupInfo *popup_info;
469 GtkWidget *menu_item;
475 menu = gtk_menu_new ();
476 popup_info = g_new0 (ModestPlatformPopupInfo, 1);
477 popup_info->uri = g_strdup (uri);
479 /* don't add actions for file: uri's -- they might confuse the user,
480 * and/or might have security implications
481 * we still allow to copy the url though
483 if (g_str_has_prefix (uri, "file:"))
486 actions_list = hildon_uri_get_actions_by_uri (uri, -1, NULL);
490 popup_info->actions = actions_list;
491 for (node = actions_list; node != NULL; node = g_slist_next (node)) {
492 const gchar *action_name;
493 const gchar *translation_domain;
494 HildonURIAction *action = (HildonURIAction *) node->data;
495 action_name = hildon_uri_action_get_name (action);
496 translation_domain = hildon_uri_action_get_translation_domain (action);
497 menu_item = gtk_menu_item_new_with_label (dgettext(translation_domain, action_name));
498 hildon_gtk_widget_set_theme_size (menu_item, MODEST_EDITABLE_SIZE);
499 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer)action_name); /* hack */
500 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item),
503 if (hildon_uri_is_default_action (action, NULL)) {
504 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
506 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
508 gtk_widget_show (menu_item);
512 /* Add the "Copy link" menu option */
513 menu_item = gtk_menu_item_new_with_label (_UR("uri_link_copy_link_location"));
514 hildon_gtk_widget_set_theme_size (menu_item, MODEST_EDITABLE_SIZE);
515 g_object_set_data (G_OBJECT(menu_item), HILDON_OSSO_URI_ACTION, (gpointer) URI_ACTION_COPY);
516 g_signal_connect (G_OBJECT (menu_item), "activate", (GCallback) activate_uri_popup_item, popup_info);
517 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
518 gtk_widget_show (menu_item);
520 /* and what to do when the link is deleted */
521 g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info);
522 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
529 modest_platform_get_icon (const gchar *name, guint icon_size)
532 GdkPixbuf* pixbuf = NULL;
533 GtkIconTheme *current_theme = NULL;
535 g_return_val_if_fail (name, NULL);
537 /* strlen == 0 is not really an error; it just
538 * means the icon is not available
540 if (!name || strlen(name) == 0)
543 current_theme = gtk_icon_theme_get_default ();
544 pixbuf = gtk_icon_theme_load_icon (current_theme, name, icon_size,
545 GTK_ICON_LOOKUP_NO_SVG,
548 g_warning ("Error loading theme icon '%s': %s\n",
556 modest_platform_get_app_name (void)
558 return _("mcen_ap_name");
562 entry_insert_text (GtkEditable *editable,
571 chars = gtk_editable_get_chars (editable, 0, -1);
572 chars_length = g_utf8_strlen (chars, -1);
575 /* Show WID-INF036 */
576 if (chars_length >= 20) {
577 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
578 _CS("ckdg_ib_maximum_characters_reached"));
580 if (modest_text_utils_is_forbidden_char (*text, FOLDER_NAME_FORBIDDEN_CHARS)) {
584 tmp = g_strndup (folder_name_forbidden_chars,
585 FOLDER_NAME_FORBIDDEN_CHARS_LENGTH);
586 msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
587 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)),
593 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (data)), NULL,
594 _CS("ckdg_ib_maximum_characters_reached"));
596 /* Write the text in the entry if it's valid */
597 g_signal_handlers_block_by_func (editable,
598 (gpointer) entry_insert_text, data);
599 gtk_editable_insert_text (editable, text, length, position);
600 g_signal_handlers_unblock_by_func (editable,
601 (gpointer) entry_insert_text, data);
604 /* Do not allow further processing */
605 g_signal_stop_emission_by_name (editable, "insert_text");
609 entry_changed (GtkEditable *editable,
613 GtkWidget *ok_button;
616 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (user_data)->action_area));
617 ok_button = GTK_WIDGET (buttons->data);
619 chars = gtk_editable_get_chars (editable, 0, -1);
620 g_return_if_fail (chars != NULL);
623 if (g_utf8_strlen (chars,-1) >= 20) {
624 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (user_data)), NULL,
625 _CS("ckdg_ib_maximum_characters_reached"));
627 gtk_widget_set_sensitive (ok_button, modest_text_utils_validate_folder_name(chars));
630 g_list_free (buttons);
637 on_response (GtkDialog *dialog,
641 GtkWidget *entry, *picker;
642 TnyFolderStore *parent;
643 const gchar *new_name;
646 if (response != GTK_RESPONSE_ACCEPT)
650 entry = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY);
651 picker = g_object_get_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER);
653 parent = TNY_FOLDER_STORE (user_data);
654 new_name = gtk_entry_get_text (GTK_ENTRY (entry));
658 parent = g_object_get_data (G_OBJECT (picker), FOLDER_PICKER_CURRENT_FOLDER);
660 /* Look for another folder with the same name */
661 if (!TNY_IS_MERGE_FOLDER (parent) &&
662 modest_tny_folder_has_subfolder_with_name (parent, new_name, TRUE))
666 if (TNY_IS_ACCOUNT (parent) &&
667 modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent)) &&
668 modest_tny_local_folders_account_folder_name_in_use (MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (parent),
676 hildon_banner_show_information (gtk_widget_get_parent (GTK_WIDGET (dialog)),
677 NULL, _CS("ckdg_ib_folder_already_exists"));
678 /* Select the text */
679 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
680 gtk_widget_grab_focus (entry);
681 /* Do not close the dialog */
682 g_signal_stop_emission_by_name (dialog, "response");
686 typedef struct _FolderChooserData {
687 TnyFolderStore *store;
692 folder_chooser_activated (ModestFolderView *folder_view,
693 TnyFolderStore *folder,
694 FolderChooserData *userdata)
696 userdata->store = folder;
697 gtk_dialog_response (GTK_DIALOG (userdata->dialog), GTK_RESPONSE_OK);
700 static TnyFolderStore *
701 folder_chooser_dialog_run (ModestFolderView *original,
702 TnyFolderStore *current,
705 GtkWidget *folder_view;
706 FolderChooserData userdata = {NULL, NULL};
708 const gchar *visible_id = NULL;
710 userdata.dialog = gtk_dialog_new ();
711 pannable = hildon_pannable_area_new ();
712 folder_view = modest_platform_create_folder_view (NULL);
714 gtk_window_set_title (GTK_WINDOW (userdata.dialog), _FM("ckdg_ti_change_folder"));
716 modest_folder_view_copy_model (MODEST_FOLDER_VIEW (original),
717 MODEST_FOLDER_VIEW (folder_view));
719 if (TNY_IS_ACCOUNT (current)) {
720 /* Local folders and MMC account are always shown
721 along with the currently visible server account */
722 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (current)) ||
723 modest_tny_account_is_memory_card_account (TNY_ACCOUNT (current)))
724 visible_id = g_object_get_data ((GObject *) picker, FOLDER_PICKER_ORIGINAL_ACCOUNT);
726 visible_id = tny_account_get_id (TNY_ACCOUNT (current));
727 } else if (TNY_IS_FOLDER (current)) {
729 account = modest_tny_folder_get_account ((TnyFolder *) current);
731 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (account)) ||
732 modest_tny_account_is_memory_card_account (TNY_ACCOUNT (account))) {
733 visible_id = g_object_get_data ((GObject *) picker, FOLDER_PICKER_ORIGINAL_ACCOUNT);
735 visible_id = tny_account_get_id (account);
737 g_object_unref (account);
741 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(original));
744 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view),
747 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (userdata.dialog)->vbox), pannable);
748 gtk_container_add (GTK_CONTAINER (pannable), folder_view);
749 gtk_widget_set_size_request (pannable, -1, 320);
751 gtk_widget_show (folder_view);
752 gtk_widget_show (pannable);
753 gtk_widget_show (userdata.dialog);
754 g_signal_connect (G_OBJECT (folder_view), "folder-activated",
755 G_CALLBACK (folder_chooser_activated),
756 (gpointer) &userdata);
758 gtk_dialog_run (GTK_DIALOG (userdata.dialog));
759 gtk_widget_destroy (userdata.dialog);
761 return userdata.store;
765 folder_store_get_display_name (TnyFolderStore *store)
767 if (TNY_IS_ACCOUNT (store)) {
768 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (store)))
769 return modest_conf_get_string (modest_runtime_get_conf(),
770 MODEST_CONF_DEVICE_NAME, NULL);
772 return g_strdup (tny_account_get_name (TNY_ACCOUNT (store)));
775 TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
777 fname = g_strdup (tny_folder_get_name (TNY_FOLDER (store)));
778 type = tny_folder_get_folder_type (TNY_FOLDER (store));
779 if (modest_tny_folder_is_local_folder (TNY_FOLDER (store)) ||
780 modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
781 type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (store));
782 if (type != TNY_FOLDER_TYPE_UNKNOWN) {
784 fname = g_strdup (modest_local_folder_info_get_type_display_name (type));
787 /* Sometimes an special folder is reported by the server as
788 NORMAL, like some versions of Dovecot */
789 if (type == TNY_FOLDER_TYPE_NORMAL ||
790 type == TNY_FOLDER_TYPE_UNKNOWN) {
791 type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
795 if (type == TNY_FOLDER_TYPE_INBOX) {
797 fname = g_strdup (_("mcen_me_folder_inbox"));
804 get_image_for_folder_store (TnyFolderStore *store,
808 const gchar *icon_name = NULL;
809 GtkWidget *image = NULL;
811 if (TNY_IS_ACCOUNT (store)) {
812 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (store)))
813 icon_name = MODEST_FOLDER_ICON_LOCAL_FOLDERS;
814 else if (modest_tny_account_is_memory_card_account (TNY_ACCOUNT (store)))
815 icon_name = MODEST_FOLDER_ICON_MMC;
817 icon_name = MODEST_FOLDER_ICON_ACCOUNT;
819 TnyFolderType type = modest_tny_folder_guess_folder_type (TNY_FOLDER (store));
820 if (modest_tny_folder_is_remote_folder (TNY_FOLDER (store))) {
822 case TNY_FOLDER_TYPE_INBOX:
823 icon_name = MODEST_FOLDER_ICON_INBOX;
826 icon_name = MODEST_FOLDER_ICON_REMOTE_FOLDER;
828 } else if (modest_tny_folder_is_local_folder (TNY_FOLDER (store))) {
830 case TNY_FOLDER_TYPE_OUTBOX:
831 icon_name = MODEST_FOLDER_ICON_OUTBOX;
833 case TNY_FOLDER_TYPE_DRAFTS:
834 icon_name = MODEST_FOLDER_ICON_DRAFTS;
836 case TNY_FOLDER_TYPE_SENT:
837 icon_name = MODEST_FOLDER_ICON_SENT;
840 icon_name = MODEST_FOLDER_ICON_NORMAL;
842 } else if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (store))) {
843 icon_name = MODEST_FOLDER_ICON_MMC_FOLDER;
848 pixbuf = modest_platform_get_icon (icon_name, size);
851 image = gtk_image_new_from_pixbuf (pixbuf);
852 g_object_unref (pixbuf);
859 folder_picker_set_store (GtkButton *button, TnyFolderStore *store)
864 g_object_set_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER, NULL);
868 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER,
869 g_object_ref (store),
870 (GDestroyNotify) g_object_unref);
871 name = folder_store_get_display_name (store);
872 hildon_button_set_value (HILDON_BUTTON (button), name);
876 image = get_image_for_folder_store (store, MODEST_ICON_SIZE_SMALL);
878 hildon_button_set_image (HILDON_BUTTON (button), image);
882 /* Always returns DUPs so you must free the returned value */
884 get_next_folder_name (const gchar *suggested_name,
885 TnyFolderStore *suggested_folder)
887 const gchar *default_name = _FM("ckdg_va_new_folder_name_stub");
889 gchar *real_suggested_name;
891 if (suggested_name !=NULL) {
892 return g_strdup (suggested_name);
895 for(i = 0; i < 100; ++ i) {
896 gboolean exists = FALSE;
899 real_suggested_name = g_strdup (default_name);
901 real_suggested_name = g_strdup_printf ("%s(%d)",
902 _FM("ckdg_va_new_folder_name_stub"),
904 exists = modest_tny_folder_has_subfolder_with_name (suggested_folder,
911 g_free (real_suggested_name);
914 /* Didn't find a free number */
916 real_suggested_name = g_strdup (default_name);
918 return real_suggested_name;
922 ModestFolderView *folder_view;
924 } FolderPickerHelper;
927 folder_picker_clicked (GtkButton *button,
928 FolderPickerHelper *helper)
930 TnyFolderStore *store, *current;
932 current = g_object_get_data (G_OBJECT (button), FOLDER_PICKER_CURRENT_FOLDER);
934 store = folder_chooser_dialog_run (helper->folder_view, current, button);
936 const gchar *current_name;
937 gboolean exists = FALSE;
939 folder_picker_set_store (GTK_BUTTON (button), store);
941 /* Update the name of the folder */
942 current_name = gtk_entry_get_text (helper->entry);
944 if (TNY_IS_FOLDER_STORE (store))
945 exists = modest_tny_folder_has_subfolder_with_name (store,
949 gchar *new_name = get_next_folder_name (NULL, store);
950 gtk_entry_set_text (helper->entry, new_name);
957 folder_picker_new (TnyFolderStore *suggested, FolderPickerHelper *helper)
960 const gchar *acc_id = NULL;
962 button = hildon_button_new (MODEST_EDITABLE_SIZE,
963 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
965 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 1.0);
969 folder_picker_set_store (GTK_BUTTON (button), suggested);
971 if (TNY_IS_ACCOUNT (suggested)) {
972 if (!modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (suggested)) &&
973 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (suggested)))
974 acc_id = tny_account_get_id ((TnyAccount *) suggested);
976 TnyAccount *account = modest_tny_folder_get_account ((TnyFolder *) suggested);
978 acc_id = tny_account_get_id ((TnyAccount *) account);
979 g_object_unref (account);
985 acc_id = modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(helper->folder_view));
987 g_object_set_data_full (G_OBJECT (button), FOLDER_PICKER_ORIGINAL_ACCOUNT,
988 g_strdup (acc_id), (GDestroyNotify) g_free);
991 g_signal_connect (G_OBJECT (button), "clicked",
992 G_CALLBACK (folder_picker_clicked),
1000 modest_platform_run_folder_common_dialog (GtkWindow *parent_window,
1001 TnyFolderStore *suggested_parent,
1002 const gchar *dialog_title,
1003 const gchar *label_text,
1004 const gchar *suggested_name,
1006 gboolean show_parent,
1007 gchar **folder_name,
1008 TnyFolderStore **parent)
1010 GtkWidget *accept_btn = NULL;
1011 GtkWidget *dialog, *entry = NULL, *label_entry = NULL, *label_location = NULL, *hbox;
1012 GtkWidget *account_picker = NULL;
1013 GList *buttons = NULL;
1015 GtkSizeGroup *sizegroup;
1016 ModestFolderView *folder_view;
1017 ModestWindow *folder_window;
1018 ModestHildon2WindowMgr *window_mgr;
1019 FolderPickerHelper *helper = NULL;
1020 GtkWidget *top_vbox, *top_align;
1022 window_mgr = (ModestHildon2WindowMgr *) modest_runtime_get_window_mgr ();
1023 folder_window = modest_hildon2_window_mgr_get_folder_window (window_mgr);
1024 g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window), GTK_RESPONSE_NONE);
1026 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (folder_window));
1028 top_vbox = gtk_vbox_new (FALSE, 0);
1029 top_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
1030 gtk_alignment_set_padding (GTK_ALIGNMENT (top_align), 0, 0, MODEST_MARGIN_DOUBLE, 0);
1032 /* Ask the user for the folder name */
1033 dialog = gtk_dialog_new_with_buttons (dialog_title,
1035 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
1036 _FM("ckdg_bd_new_folder_dialog_ok"),
1037 GTK_RESPONSE_ACCEPT,
1040 /* Add accept button (with unsensitive handler) */
1041 buttons = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
1042 accept_btn = GTK_WIDGET (buttons->data);
1044 sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
1047 label_entry = gtk_label_new (label_text);
1048 entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1049 gtk_entry_set_max_length (GTK_ENTRY (entry), 20);
1051 gtk_misc_set_alignment (GTK_MISC (label_entry), 0.0, 0.5);
1052 gtk_size_group_add_widget (sizegroup, label_entry);
1055 gtk_entry_set_text (GTK_ENTRY (entry), suggested_name);
1057 gtk_entry_set_text (GTK_ENTRY (entry), _FM("ckdg_va_new_folder_name_stub"));
1058 gtk_entry_set_width_chars (GTK_ENTRY (entry),
1059 MAX (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1),
1060 g_utf8_strlen (_FM("ckdg_va_new_folder_name_stub"), -1)));
1061 gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
1066 label_location = gtk_label_new (_FM("ckdg_fi_new_folder_location"));
1068 gtk_misc_set_alignment (GTK_MISC (label_location), 0.0, 0.5);
1069 gtk_size_group_add_widget (sizegroup, label_location);
1071 helper = g_slice_new0 (FolderPickerHelper);
1072 helper->folder_view = folder_view;
1073 helper->entry = (GtkEntry *) entry;
1075 account_picker = folder_picker_new (suggested_parent, helper);
1078 g_object_unref (sizegroup);
1080 /* Connect to the response method to avoid closing the dialog
1081 when an invalid name is selected*/
1082 g_signal_connect (dialog,
1084 G_CALLBACK (on_response),
1088 /* Track entry changes */
1089 g_signal_connect (entry,
1091 G_CALLBACK (entry_insert_text),
1093 g_signal_connect (entry,
1095 G_CALLBACK (entry_changed),
1100 /* Some locales like pt_BR need this to get the full window
1102 gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
1104 /* Create the hbox */
1106 hbox = gtk_hbox_new (FALSE, 12);
1107 gtk_box_pack_start (GTK_BOX (hbox), label_entry, FALSE, FALSE, 0);
1108 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
1110 /* Add hbox to dialog */
1111 gtk_box_pack_start (GTK_BOX (top_vbox),
1112 hbox, FALSE, FALSE, 0);
1113 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ENTRY, entry);
1117 hbox = gtk_hbox_new (FALSE, 12);
1118 gtk_box_pack_start (GTK_BOX (hbox), label_location, FALSE, FALSE, 0);
1119 gtk_box_pack_start (GTK_BOX (hbox), account_picker, TRUE, TRUE, 0);
1121 /* Add hbox to dialog */
1122 gtk_box_pack_start (GTK_BOX (top_vbox),
1123 hbox, FALSE, FALSE, 0);
1124 g_object_set_data (G_OBJECT (dialog), COMMON_FOLDER_DIALOG_ACCOUNT_PICKER, account_picker);
1126 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1127 GTK_WINDOW (dialog), parent_window);
1129 gtk_container_add (GTK_CONTAINER (top_align), top_vbox);
1130 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), top_align, TRUE, TRUE, 0);
1132 gtk_widget_show_all (GTK_WIDGET(dialog));
1134 result = gtk_dialog_run (GTK_DIALOG(dialog));
1135 if (result == GTK_RESPONSE_ACCEPT) {
1137 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1139 *parent = g_object_get_data (G_OBJECT (account_picker), FOLDER_PICKER_CURRENT_FOLDER);
1141 g_object_ref (*parent);
1145 gtk_widget_destroy (dialog);
1148 g_slice_free (FolderPickerHelper, helper);
1150 while (gtk_events_pending ())
1151 gtk_main_iteration ();
1157 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
1158 TnyFolderStore *suggested_folder,
1159 gchar *suggested_name,
1160 gchar **folder_name,
1161 TnyFolderStore **parent_folder)
1163 gchar *real_suggested_name = NULL;
1165 ModestTnyAccountStore *acc_store;
1166 TnyAccount *account;
1167 gboolean do_free = FALSE;
1169 real_suggested_name = get_next_folder_name ((const gchar *) suggested_name,
1172 /* In hildon 2.2 we always suggest the archive folder as parent */
1173 if (!suggested_folder) {
1174 acc_store = modest_runtime_get_account_store ();
1175 account = modest_tny_account_store_get_mmc_folders_account (acc_store);
1177 suggested_folder = (TnyFolderStore *)
1178 modest_tny_account_get_special_folder (account,
1179 TNY_FOLDER_TYPE_ARCHIVE);
1180 g_object_unref (account);
1185 /* If there is not archive folder then fallback to local folders account */
1186 if (!suggested_folder) {
1188 suggested_folder = (TnyFolderStore *)
1189 modest_tny_account_store_get_local_folders_account (acc_store);
1192 result = modest_platform_run_folder_common_dialog (parent_window,
1194 _HL("ckdg_ti_new_folder"),
1195 _FM("ckdg_fi_new_folder_name"),
1196 real_suggested_name,
1203 g_object_unref (suggested_folder);
1205 g_free(real_suggested_name);
1211 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
1212 TnyFolderStore *parent_folder,
1213 const gchar *suggested_name,
1214 gchar **folder_name)
1216 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent_folder), GTK_RESPONSE_REJECT);
1218 return modest_platform_run_folder_common_dialog (parent_window,
1220 _HL("ckdg_ti_rename_folder"),
1221 _HL("ckdg_fi_rename_name"),
1232 on_destroy_dialog (GtkWidget *dialog)
1234 /* This could happen when the dialogs get programatically
1235 hidden or destroyed (for example when closing the
1236 application while a dialog is being shown) */
1237 if (!GTK_IS_WIDGET (dialog))
1240 gtk_widget_destroy (dialog);
1242 if (gtk_events_pending ())
1243 gtk_main_iteration ();
1247 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
1248 const gchar *message)
1253 dialog = hildon_note_new_confirmation (parent_window, message);
1254 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1255 GTK_WINDOW (dialog), parent_window);
1257 response = gtk_dialog_run (GTK_DIALOG (dialog));
1259 on_destroy_dialog (dialog);
1265 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
1266 const gchar *message,
1267 const gchar *button_accept,
1268 const gchar *button_cancel)
1273 dialog = hildon_note_new_confirmation_add_buttons (parent_window, message,
1274 button_accept, GTK_RESPONSE_ACCEPT,
1275 button_cancel, GTK_RESPONSE_CANCEL,
1278 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1279 GTK_WINDOW (dialog), parent_window);
1281 response = gtk_dialog_run (GTK_DIALOG (dialog));
1283 on_destroy_dialog (dialog);
1289 modest_platform_run_information_dialog (GtkWindow *parent_window,
1290 const gchar *message,
1295 note = hildon_note_new_information (parent_window, message);
1297 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1298 GTK_WINDOW (note), parent_window);
1301 gtk_dialog_run (GTK_DIALOG (note));
1303 on_destroy_dialog (note);
1305 g_signal_connect_swapped (note,
1307 G_CALLBACK (on_destroy_dialog),
1310 gtk_widget_show_all (note);
1314 typedef struct _ConnectAndWaitData {
1316 GMainLoop *wait_loop;
1317 gboolean has_callback;
1319 } ConnectAndWaitData;
1323 quit_wait_loop (TnyAccount *account,
1324 ConnectAndWaitData *data)
1326 /* Set the has_callback to TRUE (means that the callback was
1327 executed and wake up every code waiting for cond to be
1329 g_mutex_lock (data->mutex);
1330 data->has_callback = TRUE;
1331 if (data->wait_loop)
1332 g_main_loop_quit (data->wait_loop);
1333 g_mutex_unlock (data->mutex);
1337 on_connection_status_changed (TnyAccount *account,
1338 TnyConnectionStatus status,
1341 TnyConnectionStatus conn_status;
1342 ConnectAndWaitData *data;
1344 /* Ignore if reconnecting or disconnected */
1345 conn_status = tny_account_get_connection_status (account);
1346 if (conn_status == TNY_CONNECTION_STATUS_RECONNECTING ||
1347 conn_status == TNY_CONNECTION_STATUS_DISCONNECTED)
1350 /* Remove the handler */
1351 data = (ConnectAndWaitData *) user_data;
1352 g_signal_handler_disconnect (account, data->handler);
1354 /* Quit from wait loop */
1355 quit_wait_loop (account, (ConnectAndWaitData *) user_data);
1359 on_tny_camel_account_set_online_cb (TnyCamelAccount *account,
1364 /* Quit from wait loop */
1365 quit_wait_loop (TNY_ACCOUNT (account), (ConnectAndWaitData *) user_data);
1369 modest_platform_connect_and_wait (GtkWindow *parent_window,
1370 TnyAccount *account)
1372 ConnectAndWaitData *data = NULL;
1373 gboolean device_online;
1375 TnyConnectionStatus conn_status;
1376 gboolean user_requested;
1378 device = modest_runtime_get_device();
1379 device_online = tny_device_is_online (device);
1381 /* Whether the connection is user requested or automatically
1382 requested, for example via D-Bus */
1383 user_requested = (parent_window) ? TRUE : FALSE;
1385 /* If there is no account check only the device status */
1390 return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1391 NULL, user_requested);
1394 /* Return if the account is already connected */
1395 conn_status = tny_account_get_connection_status (account);
1396 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED)
1399 /* Create the helper */
1400 data = g_slice_new0 (ConnectAndWaitData);
1401 data->mutex = g_mutex_new ();
1402 data->has_callback = FALSE;
1404 /* Connect the device */
1405 if (!device_online) {
1406 /* Track account connection status changes */
1407 data->handler = g_signal_connect (account, "connection-status-changed",
1408 G_CALLBACK (on_connection_status_changed),
1410 /* Try to connect the device */
1411 device_online = tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device),
1412 NULL, user_requested);
1414 /* If the device connection failed then exit */
1415 if (!device_online && data->handler)
1418 /* Force a reconnection of the account */
1419 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
1420 on_tny_camel_account_set_online_cb, data);
1423 /* Wait until the callback is executed */
1424 g_mutex_lock (data->mutex);
1425 if (!data->has_callback) {
1426 data->wait_loop = g_main_loop_new (g_main_context_new (), FALSE);
1427 gdk_threads_leave ();
1428 g_mutex_unlock (data->mutex);
1429 g_main_loop_run (data->wait_loop);
1430 g_mutex_lock (data->mutex);
1431 gdk_threads_enter ();
1433 g_mutex_unlock (data->mutex);
1436 if (g_signal_handler_is_connected (account, data->handler))
1437 g_signal_handler_disconnect (account, data->handler);
1438 g_mutex_free (data->mutex);
1439 g_main_loop_unref (data->wait_loop);
1440 g_slice_free (ConnectAndWaitData, data);
1442 conn_status = tny_account_get_connection_status (account);
1443 return (conn_status == TNY_CONNECTION_STATUS_CONNECTED) ? TRUE: FALSE;
1447 modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
1449 if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
1450 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1451 /* This must be a maildir account, which does not require a connection: */
1456 return modest_platform_connect_and_wait (parent_window, account);
1460 modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store)
1463 return TRUE; /* Maybe it is something local. */
1465 gboolean result = TRUE;
1466 if (TNY_IS_FOLDER (folder_store)) {
1467 /* Get the folder's parent account: */
1468 TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store));
1469 if (account != NULL) {
1470 result = modest_platform_connect_and_wait_if_network_account (NULL, account);
1471 g_object_unref (account);
1473 } else if (TNY_IS_ACCOUNT (folder_store)) {
1474 /* Use the folder store as an account: */
1475 result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store));
1482 modest_platform_create_sort_dialog (GtkWindow *parent_window)
1486 dialog = modest_hildon2_sort_dialog_new (parent_window);
1493 modest_platform_set_update_interval (guint minutes)
1495 #ifdef MODEST_HAVE_LIBALARM
1497 cookie_t alarm_cookie, *alarm_cookies;
1498 ModestConf *conf = modest_runtime_get_conf ();
1503 GSList *acc_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1507 modest_account_mgr_free_account_names (acc_names);
1511 /* cookie_t alarm_cookie = modest_conf_get_int (conf, MODEST_CONF_ALARM_ID, NULL); */
1513 /* Delete any existing alarm, because we will replace it: */
1514 alarm_cookies = alarmd_event_query (0,0, 0,0, MODEST_ALARMD_APPID);
1515 if (alarm_cookies) {
1516 /* alarmd_event_query returns a zero terminated array */
1517 for (; *alarm_cookies != 0; alarm_cookies++) {
1518 alarmd_event_del (*alarm_cookies);
1520 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, 0, NULL);
1523 /* 0 means no updates: */
1527 /* Register alarm: */
1529 /* Set the interval in alarm_event_t structure: */
1530 alarm_event_t *event = alarm_event_create ();
1531 alarm_event_add_actions (event, 1);
1532 alarm_action_t *action = alarm_event_get_action (event, 0);
1533 alarm_event_set_alarm_appid (event, MODEST_ALARMD_APPID);
1534 event->alarm_time = minutes * 60; /* seconds */
1536 /* Set recurrence every few minutes: */
1537 event->recur_secs = minutes*60;
1538 event->recur_count = -1; /* Means infinite */
1540 /* Specify what should happen when the alarm happens:
1541 * It should call this D-Bus method: */
1543 action->dbus_path = g_strdup(MODEST_DBUS_OBJECT);
1544 action->dbus_interface = g_strdup (MODEST_DBUS_IFACE);
1545 action->dbus_service = g_strdup (MODEST_DBUS_SERVICE);
1546 action->dbus_name = g_strdup (MODEST_DBUS_METHOD_SEND_RECEIVE);
1547 action->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_TYPE_DBUS | ALARM_ACTION_DBUS_USE_ACTIVATION;
1549 /* Use ALARM_EVENT_NO_DIALOG: Otherwise, a dialog will be shown if
1550 * exec_name or dbus_path is NULL, even though we have specified no dialog text.
1551 * Also use ALARM_EVENT_ACTIVATION so that modest is started (without UI) to get emails
1552 * This is why we want to use the Alarm API instead of just g_timeout_add().
1553 * (The old maemo email-client did this, though it isn't specified in the UI spec.)
1554 * ALARM_EVENT_CONNECTED will prevent the alarm from being called in case that the device is offline
1556 event->flags = ALARM_EVENT_CONNECTED | ALARM_EVENT_RUN_DELAYED;
1558 alarm_cookie = alarmd_event_add (event);
1561 alarm_event_delete (event);
1563 /* Store the alarm ID in GConf, so we can remove it later:
1564 * This is apparently valid between application instances. */
1565 modest_conf_set_int (conf, MODEST_CONF_ALARM_ID, alarm_cookie, NULL);
1567 if (!alarm_cookie) {
1569 g_warning ("Error setting alarm event. \n");
1573 #endif /* MODEST_HAVE_LIBALARM */
1578 modest_platform_push_email_notification(void)
1580 gboolean screen_on, app_in_foreground;
1582 /* Get the window status */
1583 app_in_foreground = hildon_program_get_is_topmost (hildon_program_get_instance ());
1585 screen_on = modest_window_mgr_screen_is_on (modest_runtime_get_window_mgr ());
1587 /* If the screen is on and the app is in the
1588 foreground we don't show anything */
1589 if (!(screen_on && app_in_foreground)) {
1591 modest_platform_play_email_tone ();
1593 /* Activate LED. This must be deactivated by
1594 modest_platform_remove_new_mail_notifications */
1595 #ifdef MODEST_HAVE_MCE
1596 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1600 MCE_ACTIVATE_LED_PATTERN,
1602 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1609 modest_platform_on_new_headers_received (GList *URI_list,
1610 gboolean show_visual)
1612 if (g_list_length (URI_list) == 0)
1615 #ifdef MODEST_HAVE_HILDON_NOTIFY
1616 /* For any other case issue a notification */
1617 HildonNotification *notification;
1618 ModestMsgNotificationData *data;
1621 TnyAccountStore *acc_store;
1622 TnyAccount *account;
1624 data = (ModestMsgNotificationData *) URI_list->data;
1626 /* String is changed in-place. There is no need to
1627 actually dup the data->from string but we just do
1628 it in order not to modify the original contents */
1629 from = g_strdup (data->from);
1630 modest_text_utils_get_display_address (from);
1632 /* Create notification */
1633 notification = hildon_notification_new (from,
1635 "qgn_list_messagin",
1636 MODEST_NOTIFICATION_CATEGORY);
1639 /* Add DBus action */
1640 hildon_notification_add_dbus_action(notification,
1643 MODEST_DBUS_SERVICE,
1646 MODEST_DBUS_METHOD_OPEN_MESSAGE,
1647 G_TYPE_STRING, data->uri,
1650 /* Set the led pattern */
1652 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1653 "time", data->time);
1655 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1657 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1659 MODEST_NEW_MAIL_LIGHTING_PATTERN);
1661 /* Make the notification persistent */
1662 notify_notification_set_hint_byte (NOTIFY_NOTIFICATION (notification),
1663 "persistent", TRUE);
1665 /* Set the number of new notifications */
1666 notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (notification),
1667 "amount", g_list_length (URI_list));
1669 /* Set the account of the headers */
1670 acc_store = (TnyAccountStore *) modest_runtime_get_account_store ();
1671 account = tny_account_store_find_account (acc_store, data->uri);
1673 const gchar *acc_name;
1675 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
1676 notify_notification_set_hint_string(NOTIFY_NOTIFICATION (notification),
1679 g_object_unref (account);
1682 if (notify_notification_show (NOTIFY_NOTIFICATION (notification), NULL)) {
1683 GSList *notifications_list = NULL;
1685 /* Get previous notifications ids */
1686 notifications_list = modest_conf_get_list (modest_runtime_get_conf (),
1687 MODEST_CONF_NOTIFICATION_IDS,
1688 MODEST_CONF_VALUE_INT, NULL);
1690 /* Save id in the list */
1691 g_object_get(G_OBJECT (notification), "id", ¬if_id, NULL);
1692 notifications_list = g_slist_prepend (notifications_list, GINT_TO_POINTER(notif_id));
1694 /* We don't listen for the "closed" signal, because we
1695 don't care about if the notification was removed or
1696 not to store the list in gconf */
1699 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1700 notifications_list, MODEST_CONF_VALUE_INT, NULL);
1702 g_slist_free (notifications_list);
1704 g_warning ("Failed to send notification");
1707 #endif /*MODEST_HAVE_HILDON_NOTIFY*/
1711 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
1714 #ifdef MODEST_HAVE_MCE
1715 osso_rpc_run_system (modest_maemo_utils_get_osso_context (),
1719 MCE_DEACTIVATE_LED_PATTERN,
1721 DBUS_TYPE_STRING, MODEST_NEW_MAIL_LIGHTING_PATTERN,
1727 #ifdef MODEST_HAVE_HILDON_NOTIFY
1728 GSList *notif_list = NULL;
1730 /* Get previous notifications ids */
1731 notif_list = modest_conf_get_list (modest_runtime_get_conf (),
1732 MODEST_CONF_NOTIFICATION_IDS,
1733 MODEST_CONF_VALUE_INT, NULL);
1735 while (notif_list) {
1737 NotifyNotification *notif;
1739 /* Nasty HACK to remove the notifications, set the id
1740 of the existing ones and then close them */
1741 notif_id = GPOINTER_TO_INT(notif_list->data);
1742 notif = notify_notification_new("dummy", NULL, NULL, NULL);
1743 g_object_set(G_OBJECT(notif), "id", notif_id, NULL);
1745 /* Close the notification, note that some ids could be
1746 already invalid, but we don't care because it does
1748 notify_notification_close(notif, NULL);
1749 g_object_unref(notif);
1751 /* Delete the link, it's like going to the next */
1752 notif_list = g_slist_delete_link (notif_list, notif_list);
1756 modest_conf_set_list (modest_runtime_get_conf (), MODEST_CONF_NOTIFICATION_IDS,
1757 notif_list, MODEST_CONF_VALUE_INT, NULL);
1759 g_slist_free (notif_list);
1761 #endif /* MODEST_HAVE_HILDON_NOTIFY */
1767 modest_platform_get_global_settings_dialog ()
1769 return modest_hildon2_global_settings_dialog_new ();
1773 modest_platform_show_help (GtkWindow *parent_window,
1774 const gchar *help_id)
1780 modest_platform_show_search_messages (GtkWindow *parent_window)
1782 osso_return_t result = OSSO_ERROR;
1784 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1785 "osso_global_search",
1786 "search_email", NULL, DBUS_TYPE_INVALID);
1788 if (result != OSSO_OK) {
1789 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1794 modest_platform_show_addressbook (GtkWindow *parent_window)
1796 osso_return_t result = OSSO_ERROR;
1798 result = osso_rpc_run_with_defaults (modest_maemo_utils_get_osso_context(),
1800 "top_application", NULL, DBUS_TYPE_INVALID);
1802 if (result != OSSO_OK) {
1803 g_warning ("%s: osso_rpc_run_with_defaults() failed.\n", __FUNCTION__);
1808 modest_platform_create_folder_view_full (TnyFolderStoreQuery *query, gboolean do_refresh)
1810 GtkWidget *widget = modest_folder_view_new_full (query, do_refresh);
1812 /* Show one account by default */
1813 modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
1814 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
1820 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
1822 return modest_platform_create_folder_view_full (query, TRUE);
1826 banner_finish (gpointer data, GObject *object)
1828 ModestWindowMgr *mgr = (ModestWindowMgr *) data;
1829 modest_window_mgr_unregister_banner (mgr);
1830 g_object_unref (mgr);
1834 modest_platform_information_banner (GtkWidget *parent,
1835 const gchar *icon_name,
1838 GtkWidget *banner_parent = NULL;
1839 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1841 if (modest_window_mgr_get_num_windows (mgr) == 0)
1844 if (parent && GTK_IS_WINDOW (parent)) {
1845 /* If the window is the active one then show the
1846 banner on top of this window */
1847 if (gtk_window_is_active (GTK_WINDOW (parent)))
1848 banner_parent = parent;
1849 /* If the window is not the topmost but it's visible
1850 (it's minimized for example) then show the banner
1852 else if (GTK_WIDGET_VISIBLE (parent))
1853 banner_parent = NULL;
1854 /* If the window is hidden (like the main window when
1855 running in the background) then do not show
1861 modest_platform_system_banner (banner_parent, icon_name, text);
1865 modest_platform_system_banner (GtkWidget *parent,
1866 const gchar *icon_name,
1869 GtkWidget *banner = NULL;
1870 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1872 if (parent && GTK_IS_WINDOW (parent)) {
1873 if (!gtk_window_is_active (GTK_WINDOW (parent)))
1877 banner = hildon_banner_show_information (parent, icon_name, text);
1879 modest_window_mgr_register_banner (mgr);
1881 g_object_weak_ref ((GObject *) banner, banner_finish, mgr);
1885 modest_platform_information_banner_with_timeout (GtkWidget *parent,
1886 const gchar *icon_name,
1892 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1895 banner = hildon_banner_show_information (parent, icon_name, text);
1896 hildon_banner_set_timeout(HILDON_BANNER(banner), timeout);
1900 modest_platform_animation_banner (GtkWidget *parent,
1901 const gchar *animation_name,
1904 GtkWidget *inf_note = NULL;
1906 g_return_val_if_fail (text != NULL, NULL);
1908 if (modest_window_mgr_get_num_windows (modest_runtime_get_window_mgr ()) == 0)
1911 /* If the parent is not visible then do not show */
1912 if (parent && !GTK_WIDGET_VISIBLE (parent))
1915 inf_note = hildon_banner_show_animation (parent, animation_name, text);
1923 TnyAccount *account;
1926 } CheckAccountIdleData;
1928 #define NUMBER_OF_TRIES 10 /* Try approx every second, ten times. */
1931 on_timeout_check_account_is_online(CheckAccountIdleData* data)
1933 gboolean stop_trying = FALSE;
1934 g_return_val_if_fail (data && data->account, FALSE);
1936 if (data && data->account &&
1937 /* We want to wait until TNY_CONNECTION_STATUS_INIT has changed to something else,
1938 * after which the account is likely to be usable, or never likely to be usable soon: */
1939 (tny_account_get_connection_status (data->account) != TNY_CONNECTION_STATUS_INIT) )
1941 data->is_online = TRUE;
1945 /* Give up if we have tried too many times: */
1946 if (data->count_tries >= NUMBER_OF_TRIES) {
1949 /* Wait for another timeout: */
1950 ++(data->count_tries);
1955 /* Allow the function that requested this idle callback to continue: */
1957 g_main_loop_quit (data->loop);
1960 g_object_unref (data->account);
1962 return FALSE; /* Don't call this again. */
1964 return TRUE; /* Call this timeout callback again. */
1968 /* Return TRUE immediately if the account is already online,
1969 * otherwise check every second for NUMBER_OF_TRIES seconds and return TRUE as
1970 * soon as the account is online, or FALSE if the account does
1971 * not become online in the NUMBER_OF_TRIES seconds.
1972 * This is useful when the D-Bus method was run immediately after
1973 * the application was started (when using D-Bus activation),
1974 * because the account usually takes a short time to go online.
1975 * The return value is maybe not very useful.
1978 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
1982 g_return_val_if_fail (account, FALSE);
1984 if (!tny_device_is_online (modest_runtime_get_device())) {
1985 printf ("DEBUG: %s: device is offline.\n", __FUNCTION__);
1989 /* The local_folders account never seems to leave TNY_CONNECTION_STATUS_INIT,
1990 * so we avoid wait unnecessarily: */
1991 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1994 /* The POP & IMAP store accounts seem to be TNY_CONNECTION_STATUS_DISCONNECTED,
1995 * and that seems to be an OK time to use them. Maybe it's just TNY_CONNECTION_STATUS_INIT that
1996 * we want to avoid. */
1997 if (tny_account_get_connection_status (account) != TNY_CONNECTION_STATUS_INIT)
2000 /* This blocks on the result: */
2001 CheckAccountIdleData *data = g_slice_new0 (CheckAccountIdleData);
2002 data->is_online = FALSE;
2003 data->account = account;
2004 g_object_ref (data->account);
2005 data->count_tries = 0;
2007 GMainContext *context = NULL; /* g_main_context_new (); */
2008 data->loop = g_main_loop_new (context, FALSE /* not running */);
2010 g_timeout_add (1000, (GSourceFunc)(on_timeout_check_account_is_online), data);
2012 /* This main loop will run until the idle handler has stopped it: */
2013 g_main_loop_run (data->loop);
2015 g_main_loop_unref (data->loop);
2016 /* g_main_context_unref (context); */
2018 is_online = data->is_online;
2019 g_slice_free (CheckAccountIdleData, data);
2027 on_cert_dialog_response (GtkDialog *dialog, gint response_id, const gchar* cert)
2029 /* GTK_RESPONSE_HELP means we need to show the certificate */
2030 if (response_id == GTK_RESPONSE_APPLY) {
2034 /* Do not close the dialog */
2035 g_signal_stop_emission_by_name (dialog, "response");
2037 msg = g_strdup_printf (_("mcen_ni_view_unknown_certificate"), cert);
2038 note = hildon_note_new_information (NULL, msg);
2039 gtk_dialog_run (GTK_DIALOG(note));
2040 gtk_widget_destroy (note);
2046 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
2047 const gchar *certificate)
2052 HildonWindowStack *stack;
2054 stack = hildon_window_stack_get_default ();
2055 win = MODEST_WINDOW (hildon_window_stack_peek (stack));
2058 g_debug ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
2063 gchar *question = g_strdup_printf (_("mcen_nc_unknown_certificate"),
2066 /* We use GTK_RESPONSE_APPLY because we want the button in the
2067 middle of OK and CANCEL the same as the browser does for
2068 example. With GTK_RESPONSE_HELP the view button is aligned
2069 to the left while the other two to the right */
2070 note = hildon_note_new_confirmation_add_buttons (
2073 _HL("wdgt_bd_yes"), GTK_RESPONSE_OK,
2074 _HL("wdgt_bd_view"), GTK_RESPONSE_APPLY, /* abusing this... */
2075 _HL("wdgt_bd_no"), GTK_RESPONSE_CANCEL,
2078 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2079 (GtkWindow *) note, (GtkWindow *) win);
2081 g_signal_connect (G_OBJECT(note), "response",
2082 G_CALLBACK(on_cert_dialog_response),
2083 (gpointer) certificate);
2085 response = gtk_dialog_run(GTK_DIALOG(note));
2087 on_destroy_dialog (note);
2090 return response == GTK_RESPONSE_OK;
2094 modest_platform_run_alert_dialog (const gchar* prompt,
2095 gboolean is_question)
2097 ModestWindow *top_win;
2098 HildonWindowStack *stack;
2100 stack = hildon_window_stack_get_default ();
2101 top_win = MODEST_WINDOW (hildon_window_stack_peek (stack));
2104 g_debug ("%s: don't show dialogs if there's no window shown; assuming 'Cancel'",
2109 gboolean retval = TRUE;
2111 /* The Tinymail documentation says that we should show Yes and No buttons,
2112 * when it is a question.
2113 * Obviously, we need tinymail to use more specific error codes instead,
2114 * so we know what buttons to show. */
2115 GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (top_win),
2117 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2118 GTK_WINDOW (dialog), GTK_WINDOW (top_win));
2120 const int response = gtk_dialog_run (GTK_DIALOG (dialog));
2121 retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
2123 on_destroy_dialog (dialog);
2125 /* Just show the error text and use the default response: */
2126 modest_platform_run_information_dialog (GTK_WINDOW (top_win),
2134 GtkWindow *parent_window;
2135 ModestConnectedPerformer callback;
2136 TnyAccount *account;
2143 on_went_online_info_free (OnWentOnlineInfo *info)
2145 /* And if we cleanup, we DO cleanup :-) */
2148 g_object_unref (info->device);
2151 if (info->parent_window)
2152 g_object_unref (info->parent_window);
2154 g_object_unref (info->account);
2156 g_slice_free (OnWentOnlineInfo, info);
2158 /* We're done ... */
2164 on_account_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data)
2166 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2168 /* Now it's really time to callback to the caller. If going online didn't succeed,
2169 * err will be set. We don't free it, Tinymail does that! If a cancel happened,
2170 * canceled will be set. Etcetera etcetera. */
2172 if (info->callback) {
2173 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2176 /* This is our last call, we must cleanup here if we didn't yet do that */
2177 on_went_online_info_free (info);
2184 on_conic_device_went_online (TnyMaemoConicDevice *device, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data)
2186 OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data;
2187 info->iap = g_strdup (iap_id);
2189 if (canceled || err || !info->account) {
2191 /* If there's a problem or if there's no account (then that's it for us, we callback
2192 * the caller's callback now. He'll have to handle err or canceled, of course.
2193 * We are not really online, as the account is not really online here ... */
2195 /* We'll use the err and the canceled of this cb. TnyMaemoConicDevice delivered us
2196 * this info. We don't cleanup err, Tinymail does that! */
2198 if (info->callback) {
2200 /* info->account can be NULL here, this means that the user did not
2201 * provide a nice account instance. We'll assume that the user knows
2202 * what he's doing and is happy with just the device going online.
2204 * We can't do magic, we don't know what account the user wants to
2205 * see going online. So just the device goes online, end of story */
2207 info->callback (canceled, err, info->parent_window, info->account, info->user_data);
2210 } else if (info->account) {
2212 /* If there's no problem and if we have an account, we'll put the account
2213 * online too. When done, the callback of bringing the account online
2214 * will callback the caller's callback. This is the most normal case. */
2216 info->device = TNY_DEVICE (g_object_ref (device));
2218 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->account), TRUE,
2219 on_account_went_online, info);
2221 /* The on_account_went_online cb frees up the info, go look if you
2222 * don't believe me! (so we return here) */
2227 /* We cleanup if we are not bringing the account online too */
2228 on_went_online_info_free (info);
2234 modest_platform_connect_and_perform (GtkWindow *parent_window,
2236 TnyAccount *account,
2237 ModestConnectedPerformer callback,
2240 gboolean device_online;
2242 TnyConnectionStatus conn_status;
2243 OnWentOnlineInfo *info;
2245 device = modest_runtime_get_device();
2246 device_online = tny_device_is_online (device);
2248 /* If there is no account check only the device status */
2251 if (device_online) {
2253 /* We promise to instantly perform the callback, so ... */
2255 callback (FALSE, NULL, parent_window, account, user_data);
2260 info = g_slice_new0 (OnWentOnlineInfo);
2263 info->device = NULL;
2264 info->account = NULL;
2267 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2269 info->parent_window = NULL;
2270 info->user_data = user_data;
2271 info->callback = callback;
2273 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2274 force, on_conic_device_went_online,
2277 /* We'll cleanup in on_conic_device_went_online */
2280 /* The other code has no more reason to run. This is all that we can do for the
2281 * caller (he should have given us a nice and clean account instance!). We
2282 * can't do magic, we don't know what account he intends to bring online. So
2283 * we'll just bring the device online (and await his false bug report). */
2289 /* Return if the account is already connected */
2291 conn_status = tny_account_get_connection_status (account);
2292 if (device_online && conn_status == TNY_CONNECTION_STATUS_CONNECTED) {
2294 /* We promise to instantly perform the callback, so ... */
2296 callback (FALSE, NULL, parent_window, account, user_data);
2302 /* Else, we are in a state that requires that we go online before we
2303 * call the caller's callback. */
2305 info = g_slice_new0 (OnWentOnlineInfo);
2307 info->device = NULL;
2309 info->account = TNY_ACCOUNT (g_object_ref (account));
2312 info->parent_window = (GtkWindow *) g_object_ref (parent_window);
2314 info->parent_window = NULL;
2316 /* So we'll put the callback away for later ... */
2318 info->user_data = user_data;
2319 info->callback = callback;
2321 if (!device_online) {
2323 /* If also the device is offline, then we connect both the device
2324 * and the account */
2326 tny_maemo_conic_device_connect_async (TNY_MAEMO_CONIC_DEVICE (device), NULL,
2327 force, on_conic_device_went_online,
2332 /* If the device is online, we'll just connect the account */
2334 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE,
2335 on_account_went_online, info);
2338 /* The info gets freed by on_account_went_online or on_conic_device_went_online
2339 * in both situations, go look if you don't believe me! */
2345 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window,
2347 TnyFolderStore *folder_store,
2348 ModestConnectedPerformer callback,
2351 TnyAccount *account = NULL;
2353 if (!folder_store ||
2354 (TNY_IS_MERGE_FOLDER (folder_store) &&
2355 (tny_folder_get_folder_type (TNY_FOLDER(folder_store)) == TNY_FOLDER_TYPE_OUTBOX))) {
2357 /* We promise to instantly perform the callback, so ... */
2359 GError *error = NULL;
2360 g_set_error (&error, TNY_ERROR_DOMAIN, TNY_SERVICE_ERROR_UNKNOWN,
2361 "Unable to move or not found folder");
2362 callback (FALSE, error, parent_window, NULL, user_data);
2363 g_error_free (error);
2367 } else if (TNY_IS_FOLDER (folder_store)) {
2368 /* Get the folder's parent account: */
2369 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2370 } else if (TNY_IS_ACCOUNT (folder_store)) {
2371 /* Use the folder store as an account: */
2372 account = TNY_ACCOUNT (g_object_ref (folder_store));
2375 if (account && (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE)) {
2376 if (!modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
2377 /* No need to connect a local account */
2379 callback (FALSE, NULL, parent_window, account, user_data);
2384 modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
2388 g_object_unref (account);
2392 src_account_connect_performer (gboolean canceled,
2394 GtkWindow *parent_window,
2395 TnyAccount *src_account,
2398 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
2400 if (canceled || err) {
2401 /* If there was any error call the user callback */
2402 info->callback (canceled, err, parent_window, src_account, info->data);
2404 /* Connect the destination account */
2405 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
2406 TNY_FOLDER_STORE (info->dst_account),
2407 info->callback, info->data);
2410 /* Free the info object */
2411 g_object_unref (info->dst_account);
2412 g_slice_free (DoubleConnectionInfo, info);
2417 modest_platform_double_connect_and_perform (GtkWindow *parent_window,
2419 TnyFolderStore *folder_store,
2420 DoubleConnectionInfo *connect_info)
2422 modest_platform_connect_if_remote_and_perform(parent_window,
2425 src_account_connect_performer,
2430 modest_platform_get_account_settings_wizard (void)
2432 ModestEasysetupWizardDialog *dialog = modest_easysetup_wizard_dialog_new ();
2434 return GTK_WIDGET (dialog);
2438 modest_platform_get_current_connection (void)
2440 TnyDevice *device = NULL;
2441 ModestConnectedVia retval = MODEST_CONNECTED_VIA_ANY;
2443 device = modest_runtime_get_device ();
2445 if (!tny_device_is_online (device))
2446 return MODEST_CONNECTED_VIA_ANY;
2448 #ifdef MODEST_HAVE_CONIC
2450 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
2452 ConIcIap *iap = tny_maemo_conic_device_get_iap (
2453 TNY_MAEMO_CONIC_DEVICE (device), iap_id);
2454 const gchar *bearer_type = con_ic_iap_get_bearer_type (iap);
2456 if (!strcmp (bearer_type, CON_IC_BEARER_WLAN_INFRA) ||
2457 !strcmp (bearer_type, CON_IC_BEARER_WLAN_ADHOC) ||
2458 !strcmp (bearer_type, "WIMAX")) {
2459 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX;
2461 retval = MODEST_CONNECTED_VIA_ANY;
2464 g_object_unref (iap);
2467 retval = MODEST_CONNECTED_VIA_WLAN_OR_WIMAX; /* assume WLAN (fast) internet */
2468 #endif /* MODEST_HAVE_CONIC */
2475 modest_platform_check_memory_low (ModestWindow *win,
2480 /* are we in low memory state? */
2481 lowmem = osso_mem_in_lowmem_state () ? TRUE : FALSE;
2483 if (win && lowmem && visuals)
2484 modest_platform_run_information_dialog (
2486 _KR("memr_ib_operation_disabled"),
2490 g_debug ("%s: low memory reached. disallowing some operations",
2497 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
2503 dialog = modest_hildon2_details_dialog_new_with_folder (parent_window, folder);
2506 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2507 GTK_WINDOW (dialog),
2509 gtk_widget_show_all (dialog);
2511 g_signal_connect_swapped (dialog, "response",
2512 G_CALLBACK (gtk_widget_destroy),
2516 typedef struct _HeaderDetailsGetSizeInfo {
2520 } HeaderDetailsGetSizeInfo;
2523 header_details_dialog_destroy (gpointer userdata,
2526 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) userdata;
2528 info->dialog = NULL;
2532 idle_get_mime_part_size_cb (gpointer userdata)
2534 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) userdata;
2535 gdk_threads_enter ();
2537 if (info->dialog && GTK_WIDGET_VISIBLE (info->dialog)) {
2538 modest_details_dialog_set_message_size (MODEST_DETAILS_DIALOG (info->dialog),
2543 g_object_weak_unref (G_OBJECT (info->dialog), header_details_dialog_destroy, info);
2544 info->dialog = NULL;
2546 g_object_unref (info->part);
2547 g_slice_free (HeaderDetailsGetSizeInfo, info);
2549 gdk_threads_leave ();
2555 get_mime_part_size_thread (gpointer thr_user_data)
2557 HeaderDetailsGetSizeInfo *info = (HeaderDetailsGetSizeInfo *) thr_user_data;
2559 TnyStream *count_stream;
2561 count_stream = modest_count_stream_new ();
2562 result = tny_mime_part_decode_to_stream (info->part, count_stream, NULL);
2563 info->total = modest_count_stream_get_count(MODEST_COUNT_STREAM (count_stream));
2564 if (info->total == 0) {
2565 modest_count_stream_reset_count(MODEST_COUNT_STREAM (count_stream));
2566 result = tny_mime_part_write_to_stream (info->part, count_stream, NULL);
2567 info->total = modest_count_stream_get_count(MODEST_COUNT_STREAM (count_stream));
2570 /* if there was an error, don't set the size (this is pretty uncommon) */
2572 g_warning ("%s: error while writing mime part to stream\n", __FUNCTION__);
2574 g_idle_add (idle_get_mime_part_size_cb, info);
2580 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
2582 gboolean async_get_size,
2588 dialog = modest_hildon2_details_dialog_new_with_header (parent_window, header, !async_get_size);
2590 if (async_get_size && msg && TNY_IS_MSG (msg)) {
2591 HeaderDetailsGetSizeInfo *info;
2592 info = g_slice_new (HeaderDetailsGetSizeInfo);
2593 info->dialog = dialog;
2595 info->part = TNY_MIME_PART (g_object_ref (msg));
2597 g_object_weak_ref (G_OBJECT (dialog), header_details_dialog_destroy, info);
2598 g_thread_create (get_mime_part_size_thread, info, FALSE, NULL);
2602 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2603 GTK_WINDOW (dialog),
2605 gtk_widget_show_all (dialog);
2607 g_signal_connect_swapped (dialog, "response",
2608 G_CALLBACK (gtk_widget_destroy),
2613 modest_platform_get_osso_context (void)
2615 return modest_maemo_utils_get_osso_context ();
2619 convert_volume_to_db (int linear_volume)
2621 gfloat linear_converted = linear_volume / 100.0;
2622 gfloat db_vol = 0.0;
2624 db_vol = 20 * log10 (linear_converted);
2625 if (isinf (db_vol) != 0)
2632 modest_platform_play_email_tone (void)
2635 gint mail_volume_int;
2637 ca_proplist *pl = NULL;
2640 #ifdef MODEST_USE_PROFILE
2641 gchar *active_profile;
2644 active_profile = profile_get_profile ();
2645 mail_tone = profile_get_value (active_profile, PROFILE_MAIL_TONE);
2646 mail_volume = profile_get_value (active_profile, PROFILE_MAIL_VOLUME);
2647 mail_volume_int = profile_parse_int (mail_volume);
2648 g_free (mail_volume);
2649 g_free (active_profile);
2651 mail_tone = g_strdup (MAIL_TONE);
2652 mail_volume_int = 100;
2655 if (mail_tone && !strstr (mail_tone, "/")) {
2658 tmp = g_strconcat ("/usr/share/sounds", mail_tone, NULL);
2663 if (mail_volume_int > 0) {
2665 if (ca_con == NULL) {
2666 if ((ret = ca_context_create (&ca_con)) != CA_SUCCESS) {
2667 g_warning("ca_context_create: %s\n", ca_strerror(ret));
2671 if ((ret = ca_context_set_driver (ca_con, "gstreamer")) != CA_SUCCESS) {
2672 g_warning ("ca_context_set_driver: %s\n", ca_strerror (ret));
2678 if (!ca_con_opened) {
2679 if ((ret = ca_context_open(ca_con)) != CA_SUCCESS) {
2680 g_warning("ca_context_open: %s\n", ca_strerror(ret));
2683 ca_con_opened = TRUE;
2687 ca_proplist_create(&pl);
2688 ca_proplist_sets(pl, CA_PROP_MEDIA_FILENAME, mail_tone);
2689 db_volume = convert_volume_to_db (mail_volume_int);
2690 ca_proplist_setf(pl, CA_PROP_CANBERRA_VOLUME, "%f", db_volume);
2692 ret = ca_context_play_full(ca_con, 0, pl, NULL, NULL);
2693 g_debug("ca_context_play_full (vol %f): %s\n", (gfloat) mail_volume_int, ca_strerror(ret));
2695 ca_proplist_destroy(pl);
2701 #define MOVE_TO_DIALOG_FOLDER_VIEW "folder-view"
2702 #define MOVE_TO_DIALOG_BACK_BUTTON "back-button"
2703 #define MOVE_TO_DIALOG_ACTION_BUTTON "action-button"
2704 #define MOVE_TO_DIALOG_SHOWING_FOLDERS "showing-folders"
2705 #define MOVE_TO_DIALOG_PANNABLE "pannable"
2706 #define MOVE_TO_FOLDER_SEPARATOR "/"
2709 translate_path (gchar **path)
2714 gboolean add_separator;
2716 parts = g_strsplit (*path, MOVE_TO_FOLDER_SEPARATOR, 0);
2720 output = g_string_new ("");
2721 add_separator = FALSE;
2723 while (*current != NULL) {
2724 TnyFolderType folder_type;
2727 if (add_separator) {
2728 output = g_string_append (output, MOVE_TO_FOLDER_SEPARATOR);
2730 add_separator = TRUE;
2733 downcase = g_ascii_strdown (*current, -1);
2734 folder_type = modest_local_folder_info_get_type (downcase);
2735 if (strcmp (downcase, "inbox") == 0) {
2736 output = g_string_append (output, _("mcen_me_folder_inbox"));
2737 } else if (folder_type == TNY_FOLDER_TYPE_ARCHIVE ||
2738 folder_type == TNY_FOLDER_TYPE_DRAFTS ||
2739 folder_type == TNY_FOLDER_TYPE_SENT ||
2740 folder_type == TNY_FOLDER_TYPE_OUTBOX) {
2741 output = g_string_append (output, modest_local_folder_info_get_type_display_name (folder_type));
2743 output = g_string_append (output, *current);
2751 *path = g_string_free (output, FALSE);
2755 move_to_dialog_set_selected_folder_store (GtkWidget *dialog,
2756 TnyFolderStore *folder_store)
2758 GtkWidget *action_button;
2759 GtkWidget *image = NULL;
2760 TnyAccount *account;
2761 gchar *account_name = NULL, *short_name = NULL;
2763 action_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2765 /* Get account name */
2766 if (TNY_IS_FOLDER (folder_store))
2767 account = tny_folder_get_account (TNY_FOLDER (folder_store));
2769 account = g_object_ref (folder_store);
2771 if (modest_tny_account_is_virtual_local_folders (account))
2772 account_name = modest_conf_get_string (modest_runtime_get_conf(),
2773 MODEST_CONF_DEVICE_NAME, NULL);
2776 account_name = g_strdup (tny_account_get_name (account));
2778 g_object_unref (account);
2780 /* Set title of button: account or folder name */
2781 if (TNY_IS_FOLDER (folder_store))
2782 short_name = folder_store_get_display_name (folder_store);
2784 short_name = g_strdup (account_name);
2786 hildon_button_set_title (HILDON_BUTTON (action_button), short_name);
2788 /* Set value of button, folder full name */
2789 if (TNY_IS_CAMEL_FOLDER (folder_store)) {
2790 const gchar *camel_full_name;
2791 gchar *last_slash, *full_name;
2793 camel_full_name = tny_camel_folder_get_full_name (TNY_CAMEL_FOLDER (folder_store));
2794 last_slash = g_strrstr (camel_full_name, "/");
2796 gchar *prefix = g_strndup (camel_full_name, last_slash - camel_full_name + 1);
2797 full_name = g_strconcat (account_name, MOVE_TO_FOLDER_SEPARATOR, prefix, short_name, NULL);
2800 full_name = g_strconcat (account_name, MOVE_TO_FOLDER_SEPARATOR,
2804 translate_path (&full_name);
2805 hildon_button_set_value (HILDON_BUTTON (action_button), full_name);
2808 g_free (account_name);
2809 g_free (short_name);
2811 /* Set image for the button */
2812 image = get_image_for_folder_store (folder_store, MODEST_ICON_SIZE_BIG);
2814 hildon_button_set_image (HILDON_BUTTON (action_button), image);
2818 move_to_dialog_show_accounts (GtkWidget *dialog)
2820 GtkWidget *back_button;
2821 GtkWidget *folder_view;
2822 GtkWidget *pannable;
2823 GtkWidget *action_button;
2825 back_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON));
2826 action_button = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2827 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2828 pannable = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE));
2830 gtk_widget_set_sensitive (back_button, FALSE);
2831 gtk_widget_set_sensitive (action_button, FALSE);
2833 /* Need to set this here, otherwise callbacks called because
2834 of filtering won't perform correctly */
2835 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS, GINT_TO_POINTER (FALSE));
2837 /* Reset action button */
2838 hildon_button_set_title (HILDON_BUTTON (action_button), NULL);
2839 hildon_button_set_value (HILDON_BUTTON (action_button), NULL);
2840 hildon_button_set_image (HILDON_BUTTON (action_button), NULL);
2842 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (folder_view), NULL);
2843 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (folder_view), TRUE);
2844 modest_folder_view_set_style (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
2845 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2846 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2847 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2848 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2849 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view),
2850 MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS);
2851 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2852 MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS);
2853 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
2857 move_to_dialog_show_folders (GtkWidget *dialog, TnyFolderStore *folder_store)
2859 GtkWidget *back_button;
2860 GtkWidget *folder_view;
2861 TnyAccount *account;
2862 const gchar *account_id;
2863 GtkWidget *pannable;
2864 GtkWidget *action_button;
2867 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON));
2869 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON));
2871 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2873 GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE));
2875 gtk_widget_set_sensitive (back_button, TRUE);
2876 gtk_widget_set_sensitive (action_button, TRUE);
2878 /* Need to set this here, otherwise callbacks called because
2879 of filtering won't perform correctly */
2880 g_object_set_data (G_OBJECT (dialog),
2881 MOVE_TO_DIALOG_SHOWING_FOLDERS,
2882 GINT_TO_POINTER (TRUE));
2884 account = TNY_ACCOUNT (folder_store);
2885 if (modest_tny_account_is_virtual_local_folders (account)) {
2886 account_id = tny_account_get_id (account);
2887 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2888 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2889 } else if (modest_tny_account_is_memory_card_account (account)) {
2890 account_id = tny_account_get_id (account);
2891 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2892 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2894 account_id = tny_account_get_id (account);
2895 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2896 MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS);
2897 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view),
2898 MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS);
2901 move_to_dialog_set_selected_folder_store (dialog, folder_store);
2902 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (folder_view),
2905 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (folder_view), FALSE);
2906 modest_folder_view_set_style (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
2907 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS);
2908 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (folder_view), MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS);
2909 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (pannable), 0, 0);
2913 on_move_to_dialog_back_clicked (GtkButton *button,
2916 GtkWidget *dialog = (GtkWidget *) userdata;
2918 /* Back to show accounts */
2919 move_to_dialog_show_accounts (dialog);
2923 on_move_to_dialog_row_activated (GtkTreeView *tree_view,
2925 GtkTreeViewColumn *column,
2928 TnyFolderStore *selected = NULL;
2930 GtkWidget *folder_view;
2931 gboolean showing_folders;
2933 dialog = (GtkWidget *) user_data;
2934 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog),
2935 MOVE_TO_DIALOG_SHOWING_FOLDERS));
2937 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
2938 MOVE_TO_DIALOG_FOLDER_VIEW));
2940 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2944 if (!showing_folders) {
2945 gboolean valid = TRUE;
2947 if (TNY_IS_ACCOUNT (selected) &&
2948 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (selected))) {
2949 ModestProtocolType protocol_type;
2951 protocol_type = modest_tny_account_get_protocol_type (TNY_ACCOUNT (selected));
2952 valid = !modest_protocol_registry_protocol_type_has_tag
2953 (modest_runtime_get_protocol_registry (),
2955 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
2958 move_to_dialog_show_folders (dialog, selected);
2960 move_to_dialog_set_selected_folder_store (dialog, selected);
2962 g_object_unref (selected);
2966 on_move_to_dialog_selection_changed (GtkTreeSelection *selection,
2969 gboolean showing_folders;
2972 dialog = (GtkWidget *) user_data;
2973 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS));
2974 if (showing_folders) {
2975 TnyFolderStore *selected;
2976 GtkWidget *folder_view;
2978 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
2979 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2982 move_to_dialog_set_selected_folder_store (dialog, selected);
2983 g_object_unref (selected);
2989 on_move_to_dialog_action_clicked (GtkButton *selection,
2993 gboolean showing_folders;
2995 dialog = (GtkWidget *) user_data;
2996 showing_folders = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_SHOWING_FOLDERS));
2997 if (showing_folders) {
2998 TnyFolderStore *selected;
2999 GtkWidget *folder_view;
3001 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW));
3002 selected = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3005 /* It's not possible to select root folders as
3006 targets unless they're the local account or
3007 the memory card account */
3008 if ((TNY_IS_FOLDER (selected) && !TNY_IS_MERGE_FOLDER (selected)) ||
3009 (TNY_IS_ACCOUNT (selected) &&
3010 (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (selected)) ||
3011 modest_tny_account_is_memory_card_account (TNY_ACCOUNT (selected)))))
3012 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
3013 g_object_unref (selected);
3019 move_to_dialog_activity_changed (ModestFolderView *folder_view, gboolean activity, GtkDialog *dialog)
3021 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (dialog), activity?1:0);
3025 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
3026 GtkWidget **folder_view)
3028 GtkWidget *dialog, *folder_view_container;
3030 GtkWidget *buttons_hbox;
3031 GtkWidget *back_button;
3032 GdkPixbuf *back_pixbuf;
3033 GtkWidget *top_vbox;
3034 GtkWidget *action_button;
3035 GtkTreeSelection *selection;
3037 /* Create dialog. We cannot use a touch selector because we
3038 need to use here the folder view widget directly */
3039 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3040 GTK_WINDOW (parent_window),
3041 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
3042 GTK_DIALOG_DESTROY_WITH_PARENT,
3043 _HL("wdgt_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
3046 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
3047 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_NONE);
3048 top_vbox = gtk_vbox_new (FALSE, MODEST_MARGIN_HALF);
3050 /* Create folder view */
3051 *folder_view = modest_platform_create_folder_view_full (NULL, FALSE);
3052 g_signal_connect (G_OBJECT (*folder_view), "activity-changed", G_CALLBACK (move_to_dialog_activity_changed),
3055 modest_folder_view_set_cell_style (MODEST_FOLDER_VIEW (*folder_view),
3056 MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT);
3057 modest_folder_view_show_message_count (MODEST_FOLDER_VIEW (*folder_view),
3059 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (*folder_view),
3060 (TnyAccountStore *) modest_runtime_get_account_store ());
3062 buttons_hbox = gtk_hbox_new (FALSE, MODEST_MARGIN_HALF);
3063 back_button = gtk_button_new ();
3064 back_pixbuf = modest_platform_get_icon (_FM("filemanager_folder_up"), MODEST_ICON_SIZE_BIG);
3066 gtk_button_set_image (GTK_BUTTON (back_button), gtk_image_new_from_pixbuf (back_pixbuf));
3067 g_object_unref (back_pixbuf);
3070 action_button = hildon_button_new (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
3071 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
3072 gtk_button_set_alignment (GTK_BUTTON (action_button), 0.0, 0.5);
3074 gtk_box_pack_start (GTK_BOX (buttons_hbox), back_button, FALSE, FALSE, 0);
3075 gtk_box_pack_start (GTK_BOX (buttons_hbox), action_button, TRUE, TRUE, 0);
3076 gtk_widget_set_sensitive (GTK_WIDGET (back_button), FALSE);
3077 gtk_widget_set_sensitive (GTK_WIDGET (action_button), FALSE);
3078 gtk_box_pack_start (GTK_BOX (top_vbox), buttons_hbox, FALSE, FALSE, 0);
3080 /* Create pannable and add it to the dialog */
3081 folder_view_container = hildon_pannable_area_new ();
3082 gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
3083 gtk_box_pack_start (GTK_BOX (top_vbox), folder_view_container, TRUE, TRUE, 0);
3085 gtk_container_add (GTK_CONTAINER (align), top_vbox);
3086 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 0);
3088 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3090 gtk_widget_show (GTK_DIALOG (dialog)->vbox);
3091 gtk_widget_show (folder_view_container);
3092 gtk_widget_show (align);
3093 gtk_widget_show (top_vbox);
3094 gtk_widget_show (*folder_view);
3095 gtk_widget_show_all (back_button);
3096 gtk_widget_show (action_button);
3097 gtk_widget_show (buttons_hbox);
3098 gtk_widget_show (dialog);
3100 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_FOLDER_VIEW, *folder_view);
3101 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_BACK_BUTTON, back_button);
3102 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_ACTION_BUTTON, action_button);
3103 g_object_set_data (G_OBJECT (dialog), MOVE_TO_DIALOG_PANNABLE, folder_view_container);
3105 /* Simulate the behaviour of a HildonPickerDialog by emitting
3106 a response when a folder is selected */
3107 g_signal_connect (*folder_view, "row-activated",
3108 G_CALLBACK (on_move_to_dialog_row_activated),
3111 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*folder_view));
3112 g_signal_connect (selection, "changed",
3113 G_CALLBACK (on_move_to_dialog_selection_changed),
3116 g_signal_connect (action_button, "clicked",
3117 G_CALLBACK (on_move_to_dialog_action_clicked),
3120 g_signal_connect (back_button, "clicked",
3121 G_CALLBACK (on_move_to_dialog_back_clicked),
3124 move_to_dialog_show_accounts (dialog);
3130 modest_platform_get_list_to_move (ModestWindow *window)
3132 TnyList *list = NULL;
3134 if (MODEST_IS_HEADER_WINDOW (window)) {
3135 ModestHeaderView *header_view;
3137 header_view = modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window));
3138 list = modest_header_view_get_selected_headers (header_view);
3139 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3140 ModestFolderView *folder_view;
3141 TnyFolderStore *selected_folder;
3143 list = TNY_LIST (tny_simple_list_new ());
3144 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window));
3145 selected_folder = modest_folder_view_get_selected (folder_view);
3146 if (selected_folder) {
3147 tny_list_prepend (list, G_OBJECT (selected_folder));
3148 g_object_unref (selected_folder);
3151 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3154 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
3156 list = TNY_LIST (tny_simple_list_new ());
3157 tny_list_prepend (list, G_OBJECT (header));
3158 g_object_unref (header);
3161 g_return_val_if_reached (NULL);