Statistics
| Branch: | Revision:

root / trunk / Pithos.Client.WPF / FileProperties / ContainerPropertiesViewModel.cs @ 1e4f1775

History | View | Annotate | Download (13.1 kB)

1
#region
2
/* -----------------------------------------------------------------------
3
 * <copyright file="ContainerPropertiesViewModel.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.Concurrent;
44
using System.Collections.Generic;
45
using System.Collections.ObjectModel;
46
using System.ComponentModel.Composition;
47
using System.Diagnostics.Contracts;
48
using System.Linq;
49
using System.Net;
50
using System.Text;
51
using System.Threading.Tasks;
52
using System.Windows;
53
using Caliburn.Micro;
54
using Pithos.Network;
55

    
56
namespace Pithos.Client.WPF.FileProperties
57
{
58
    [Export(typeof(ContainerPropertiesViewModel))]
59
    public class ContainerPropertiesViewModel:Screen
60
    {
61
        private string _containerName;
62

    
63
        /// <summary>
64
        /// Name of the displayed container
65
        /// </summary>
66
        public string ContainerName
67
        {
68
            get { return _containerName; }
69
            set
70
            {
71
                _containerName = value;
72
                NotifyOfPropertyChange(()=>ContainerName);
73
            }
74
        }
75

    
76
        private string _title;
77
        /// <summary>
78
        /// Window title
79
        /// </summary>
80
        public string Title
81
        {
82
            get { return _title; }
83
            set
84
            {
85
                _title = value;
86
                NotifyOfPropertyChange(() => Title);
87
            }
88
        }
89

    
90
        private long _count;
91

    
92
        /// <summary>
93
        /// Count of files in the container
94
        /// </summary>
95
        public long Count
96
        {
97
            get { return _count; }
98
            set
99
            {
100
                _count = value;
101
                NotifyOfPropertyChange(() => Count);
102
            }
103
        }
104

    
105
        private DateTime _modified;
106

    
107
        /// <summary>
108
        /// Date of last modification
109
        /// </summary>
110
        public DateTime Modified
111
        {
112
            get { return _modified; }
113
            set
114
            {
115
                _modified = value;
116
                NotifyOfPropertyChange(() => Modified);
117
            }
118
        }
119

    
120
        private string _size;
121

    
122
        /// <summary>
123
        /// Total size of the container in bytes
124
        /// </summary>
125
        public string Size
126
        {
127
            get { return _size; }
128
            set
129
            {
130
                _size = value;
131
                NotifyOfPropertyChange(() => Size);
132
            }
133
        }
134

    
135
        private string _shortSize;
136

    
137
        /// <summary>
138
        /// Total size of the container formatted in KB,MB etc
139
        /// </summary>
140
        public string ShortSize
141
        {
142
            get { return _shortSize; }
143
            set
144
            {
145
                _shortSize = value;
146
                NotifyOfPropertyChange(() => ShortSize);
147
            }
148
        }
149

    
150
        private int _blockSize;
151

    
152
        /// <summary>
153
        /// Block size used by the container
154
        /// </summary>
155
        public int BlockSize
156
        {
157
            get { return _blockSize; }
158
            set
159
            {
160
                _blockSize = value;
161
                NotifyOfPropertyChange(() => BlockSize);
162
            }
163
        }
164

    
165
        private string _blockHash;
166

    
167
        /// <summary>
168
        /// Hash algorithm used to calculate block hashes
169
        /// </summary>
170
        public string BlockHash
171
        {
172
            get { return _blockHash; }
173
            set
174
            {
175
                _blockHash = value;
176
                NotifyOfPropertyChange(() => BlockHash);
177
            }
178
        }
179

    
180
        private ShellViewModel _shell;
181

    
182
        /// <summary>
183
        /// Reference to the parent Shell
184
        /// </summary>
185
        protected ShellViewModel Shell
186
        {
187
            get { return _shell; }
188
            set
189
            {
190
                _shell = value;
191
                NotifyOfPropertyChange(() => Shell);
192
            }
193
        }
194

    
195
        private ContainerInfo _container;
196
        /// <summary>
197
        /// The displayed ContainerInfo
198
        /// </summary>
199
        protected ContainerInfo Container
200
        {
201
            get { return _container; }
202
            set
203
            {
204
                _container = value;
205

    
206
                
207

    
208
                LoadFromDictionary(Tags, value.Tags);
209
                TagsChanged = false;
210
                //LoadFromDictionary(Policies, value.Policies);
211

    
212
                if (value.Policies.ContainsKey("Versioning"))
213
                {
214
                    Versioning version;
215
                    if (Enum.TryParse(value.Policies["Versioning"], out version))
216
                    {
217
                        SelectedVersion = version;
218
                    }
219
                }
220

    
221
                if (value.Policies.ContainsKey("Quota"))
222
                {
223
                    int quota;
224
                    if (int.TryParse(value.Policies["Quota"], out quota))
225
                    {
226
                        Quota=quota;
227
                    }
228
                }
229

    
230
                Title = String.Format("{0} Properties", _container.Name);
231
                Count = value.Count;
232
                ShortSize = value.Bytes.ToByteSize();
233
                Size = String.Format("{0} ({1:N0} bytes)", ShortSize, value.Bytes);
234
                Modified = value.Last_Modified;
235
                BlockSize = value.BlockSize;
236
                BlockHash = value.BlockHash;                
237
                ContainerName = Uri.UnescapeDataString(value.Name.Split('/').Last());                                                
238

    
239
                NotifyOfPropertyChange(() => Container);
240
                IsBusy = false;
241
            }
242
        }
243

    
244
        private int _quota;
245
        public int Quota
246
        {
247
            get { return _quota; }
248
            set
249
            {
250
                if (value < 0)
251
                    throw new ArgumentOutOfRangeException("Quota");
252

    
253
                _quota = value;                
254
                NotifyOfPropertyChange(() => Quota);
255
            }
256
        }
257

    
258

    
259

    
260
        private Versioning[] _versions={Versioning.manual,Versioning.auto,Versioning.none};
261
        public Versioning[] Versions
262
        {
263
            get { return _versions; }
264
        }
265

    
266

    
267
        private Versioning _selectedVersion;
268
        public Versioning SelectedVersion
269
        {
270
            get { return _selectedVersion; }
271
            set { 
272
                _selectedVersion = value;
273
                NotifyOfPropertyChange(()=>SelectedVersion);
274
            }
275
        }
276

    
277
        private void LoadFromDictionary(ICollection<MetaValue> collection,Dictionary<string,string> source  )
278
        {
279
            collection.Clear();
280
            var items = from item in source
281
                        select new MetaValue(item.Key, item.Value);
282
            
283
            items.Apply(collection.Add);
284
        }
285

    
286
        private MetaValue _currentTag;
287
        public MetaValue CurrentTag
288
        {
289
            get { return _currentTag; }
290
            set
291
            {
292
                _currentTag = (value == null) ? new MetaValue() : value.Clone();
293
                _currentTag.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddTag);
294

    
295
                NotifyOfPropertyChange(() => CurrentTag);
296
                NotifyOfPropertyChange(() => CanAddTag);
297
            }
298
        }
299

    
300
        private readonly ObservableCollection<MetaValue> _tags;
301
        public ObservableCollection<MetaValue> Tags
302
        {
303
            get { return _tags; }
304
        }
305

    
306
        public bool CanAddTag
307
        {
308
            get { return !String.IsNullOrWhiteSpace(CurrentTag.Name); }
309
        }
310

    
311
        public void AddTag()
312
        {
313
            var existingTag = Tags.FirstOrDefault(tag => tag.Name == CurrentTag.Name);
314
            if (existingTag == null)
315
                Tags.Add(CurrentTag.Clone());
316
            else
317
            {
318
                existingTag.Value = CurrentTag.Value;
319
            }
320
        }
321

    
322
       /* private readonly ObservableCollection<MetaValue> _policies;
323
        public ObservableCollection<MetaValue> Policies
324
        {
325
            get { return _policies; }
326
        }*/
327

    
328
        private bool _tagsChanged;
329
        public bool TagsChanged
330
        {
331
            get { return _tagsChanged; }
332
            private set
333
            {
334
                _tagsChanged = value;
335
                NotifyOfPropertyChange(()=>TagsChanged);
336
                NotifyOfPropertyChange(() => CanApplyChanges);
337
            }
338
        }
339

    
340
        //public bool PoliciesChanged { get; private set; }
341

    
342
        private bool _isBusy=true;
343
        public bool IsBusy
344
        {
345
            get { return _isBusy; }
346
            set
347
            {
348
                _isBusy = value;
349
                NotifyOfPropertyChange(()=>IsBusy);
350
            }
351
        }
352

    
353
        public ContainerPropertiesViewModel(ShellViewModel shell, Task<ContainerInfo> container, string localFolderName)
354
        {
355
            if (shell==null)
356
                throw new ArgumentNullException("shell");
357
            if (container==null)
358
                throw new ArgumentNullException("container");
359
            if (String.IsNullOrWhiteSpace(localFolderName))
360
                throw new ArgumentNullException("localFolderName");
361
            Contract.EndContractBlock();
362
            
363
            _tags = new ObservableCollection<MetaValue>();
364
            _tags.CollectionChanged += (sender, evt) => { TagsChanged = true; };
365

    
366
            /*_policies = new ObservableCollection<MetaValue>();
367
            _policies.CollectionChanged += (sender, evt) => { PoliciesChanged = true; };
368
*/
369

    
370
            Shell = shell;
371
            ContainerName = localFolderName;
372
            container.ContinueWith(t =>{                
373
                if (t.IsFaulted)
374
                {
375
                    IsBusy = false;
376
                    Execute.OnUIThread(() => ShowError(t.Exception));
377
                    this.TryClose();
378

    
379
                }
380
                else
381
                    Execute.OnUIThread(()=>Container = t.Result);                                           
382
            });
383
        }
384

    
385
        private void ShowError(AggregateException exception)
386
        {
387
            MessageView view=null;
388
            if (exception.InnerException is RetryException)
389
                view=new MessageView(exception.InnerException as RetryException);
390
            else if (exception.InnerException is WebException)
391
                view = new MessageView(exception.InnerException as WebException);
392
            else
393
                view = new MessageView(exception.InnerException);
394
            view.ShowDialog();
395
        }
396

    
397
        public void Reload()
398
        {
399
            Container = Shell.RefreshContainerInfo(Container);
400
        }
401

    
402
        public override void CanClose(Action<bool> callback)
403
        {
404
            base.CanClose(callback);
405
        }
406

    
407
        public void SaveChanges()
408
        {
409
            DoSave();
410
            TryClose();
411
        }
412

    
413
        public void RejectChanges()
414
        {
415
            TryClose();
416
        }
417

    
418
        public void ApplyChanges()
419
        {
420
            DoSave();
421
        }
422

    
423
        public bool CanApplyChanges
424
        {
425
            get { return TagsChanged; }
426
        }
427

    
428
        private void DoSave()
429
        {
430
            
431
            if (TagsChanged)
432
            {
433
                Container.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
434
                var monitor = Shell.Monitors[Container.AccountKey];
435
                monitor.CloudClient.UpdateMetadata(Container);
436
            }
437

    
438
            //Container.Policies["Quota"] = Quota.ToString();
439
            //Container.Policies["Versioning"] = Enum.GetName(typeof (Versioning), SelectedVersion);
440

    
441
/*
442
            if (PoliciesChanged)
443
            {
444
                Container.Policies = this.Policies.ToDictionary(policy=> policy.Name, tag => tag.Value);
445
            }
446
*/
447
            
448

    
449
        }
450

    
451
    }
452

    
453
    
454
}