#region
/* -----------------------------------------------------------------------
*
*
* Copyright 2011-2012 GRNET S.A. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and
* documentation are those of the authors and should not be
* interpreted as representing official policies, either expressed
* or implied, of GRNET S.A.
*
* -----------------------------------------------------------------------
*/
#endregion
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using Caliburn.Micro;
using Pithos.Client.WPF.FileProperties;
using Pithos.Core;
using Pithos.Interfaces;
using Pithos.Network;
namespace Pithos.Client.WPF
{
using System;
using System.Linq;
///
/// TODO: Update summary.
///
[Export(typeof(FilePropertiesViewModel))]
public class FilePropertiesViewModel : Screen
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
NotifyOfPropertyChange(()=>Title);
}
}
private bool _isPublic;
public bool IsPublic
{
get { return _isPublic; }
set
{
_isPublic = value;
NotifyOfPropertyChange(()=>IsPublic);
}
}
private string _contentDisposition;
public string ContentDisposition
{
get { return _contentDisposition; }
set
{
_contentDisposition = value;
NotifyOfPropertyChange(() => ContentDisposition);
}
}
private string _contentEncoding;
public string ContentEncoding
{
get { return _contentEncoding; }
set
{
_contentEncoding = value;
NotifyOfPropertyChange(() => ContentEncoding);
}
}
private string _manifest;
public string Manifest
{
get { return _manifest; }
set
{
_manifest = value;
NotifyOfPropertyChange(() => Manifest);
}
}
private string _kind;
public string Kind
{
get { return _kind; }
set
{
_kind = value;
NotifyOfPropertyChange(() => Kind);
}
}
private string _size;
public string Size
{
get { return _size; }
set
{
_size = value;
NotifyOfPropertyChange(() => Size);
}
}
private string _shortSize;
public string ShortSize
{
get { return _shortSize; }
set
{
_shortSize = value;
NotifyOfPropertyChange(() => ShortSize);
}
}
private string _where;
public string Where
{
get { return _where; }
set
{
_where = value;
NotifyOfPropertyChange(() => Where);
}
}
private DateTime _modified;
public DateTime Modified
{
get { return _modified; }
set
{
_modified = value;
NotifyOfPropertyChange(() => Modified);
}
}
private string _modifiedBy;
public string ModifiedBy
{
get { return _modifiedBy; }
set
{
_modifiedBy = value;
NotifyOfPropertyChange(() => ModifiedBy);
}
}
private long _version;
public long Version
{
get { return _version; }
set
{
_version = value;
NotifyOfPropertyChange(() => Version);
}
}
private string _localFileName;
protected string LocalFileName
{
get { return _localFileName; }
set
{
_localFileName = value;
NotifyOfPropertyChange(() => LocalFileName);
}
}
private BitmapSource _fileIcon;
public BitmapSource FileIcon
{
get { return _fileIcon; }
set
{
_fileIcon = value;
NotifyOfPropertyChange(() => FileIcon);
}
}
private string _publicUrl;
public string PublicUrl
{
get { return _publicUrl; }
set
{
_publicUrl = value;
NotifyOfPropertyChange(() => PublicUrl);
}
}
private string _fileName;
public string FileName
{
get { return _fileName; }
set
{
_fileName = value;
NotifyOfPropertyChange(() => FileName);
}
}
private string _container;
public string Container
{
get { return _container; }
set
{
_container = value;
NotifyOfPropertyChange(() => Container);
}
}
private string _synchStatus;
public string SynchStatus
{
get { return _synchStatus; }
set
{
_synchStatus = value;
NotifyOfPropertyChange(()=>SynchStatus);
}
}
private Permission _currentPermission;
public Permission CurrentPermission
{
get { return _currentPermission; }
set
{
_currentPermission = (value==null)?new Permission() : value.Clone();
_currentPermission.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddPermission);
NotifyOfPropertyChange(()=>CurrentPermission);
NotifyOfPropertyChange(() => CanAddPermission);
}
}
public bool CanAddPermission
{
get { return !String.IsNullOrWhiteSpace(CurrentPermission.UserName); }
}
public void AddPermission()
{
var existingPermission = Permissions.FirstOrDefault(perm => perm.UserName == CurrentPermission.UserName);
if (existingPermission==null)
Permissions.Add(CurrentPermission.Clone());
else
{
existingPermission.Read = CurrentPermission.Read;
}
}
public bool CanAddTag
{
get { return !String.IsNullOrWhiteSpace(CurrentTag.Name); }
}
public void AddTag()
{
var existingTag = Tags.FirstOrDefault(tag => tag.Name == CurrentTag.Name);
if (existingTag == null)
Tags.Add(CurrentTag.Clone());
else
{
existingTag.Value = CurrentTag.Value;
}
}
public bool TagsChanged { get; private set; }
public bool PermissionsChanged { get; private set; }
private bool _isBusy = true;
public bool IsBusy
{
get { return _isBusy; }
set
{
_isBusy = value;
NotifyOfPropertyChange(() => IsBusy);
}
}
public FilePropertiesViewModel(ShellViewModel shell,Task pithosFile,string localFileName)
{
if (shell==null)
throw new ArgumentNullException("shell");
if (pithosFile==null)
throw new ArgumentNullException("pithosFile");
if (String.IsNullOrWhiteSpace(localFileName))
throw new ArgumentNullException("localFileName");
Contract.EndContractBlock();
_tags = new ObservableCollection();
_tags.CollectionChanged += (sender, evt) => { TagsChanged = true; };
_permissions = new ObservableCollection();
_permissions.CollectionChanged += (sender, evt) => { PermissionsChanged = true; };
CurrentPermission=new Permission();
CurrentTag=new MetaValue();
Shell = shell;
LocalFileName = localFileName;
var name=Path.GetFileName(localFileName);
DisplayName = String.Format("{0} File Properties", name);
pithosFile.ContinueWith(t =>
{
if (t.IsFaulted)
{
IsBusy = false;
Execute.OnUIThread(()=>ShowError(t.Exception));
this.TryClose();
}
else
Execute.OnUIThread(() => PithosFile = t.Result);
});
}
private void ShowError(AggregateException exception)
{
MessageView view;
if (exception.InnerException is RetryException)
view = new MessageView(exception.InnerException as RetryException);
else if (exception.InnerException is WebException)
view = new MessageView(exception.InnerException as WebException);
else
view = new MessageView(exception.InnerException);
view.ShowDialog();
}
protected ShellViewModel Shell { get; set; }
private ObjectInfo _pithosFile;
public ObjectInfo PithosFile
{
get { return _pithosFile; }
set
{
_pithosFile = value;
Permissions.Clear();
Tags.Clear();
var perms=from permission in value.Permissions
select new Permission(permission.Key, permission.Value);
perms.Apply(perm=>Permissions.Add(perm));
var tags=from tag in value.Tags
select new MetaValue(tag.Key, tag.Value);
tags.Apply(tag=>Tags.Add(tag));
Title = String.Format("{0} Properties", value.Name);
Kind=value.Content_Type;
ShortSize = value.Bytes.ToByteSize();
Size = String.Format("{0} ({1:N0} bytes)", ShortSize, value.Bytes);
Where = Uri.UnescapeDataString(value.Name);
FileName = Uri.UnescapeDataString(value.Name.Split('/').Last());
Container = value.Container;
Modified = value.Last_Modified;
ModifiedBy = value.ModifiedBy;
Version = value.Version??0;
ContentDisposition = value.ContendDisposition;
ContentEncoding = value.ContentEncoding;
Manifest = value.Manifest;
IsPublic = value.IsPublic;
if (IsPublic)
PublicUrl = String.Format("{0}/v1{1}", Shell.Accounts.First(account=>account.UserName==PithosFile.Account).SiteUri,value.PublicUrl);
if (Directory.Exists(LocalFileName))
{
FileIcon= new BitmapImage(new Uri("../Images/Folder.ico",UriKind.Relative));
}
else if (File.Exists(LocalFileName))
{
using (var icon = Icon.ExtractAssociatedIcon(LocalFileName))
{
FileIcon = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
var status=Shell.GetFileStatus(LocalFileName);
SynchStatus = Enum.GetName(typeof (FileStatus), status);
NotifyOfPropertyChange(()=>PithosFile);
IsBusy = false;
}
}
private MetaValue _currentTag;
public MetaValue CurrentTag
{
get { return _currentTag; }
set
{
_currentTag = (value==null)?new MetaValue() : value.Clone();
_currentTag.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddTag);
NotifyOfPropertyChange(()=>CurrentTag);
NotifyOfPropertyChange(() => CanAddTag);
}
}
private readonly ObservableCollection _tags ;
public ObservableCollection Tags
{
get { return _tags;}
}
private readonly ObservableCollection _permissions ;
public ObservableCollection Permissions
{
get { return _permissions; }
}
public void Reload()
{
PithosFile=Shell.RefreshObjectInfo(PithosFile);
}
public override void CanClose(Action callback)
{
base.CanClose(callback);
}
public void SaveChanges()
{
DoSave();
TryClose();
}
public void RejectChanges()
{
TryClose();
}
public void ApplyChanges()
{
DoSave();
}
private void DoSave()
{
if (TagsChanged)
{
PithosFile.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
}
if (PermissionsChanged)
{
PithosFile.Permissions = this.Permissions.ToDictionary(perm => perm.UserName, perm =>
(perm.Value.Trim()));
}
PithosFile.ContendDisposition = ContentDisposition;
PithosFile.ContentEncoding = ContentEncoding;
PithosFile.Manifest = Manifest;
PithosFile.IsPublic = IsPublic;
var monitor = Shell.Monitors[PithosFile.AccountKey];
monitor.CloudClient.UpdateMetadata(PithosFile);
TagsChanged = false;
PermissionsChanged = false;
}
}
}