2 /* -----------------------------------------------------------------------
\r
3 * <copyright file="SelectiveSynchViewModel.cs" company="GRNet">
\r
5 * Copyright 2011-2012 GRNET S.A. All rights reserved.
\r
7 * Redistribution and use in source and binary forms, with or
\r
8 * without modification, are permitted provided that the following
\r
9 * conditions are met:
\r
11 * 1. Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\r
15 * 2. Redistributions in binary form must reproduce the above
\r
16 * copyright notice, this list of conditions and the following
\r
17 * disclaimer in the documentation and/or other materials
\r
18 * provided with the distribution.
\r
21 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
\r
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
\r
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
\r
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
\r
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
\r
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
\r
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
32 * POSSIBILITY OF SUCH DAMAGE.
\r
34 * The views and conclusions contained in the software and
\r
35 * documentation are those of the authors and should not be
\r
36 * interpreted as representing official policies, either expressed
\r
37 * or implied, of GRNET S.A.
\r
39 * -----------------------------------------------------------------------
\r
43 using System.Collections.Generic;
\r
44 using System.Collections.ObjectModel;
\r
46 using System.Threading.Tasks;
\r
47 using Caliburn.Micro;
\r
48 using Pithos.Client.WPF.Properties;
\r
49 using Pithos.Client.WPF.Utils;
\r
51 using Pithos.Interfaces;
\r
52 using Pithos.Network;
\r
54 namespace Pithos.Client.WPF.SelectiveSynch
\r
56 class SelectiveSynchViewModel:Screen
\r
58 private readonly IEventAggregator _events ;
\r
61 public AccountSettings Account { get; set; }
\r
63 private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
\r
64 public ObservableCollection<DirectoryRecord> RootNodes
\r
66 get { return _rootNodes; }
\r
69 private ObservableCollection<ObjectInfo> _checks;
\r
70 //private readonly PithosMonitor _monitor;
\r
71 private bool _isBusy=true;
\r
72 private string _apiKey;
\r
74 public ObservableCollection<ObjectInfo> Checks
\r
76 get { return _checks; }
\r
79 public void GetChecks()
\r
81 var root = RootNodes[0];
\r
82 _checks = new ObservableCollection<ObjectInfo>(
\r
83 from DirectoryRecord record in root
\r
84 where record.IsChecked==true
\r
85 select record.ObjectInfo);
\r
86 NotifyOfPropertyChange(() => Checks);
\r
89 public SelectiveSynchViewModel(/*PithosMonitor monitor,*/ IEventAggregator events, AccountSettings account, string apiKey)
\r
92 AccountName = account.AccountName;
\r
93 DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
\r
94 //_monitor = monitor;
\r
97 TaskEx.Run(LoadRootNode);
\r
100 private void LoadRootNode()
\r
103 var client = new CloudFilesClient(AccountName,_apiKey){AuthenticationUrl=Account.ServerUrl,UsePithos=true};
\r
104 client.Authenticate();
\r
107 var dirs = from container in client.ListContainers(AccountName)
\r
108 where container.Name != "trash"
\r
109 select new DirectoryRecord
\r
111 DisplayName = container.Name,
\r
112 Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
\r
113 Directories = (from dir in client.ListObjects(AccountName, container.Name)
\r
114 select dir).ToTree()
\r
116 var ownFolders = dirs.ToList();
\r
118 var accountNodes=from account in client.ListSharingAccounts()
\r
119 select new DirectoryRecord
\r
121 DisplayName=account.name,
\r
122 Uri=new Uri(client.StorageUrl,"../"+ account.name),
\r
123 Directories=(from container in client.ListContainers(account.name)
\r
124 select new DirectoryRecord
\r
126 DisplayName=container.Name,
\r
127 Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
\r
128 Directories=(from folder in client.ListObjects(account.name,container.Name)
\r
129 select folder).ToTree()
\r
133 var othersNode = new DirectoryRecord
\r
135 DisplayName = "Shared to me",
\r
136 Directories=accountNodes.ToList()
\r
140 var rootItem = new DirectoryRecord
\r
142 DisplayName = AccountName ,
\r
143 Directories = ownFolders.ToList()
\r
146 Execute.OnUIThread(() =>
\r
148 RootNodes.Add(rootItem);
\r
149 RootNodes.Add(othersNode);
\r
152 SetInitialSelections(Account);
\r
164 NotifyOfPropertyChange(()=>IsBusy);
\r
168 private void SetInitialSelections(AccountSettings account)
\r
170 var selections = account.SelectiveFolders;
\r
174 //Initially, all nodes are checked
\r
175 //We need to *uncheck* the nodes that are not selected
\r
177 var allNodes = (from DirectoryRecord rootRecord in RootNodes
\r
178 from DirectoryRecord record in rootRecord
\r
179 select record).ToList();
\r
180 //WARNING: Using IsChecked marks the item as REMOVED
\r
181 allNodes.Apply(record => record.IsExplicitlyChecked = false);
\r
183 if (selections.Count == 0)
\r
185 // allNodes.Apply(record => record.IsChecked = false);
\r
189 var selects = (from DirectoryRecord rootRecord in RootNodes
\r
190 from DirectoryRecord record in rootRecord
\r
191 where record.Uri !=null && selections.Contains(record.Uri.ToString())
\r
192 select record).ToList();
\r
193 //var shouldBeChecked = allNodes.Except(selects).ToList();
\r
195 //WARNING: Using IsChecked marks the item as ADDED
\r
196 selects.Apply(record=>record.IsExplicitlyChecked=true);
\r
198 //shouldBeChecked.Apply(record => record.IsChecked = true);
\r
204 protected string AccountName { get; set; }
\r
206 public void SaveChanges()
\r
208 var uris = (from DirectoryRecord root in RootNodes
\r
209 from DirectoryRecord record in root
\r
210 where record.IsChecked == true && record.Uri != null
\r
211 select record.Uri).ToArray();
\r
213 SaveSettings(uris);
\r
215 //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
\r
217 var added = (from DirectoryRecord root in RootNodes
\r
218 from DirectoryRecord record in root
\r
219 where record.Added && record.Uri != null
\r
220 select record.Uri).ToArray();
\r
221 var removed = (from DirectoryRecord root in RootNodes
\r
222 from DirectoryRecord record in root
\r
223 where record.Removed && record.Uri != null
\r
224 select record.Uri).ToArray();
\r
225 //TODO: Include Uris for the containers as well
\r
226 _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
\r
235 private void SaveSettings(IEnumerable<Uri> uris)
\r
237 var selections = uris.Select(uri => uri.ToString()).ToArray();
\r
239 Account.SelectiveFolders.Clear();
\r
240 Account.SelectiveFolders.AddRange(selections);
\r
241 Settings.Default.Save();
\r
244 public void RejectChanges()
\r