Statistics
| Branch: | Revision:

root / trunk / Pithos.Client.WPF / FileProperties / ContainerPropertiesViewModel.cs @ 4671d606

History | View | Annotate | Download (13.3 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.IO;
49
using System.Linq;
50
using System.Net;
51
using System.Text;
52
using System.Threading.Tasks;
53
using System.Windows;
54
using Caliburn.Micro;
55
using Pithos.Network;
56

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

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

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

    
91
        private long _count;
92

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

    
106
        private DateTime _modified;
107

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

    
121
        private string _size;
122

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

    
136
        private string _shortSize;
137

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

    
151
        private int _blockSize;
152

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

    
166
        private string _blockHash;
167

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

    
181
        private ShellViewModel _shell;
182

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

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

    
207
                
208

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

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

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

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

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

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

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

    
259

    
260

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

    
267

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

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

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

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

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

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

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

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

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

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

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

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

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

    
372
            var name = Path.GetFileName(localFolderName);
373
            DisplayName = String.Format("{0} Container Properties", name);
374

    
375
            Shell = shell;
376
            ContainerName = localFolderName;
377
            container.ContinueWith(t =>{                
378
                if (t.IsFaulted)
379
                {
380
                    IsBusy = false;
381
                    Execute.OnUIThread(() => ShowError(t.Exception));
382
                    this.TryClose();
383

    
384
                }
385
                else
386
                    Execute.OnUIThread(()=>Container = t.Result);                                           
387
            });
388
        }
389

    
390
        private void ShowError(AggregateException exception)
391
        {
392
            MessageView view=null;
393
            if (exception.InnerException is RetryException)
394
                view=new MessageView(exception.InnerException as RetryException);
395
            else if (exception.InnerException is WebException)
396
                view = new MessageView(exception.InnerException as WebException);
397
            else
398
                view = new MessageView(exception.InnerException);
399
            view.ShowDialog();
400
        }
401

    
402
        public void Reload()
403
        {
404
            Container = Shell.RefreshContainerInfo(Container);
405
        }
406

    
407
        public override void CanClose(Action<bool> callback)
408
        {
409
            base.CanClose(callback);
410
        }
411

    
412
        public void SaveChanges()
413
        {
414
            DoSave();
415
            TryClose();
416
        }
417

    
418
        public void RejectChanges()
419
        {
420
            TryClose();
421
        }
422

    
423
        public void ApplyChanges()
424
        {
425
            DoSave();
426
        }
427

    
428
        public bool CanApplyChanges
429
        {
430
            get { return TagsChanged; }
431
        }
432

    
433
        private void DoSave()
434
        {
435
            
436
            if (TagsChanged)
437
            {
438
                Container.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
439
                var monitor = Shell.Monitors[Container.AccountKey];
440
                monitor.CloudClient.UpdateMetadata(Container);
441
            }
442

    
443
            //Container.Policies["Quota"] = Quota.ToString();
444
            //Container.Policies["Versioning"] = Enum.GetName(typeof (Versioning), SelectedVersion);
445

    
446
/*
447
            if (PoliciesChanged)
448
            {
449
                Container.Policies = this.Policies.ToDictionary(policy=> policy.Name, tag => tag.Value);
450
            }
451
*/
452
            
453

    
454
        }
455

    
456
    }
457

    
458
    
459
}