#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; namespace Pithos.Client.WPF.SelectiveSynch { class SelectiveSynchViewModel:Screen { private const string DirectoryType = "application/directory"; 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; 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) { Account = account; AccountName = account.AccountName; DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName); _monitor = monitor; _events = events; TaskEx.Run(LoadRootNode); } private void LoadRootNode() { var client = _monitor.CloudClient; var dirs = from container in client.ListContainers(_monitor.UserName) 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(_monitor.UserName, container.Name) where dir.Content_Type == DirectoryType 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.Content_Type==DirectoryType 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(); 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.IsChecked=false); 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); } } }