root/trunk/src/tmut-menu-view.c

Revision 76 (checked in by pvanhoof, 7 months ago)
        • Implemented simple account management
        • Implemented a new account store
Line 
1 /* TMut
2  * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with self library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #if HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <glib/gi18n-lib.h>
25
26 #include "tmut-account-store.h"
27 #include "tmut-menu-view.h"
28 #include "tmut-folder-view.h"
29 #include "tmut-msg-creator.h"
30 #include "tmut-folder-selector.h"
31 #include "tmut-shell-window.h"
32 #include "tmut-shell-child.h"
33 #include "tmut-account-manager.h"
34
35 #include <tny-gtk-folder-store-tree-model.h>
36 #include <tny-gtk-account-list-model.h>
37
38 static GObjectClass *parent_class = NULL;
39
40 typedef struct _TMutMenuViewPriv TMutMenuViewPriv;
41
42 struct _TMutMenuViewPriv
43 {
44         GtkTreeView *folders_treeview;
45         GtkComboBox *accounts_combo;
46         TMutShellWindow *shell;
47         TnyAccountStore *account_store;
48         TnyAccount *active_account;
49         gint account_created_signal, account_deleted_signal;
50 };
51
52 #define TMUT_MENU_VIEW_GET_PRIVATE(o) \
53         (G_TYPE_INSTANCE_GET_PRIVATE ((o), TMUT_TYPE_MENU_VIEW, TMutMenuViewPriv))
54
55 static void
56 status_update (GObject *sender, TnyStatus *status, gpointer user_data)
57 {
58         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (user_data);
59
60         if (priv->shell)
61                 gtk_progress_set_percentage (tmut_shell_window_get_progress (priv->shell),
62                                 tny_status_get_fraction (status));
63
64         return;
65 }
66
67
68 static void
69 on_copy_done (TnyFolder *folder, gboolean canceled, TnyFolderStore *into, TnyFolder *new_folder, GError *err, gpointer user_data)
70 {
71         TMutMenuView *self = TMUT_MENU_VIEW (user_data);
72         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
73         gchar *msg = "";
74
75         if (canceled)
76                 msg = _("User canceled the operation");
77         else if (err)
78                 msg = err->message;
79
80         if (err || canceled)
81         {
82                 GtkWidget *dialog = gtk_message_dialog_new (
83                                 GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))),
84                                 GTK_DIALOG_DESTROY_WITH_PARENT,
85                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, msg);
86                 g_signal_connect_swapped (dialog, "response",
87                         G_CALLBACK (gtk_widget_destroy), dialog);
88                 gtk_widget_show_all (dialog);
89         }
90
91         g_object_unref (user_data);
92
93         return;
94 }
95 typedef enum {
96         DO_COPY,
97         DO_MOVE
98 } MoveCopyOption;
99
100 typedef struct {
101         TnyFolder *from;
102         TMutMenuView *self;
103         gboolean del_originals;
104 } OnMoveSelectedInfo;
105
106 static void
107 on_folder_selected_for_move (GtkWidget *widget, gpointer user_data)
108 {
109         OnMoveSelectedInfo *info = (OnMoveSelectedInfo *) user_data;
110         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (info->self);
111         TnyFolderStore *into = tmut_folder_selector_get_current (TMUT_FOLDER_SELECTOR (widget));
112
113         tmut_shell_window_back (priv->shell);
114
115         if (into)
116         {
117                 GtkWidget *dialog, *entry;
118                 gint result;
119
120                 dialog = gtk_dialog_new_with_buttons (_("Name target folder"),
121                                 GTK_WINDOW (priv->shell),
122                                 GTK_DIALOG_MODAL,
123                                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
124                                 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
125                                 NULL);
126                 entry = gtk_entry_new ();
127                 gtk_entry_set_text (GTK_ENTRY (entry), tny_folder_get_name (info->from));
128                 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), entry);
129                 gtk_widget_show (entry);
130
131                 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
132                 {
133
134                         const gchar *new_name = gtk_entry_get_text (GTK_ENTRY (entry));
135
136                         tny_folder_copy_async (info->from, into,
137                                 new_name, info->del_originals, on_copy_done,
138                                 status_update,
139                                 g_object_ref (info->self));
140                 }
141
142                 if (dialog)
143                         gtk_widget_destroy (dialog);
144
145                 g_object_unref (into);
146         }
147
148
149         return;
150 }
151
152 static void
153 on_folder_selected_for_move_destroy (GtkWidget *widget, gpointer user_data)
154 {
155         OnMoveSelectedInfo *info = (OnMoveSelectedInfo *) user_data;
156
157         g_object_unref (info->from);
158         g_object_unref (info->self);
159         g_slice_free (OnMoveSelectedInfo, info);
160
161         return;
162 }
163
164
165 void
166 folder_mover_helper (GObject *sender, TMutMenuView *self, MoveCopyOption option)
167 {
168         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
169         GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->folders_treeview);
170         GtkTreeModel *model;
171         GtkTreeIter iter;
172
173         if (gtk_tree_selection_get_selected (selection, &model, &iter))
174         {
175                 gint type;
176                 gtk_tree_model_get (model, &iter,
177                         TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
178                         &type, -1);
179
180                 if (type != TNY_FOLDER_TYPE_ROOT)
181                 {
182                         TnyFolder *folder;
183                         TMutFolderSelector *view;
184                         OnMoveSelectedInfo *info;
185
186                         gtk_tree_model_get (model, &iter,
187                                 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
188                                 &folder, -1);
189                         if (folder) {
190                                 gboolean del_originals = TRUE;
191
192                                 info = g_slice_new0 (OnMoveSelectedInfo);
193                                 info->self = TMUT_MENU_VIEW (g_object_ref (self));
194                                 info->from = TNY_FOLDER (g_object_ref (folder));
195
196                                 if (option == DO_MOVE)
197                                         info->del_originals = TRUE;
198
199                                 view = tmut_folder_selector_new ();
200                                 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (view), priv->account_store);
201                                 g_signal_connect (G_OBJECT (view), "folder-selected",
202                                         G_CALLBACK (on_folder_selected_for_move), info);
203                                 g_signal_connect (G_OBJECT (view), "destroy",
204                                         G_CALLBACK (on_folder_selected_for_move_destroy), info);
205                                 gtk_widget_show (GTK_WIDGET (view));
206                                 tmut_shell_window_set_child (
207                                         tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)),
208                                         TMUT_SHELL_CHILD (view), _("Select destination"));
209
210                                 g_object_unref (folder);
211                         }
212                 }
213         }
214
215         return;
216 }
217
218
219 void 
220 tmut_menu_view_on_folder_copy_activated (GObject *sender, TMutMenuView *self)
221 {
222         folder_mover_helper (sender, self, DO_COPY);
223         return;
224 }
225
226 void
227 tmut_menu_view_on_folder_move_activated (GObject *sender, TMutMenuView *self)
228 {
229         folder_mover_helper (sender, self, DO_MOVE);
230         return;
231 }
232
233
234 void 
235 tmut_menu_view_on_folder_rename_activated (GObject *sender, TMutMenuView *self)
236 {
237         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
238         GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->folders_treeview);
239         GtkTreeModel *model;
240         GtkTreeIter iter;
241
242         if (gtk_tree_selection_get_selected (selection, &model, &iter))
243         {
244                 gint type;
245                 gtk_tree_model_get (model, &iter,
246                         TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
247                         &type, -1);
248
249                 if (type != TNY_FOLDER_TYPE_ROOT)
250                 {
251                         TnyFolder *folder;
252
253                         gtk_tree_model_get (model, &iter,
254                                 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
255                                 &folder, -1);
256
257                         if (folder)
258                         {
259                                 GtkWidget *dialog, *entry;
260                                 gint result;
261
262                                 dialog = gtk_dialog_new_with_buttons (_("Rename folder"),
263                                                 GTK_WINDOW (priv->shell),
264                                                 GTK_DIALOG_MODAL,
265                                                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
266                                                 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
267                                                 NULL);
268
269                                 entry = gtk_entry_new ();
270                                 gtk_entry_set_text (GTK_ENTRY (entry), tny_folder_get_name (folder));
271                                 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), entry);
272                                 gtk_widget_show (entry);
273
274                                 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
275                                 {
276                                         const gchar *newname = gtk_entry_get_text (GTK_ENTRY (entry));
277
278                                         tny_folder_copy_async (folder, tny_folder_get_folder_store (folder),
279                                                 newname, TRUE, on_copy_done,
280                                                 status_update, g_object_ref (self));
281                                 }
282
283                                 if (dialog)
284                                         gtk_widget_destroy (dialog);
285
286                                 g_object_unref (folder);
287                         }
288                 }
289         }
290
291         return;}
292
293 void
294 tmut_menu_view_on_folder_create_activated (GObject *sender, TMutMenuView *self)
295 {
296         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
297         GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->folders_treeview);
298         GtkTreeModel *model;
299         GtkTreeIter iter;
300
301         if (gtk_tree_selection_get_selected (selection, &model, &iter))
302         {
303                 gint type;
304                 gtk_tree_model_get (model, &iter,
305                         TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
306                         &type, -1);
307                 if (type != TNY_FOLDER_TYPE_ROOT)
308                 {
309                         TnyFolderStore *store;
310                         GtkWidget *dialog, *entry;
311                         gint result;
312                         gtk_tree_model_get (model, &iter,
313                                 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
314                                 &store, -1);
315                         dialog = gtk_dialog_new_with_buttons (_("Create a folder"),
316                                         GTK_WINDOW (priv->shell),
317                                         GTK_DIALOG_MODAL,
318                                         GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
319                                         GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
320                                         NULL);
321
322                         entry = gtk_entry_new ();
323                         gtk_entry_set_text (GTK_ENTRY (entry), _("New folder"));
324                         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), entry);
325                         gtk_widget_show (entry);
326                         if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
327                         {
328                                 GError *err = NULL;
329                                 const gchar *newname = gtk_entry_get_text (GTK_ENTRY (entry));
330                                 TnyFolder *created = tny_folder_store_create_folder (store, newname, &err);
331                                 if (created) /* Can be NULL on failure */
332                                         g_object_unref (created);
333                                 if (err) {
334                                         GtkWidget *edialog;
335                                         gtk_widget_destroy (dialog);
336                                         dialog = NULL;
337                                         edialog = gtk_message_dialog_new (
338                                                         GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))),
339                                                         GTK_DIALOG_DESTROY_WITH_PARENT,
340                                                         GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
341                                                         err->message);
342                                         g_signal_connect_swapped (edialog, "response",
343                                                 G_CALLBACK (gtk_widget_destroy), edialog);
344                                         gtk_widget_show_all (edialog);
345                                         g_error_free (err);
346                                 }
347                         }
348
349                         if (dialog)
350                                 gtk_widget_destroy (dialog);
351                         g_object_unref (store);
352                 }
353
354         }
355
356         return;
357 }
358
359 void
360 tmut_menu_view_on_folder_delete_activated (GObject *sender, TMutMenuView *self)
361 {
362         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
363         GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->folders_treeview);
364         GtkTreeModel *model;
365         GtkTreeIter iter;
366
367         if (gtk_tree_selection_get_selected (selection, &model, &iter))
368         {
369                 gint type;
370                 gtk_tree_model_get (model, &iter,
371                         TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
372                         &type, -1);
373                 if (type != TNY_FOLDER_TYPE_ROOT)
374                 {
375                         TnyFolder *folder = NULL;
376                         gtk_tree_model_get (model, &iter,
377                                 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
378                                 &folder, -1);
379                         if (folder)
380                         {
381                                 gint result;
382                                 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Delete a folder"),
383                                           GTK_WINDOW (priv->shell),
384                                           GTK_DIALOG_MODAL,
385                                           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
386                                           GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
387                                           NULL);
388                                 GtkWidget *label = gtk_label_new (_("Are you sure you want to delete this folder?"));
389                                 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
390                                 gtk_widget_show (label);
391                                 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
392                                 {
393                                         GError *err = NULL;
394                                         TnyFolderStore *store = tny_folder_get_folder_store (folder);
395                                         tny_folder_store_remove_folder (store, folder, &err);
396                                         if (err) {
397                                                 GtkWidget *edialog;
398                                                 gtk_widget_destroy (dialog);
399                                                 dialog = NULL;
400                                                 edialog = gtk_message_dialog_new (
401                                                         GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))),
402                                                         GTK_DIALOG_DESTROY_WITH_PARENT,
403                                                         GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
404                                                         err->message);
405                                                 g_signal_connect_swapped (edialog, "response",
406                                                         G_CALLBACK (gtk_widget_destroy), edialog);
407                                                 gtk_widget_show_all (edialog);
408                                                 g_error_free (err);
409                                         }
410                                         g_object_unref (store);
411                                 }
412                                 if (dialog)
413                                         gtk_widget_destroy (dialog);
414                                 g_object_unref (folder);
415                         }
416                 }
417         }
418
419         return;
420 }
421
422 static void
423 tmut_menu_view_on_onli_activated (GtkMenuItem *menuitem, TMutMenuView *self)
424 {
425         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
426         TnyDevice *device = tny_account_store_get_device (priv->account_store);
427
428         if (!tny_device_is_online (device)) {
429                 GtkWidget *label = gtk_bin_get_child (GTK_BIN (menuitem));
430                 tny_device_force_online (device);
431                 gtk_label_set (GTK_LABEL (label), _("Force offline"));
432         } else {
433                 GtkWidget *label = gtk_bin_get_child (GTK_BIN (menuitem));
434                 tny_device_force_offline (device);
435                 gtk_label_set (GTK_LABEL (label), _("Force online"));
436         }
437
438         g_object_unref (device);
439         return;
440 }
441
442 void 
443 tmut_menu_view_on_new_msg_activated (GObject *sender, TMutMenuView *self)
444 {
445         TMutMsgCreator *view = tmut_msg_creator_new ();
446         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
447
448         if (priv->account_store)
449                 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (view), priv->account_store);
450
451         gtk_widget_show (GTK_WIDGET (view));
452         tmut_shell_window_set_child (
453                 tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)),
454                 TMUT_SHELL_CHILD (view), NULL);
455
456         return;
457
458 }
459
460 void 
461 tmut_menu_view_on_account_manager_activated (GObject *sender, TMutMenuView *self)
462 {
463         TMutAccountManager *view = tmut_account_manager_new ();
464         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
465
466         if (priv->account_store)
467                 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (view), priv->account_store);
468
469         gtk_widget_show (GTK_WIDGET (view));
470         tmut_shell_window_set_child (
471                 tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)),
472                 TMUT_SHELL_CHILD (view), NULL);
473
474         return;
475 }
476
477
478 static void
479 popup_the_actions_menu (GtkButton *button, gpointer user_data)
480 {
481         GtkMenu *menu = (GtkMenu *) user_data;
482         gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
483                         0, gtk_get_current_event_time ());
484         return;
485 }
486
487 typedef struct {
488         TnyDevice *device;
489         GtkMenuItem *menuitem;
490 } CheckOnlineStateInfo;
491
492 static gboolean
493 check_online_state_idle (gpointer user_data)
494 {
495         CheckOnlineStateInfo *info = (CheckOnlineStateInfo *) user_data;
496
497         if (!tny_device_is_online (info->device)) {
498                 GtkWidget *label = gtk_bin_get_child (GTK_BIN (info->menuitem));
499                 gtk_label_set (GTK_LABEL (label), _("Force online"));
500         } else {
501                 GtkWidget *label = gtk_bin_get_child (GTK_BIN (info->menuitem));
502                 gtk_label_set (GTK_LABEL (label), _("Force offline"));
503         }
504
505         return FALSE;
506 }
507
508 static void
509 check_online_state_destroy (gpointer user_data)
510 {
511         CheckOnlineStateInfo *info = (CheckOnlineStateInfo *) user_data;
512         g_object_unref (info->device);
513         g_object_unref (info->menuitem);
514         g_slice_free (CheckOnlineStateInfo, info);
515         return;
516 }
517
518 static void
519 tmut_menu_view_create_menu_default (TMutMenuView *self)
520 {
521         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
522         CheckOnlineStateInfo *info = g_slice_new0 (CheckOnlineStateInfo);
523         GtkMenu *menu;
524         GtkWidget *fcreate_menuitem, *fmove_menuitem, *fdel_menuitem,
525                   *nmsg_menuitem, *fcopy_menuitem, *frename_menuitem,
526                   *onli_menuitem, *accmng_menuitem;
527         GtkButton *menu_button;
528
529         info->device = tny_account_store_get_device (priv->account_store);
530         menu_button = GTK_BUTTON (gtk_button_new_with_label (_("Actions")));
531         menu = GTK_MENU (gtk_menu_new ());
532         fcreate_menuitem = gtk_menu_item_new_with_label (_("Create new folder"));
533         fmove_menuitem = gtk_menu_item_new_with_label (_("Move a folder"));
534         fcopy_menuitem = gtk_menu_item_new_with_label (_("Copy a folder"));
535         frename_menuitem = gtk_menu_item_new_with_label (_("Rename a folder"));
536         fdel_menuitem = gtk_menu_item_new_with_label (_("Delete a folder"));
537         nmsg_menuitem = gtk_menu_item_new_with_label (_("New message"));
538         accmng_menuitem = gtk_menu_item_new_with_label (_("Account manager"));
539
540         if (!tny_device_is_online (info->device))
541                 onli_menuitem = gtk_menu_item_new_with_label (_("Force offline"));
542         else
543                 onli_menuitem = gtk_menu_item_new_with_label (_("Force online"));
544
545         info->menuitem = g_object_ref (onli_menuitem);
546
547         g_idle_add_full (5000, check_online_state_idle,
548                 info, check_online_state_destroy);
549
550         gtk_widget_show (accmng_menuitem);
551         gtk_widget_show (onli_menuitem);
552         gtk_widget_show (nmsg_menuitem);
553         gtk_widget_show (fcreate_menuitem);
554         gtk_widget_show (fmove_menuitem);
555         gtk_widget_show (fcopy_menuitem);
556         gtk_widget_show (frename_menuitem);
557         gtk_widget_show (fdel_menuitem);
558         gtk_widget_show (GTK_WIDGET (menu));
559         gtk_widget_show (GTK_WIDGET (menu_button));
560
561         gtk_menu_prepend (menu, accmng_menuitem);
562         gtk_menu_prepend (menu, onli_menuitem);
563         gtk_menu_prepend (menu, nmsg_menuitem);
564         gtk_menu_prepend (menu, fcreate_menuitem);
565         gtk_menu_prepend (menu, fcopy_menuitem);
566         gtk_menu_prepend (menu, fmove_menuitem);
567         gtk_menu_prepend (menu, frename_menuitem);
568         gtk_menu_prepend (menu, fdel_menuitem);
569         gtk_menu_attach_to_widget (menu, GTK_WIDGET (menu_button), NULL);
570         gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (menu_button), FALSE, TRUE, 0);
571
572         g_signal_connect (G_OBJECT (menu_button), "clicked",
573                 G_CALLBACK (popup_the_actions_menu), menu);
574         g_signal_connect (G_OBJECT (accmng_menuitem), "activate",
575                 G_CALLBACK (tmut_menu_view_on_account_manager_activated), self);
576         g_signal_connect (G_OBJECT (onli_menuitem), "activate",
577                 G_CALLBACK (tmut_menu_view_on_onli_activated), self);
578         g_signal_connect (G_OBJECT (nmsg_menuitem), "activate",
579                 G_CALLBACK (tmut_menu_view_on_new_msg_activated), self);
580         g_signal_connect (G_OBJECT (fcreate_menuitem), "activate",
581                 G_CALLBACK (tmut_menu_view_on_folder_create_activated), self);
582         g_signal_connect (G_OBJECT (fmove_menuitem), "activate",
583                 G_CALLBACK (tmut_menu_view_on_folder_move_activated), self);
584         g_signal_connect (G_OBJECT (fcopy_menuitem), "activate",
585                 G_CALLBACK (tmut_menu_view_on_folder_copy_activated), self);
586         g_signal_connect (G_OBJECT (frename_menuitem), "activate",
587                 G_CALLBACK (tmut_menu_view_on_folder_rename_activated), self);
588         g_signal_connect (G_OBJECT (fdel_menuitem), "activate",
589                 G_CALLBACK (tmut_menu_view_on_folder_delete_activated), self);
590
591         return;
592 }
593
594
595 void 
596 tmut_menu_view_set_active_account (TMutMenuView *self, TnyAccount *account)
597 {
598         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
599         TnyFolderStoreQuery *query;
600         GtkTreeModel *old_model, *model = NULL;
601
602         query = tny_folder_store_query_new ();
603         tny_folder_store_query_add_item (query, NULL,
604                 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
605         model = tny_gtk_folder_store_tree_model_new (query);
606         tny_gtk_folder_store_tree_model_append (TNY_GTK_FOLDER_STORE_TREE_MODEL (model),
607                 TNY_FOLDER_STORE (account), tny_account_get_name (account));
608
609         gtk_tree_view_set_model (priv->folders_treeview, model);
610
611         if (priv->active_account)
612                 g_object_unref (priv->active_account);
613         priv->active_account = g_object_ref (account);
614
615         g_object_unref (model);
616
617         return;
618 }
619
620
621 static void
622 on_account_changed (GtkComboBox *combobox, gpointer user_data)
623 {
624         TMutMenuView *self = TMUT_MENU_VIEW (user_data);
625         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
626         GtkTreeIter iter;
627         TnyAccount *account = NULL;
628         GtkTreeModel *model = gtk_combo_box_get_model (combobox);
629
630         if (gtk_combo_box_get_active_iter (priv->accounts_combo, &iter))
631         {
632                 gtk_tree_model_get (model, &iter,
633                         TNY_GTK_ACCOUNT_LIST_MODEL_INSTANCE_COLUMN,
634                         &account, -1);
635                 if (account) {
636                         tmut_menu_view_set_active_account (TMUT_MENU_VIEW (user_data), account);
637                         g_object_unref (account);
638                 }
639         }
640
641         return;
642 }
643
644 static void
645 on_account_created (TMutAccountStore *store, TnyAccount *account, TMutMenuView *self)
646 {
647         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
648         TnyList *model = TNY_LIST (gtk_combo_box_get_model (priv->accounts_combo));
649         tny_list_prepend (model, (GObject *) account);
650 }
651
652
653 static void
654 on_account_deleted (TMutAccountStore *store, TnyAccount *account, TMutMenuView *self)
655 {
656         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
657         TnyList *model = TNY_LIST (gtk_combo_box_get_model (priv->accounts_combo));
658         if (account == priv->active_account) {
659                 g_object_unref (priv->active_account);
660                 priv->active_account = NULL;
661                 gtk_tree_view_set_model (priv->folders_treeview, NULL);
662         }
663         gtk_combo_box_set_active (priv->accounts_combo, -1);
664         tny_list_remove (model, (GObject *) account);
665 }
666
667 static void
668 disconnect_account_store (TMutMenuViewPriv *priv)
669 {
670         g_signal_handler_disconnect (priv->account_store, priv->account_created_signal);
671         g_signal_handler_disconnect (priv->account_store, priv->account_deleted_signal);
672         g_object_unref (priv->account_store);
673         priv->account_store = NULL;
674 }
675
676 static void
677 tmut_menu_view_set_account_store (TnyAccountStoreView *self, TnyAccountStore *account_store)
678 {
679         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
680         TnyList *accounts = TNY_LIST (tny_gtk_account_list_model_new ());
681
682         tny_account_store_get_accounts (account_store, accounts,
683                 TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
684         gtk_combo_box_set_model (priv->accounts_combo, GTK_TREE_MODEL (accounts));
685         gtk_combo_box_set_active (priv->accounts_combo, 0);
686
687         if (priv->account_store)
688                 disconnect_account_store (priv);
689         priv->account_store = TNY_ACCOUNT_STORE (g_object_ref (account_store));
690
691         priv->account_created_signal = g_signal_connect (G_OBJECT (priv->account_store), "account_created",
692                 G_CALLBACK (on_account_created), self);
693         priv->account_deleted_signal = g_signal_connect (G_OBJECT (priv->account_store), "account_deleted",
694                 G_CALLBACK (on_account_deleted), self);
695
696         TMUT_MENU_VIEW_GET_CLASS (self)->create_menu (TMUT_MENU_VIEW (self));
697
698         return;
699 }
700
701
702 static void
703 on_folder_changed (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
704 {
705         TMutMenuView *self = TMUT_MENU_VIEW (user_data);
706         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
707         GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
708         GtkTreeModel *model;
709         GtkTreeIter iter;
710
711         if (gtk_tree_selection_get_selected (selection, &model, &iter))
712         {
713                 gint type;
714                 gtk_tree_model_get (model, &iter,
715                         TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
716                         &type, -1);
717                 if (type != TNY_FOLDER_TYPE_ROOT)
718                 {
719                         TnyFolder *folder;
720                         TMutFolderView *view;
721
722                         gtk_tree_model_get (model, &iter,
723                                 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
724                                 &folder, -1);
725                         if (!folder)
726                                 return;
727                         view = tmut_folder_view_new (priv->account_store);
728                         tmut_folder_view_set_active_folder (view, folder);
729                         gtk_widget_show (GTK_WIDGET (view));
730                         tmut_shell_window_set_child (
731                                 tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)),
732                                 TMUT_SHELL_CHILD (view), NULL);
733                         g_object_unref (folder);
734                 }
735         }
736
737         return;
738 }
739
740
741 static void
742 tmut_menu_view_instance_init (GTypeInstance *instance, gpointer g_class)
743 {
744         TMutMenuView *self = (TMutMenuView *) instance;
745         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
746         GtkVBox *vbox = GTK_VBOX (self);
747         GtkCellRenderer *renderer;
748         GtkTreeViewColumn *column;
749         GtkTreeSelection *select;
750         GtkWidget *sw;
751
752         priv->active_account = NULL;
753         priv->account_store = NULL;
754         priv->account_created_signal = -1;
755         priv->account_deleted_signal = -1;
756
757         priv->accounts_combo = GTK_COMBO_BOX (gtk_combo_box_new ());
758         gtk_widget_show (GTK_WIDGET (priv->accounts_combo));
759         renderer = gtk_cell_renderer_text_new();
760         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (priv->accounts_combo), renderer, TRUE);
761         gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT (priv->accounts_combo), renderer,
762                 "text", TNY_GTK_ACCOUNT_LIST_MODEL_NAME_COLUMN, NULL);
763         gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->accounts_combo),
764                 FALSE, TRUE, 0);
765         sw = gtk_scrolled_window_new (NULL, NULL);
766         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
767                 GTK_SHADOW_NONE);
768         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
769                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
770         gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
771         gtk_widget_show (sw);
772         priv->folders_treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
773         gtk_tree_view_set_headers_visible (priv->folders_treeview, FALSE);
774         gtk_tree_view_set_rules_hint (priv->folders_treeview, TRUE);
775         gtk_tree_view_set_fixed_height_mode (priv->folders_treeview, TRUE);
776         gtk_widget_show (GTK_WIDGET (priv->folders_treeview));
777         gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->folders_treeview));
778
779         renderer = gtk_cell_renderer_text_new ();
780         column = gtk_tree_view_column_new_with_attributes (_("Folder"), renderer,
781                         "text", TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, NULL);
782         gtk_tree_view_column_set_sort_column_id (column,
783                 TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
784         gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
785         gtk_tree_view_append_column (GTK_TREE_VIEW(priv->folders_treeview), column);
786
787         select = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->folders_treeview));
788         gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
789
790         g_signal_connect (G_OBJECT (priv->accounts_combo), "changed",
791                 G_CALLBACK (on_account_changed), self);
792         g_signal_connect (G_OBJECT (priv->folders_treeview), "row-activated",
793                 G_CALLBACK (on_folder_changed), self);
794
795         return;
796 }
797
798 static void
799 tmut_menu_view_finalize (GObject *object)
800 {
801         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (object);
802
803         if (priv->active_account)
804                 g_object_unref (priv->active_account);
805
806         if (priv->account_store)
807                 disconnect_account_store (priv);
808
809         if (priv->account_store)
810                 g_object_unref (priv->account_store);
811
812         (*parent_class->finalize) (object);
813
814         return;
815 }
816
817 TMutShellWindow*
818 tmut_menu_view_get_window (TMutShellChild *self)
819 {
820         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
821         return priv->shell;
822 }
823
824 void 
825 tmut_menu_view_set_window (TMutShellChild *self, TMutShellWindow *window)
826 {
827         TMutMenuViewPriv *priv = TMUT_MENU_VIEW_GET_PRIVATE (self);
828         priv->shell = window;
829         return;
830 }
831
832 static void
833 tmut_shell_child_init (gpointer g, gpointer iface_data)
834 {
835         TMutShellChildIface *klass = (TMutShellChildIface *)g;
836
837         klass->get_window= tmut_menu_view_get_window;
838         klass->set_window= tmut_menu_view_set_window;
839
840         return;
841 }
842
843 static void
844 tny_account_store_view_init (gpointer g, gpointer iface_data)
845 {
846         TnyAccountStoreViewIface *klass = (TnyAccountStoreViewIface *)g;
847
848         klass->set_account_store= tmut_menu_view_set_account_store;
849
850         return;
851 }
852
853 static void
854 tmut_menu_view_class_init (TMutMenuViewClass *class)
855 {
856         GObjectClass *object_class;
857
858         parent_class = g_type_class_peek_parent (class);
859         object_class = (GObjectClass*) class;
860
861         object_class->finalize = tmut_menu_view_finalize;
862
863         class->create_menu= tmut_menu_view_create_menu_default;
864
865         g_type_class_add_private (object_class, sizeof (TMutMenuViewPriv));
866
867         return;
868 }
869
870 /**
871  * tmut_menu_view_new:
872  *
873  *
874  * Return value: A new #TnySummaryView instance implemented for TMUT
875  **/
876 TMutMenuView*
877 tmut_menu_view_new (void)
878 {
879         TMutMenuView *self = g_object_new (TMUT_TYPE_MENU_VIEW, NULL);
880
881         return TMUT_MENU_VIEW (self);
882 }
883
884 GType
885 tmut_menu_view_get_type (void)
886 {
887         static GType type = 0;
888
889         if (G_UNLIKELY(type == 0))
890         {
891                 static const GTypeInfo info =
892                 {
893                   sizeof (TMutMenuViewClass),
894                   NULL,   /* base_init */
895                   NU