2 /* -----------------------------------------------------------------------
3 * <copyright file="FilePropertiesViewModel.cs" company="GRNet">
5 * Copyright 2011-2012 GRNET S.A. All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * 1. Redistributions of source code must retain the above
12 * copyright notice, this list of conditions and the following
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.
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.
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.
39 * -----------------------------------------------------------------------
43 using System.Collections.ObjectModel;
44 using System.ComponentModel.Composition;
45 using System.Diagnostics.Contracts;
49 using System.Threading.Tasks;
51 using System.Windows.Interop;
52 using System.Windows.Media.Imaging;
54 using Pithos.Client.WPF.FileProperties;
56 using Pithos.Interfaces;
59 namespace Pithos.Client.WPF
65 /// TODO: Update summary.
67 [Export(typeof(FilePropertiesViewModel))]
68 public class FilePropertiesViewModel : Screen
70 private string _title;
73 get { return _title; }
77 NotifyOfPropertyChange(()=>Title);
82 private bool _isPublic;
85 get { return _isPublic; }
89 NotifyOfPropertyChange(()=>IsPublic);
93 private string _contentDisposition;
94 public string ContentDisposition
96 get { return _contentDisposition; }
99 _contentDisposition = value;
100 NotifyOfPropertyChange(() => ContentDisposition);
104 private string _contentEncoding;
105 public string ContentEncoding
107 get { return _contentEncoding; }
110 _contentEncoding = value;
111 NotifyOfPropertyChange(() => ContentEncoding);
116 private string _manifest;
117 public string Manifest
119 get { return _manifest; }
123 NotifyOfPropertyChange(() => Manifest);
127 private string _kind;
130 get { return _kind; }
134 NotifyOfPropertyChange(() => Kind);
138 private string _size;
141 get { return _size; }
145 NotifyOfPropertyChange(() => Size);
149 private string _shortSize;
150 public string ShortSize
152 get { return _shortSize; }
156 NotifyOfPropertyChange(() => ShortSize);
160 private string _where;
163 get { return _where; }
167 NotifyOfPropertyChange(() => Where);
171 private DateTime _modified;
172 public DateTime Modified
174 get { return _modified; }
178 NotifyOfPropertyChange(() => Modified);
182 private string _modifiedBy;
183 public string ModifiedBy
185 get { return _modifiedBy; }
189 NotifyOfPropertyChange(() => ModifiedBy);
193 private long _version;
196 get { return _version; }
200 NotifyOfPropertyChange(() => Version);
204 private string _localFileName;
205 protected string LocalFileName
207 get { return _localFileName; }
210 _localFileName = value;
211 NotifyOfPropertyChange(() => LocalFileName);
215 private BitmapSource _fileIcon;
216 public BitmapSource FileIcon
218 get { return _fileIcon; }
222 NotifyOfPropertyChange(() => FileIcon);
226 private string _publicUrl;
227 public string PublicUrl
229 get { return _publicUrl; }
233 NotifyOfPropertyChange(() => PublicUrl);
237 private string _fileName;
238 public string FileName
240 get { return _fileName; }
244 NotifyOfPropertyChange(() => FileName);
248 private string _container;
249 public string Container
251 get { return _container; }
255 NotifyOfPropertyChange(() => Container);
259 private string _synchStatus;
260 public string SynchStatus
262 get { return _synchStatus; }
265 _synchStatus = value;
266 NotifyOfPropertyChange(()=>SynchStatus);
270 private Permission _currentPermission;
271 public Permission CurrentPermission
273 get { return _currentPermission; }
276 _currentPermission = (value==null)?new Permission() : value.Clone();
277 _currentPermission.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddPermission);
279 NotifyOfPropertyChange(()=>CurrentPermission);
280 NotifyOfPropertyChange(() => CanAddPermission);
284 public bool CanAddPermission
286 get { return !String.IsNullOrWhiteSpace(CurrentPermission.UserName); }
289 public void AddPermission()
291 var existingPermission = Permissions.FirstOrDefault(perm => perm.UserName == CurrentPermission.UserName);
292 if (existingPermission==null)
293 Permissions.Add(CurrentPermission.Clone());
296 existingPermission.Read = CurrentPermission.Read;
300 public bool CanAddTag
302 get { return !String.IsNullOrWhiteSpace(CurrentTag.Name); }
307 var existingTag = Tags.FirstOrDefault(tag => tag.Name == CurrentTag.Name);
308 if (existingTag == null)
309 Tags.Add(CurrentTag.Clone());
312 existingTag.Value = CurrentTag.Value;
317 public bool TagsChanged { get; private set; }
318 public bool PermissionsChanged { get; private set; }
320 private bool _isBusy = true;
323 get { return _isBusy; }
327 NotifyOfPropertyChange(() => IsBusy);
332 public FilePropertiesViewModel(ShellViewModel shell,Task<ObjectInfo> pithosFile,string localFileName)
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();
343 _tags = new ObservableCollection<MetaValue>();
344 _tags.CollectionChanged += (sender, evt) => { TagsChanged = true; };
345 _permissions = new ObservableCollection<Permission>();
346 _permissions.CollectionChanged += (sender, evt) => { PermissionsChanged = true; };
349 CurrentPermission=new Permission();
350 CurrentTag=new MetaValue();
354 LocalFileName = localFileName;
355 pithosFile.ContinueWith(t =>
360 Execute.OnUIThread(()=>ShowError(t.Exception));
365 Execute.OnUIThread(() => PithosFile = t.Result);
370 private void ShowError(AggregateException exception)
373 if (exception.InnerException is RetryException)
374 view = new MessageView(exception.InnerException as RetryException);
375 else if (exception.InnerException is WebException)
376 view = new MessageView(exception.InnerException as WebException);
378 view = new MessageView(exception.InnerException);
383 protected ShellViewModel Shell { get; set; }
385 private ObjectInfo _pithosFile;
386 public ObjectInfo PithosFile
388 get { return _pithosFile; }
396 var perms=from permission in value.Permissions
397 select new Permission(permission.Key, permission.Value);
398 perms.Apply(perm=>Permissions.Add(perm));
400 var tags=from tag in value.Tags
401 select new MetaValue(tag.Key, tag.Value);
402 tags.Apply(tag=>Tags.Add(tag));
404 Title = String.Format("{0} Properties", value.Name);
405 Kind=value.Content_Type;
406 ShortSize = value.Bytes.ToByteSize();
407 Size = String.Format("{0} ({1:N0} bytes)", ShortSize, value.Bytes);
408 Where = Uri.UnescapeDataString(value.Name);
409 FileName = Uri.UnescapeDataString(value.Name.Split('/').Last());
410 Container = value.Container;
411 Modified = value.Last_Modified;
412 ModifiedBy = value.ModifiedBy;
413 Version = value.Version??0;
415 ContentDisposition = value.ContendDisposition;
416 ContentEncoding = value.ContentEncoding;
417 Manifest = value.Manifest;
418 IsPublic = value.IsPublic;
420 PublicUrl = String.Format("{0}/v1{1}", Shell.Accounts.First(account=>account.UserName==PithosFile.Account).SiteUri,value.PublicUrl);
422 if (Directory.Exists(LocalFileName))
424 FileIcon= new BitmapImage(new Uri("../Images/Folder.ico",UriKind.Relative));
426 else if (File.Exists(LocalFileName))
428 using (var icon = Icon.ExtractAssociatedIcon(LocalFileName))
430 FileIcon = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty,
431 BitmapSizeOptions.FromEmptyOptions());
435 var status=Shell.GetFileStatus(LocalFileName);
436 SynchStatus = Enum.GetName(typeof (FileStatus), status);
439 NotifyOfPropertyChange(()=>PithosFile);
444 private MetaValue _currentTag;
445 public MetaValue CurrentTag
447 get { return _currentTag; }
450 _currentTag = (value==null)?new MetaValue() : value.Clone();
451 _currentTag.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddTag);
453 NotifyOfPropertyChange(()=>CurrentTag);
454 NotifyOfPropertyChange(() => CanAddTag);
458 private readonly ObservableCollection<MetaValue> _tags ;
459 public ObservableCollection<MetaValue> Tags
464 private readonly ObservableCollection<Permission> _permissions ;
467 public ObservableCollection<Permission> Permissions
469 get { return _permissions; }
474 PithosFile=Shell.RefreshObjectInfo(PithosFile);
477 public override void CanClose(Action<bool> callback)
479 base.CanClose(callback);
482 public void SaveChanges()
488 public void RejectChanges()
493 public void ApplyChanges()
498 private void DoSave()
502 PithosFile.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
505 if (PermissionsChanged)
507 PithosFile.Permissions = this.Permissions.ToDictionary(perm => perm.UserName, perm =>
508 (perm.Value.Trim()));
511 PithosFile.ContendDisposition = ContentDisposition;
512 PithosFile.ContentEncoding = ContentEncoding;
513 PithosFile.Manifest = Manifest;
514 PithosFile.IsPublic = IsPublic;
516 var monitor = Shell.Monitors[PithosFile.AccountKey];
517 monitor.CloudClient.UpdateMetadata(PithosFile);
521 PermissionsChanged = false;