#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.Concurrent;
using System.ComponentModel.Composition;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using Caliburn.Micro;
using Pithos.Client.WPF.Configuration;
using Pithos.Client.WPF.SelectiveSynch;
using Pithos.Core;
using Pithos.Interfaces;
using System;
using System.Linq;
using Screen = Caliburn.Micro.Screen;
namespace Pithos.Client.WPF.Preferences
{
///
/// TODO: Update summary.
///
[Export]
public class PreferencesViewModel : Screen
{
private IEventAggregator _events;
private PithosSettings _settings;
public PithosSettings Settings
{
get { return _settings; }
set
{
_settings = value;
NotifyOfPropertyChange(()=>Settings);
}
}
private ObservableConcurrentCollection _accounts;
public ObservableConcurrentCollection Accounts
{
get { return _accounts; }
set
{
_accounts = value;
NotifyOfPropertyChange(()=>Accounts);
}
}
public bool StartOnSystemStartup { get; set; }
public ShellViewModel Shell { get; set; }
//ShellExtensionController _extensionController=new ShellExtensionController();
public PreferencesViewModel(IWindowManager windowManager, IEventAggregator events, ShellViewModel shell, PithosSettings settings, string currentTab)
{
_windowManager = windowManager;
_events = events;
DisplayName = "Pithos Preferences";
Shell = shell;
Settings=settings;
Accounts = new ObservableConcurrentCollection();
if (settings.Accounts == null)
{
settings.Accounts=new AccountsCollection();
settings.Save();
}
Accounts.AddFromEnumerable(settings.Accounts);
var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
_shortcutPath = Path.Combine(startupPath, "Pithos.lnk");
StartOnSystemStartup = File.Exists(_shortcutPath);
SelectedTab = currentTab;
}
private string _selectedTab="General";
public string SelectedTab
{
get { return _selectedTab; }
set
{
_selectedTab = value??"General";
NotifyOfPropertyChange(()=>SelectedTab);
NotifyOfPropertyChange(() => AccountTabSelected);
}
}
public bool AccountTabSelected
{
get { return _selectedTab == "AccountTab"; }
}
#region Preferences Properties
private bool _noProxy;
public bool NoProxy
{
get { return _noProxy; }
set
{
_noProxy = value;
NotifyOfPropertyChange(()=>NoProxy);
}
}
private bool _defaultProxy;
public bool DefaultProxy
{
get { return _defaultProxy; }
set
{
_defaultProxy = value;
NotifyOfPropertyChange(() => DefaultProxy);
}
}
private bool _manualProxy;
public bool ManualProxy
{
get { return _manualProxy; }
set
{
_manualProxy = value;
NotifyOfPropertyChange(() => ManualProxy);
}
}
#endregion
public int StartupDelay
{
get { return (int) Settings.StartupDelay.TotalMinutes; }
set
{
if (value<0)
throw new ArgumentOutOfRangeException("value","The Startup Delay must be greater or equal to 0");
Settings.StartupDelay = TimeSpan.FromMinutes(value);
NotifyOfPropertyChange(()=>StartupDelay);
}
}
#region Commands
public bool CanSelectiveSyncFolders
{
get { return CurrentAccount != null; }
}
public void SelectiveSyncFolders()
{
var monitor = Shell.Monitors[CurrentAccount.AccountName];
var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount);
if (_windowManager.ShowDialog(model) == true)
{
}
}
public async Task RefreshApiKey()
{
await Shell.TryAuthorize(CurrentAccount.AccountName, 3);
NotifyOfPropertyChange(()=>CurrentAccount);
}
public void SaveChanges()
{
DoSave();
TryClose(true);
}
public void RejectChanges()
{
Settings.Reload();
TryClose(false);
}
public void ApplyChanges()
{
DoSave();
}
private void DoSave()
{
Settings.Save();
//SetStartupMode();
foreach (var account in Settings.Accounts)
{
Shell.MonitorAccount(account);
}
NotifyOfPropertyChange(()=>Settings);
}
/* public void ChangePithosFolder()
{
var browser = new FolderBrowserDialog();
browser.SelectedPath = Settings.PithosPath;
var result = browser.ShowDialog((IWin32Window)GetView());
if (result == DialogResult.OK)
{
var newPath = browser.SelectedPath;
var accountName = CurrentAccount.AccountName;
var monitor = Shell.Monitors[accountName];
monitor.Stop();
Shell.Monitors.Remove(accountName);
Directory.Move(Settings.PithosPath, newPath);
Settings.PithosPath = newPath;
Settings.Save();
Shell.MonitorAccount(CurrentAccount);
NotifyOfPropertyChange(() => Settings);
}
}
*/
public void AddAccount()
{
var wizard = new AddAccountViewModel();
if (_windowManager.ShowDialog(wizard) == true)
{
string selectedPath = wizard.AccountPath;
var initialRootPath = Path.Combine(selectedPath, "Okeanos");
var actualRootPath= initialRootPath;
int attempt = 1;
while (Directory.Exists(actualRootPath) || File.Exists(actualRootPath))
{
actualRootPath = String.Format("{0} {1}", initialRootPath,attempt++);
}
var newAccount = new AccountSettings
{
AccountName = wizard.AccountName,
ServerUrl=wizard.CurrentServer,
ApiKey=wizard.Token,
RootPath = actualRootPath,
IsActive=wizard.IsAccountActive
};
Settings.Accounts.Add(newAccount);
(Accounts as IProducerConsumerCollection).TryAdd(newAccount);
CurrentAccount = newAccount;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(() => Settings);
}
}
public async void AddPithosAccount()
{
var credentials=await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
if (account == null)
{
account=new AccountSettings{
AccountName=credentials.UserName,
ApiKey=credentials.Password
};
Settings.Accounts.Add(account);
(Accounts as IProducerConsumerCollection).TryAdd(account);
}
else
{
account.ApiKey=credentials.Password;
}
//SelectedAccountIndex= Settings.Accounts.IndexOf(account);
CurrentAccount = account;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(()=>Settings);
}
public void RemoveAccount()
{
var accountName = CurrentAccount.AccountName;
Settings.Accounts.Remove(CurrentAccount);
Accounts.TryRemove(CurrentAccount);
CurrentAccount = null;
//Accounts = Settings.Accounts;
//Settings.Save();
Shell.RemoveMonitor(accountName);
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(() => Settings);
//NotifyOfPropertyChange("Settings.Accounts");
}
public bool CanRemoveAccount
{
get { return (CurrentAccount != null); }
}
public bool ExtensionsActivated
{
get { return Settings.ExtensionsActivated; }
set
{
if (Settings.ExtensionsActivated == value)
return;
Settings.ExtensionsActivated = value;
/*
if (value)
_extensionController.RegisterExtensions();
else
{
_extensionController.UnregisterExtensions();
}
*/
NotifyOfPropertyChange(() => ExtensionsActivated);
}
}
#endregion
/* private int _selectedAccountIndex;
public int SelectedAccountIndex
{
get { return _selectedAccountIndex; }
set
{
//var accountCount=Settings.Accounts.Count;
//if (accountCount == 0)
// return;
//if (0 <= value && value < accountCount)
// _selectedAccountIndex = value;
//else
// _selectedAccountIndex = 0;
_selectedAccountIndex = value;
NotifyOfPropertyChange(() => CurrentAccount);
NotifyOfPropertyChange(() => CanRemoveAccount);
NotifyOfPropertyChange(()=>SelectedAccountIndex);
}
}*/
private AccountSettings _currentAccount;
private IWindowManager _windowManager;
private string _shortcutPath;
public AccountSettings CurrentAccount
{
get { return _currentAccount; }
set
{
_currentAccount = value;
NotifyOfPropertyChange(()=>CurrentAccount);
NotifyOfPropertyChange(() => CanRemoveAccount);
NotifyOfPropertyChange(() => CanSelectiveSyncFolders);
NotifyOfPropertyChange(() => CanMoveAccountFolder);
}
}
/*
public AccountSettings CurrentAccount
{
get {
if (0 <= SelectedAccountIndex && SelectedAccountIndex < Settings.Accounts.Count)
return Settings.Accounts[SelectedAccountIndex];
return null;
}
}
*/
public bool CanMoveAccountFolder
{
get { return CurrentAccount != null; }
}
public void MoveAccountFolder()
{
using (var dlg = new FolderBrowserDialog())
{
var currentFolder = CurrentAccount.RootPath;
dlg.SelectedPath = currentFolder;
//Ask the user to select a folder
//Note: We need a parent window here, which we retrieve with GetView
var view = (Window)GetView();
if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
return;
var newPath= dlg.SelectedPath;
//Find the account's monitor and stop it
PithosMonitor monitor;
if (Shell.Monitors.TryGetValue(CurrentAccount.AccountName, out monitor))
{
monitor.Stop();
var oldPath = monitor.RootPath;
//The old directory may not exist eg. if we create an account for the first time
if (Directory.Exists(oldPath))
{
//If it does, do the move
//Now Create all of the directories
foreach (string dirPath in Directory.EnumerateDirectories(oldPath, "*",
SearchOption.AllDirectories))
Directory.CreateDirectory(dirPath.Replace(oldPath, newPath));
//Copy all the files
foreach (string newFilePath in Directory.EnumerateFiles(oldPath, "*.*",
SearchOption.AllDirectories))
File.Copy(newFilePath, newFilePath.Replace(oldPath, newPath));
Directory.Delete(oldPath, true);
//We also need to change the path of the existing file states
if (monitor != null)
monitor.MoveFileStates(oldPath, newPath);
}
}
//Replace the old rootpath with the new
CurrentAccount.RootPath = newPath;
//TODO: This will save all settings changes. Too coarse grained, need to fix at a later date
Settings.Save();
//And start the monitor on the new RootPath
if (monitor != null)
{
monitor.RootPath = newPath;
if (CurrentAccount.IsActive)
monitor.Start();
}
else
Shell.MonitorAccount(CurrentAccount);
//Finally, notify that the Settings, CurrentAccount have changed
NotifyOfPropertyChange(() => CurrentAccount);
NotifyOfPropertyChange(() => Settings);
}
}
}
}