Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (15.5 kB)

1
#region
2
/* -----------------------------------------------------------------------
3
 * <copyright file="FilePropertiesViewModel.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

    
43
using System.Collections.ObjectModel;
44
using System.ComponentModel.Composition;
45
using System.Diagnostics.Contracts;
46
using System.Drawing;
47
using System.IO;
48
using System.Net;
49
using System.Threading.Tasks;
50
using System.Windows;
51
using System.Windows.Interop;
52
using System.Windows.Media.Imaging;
53
using Caliburn.Micro;
54
using Pithos.Client.WPF.FileProperties;
55
using Pithos.Core;
56
using Pithos.Interfaces;
57
using Pithos.Network;
58

    
59
namespace Pithos.Client.WPF
60
{
61
    using System;
62
    using System.Linq;
63

    
64
    /// <summary>
65
    /// TODO: Update summary.
66
    /// </summary>
67
    [Export(typeof(FilePropertiesViewModel))]
68
    public class FilePropertiesViewModel : Screen
69
    {
70
        private string _title;
71
        public string Title
72
        {
73
            get { return _title; }
74
            set
75
            {
76
                _title = value;
77
                NotifyOfPropertyChange(()=>Title);
78
            }
79
        }
80

    
81

    
82
        private bool _isPublic;
83
        public bool IsPublic
84
        {
85
            get { return _isPublic; }
86
            set
87
            {
88
                _isPublic = value;
89
                NotifyOfPropertyChange(()=>IsPublic);
90
            }
91
        }
92

    
93
        private string _contentDisposition;
94
        public string ContentDisposition
95
        {
96
            get { return _contentDisposition; }
97
            set
98
            {
99
                _contentDisposition = value;
100
                NotifyOfPropertyChange(() => ContentDisposition);
101
            }
102
        }
103

    
104
        private string _contentEncoding;
105
        public string ContentEncoding
106
        {
107
            get { return _contentEncoding; }
108
            set
109
            {
110
                _contentEncoding = value;
111
                NotifyOfPropertyChange(() => ContentEncoding);
112
            }
113
        }
114

    
115

    
116
        private string _manifest;
117
        public string Manifest
118
        {
119
            get { return _manifest; }
120
            set
121
            {
122
                _manifest = value;
123
                NotifyOfPropertyChange(() => Manifest);
124
            }
125
        }
126

    
127
        private string _kind;
128
        public string Kind
129
        {
130
            get { return _kind; }
131
            set
132
            {
133
                _kind = value;
134
                NotifyOfPropertyChange(() => Kind);
135
            }
136
        }
137

    
138
        private string _size;
139
        public string Size
140
        {
141
            get { return _size; }
142
            set
143
            {
144
                _size = value;
145
                NotifyOfPropertyChange(() => Size);
146
            }
147
        }
148

    
149
        private string _shortSize;
150
        public string ShortSize
151
        {
152
            get { return _shortSize; }
153
            set
154
            {
155
                _shortSize = value;
156
                NotifyOfPropertyChange(() => ShortSize);
157
            }
158
        }
159

    
160
        private string _where;
161
        public string Where
162
        {
163
            get { return _where; }
164
            set
165
            {
166
                _where = value;
167
                NotifyOfPropertyChange(() => Where);
168
            }
169
        }
170

    
171
        private DateTime _modified;
172
        public DateTime Modified
173
        {
174
            get { return _modified; }
175
            set
176
            {
177
                _modified = value;
178
                NotifyOfPropertyChange(() => Modified);
179
            }
180
        }
181

    
182
        private string _modifiedBy;
183
        public string ModifiedBy
184
        {
185
            get { return _modifiedBy; }
186
            set
187
            {
188
                _modifiedBy = value;
189
                NotifyOfPropertyChange(() => ModifiedBy);
190
            }
191
        }
192

    
193
        private long _version;
194
        public long Version
195
        {
196
            get { return _version; }
197
            set
198
            {
199
                _version = value;
200
                NotifyOfPropertyChange(() => Version);
201
            }
202
        }
203

    
204
        private string _localFileName;
205
        protected string LocalFileName
206
        {
207
            get { return _localFileName; }
208
            set
209
            {
210
                _localFileName = value;
211
                NotifyOfPropertyChange(() => LocalFileName);
212
            }
213
        }
214

    
215
        private BitmapSource _fileIcon;
216
        public BitmapSource FileIcon
217
        {
218
            get { return _fileIcon; }
219
            set
220
            {
221
                _fileIcon = value;
222
                NotifyOfPropertyChange(() => FileIcon);
223
            }
224
        }
225

    
226
        private string _publicUrl;
227
        public string PublicUrl
228
        {
229
            get { return _publicUrl; }
230
            set
231
            {
232
                _publicUrl = value;
233
                NotifyOfPropertyChange(() => PublicUrl);
234
            }
235
        }
236

    
237
        private string _fileName;
238
        public string FileName
239
        {
240
            get { return _fileName; }
241
            set
242
            {
243
                _fileName = value;
244
                NotifyOfPropertyChange(() => FileName);
245
            }
246
        }
247

    
248
        private string _container;
249
        public string Container
250
        {
251
            get { return _container; }
252
            set
253
            {
254
                _container = value;
255
                NotifyOfPropertyChange(() => Container);
256
            }
257
        }
258

    
259
        private string _synchStatus;
260
        public string SynchStatus
261
        {
262
            get { return _synchStatus; }
263
            set
264
            {
265
                _synchStatus = value;
266
                NotifyOfPropertyChange(()=>SynchStatus);
267
            }
268
        }
269
        
270
        private Permission _currentPermission;
271
        public Permission CurrentPermission
272
        {
273
            get { return _currentPermission; }
274
            set
275
            {                
276
                _currentPermission = (value==null)?new Permission() : value.Clone();
277
                _currentPermission.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddPermission);
278

    
279
                NotifyOfPropertyChange(()=>CurrentPermission);
280
                NotifyOfPropertyChange(() => CanAddPermission);
281
            }
282
        }
283

    
284
        public bool CanAddPermission
285
        {
286
            get { return !String.IsNullOrWhiteSpace(CurrentPermission.UserName); }
287
        }
288

    
289
        public void AddPermission()
290
        {
291
            var existingPermission = Permissions.FirstOrDefault(perm => perm.UserName == CurrentPermission.UserName);
292
            if (existingPermission==null)
293
                Permissions.Add(CurrentPermission.Clone());
294
            else
295
            {
296
                existingPermission.Read = CurrentPermission.Read;
297
            }
298
        }
299

    
300
        public bool CanAddTag
301
        {
302
            get { return !String.IsNullOrWhiteSpace(CurrentTag.Name); }
303
        }
304

    
305
        public void AddTag()
306
        {
307
            var existingTag = Tags.FirstOrDefault(tag => tag.Name == CurrentTag.Name);           
308
            if (existingTag == null)
309
                Tags.Add(CurrentTag.Clone());
310
            else
311
            {
312
                existingTag.Value = CurrentTag.Value;
313
            }
314
        }
315

    
316

    
317
        public bool TagsChanged { get; private set; }
318
        public bool PermissionsChanged { get; private set; }
319

    
320
        private bool _isBusy = true;
321
        public bool IsBusy
322
        {
323
            get { return _isBusy; }
324
            set
325
            {
326
                _isBusy = value;
327
                NotifyOfPropertyChange(() => IsBusy);
328
            }
329
        }
330

    
331

    
332
        public FilePropertiesViewModel(ShellViewModel shell,Task<ObjectInfo> pithosFile,string localFileName)
333
        {
334
            if (shell==null)
335
                throw new ArgumentNullException("shell");
336
            if (pithosFile==null)
337
                throw new ArgumentNullException("pithosFile");
338
            if (String.IsNullOrWhiteSpace(localFileName))
339
                throw new ArgumentNullException("localFileName");
340
            Contract.EndContractBlock();
341

    
342

    
343
            _tags = new ObservableCollection<MetaValue>();
344
            _tags.CollectionChanged += (sender, evt) => { TagsChanged = true; };
345
            _permissions = new ObservableCollection<Permission>();
346
            _permissions.CollectionChanged += (sender, evt) => { PermissionsChanged = true; };
347
            
348

    
349
            CurrentPermission=new Permission();
350
            CurrentTag=new MetaValue();
351

    
352

    
353
            Shell = shell;
354
            LocalFileName = localFileName;
355

    
356
            var name=Path.GetFileName(localFileName);
357
            DisplayName = String.Format("{0} File Properties", name);
358

    
359
            pithosFile.ContinueWith(t =>
360
            {
361
                if (t.IsFaulted)
362
                {
363
                    IsBusy = false;
364
                    Execute.OnUIThread(()=>ShowError(t.Exception));
365
                    this.TryClose();
366

    
367
                }
368
                else
369
                    Execute.OnUIThread(() => PithosFile = t.Result);
370
            });       
371
                 
372
        }
373

    
374
        private void ShowError(AggregateException exception)
375
        {
376
            MessageView view;
377
            if (exception.InnerException is RetryException)
378
                view = new MessageView(exception.InnerException as RetryException);
379
            else if (exception.InnerException is WebException)
380
                view = new MessageView(exception.InnerException as WebException);
381
            else
382
                view = new MessageView(exception.InnerException);
383
            view.ShowDialog();
384
        }
385

    
386

    
387
        protected ShellViewModel Shell { get; set; }
388

    
389
        private ObjectInfo _pithosFile;
390
        public ObjectInfo PithosFile
391
        {
392
            get { return _pithosFile; }
393
            set
394
            {
395
                _pithosFile = value;
396
                
397
                Permissions.Clear();
398
                Tags.Clear();
399

    
400
                var perms=from permission in value.Permissions
401
                            select new Permission(permission.Key, permission.Value);
402
                perms.Apply(perm=>Permissions.Add(perm));
403
                
404
                var tags=from tag in value.Tags
405
                             select new MetaValue(tag.Key, tag.Value);
406
                tags.Apply(tag=>Tags.Add(tag));
407

    
408
                Title = String.Format("{0} Properties", value.Name);
409
                Kind=value.Content_Type;
410
                ShortSize = value.Bytes.ToByteSize();
411
                Size = String.Format("{0} ({1:N0} bytes)", ShortSize, value.Bytes);
412
                Where = Uri.UnescapeDataString(value.Name);
413
                FileName = Uri.UnescapeDataString(value.Name.Split('/').Last());
414
                Container = value.Container;
415
                Modified = value.Last_Modified;
416
                ModifiedBy = value.ModifiedBy;
417
                Version = value.Version??0;
418

    
419
                ContentDisposition = value.ContendDisposition;
420
                ContentEncoding = value.ContentEncoding;
421
                Manifest = value.Manifest;
422
                IsPublic = value.IsPublic;
423
                if (IsPublic)
424
                    PublicUrl = String.Format("{0}/v1{1}", Shell.Accounts.First(account=>account.UserName==PithosFile.Account).SiteUri,value.PublicUrl);
425

    
426
                if (Directory.Exists(LocalFileName))
427
                {
428
                    FileIcon= new BitmapImage(new Uri("../Images/Folder.ico",UriKind.Relative));
429
                }
430
                else if (File.Exists(LocalFileName))
431
                {
432
                    using (var icon = Icon.ExtractAssociatedIcon(LocalFileName))
433
                    {
434
                        FileIcon = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty,
435
                                                                       BitmapSizeOptions.FromEmptyOptions());
436
                    }
437
                }
438

    
439
                var status=Shell.GetFileStatus(LocalFileName);
440
                SynchStatus = Enum.GetName(typeof (FileStatus), status);
441

    
442

    
443
                NotifyOfPropertyChange(()=>PithosFile);
444
                IsBusy = false;
445
            }
446
        }
447

    
448
        private MetaValue _currentTag;
449
        public MetaValue CurrentTag
450
        {
451
            get { return _currentTag; }
452
            set
453
            {
454
                _currentTag = (value==null)?new MetaValue() : value.Clone();
455
                _currentTag.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddTag);
456

    
457
                NotifyOfPropertyChange(()=>CurrentTag);
458
                NotifyOfPropertyChange(() => CanAddTag);
459
            }
460
        }
461

    
462
        private readonly ObservableCollection<MetaValue> _tags ;
463
        public ObservableCollection<MetaValue> Tags
464
        {
465
            get { return _tags;}
466
        }
467

    
468
        private readonly ObservableCollection<Permission> _permissions ;
469
        
470

    
471
        public ObservableCollection<Permission> Permissions
472
        {
473
            get { return _permissions; }
474
        }
475

    
476
        public void Reload()
477
        {
478
            PithosFile=Shell.RefreshObjectInfo(PithosFile);
479
        }
480

    
481
        public override void CanClose(Action<bool> callback)
482
        {
483
            base.CanClose(callback);
484
        }
485

    
486
        public void SaveChanges()
487
        {
488
            DoSave();
489
            TryClose();
490
        }
491

    
492
        public void RejectChanges()
493
        {
494
            TryClose();
495
        }
496

    
497
        public void ApplyChanges()
498
        {
499
            DoSave();
500
        }
501

    
502
        private void DoSave()
503
        {
504
            if (TagsChanged)
505
            {
506
                PithosFile.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
507
            }
508
            
509
            if (PermissionsChanged)
510
            {
511
                PithosFile.Permissions = this.Permissions.ToDictionary(perm => perm.UserName, perm => 
512
                    (perm.Value.Trim()));
513
            }
514

    
515
            PithosFile.ContendDisposition = ContentDisposition;
516
            PithosFile.ContentEncoding = ContentEncoding;
517
            PithosFile.Manifest = Manifest;
518
            PithosFile.IsPublic = IsPublic;
519
            
520
            var monitor = Shell.Monitors[PithosFile.AccountKey];
521
            monitor.CloudClient.UpdateMetadata(PithosFile);
522

    
523

    
524
            TagsChanged = false;
525
            PermissionsChanged = false;
526
        }
527

    
528

    
529
    }
530
}