Changed Display name for Shared Item root folder
[pithos-ms-client] / trunk / Pithos.Client.WPF / SelectiveSynch / SelectiveSynchViewModel.cs
1 #region
2 /* -----------------------------------------------------------------------
3  * <copyright file="SelectiveSynchViewModel.cs" company="GRNet">
4  * 
5  * Copyright 2011-2012 GRNET S.A. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  *   1. Redistributions of source code must retain the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer.
14  *
15  *   2. Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials
18  *      provided with the distribution.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * The views and conclusions contained in the software and
35  * documentation are those of the authors and should not be
36  * interpreted as representing official policies, either expressed
37  * or implied, of GRNET S.A.
38  * </copyright>
39  * -----------------------------------------------------------------------
40  */
41 #endregion
42 using System;
43 using System.Collections.Generic;
44 using System.Collections.ObjectModel;
45 using System.Linq;
46 using System.Threading.Tasks;
47 using Caliburn.Micro;
48 using Pithos.Client.WPF.Properties;
49 using Pithos.Client.WPF.Utils;
50 using Pithos.Core;
51 using Pithos.Interfaces;
52
53 namespace Pithos.Client.WPF.SelectiveSynch
54 {
55     class SelectiveSynchViewModel:Screen
56     {        
57         private readonly IEventAggregator _events ;
58
59
60         public AccountSettings Account { get; set; }
61
62         private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
63         public ObservableCollection<DirectoryRecord> RootNodes
64         {
65             get { return _rootNodes; }
66         }
67
68         private ObservableCollection<ObjectInfo> _checks;
69         private readonly PithosMonitor _monitor;
70         private bool _isBusy=true;
71
72         public ObservableCollection<ObjectInfo> Checks
73         {
74             get { return _checks; }
75         }
76
77         public void GetChecks()
78         {
79             var root = RootNodes[0];            
80             _checks = new ObservableCollection<ObjectInfo>(
81                 from DirectoryRecord record in root
82                 where record.IsChecked==true
83                 select record.ObjectInfo);
84             NotifyOfPropertyChange(() => Checks);
85         }
86
87         public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
88         {
89             Account = account;
90             AccountName = account.AccountName;
91             DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
92             _monitor = monitor;
93             _events = events;
94             TaskEx.Run(LoadRootNode);
95         }
96
97         private void LoadRootNode()
98         {
99             var client = _monitor.CloudClient;
100
101             var dirs = from container in client.ListContainers(_monitor.UserName)                       
102                        select new DirectoryRecord
103                                   {
104                                       DisplayName = container.Name,
105                                       Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
106                                       Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name)                                                     
107                                                      where dir.IsDirectory
108                                                      select dir).ToTree()
109                                   };
110             var ownFolders = dirs.ToList();
111
112             var accountNodes=from account in client.ListSharingAccounts()
113                              select new DirectoryRecord
114                              {
115                                 DisplayName=account.name,
116                                 Uri=new Uri(client.StorageUrl,"../"+ account.name),
117                                 Directories=(from container in client.ListContainers(account.name)
118                                             select new DirectoryRecord
119                                                         {
120                                                             DisplayName=container.Name,
121                                                             Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
122                                                             Directories=(from folder in client.ListObjects(account.name,container.Name)
123                                                                         where folder.IsDirectory
124                                                                         select folder).ToTree()
125                                                         }).ToList()
126                              };                                                          
127
128             var othersNode = new DirectoryRecord
129                                  {
130                                      DisplayName = "Shared to me",
131                                      Directories=accountNodes.ToList()
132                                  };
133
134             
135             var rootItem = new DirectoryRecord
136                                {
137                                    DisplayName = AccountName ,
138                                    Directories = ownFolders.ToList()
139                                };
140
141             Execute.OnUIThread(() =>
142                                    {
143                                        RootNodes.Add(rootItem);
144                                        RootNodes.Add(othersNode);
145                                    });
146
147             SetInitialSelections(Account);
148             
149             IsBusy = false;
150         }
151
152         public bool IsBusy
153         {
154             get {
155                 return _isBusy;
156             }
157             set {
158                 _isBusy = value;
159                 NotifyOfPropertyChange(()=>IsBusy);
160             }
161         }
162
163         private void SetInitialSelections(AccountSettings account)
164         {
165             var selections = account.SelectiveFolders;
166
167
168                 
169             //Initially, all nodes are checked
170             //We need to *uncheck* the nodes that are not selected
171
172             var allNodes = (from DirectoryRecord rootRecord in RootNodes
173                            from DirectoryRecord record in rootRecord
174                            select record).ToList();
175
176             if (selections.Count == 0)
177             {
178                 allNodes.Apply(record => record.IsChecked = false);
179                 return;
180             } 
181             
182             var selects = (from DirectoryRecord rootRecord in RootNodes
183                           from DirectoryRecord record in rootRecord
184                           where record.Uri !=null &&  !selections.Contains(record.Uri.ToString())
185                           select record).ToList();
186             var shouldBeChecked = allNodes.Except(selects).ToList();
187
188             selects.Apply(record=>record.IsChecked=false);
189
190             shouldBeChecked.Apply(record => record.IsChecked = true);
191             
192             
193
194         }
195
196         protected string AccountName { get; set; }
197
198         public void SaveChanges()
199         {
200             var uris = (from DirectoryRecord root in RootNodes
201                         from DirectoryRecord record in root
202                         where record.IsChecked == true && record.Uri != null
203                         select record.Uri).ToArray();            
204
205             SaveSettings(uris);
206             
207             //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
208
209             var added = (from DirectoryRecord root in RootNodes
210                          from DirectoryRecord record in root
211                          where record.Added && record.Uri != null
212                          select record.Uri).ToArray();
213             var removed = (from DirectoryRecord root in RootNodes
214                            from DirectoryRecord record in root
215                           where record.Removed && record.Uri != null
216                          select record.Uri).ToArray();
217             //TODO: Include Uris for the containers as well
218             _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
219             
220
221             
222
223             TryClose(true);
224         }
225
226         
227         private void SaveSettings(IEnumerable<Uri> uris)
228         {
229             var selections = uris.Select(uri => uri.ToString()).ToArray();
230
231             Account.SelectiveFolders.Clear();
232             Account.SelectiveFolders.AddRange(selections);
233             Settings.Default.Save();            
234         }        
235
236         public void RejectChanges()
237         {
238             TryClose(false);
239         }
240     }
241 }