Statistics
| Branch: | Revision:

root / trunk / Pithos.Client.WPF / SelectiveSynch / SelectiveSynchViewModel.cs @ 0a9d4d18

History | View | Annotate | Download (9.5 kB)

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 const string DirectoryType = "application/directory";
58
        private readonly IEventAggregator _events ;
59

    
60

    
61
        public AccountSettings Account { get; set; }
62

    
63
        private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
64
        public ObservableCollection<DirectoryRecord> RootNodes
65
        {
66
            get { return _rootNodes; }
67
        }
68

    
69
        private ObservableCollection<ObjectInfo> _checks;
70
        private readonly PithosMonitor _monitor;
71
        private bool _isBusy=true;
72

    
73
        public ObservableCollection<ObjectInfo> Checks
74
        {
75
            get { return _checks; }
76
        }
77

    
78
        public void GetChecks()
79
        {
80
            var root = RootNodes[0];            
81
            _checks = new ObservableCollection<ObjectInfo>(
82
                from DirectoryRecord record in root
83
                where record.IsChecked==true
84
                select record.ObjectInfo);
85
            NotifyOfPropertyChange(() => Checks);
86
        }
87

    
88
        public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
89
        {
90
            Account = account;
91
            AccountName = account.AccountName;
92
            DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
93
            _monitor = monitor;
94
            _events = events;
95
            TaskEx.Run(LoadRootNode);
96
        }
97

    
98
        private void LoadRootNode()
99
        {
100
            var client = _monitor.CloudClient;
101

    
102
            var dirs = from container in client.ListContainers(_monitor.UserName)                       
103
                       select new DirectoryRecord
104
                                  {
105
                                      DisplayName = container.Name,
106
                                      Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
107
                                      Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name)                                                     
108
                                                     where dir.Content_Type == DirectoryType
109
                                                     select dir).ToTree()
110
                                  };
111
            var ownFolders = dirs.ToList();
112

    
113
            var accountNodes=from account in client.ListSharingAccounts()
114
                             select new DirectoryRecord
115
                             {
116
                                DisplayName=account.name,
117
                                Uri=new Uri(client.StorageUrl,"../"+ account.name),
118
                                Directories=(from container in client.ListContainers(account.name)
119
                                            select new DirectoryRecord
120
                                                        {
121
                                                            DisplayName=container.Name,
122
                                                            Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
123
                                                            Directories=(from folder in client.ListObjects(account.name,container.Name)
124
                                                                        where folder.Content_Type==DirectoryType
125
                                                                        select folder).ToTree()
126
                                                        }).ToList()
127
                             };                                                          
128

    
129
            var othersNode = new DirectoryRecord
130
                                 {
131
                                     DisplayName = "Others",
132
                                     Directories=accountNodes.ToList()
133
                                 };
134

    
135
            
136
            var rootItem = new DirectoryRecord
137
                               {
138
                                   DisplayName = AccountName ,
139
                                   Directories = ownFolders.ToList()
140
                               };
141

    
142
            Execute.OnUIThread(() =>
143
                                   {
144
                                       RootNodes.Add(rootItem);
145
                                       RootNodes.Add(othersNode);
146
                                   });
147

    
148
            SetInitialSelections(Account);
149
            
150
            IsBusy = false;
151
        }
152

    
153
        public bool IsBusy
154
        {
155
            get {
156
                return _isBusy;
157
            }
158
            set {
159
                _isBusy = value;
160
                NotifyOfPropertyChange(()=>IsBusy);
161
            }
162
        }
163

    
164
        private void SetInitialSelections(AccountSettings account)
165
        {
166
            var selections = account.SelectiveFolders;
167

    
168

    
169
                
170
            //Initially, all nodes are checked
171
            //We need to *uncheck* the nodes that are not selected
172

    
173
            var allNodes = (from DirectoryRecord rootRecord in RootNodes
174
                           from DirectoryRecord record in rootRecord
175
                           select record).ToList();
176

    
177
            if (selections.Count == 0)
178
            {
179
                allNodes.Apply(record => record.IsChecked = false);
180
                return;
181
            } 
182
            
183
            var selects = (from DirectoryRecord rootRecord in RootNodes
184
                          from DirectoryRecord record in rootRecord
185
                          where record.Uri !=null &&  !selections.Contains(record.Uri.ToString())
186
                          select record).ToList();
187
            var shouldBeChecked = allNodes.Except(selects).ToList();
188

    
189
            selects.Apply(record=>record.IsChecked=false);
190

    
191
            shouldBeChecked.Apply(record => record.IsChecked = true);
192
            
193
            
194

    
195
        }
196

    
197
        protected string AccountName { get; set; }
198

    
199
        public void SaveChanges()
200
        {
201
            var uris = (from DirectoryRecord root in RootNodes
202
                        from DirectoryRecord record in root
203
                        where record.IsChecked == true && record.Uri != null
204
                        select record.Uri).ToArray();            
205

    
206
            SaveSettings(uris);
207
            
208
            //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
209

    
210
            var added = (from DirectoryRecord root in RootNodes
211
                         from DirectoryRecord record in root
212
                         where record.Added && record.Uri != null
213
                         select record.Uri).ToArray();
214
            var removed = (from DirectoryRecord root in RootNodes
215
                           from DirectoryRecord record in root
216
                          where record.Removed && record.Uri != null
217
                         select record.Uri).ToArray();
218
            //TODO: Include Uris for the containers as well
219
            _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
220
            
221

    
222
            
223

    
224
            TryClose(true);
225
        }
226

    
227
        
228
        private void SaveSettings(IEnumerable<Uri> uris)
229
        {
230
            var selections = uris.Select(uri => uri.ToString()).ToArray();
231

    
232
            Account.SelectiveFolders.Clear();
233
            Account.SelectiveFolders.AddRange(selections);
234
            Settings.Default.Save();            
235
        }        
236

    
237
        public void RejectChanges()
238
        {
239
            TryClose(false);
240
        }
241
    }
242
}