#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;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Caliburn.Micro;
using Pithos.Client.WPF.Properties;
using Pithos.Client.WPF.Utils;
using Pithos.Core;
using Pithos.Interfaces;
using Pithos.Network;
namespace Pithos.Client.WPF.SelectiveSynch
{
class SelectiveSynchViewModel:Screen
{
private readonly IEventAggregator _events ;
public AccountSettings Account { get; set; }
private readonly ObservableCollection _rootNodes=new ObservableCollection();
public ObservableCollection RootNodes
{
get { return _rootNodes; }
}
private ObservableCollection _checks;
//private readonly PithosMonitor _monitor;
private bool _isBusy=true;
private string _apiKey;
public ObservableCollection Checks
{
get { return _checks; }
}
public void GetChecks()
{
var root = RootNodes[0];
_checks = new ObservableCollection(
from DirectoryRecord record in root
where record.IsChecked==true
select record.ObjectInfo);
NotifyOfPropertyChange(() => Checks);
}
public SelectiveSynchViewModel(/*PithosMonitor monitor,*/ IEventAggregator events, AccountSettings account, string apiKey)
{
Account = account;
AccountName = account.AccountName;
DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
//_monitor = monitor;
_events = events;
_apiKey = apiKey;
TaskEx.Run(LoadRootNode);
}
private void LoadRootNode()
{
//TODO: Check this
var client = new CloudFilesClient(AccountName,_apiKey){AuthenticationUrl=Account.ServerUrl,UsePithos=true};
client.Authenticate();
var dirs = from container in client.ListContainers(AccountName)
select new DirectoryRecord
{
DisplayName = container.Name,
Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
Directories = (from dir in client.ListObjects(AccountName, container.Name)
where dir.IsDirectory
select dir).ToTree()
};
var ownFolders = dirs.ToList();
var accountNodes=from account in client.ListSharingAccounts()
select new DirectoryRecord
{
DisplayName=account.name,
Uri=new Uri(client.StorageUrl,"../"+ account.name),
Directories=(from container in client.ListContainers(account.name)
select new DirectoryRecord
{
DisplayName=container.Name,
Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
Directories=(from folder in client.ListObjects(account.name,container.Name)
where folder.IsDirectory
select folder).ToTree()
}).ToList()
};
var othersNode = new DirectoryRecord
{
DisplayName = "Others",
Directories=accountNodes.ToList()
};
var rootItem = new DirectoryRecord
{
DisplayName = AccountName ,
Directories = ownFolders.ToList()
};
Execute.OnUIThread(() =>
{
RootNodes.Add(rootItem);
RootNodes.Add(othersNode);
});
SetInitialSelections(Account);
IsBusy = false;
}
public bool IsBusy
{
get {
return _isBusy;
}
set {
_isBusy = value;
NotifyOfPropertyChange(()=>IsBusy);
}
}
private void SetInitialSelections(AccountSettings account)
{
var selections = account.SelectiveFolders;
//Initially, all nodes are checked
//We need to *uncheck* the nodes that are not selected
var allNodes = (from DirectoryRecord rootRecord in RootNodes
from DirectoryRecord record in rootRecord
select record).ToList();
allNodes.Apply(record => record.IsChecked = false);
if (selections.Count == 0)
{
// allNodes.Apply(record => record.IsChecked = false);
return;
}
var selects = (from DirectoryRecord rootRecord in RootNodes
from DirectoryRecord record in rootRecord
where record.Uri !=null && selections.Contains(record.Uri.ToString())
select record).ToList();
//var shouldBeChecked = allNodes.Except(selects).ToList();
selects.Apply(record=>record.IsExplicitlyChecked=true);
//shouldBeChecked.Apply(record => record.IsChecked = true);
}
protected string AccountName { get; set; }
public void SaveChanges()
{
var uris = (from DirectoryRecord root in RootNodes
from DirectoryRecord record in root
where record.IsChecked == true && record.Uri != null
select record.Uri).ToArray();
SaveSettings(uris);
//RootNodes is an ObservableCollection, it can't be enumerated iterativelly
var added = (from DirectoryRecord root in RootNodes
from DirectoryRecord record in root
where record.Added && record.Uri != null
select record.Uri).ToArray();
var removed = (from DirectoryRecord root in RootNodes
from DirectoryRecord record in root
where record.Removed && record.Uri != null
select record.Uri).ToArray();
//TODO: Include Uris for the containers as well
_events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
TryClose(true);
}
private void SaveSettings(IEnumerable uris)
{
var selections = uris.Select(uri => uri.ToString()).ToArray();
Account.SelectiveFolders.Clear();
Account.SelectiveFolders.AddRange(selections);
Settings.Default.Save();
}
public void RejectChanges()
{
TryClose(false);
}
}
}