485b26bd30a4626a4438213494a270bb5fe05ccc
[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_information_banner_with_timeout (GtkWidget *widget,
378                                                  const gchar *icon_name,
379                                                  const gchar *text,
380                                                  gint timeout)
381 {
382         g_warning ("NOT IMPLEMENTED");;
383 }
384
385 GtkWidget *
386 modest_platform_animation_banner (GtkWidget *widget,
387                                   const gchar *icon_name,
388                                   const gchar *text)
389 {
390         g_warning ("NOT IMPLEMENTED");
391         return NULL;
392 }
393
394
395 void
396 modest_platform_show_search_messages (GtkWindow *parent_window)
397 {
398         g_warning ("NOT IMPLEMENTED");;
399 }
400
401 GtkWidget *
402 modest_platform_create_folder_view (TnyFolderStoreQuery *query)
403 {
404         GtkWidget *widget = modest_folder_view_new (query);
405
406         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE);
407         /* Show all accounts by default */
408         modest_folder_view_set_style (MODEST_FOLDER_VIEW (widget),
409                                       MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
410
411         return widget;
412 }
413
414 gboolean
415 modest_platform_run_alert_dialog (const gchar* prompt, 
416                                   gboolean is_question)
417 {
418         /* TODO */
419         return TRUE;
420 }
421
422 void 
423 modest_platform_connect_and_perform (GtkWindow *parent_window, 
424                                      gboolean force,
425                                      TnyAccount *account, 
426                                      ModestConnectedPerformer callback, 
427                                      gpointer user_data)
428 {
429         if (callback)
430                 callback (FALSE, NULL, parent_window, account, user_data);
431 }
432
433 void 
434 modest_platform_double_connect_and_perform (GtkWindow *parent_window, 
435                                             gboolean force,
436                                             TnyFolderStore *folder_store,
437                                             DoubleConnectionInfo *connect_info)
438 {
439         if (connect_info->callback)
440                 connect_info->callback (FALSE, NULL, parent_window, TNY_ACCOUNT (folder_store), connect_info->data);
441 }
442
443 void 
444 modest_platform_connect_and_perform_if_network_account (GtkWindow *parent_window, 
445                                                         gboolean force,
446                                                         TnyAccount *account,
447                                                         ModestConnectedPerformer callback, 
448                                                         gpointer user_data)
449 {
450         if (callback)
451                 callback (FALSE, NULL, parent_window, account, user_data);
452 }
453
454 void
455 modest_platform_connect_and_perform_if_network_folderstore (GtkWindow *parent_window, 
456                                                             TnyFolderStore *folder_store, 
457                                                             ModestConnectedPerformer callback, 
458                                                             gpointer user_data)
459 {
460         if (callback)
461                 callback (FALSE, NULL, parent_window, NULL, user_data);
462 }
463
464
465 void 
466 modest_platform_remove_new_mail_notifications (gboolean only_visuals)
467 {
468         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
469 }
470
471 gboolean 
472 modest_platform_check_and_wait_for_account_is_online(TnyAccount *account)
473 {
474         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
475         return TRUE;
476 }
477
478 gboolean 
479 modest_platform_run_certificate_confirmation_dialog (const gchar* server_name,
480                                                      const gchar *certificate)
481 {
482         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
483         return TRUE;
484 }
485
486 gint
487 modest_platform_run_rename_folder_dialog (GtkWindow *parent_window,
488                                           TnyFolderStore *parent_folder,
489                                           const gchar *suggested_name,
490                                           gchar **folder_name)
491 {
492         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
493         return GTK_RESPONSE_CANCEL;
494 }
495
496 void 
497 modest_platform_show_addressbook (GtkWindow *parent_window)
498 {
499         g_warning ("NOT IMPLEMENTED %s", __FUNCTION__);
500 }
501
502 GtkWidget *
503 modest_platform_get_account_settings_dialog (ModestAccountSettings *settings)
504 {
505         ModestAccountSettingsDialog *dialog = modest_default_account_settings_dialog_new ();
506
507         modest_account_settings_dialog_load_settings (dialog, settings);
508         return GTK_WIDGET (dialog);
509 }
510
511 GtkWidget *
512 modest_platform_get_account_settings_wizard (void)
513 {
514         GtkWidget *widget = modest_account_assistant_new (modest_runtime_get_account_mgr ());
515         return widget;
516 }
517
518
519
520 gboolean modest_platform_check_memory_low (ModestWindow *win,
521                                            gboolean visuals)
522 {
523         g_debug ("%s not implemented", __FUNCTION__);
524         return FALSE;
525 }
526
527 void 
528 modest_platform_run_folder_details_dialog (GtkWindow *parent_window,
529                                            TnyFolder *folder)
530 {
531         GtkWidget *dialog;
532         
533         /* Create dialog */
534         dialog = modest_details_dialog_new_with_folder (parent_window, folder);
535
536         /* Run dialog */
537         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
538                                      GTK_WINDOW (dialog), 
539                                      parent_window);
540         gtk_widget_show_all (dialog);
541
542         g_signal_connect_swapped (dialog, "response", 
543                                   G_CALLBACK (gtk_widget_destroy),
544                                   dialog);
545 }
546
547 void
548 modest_platform_run_header_details_dialog (GtkWindow *parent_window,
549                                            TnyHeader *header,
550                                            gboolean async_get_size, 
551                                            TnyMsg *msg)
552 {
553         GtkWidget *dialog;
554         
555         /* Create dialog */
556         dialog = modest_details_dialog_new_with_header (parent_window, header, TRUE);
557
558         /* Run dialog */
559         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
560                                      GTK_WINDOW (dialog),
561                                      parent_window);
562         gtk_widget_show_all (dialog);
563
564         g_signal_connect_swapped (dialog, "response", 
565                                   G_CALLBACK (gtk_widget_destroy),
566                                   dialog);
567 }
568
569 GtkWidget* 
570 modest_platform_create_move_to_dialog (GtkWindow *parent_window,
571                                        GtkWidget **folder_view)
572 {
573         GtkWidget *dialog, *folder_view_container;
574
575         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
576                                               GTK_WINDOW (parent_window),
577                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR |
578                                               GTK_DIALOG_DESTROY_WITH_PARENT,
579                                               _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK,
580                                               _("mcen_bd_new"), MODEST_GTK_RESPONSE_NEW_FOLDER,
581                                               _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL,
582                                               NULL);
583
584         /* Create folder view */
585         *folder_view = modest_platform_create_folder_view (NULL);
586
587         /* Create pannable and add it to the dialog */
588         folder_view_container = gtk_scrolled_window_new (NULL, NULL);
589         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (folder_view_container),
590                                          GTK_POLICY_AUTOMATIC,
591                                          GTK_POLICY_AUTOMATIC);
592         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), folder_view_container);
593         gtk_container_add (GTK_CONTAINER (folder_view_container), *folder_view);
594
595         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
596
597         return dialog;
598 }
599
600 TnyList *
601 modest_platform_get_list_to_move (ModestWindow *window)
602 {
603         TnyList *list = NULL;
604
605         /* If it's a main window then it could be that we're moving a
606            folder or a set of messages */
607         if (MODEST_IS_MAIN_WINDOW (window)) {
608                 ModestHeaderView *header_view = NULL;
609                 ModestFolderView *folder_view = NULL;
610
611                 folder_view = (ModestFolderView *)
612                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
613                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
614                 header_view = (ModestHeaderView *)
615                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
616                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
617
618                 /* Get folder or messages to transfer */
619                 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
620                         TnyFolderStore *src_folder;
621
622                         src_folder = modest_folder_view_get_selected (folder_view);
623                         if (src_folder) {
624                                 list = tny_simple_list_new ();
625                                 tny_list_prepend (list, G_OBJECT (src_folder));
626                                 g_object_unref (src_folder);
627                         }
628                 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
629                         list = modest_header_view_get_selected_headers(header_view);
630                 }
631         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
632                 TnyHeader *header = NULL;
633
634                 /* We simply return the currently viewed message */
635                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (window));
636                 if (header) {
637                         list = tny_simple_list_new ();
638                         tny_list_prepend (list, G_OBJECT (header));
639                         g_object_unref (header);
640                 }
641         } else {
642                 g_return_val_if_reached (NULL);
643         }
644
645         return list;
646 }