Emit dbus signal on changing SEEN flag.
[modest] / src / gnome / modest-platform.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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.
16  *
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.
28  */
29
30 #include <libgnomevfs/gnome-vfs-mime.h>
31 #include <libgnomeui/gnome-icon-lookup.h>
32 #include <tny-gnome-device.h>
33 #include <tny-camel-imap-store-account.h>
34 #include <tny-camel-pop-store-account.h>
35 #include <tny-simple-list.h>
36 #include <tny-error.h>
37 #include <tny-merge-folder.h>
38 #include "modest-platform.h"
39 #include "modest-mail-operation-queue.h"
40 #include "modest-runtime.h"
41 #include "gnome/modest-gnome-global-settings-dialog.h"
42 #include "widgets/modest-default-account-settings-dialog.h"
43 #include "gnome/modest-account-assistant.h"
44 #include "gnome/modest-gnome-sort-dialog.h"
45 #include "widgets/modest-details-dialog.h"
46 #include "widgets/modest-main-window.h"
47
48 gboolean
49 modest_platform_init (int argc, char *argv[])
50 {       
51         return TRUE; /* nothing to do */
52 }
53
54
55 gboolean modest_platform_uninit (void)
56 {
57         return TRUE; /*nothing to do */
58 }
59
60
61 TnyDevice*
62 modest_platform_get_new_device (void)
63 {
64         return TNY_DEVICE (tny_gnome_device_new ());
65 }
66
67
68 gchar*
69 modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type,
70                                           gchar **effective_mime_type)
71 {
72         GString *mime_str = NULL;
73         gchar *icon_name  = NULL;
74         gchar *uri;
75         const static gchar* octet_stream = "application/octet-stream";
76         
77         g_return_val_if_fail (name || mime_type, NULL);
78
79         if (!mime_type || g_ascii_strcasecmp (mime_type, octet_stream)) 
80                 mime_str = g_string_new(gnome_vfs_mime_type_from_name_or_default
81                                         (name, "application/octet-stream"));
82         else {
83                 mime_str = g_string_new (mime_type);
84                 g_string_ascii_down (mime_str);
85         }
86
87         uri = g_strconcat ("file:///", name ? name : "dummy", NULL);
88         icon_name  = gnome_icon_lookup (gtk_icon_theme_get_default(), NULL,
89                                         uri, NULL, NULL, mime_str->str, 0, 0);
90         g_free (uri);
91
92         if (effective_mime_type)
93                 *effective_mime_type = g_string_free (mime_str, FALSE);
94         else
95                 g_string_free (mime_str, TRUE);
96
97         return icon_name;
98 }
99
100 gboolean 
101 modest_platform_activate_uri (const gchar *uri)
102 {
103         g_warning ("NOT IMPLEMENTED");;
104         return FALSE;
105 }
106
107 gboolean 
108 modest_platform_activate_file (const gchar *path, const gchar *mime_type)
109 {
110         g_warning ("NOT IMPLEMENTED");;
111         return FALSE;
112 }
113
114 gboolean 
115 modest_platform_show_uri_popup (const gchar *uri)
116 {
117         g_warning ("NOT IMPLEMENTED");;
118         return FALSE;
119 }
120
121 GdkPixbuf*
122 modest_platform_get_icon (const gchar *name, guint icon_size)
123 {
124         GError *err = NULL;
125         GdkPixbuf* pixbuf;
126
127         g_return_val_if_fail (name, NULL);
128
129         pixbuf = gdk_pixbuf_new_from_file (name, &err);
130
131         if (!pixbuf) {
132 /*              g_printerr ("modest: error while loading icon '%s': %s\n", */
133 /*                          name, err->message); */
134                 g_error_free (err);
135                 err = NULL;
136
137                 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), name, icon_size, 0, &err);
138                 if (!pixbuf) {
139                         g_error_free (err);
140                 }
141         }
142         
143         return pixbuf;
144 }
145
146
147 const gchar*
148 modest_platform_get_app_name (void)
149 {
150         return ("Modest");
151 }
152
153 gint 
154 modest_platform_run_new_folder_dialog (GtkWindow *parent_window,
155                                        TnyFolderStore *suggested_parent,
156                                        gchar *suggested_name,
157                                        gchar **folder_name,
158                                        TnyFolderStore **parent_folder)
159 {
160         GtkWidget *dialog, *entry;
161         gint result;
162
163         /* Ask the user for the folder name */
164         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
165                                               parent_window,
166                                               GTK_DIALOG_MODAL,
167                                               GTK_STOCK_CANCEL,
168                                               GTK_RESPONSE_REJECT,
169                                               GTK_STOCK_OK,
170                                               GTK_RESPONSE_ACCEPT,
171                                               NULL);
172         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
173                             gtk_label_new (_("Please enter a name for the new folder")),
174                             FALSE, FALSE, 0);
175                 
176         entry = gtk_entry_new_with_max_length (40);
177         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
178                             entry,
179                             TRUE, FALSE, 0);
180         
181         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
182
183         result = gtk_dialog_run (GTK_DIALOG(dialog));
184         if (result == GTK_RESPONSE_ACCEPT)
185                 *folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
186
187         gtk_widget_destroy (dialog);
188
189         if (parent_folder != NULL) {
190                 parent_folder = suggested_parent?g_object_ref (suggested_parent): NULL;
191         }
192
193         return result;
194 }
195
196
197 gint
198 modest_platform_run_confirmation_dialog (GtkWindow *parent_window,
199                                          const gchar *msg)
200 {
201         gint response;
202         GtkWidget *dialog;
203
204         dialog = gtk_message_dialog_new (parent_window,
205                                          GTK_DIALOG_MODAL,
206                                          GTK_MESSAGE_QUESTION,
207                                          GTK_BUTTONS_OK_CANCEL,
208                                          msg);
209
210         response = gtk_dialog_run (GTK_DIALOG(dialog));
211         gtk_widget_destroy (dialog);
212         
213         return response;
214 }
215
216 gint
217 modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window,
218                                                       const gchar *message,
219                                                       const gchar *button_accept,
220                                                       const gchar *button_cancel)
221 {
222         gint response;
223         GtkWidget *dialog;
224
225         dialog = gtk_dialog_new_with_buttons (message,
226                                               parent_window,
227                                               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
228                                               button_accept,
229                                               GTK_RESPONSE_ACCEPT,
230                                               button_cancel,
231                                               GTK_RESPONSE_CANCEL,
232                                               NULL);
233
234         response = gtk_dialog_run (GTK_DIALOG(dialog));
235         gtk_widget_destroy (dialog);
236         
237         return response;
238 }
239
240 void
241 modest_platform_run_information_dialog (GtkWindow *parent_window,
242                                         const gchar *message,
243                                         gboolean block)
244 {
245         GtkWidget *dialog;
246
247         dialog = gtk_message_dialog_new (parent_window,
248                                          GTK_DIALOG_MODAL,
249                                          GTK_MESSAGE_INFO,
250                                          GTK_BUTTONS_OK,
251                                          message);
252
253         gtk_dialog_run (GTK_DIALOG (dialog));
254         gtk_widget_destroy (dialog);
255         
256 }
257
258 gboolean modest_platform_connect_and_wait (GtkWindow *parent_window, TnyAccount *account)
259 {
260         /* TODO: Do something with network-manager? 
261            Otherwise, maybe it is safe to assume that we would already be online if we could be. */
262         return TRUE;
263 }
264
265 gboolean modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account)
266 {
267         /* TODO: Do something with network-manager? 
268            Otherwise, maybe it is safe to assume that we would already be online if we could be. */
269         return TRUE;
270 }
271
272
273 void
274 modest_platform_connect_if_remote_and_perform (GtkWindow *parent_window, 
275                                                gboolean force,
276                                                TnyFolderStore *folder_store, 
277                                                ModestConnectedPerformer callback, 
278                                                gpointer user_data)
279 {
280         TnyAccount *account = NULL;
281
282         if (!folder_store ||
283             (TNY_IS_MERGE_FOLDER (folder_store) &&
284              (tny_folder_get_folder_type (TNY_FOLDER(folder_store)) == TNY_FOLDER_TYPE_OUTBOX))) {
285
286                 /* We promise to instantly perform the callback, so ... */
287                 if (callback) {
288                         GError *error = NULL;
289                         g_set_error (&error, TNY_ERROR_DOMAIN, TNY_SERVICE_ERROR_UNKNOWN,
290                                      "Unable to move or not found folder");
291                         callback (FALSE, error, parent_window, NULL, user_data);
292                         g_error_free (error);
293                 }
294                 return;
295
296         } else if (TNY_IS_FOLDER (folder_store)) {
297                 /* Get the folder's parent account: */
298                 account = tny_folder_get_account(TNY_FOLDER (folder_store));
299         } else if (TNY_IS_ACCOUNT (folder_store)) {
300                 /* Use the folder store as an account: */
301                 account = TNY_ACCOUNT (folder_store);
302         }
303  
304         if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) {
305                 if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) &&
306                     !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) {
307
308                         /* This IS a local account like a maildir account, which does not require 
309                          * a connection. (original comment had a vague assumption in its language
310                          * usage. There's no assuming needed, this IS what it IS: a local account), */
311  
312                         /* We promise to instantly perform the callback, so ... */
313                         if (callback) {
314                                 callback (FALSE, NULL, parent_window, account, user_data);
315                         }
316                         
317                         return;
318                 }
319         }
320  
321         modest_platform_connect_and_perform (parent_window, force, account, callback, user_data);
322  
323         return;
324 }
325
326
327 gboolean modest_platform_set_update_interval (guint minutes)
328 {
329         /* TODO. */
330         return FALSE;
331 }
332
333 GtkWidget *
334 modest_platform_create_sort_dialog (GtkWindow *parent_window)
335 {
336         return modest_gnome_sort_dialog_new (parent_window);
337 }
338
339 GtkWidget *
340 modest_platform_get_global_settings_dialog ()
341 {
342         return modest_gnome_global_settings_dialog_new ();
343 }
344
345 void
346 modest_platform_push_email_notification(void)
347 {
348         /* TODO: implement this */
349         g_print ("--------------- NEW MESSAGE ARRIVED ---------------\n");
350 }
351
352 void 
353 modest_platform_on_new_headers_received (GList *URI_list,
354                                          gboolean show_visual)
355 {
356         /* TODO: implement this */
357         g_print ("--------------- NEW MESSAGE ARRIVED ---------------\n");
358 }
359
360
361
362 void
363 modest_platform_show_help (GtkWindow *parent_window, const gchar *help_id)
364 {
365         return; /* TODO */
366 }
367
368 void 
369 modest_platform_information_banner (GtkWidget *widget,
370                                     const gchar *icon_name,
371                                     const gchar *text)
372 {
373         g_warning ("NOT IMPLEMENTED");;
374 }
375
376 void 
377 modest_platform_system_banner (GtkWidget *widget,
378                                const gchar *icon_name,
379                                const gchar *text)
380 {
381         g_warning ("NOT IMPLEMENTED");;
382 }
383
384 void
385 modest_platform_information_banner_with_timeout (GtkWidget *widget,
386                                                  const gchar *icon_name,
387                                                  const gchar *text,
388                                                  gint timeout)
389 {
390         g_warning ("NOT IMPLEMENTED");;
391 }
392
393 GtkWidget *
394 modest_platform_animation_banner (GtkWidget *widget,
395                                   const gchar *icon_name,
396                                   const gchar *text)
397 {
398         g_warning ("NOT IMPLEMENTED");
399         return NULL;
400 }
401
402
403 void
404 modest_platform_show_search_messages (GtkWindow *parent_window)
405 {
406         g_warning ("NOT IMPLEMENTED");;
407 }
408
409 GtkWidget *
410 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
411 {
412         GtkWidget *widget = modest_folder_view_new (query);
413
414         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE);
415         /* Show all accounts by default */
416         modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
417                                       MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
418
419         return widget;
420 }
421
422 gboolean
423 modest_platform_run_alert_dialog (const gchar* prompt, 
424                                   gboolean is_question)
425 {
426         /* TODO */
427         return TRUE;
428 }
429
430 void 
431 modest_platform_connect_and_perform (GtkWindow *parent_window, 
432                                      gboolean force,
433                                      TnyAccount *account, 
434                                      ModestConnectedPerformer callback, 
435                                      gpointer user_data)
436 {
437         if (callback)
438                 callback (FALSE, NULL, parent_window, account, user_data);
439 }
440
441 void 
442 modest_platform_double_connect_and_perform (GtkWindow *parent_window, 
443                                             gboolean force,
444                                             TnyFolderStore *folder_store,
445                                             DoubleConnectionInfo *connect_info)
446 {
447         if (connect_info->callback)
448                 connect_info->callback (FALSE, NULL, parent_window, TNY_ACCOUNT (folder_store), connect_info->data);
449 }
450
451 void 
452 modest_platform_connect_and_perform_if_network_account (GtkWindow *parent_window, 
453                                                         gboolean force,
454                                                         TnyAccount *account,
455                                                         ModestConnectedPerformer callback, 
456                                                         gpointer user_data)
457 {
458         if (callback)
459                 callback (FALSE, NULL, parent_window, account, user_data);
460 }
461
462 void
463 modest_platform_connect_and_perform_if_network_folderstore (GtkWindow *parent_window, 
464                                                             TnyFolderStore *folder_store, 
465                                                             ModestConnectedPerformer callback, 
466                                                             gpointer user_data)
467 {
468         if (callback)
469                 callback (FALSE, NULL, parent_window, NULL, user_data);
470 }
471
472
473 void 
474 modest_platform_remove_new_mail_notifications (gboolean only_visuals, const gchar *acc_name)
475 {
476         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
477 }
478
479 gboolean 
480 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
481 {
482         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
483         return TRUE;
484 }
485
486 gboolean 
487 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
488                                                      const gchar *certificate)
489 {
490         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
491         return TRUE;
492 }
493
494 gint
495 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
496                                           TnyFolderStore *parent_folder,
497                                           const gchar *suggested_name,
498                                           gchar **folder_name)
499 {
500         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
501         return GTK_RESPONSE_CANCEL;
502 }
503
504 void 
505 modest_platform_show_addressbook (GtkWindow *parent_window)
506 {
507         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
508 }
509
510 GtkWidget *
511 modest_platform_get_account_settings_dialog (ModestAccountSettings *settings)
512 {
513         ModestAccountSettingsDialog *dialog = modest_default_account_settings_dialog_new ();
514
515         modest_account_settings_dialog_load_settings (dialog, settings);
516         return GTK_WIDGET (dialog);
517 }
518
519 GtkWidget *
520 modest_platform_get_account_settings_wizard (void)
521 {
522         GtkWidget *widget = modest_account_assistant_new (modest_runtime_get_account_mgr ());
523         return widget;
524 }
525
526
527
528 gboolean modest_platform_check_memory_low (ModestWindow *win,
529                                            gboolean visuals)
530 {
531         g_debug ("%s not implemented", __FUNCTION__);
532         return FALSE;
533 }
534
535 void 
536 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
537                                            TnyFolder *folder)
538 {
539         GtkWidget *dialog;
540         
541         /* Create dialog */
542         dialog = modest_details_dialog_new_with_folder (parent_window, folder);
543
544         /* Run dialog */
545         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
546                                      GTK_WINDOW (dialog), 
547                                      parent_window);
548         gtk_widget_show_all (dialog);
549
550         g_signal_connect_swapped (dialog, "response", 
551                                   G_CALLBACK (gtk_widget_destroy),
552                                   dialog);
553 }
554
555 void
556 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
557                                            TnyHeader *header,
558                                            gboolean async_get_size, 
559                                            TnyMsg *msg)
560 {
561         GtkWidget *dialog;
562         
563         /* Create dialog */
564         dialog = modest_details_dialog_new_with_header (parent_window, header, TRUE);
565
566         /* Run dialog */
567         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
568                                      GTK_WINDOW (dialog),
569                                      parent_window);
570         gtk_widget_show_all (dialog);
571
572         g_signal_connect_swapped (dialog, "response", 
573                                   G_CALLBACK (gtk_widget_destroy),
574                                   dialog);
575 }
576
577 GtkWidget* 
578 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
579                                        GtkWidget **folder_view)
580 {
581         GtkWidget *dialog, *folder_view_container;
582
583         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
584                                               GTK_WINDOW (parent_window),
585                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
586                                               GTK_DIALOG_DESTROY_WITH_PARENT,
587                                               _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
588                                               _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
589                                               _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
590                                               NULL);
591
592         /* Create folder view */
593         *folder_view = modest_platform_create_folder_view (NULL);
594
595         /* Create pannable and add it to the dialog */
596         folder_view_container = gtk_scrolled_window_new (NULL, NULL);
597         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (folder_view_container),
598                                          GTK_POLICY_AUTOMATIC,
599                                          GTK_POLICY_AUTOMATIC);
600         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
601         gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
602
603         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
604
605         return dialog;
606 }
607
608 TnyList *
609 modest_platform_get_list_to_move (ModestWindow *window)
610 {
611         TnyList *list = NULL;
612
613         /* If it's a main window then it could be that we're moving a
614            folder or a set of messages */
615         if (MODEST_IS_MAIN_WINDOW (window)) {
616                 ModestHeaderView *header_view = NULL;
617                 ModestFolderView *folder_view = NULL;
618
619                 folder_view = (ModestFolderView *)
620                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
621                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
622                 header_view = (ModestHeaderView *)
623                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
624                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
625
626                 /* Get folder or messages to transfer */
627                 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
628                         TnyFolderStore *src_folder;
629
630                         src_folder = modest_folder_view_get_selected (folder_view);
631                         if (src_folder) {
632                                 list = tny_simple_list_new ();
633                                 tny_list_prepend (list, G_OBJECT (src_folder));
634                                 g_object_unref (src_folder);
635                         }
636                 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
637                         list = modest_header_view_get_selected_headers(header_view);
638                 }
639         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
640                 TnyHeader *header = NULL;
641
642                 /* We simply return the currently viewed message */
643                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
644                 if (header) {
645                         list = tny_simple_list_new ();
646                         tny_list_prepend (list, G_OBJECT (header));
647                         g_object_unref (header);
648                 }
649         } else {
650                 g_return_val_if_reached (NULL);
651         }
652
653         return list;
654 }
655
656 DBusConnection*
657 modest_platform_get_dbus_connection (void)
658 {
659         return NULL;
660 }
661
662 void
663 modest_platform_emit_folder_updated_signal (const gchar *account_id, const gchar *folder_id)
664 {
665         return;
666 }
667
668
669 void
670 modest_platform_emit_account_created_signal (const gchar *account_id)
671 {
672         return;
673 }
674
675 void
676 modest_platform_emit_account_removed_signal (const gchar *account_id)
677 {
678         return;
679 }
680
681 void
682 modest_platform_emit_msg_read_changed_signal (const gchar *msg_uid,
683                                               gboolean is_read)
684 {
685         return;
686 }