// -----------------------------------------------------------------------
//
// TODO: Update copyright text.
//
// -----------------------------------------------------------------------
using System.Collections.Concurrent;
using System.ComponentModel.Composition;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Forms;
using Caliburn.Micro;
using IWshRuntimeLibrary;
using Pithos.Client.WPF.Configuration;
using Pithos.Client.WPF.Preferences;
using Pithos.Client.WPF.SelectiveSynch;
using Pithos.Core;
using Pithos.Interfaces;
using File = System.IO.File;
using Screen = Caliburn.Micro.Screen;
namespace Pithos.Client.WPF
{
using System;
using System.Linq;
using System.Threading.Tasks;
///
/// 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; }
private static void CreateShortcut(string shortcutPath)
{
var wshShell = new WshShellClass();
var shortcut = (IWshRuntimeLibrary.IWshShortcut) wshShell.CreateShortcut(
shortcutPath);
var exePath = Assembly.GetExecutingAssembly().Location;
shortcut.TargetPath = exePath;
shortcut.WorkingDirectory = Path.GetDirectoryName(exePath);
shortcut.Description = "Pithos";
shortcut.Save();
}
public ShellViewModel Shell { get; set; }
//ShellExtensionController _extensionController=new ShellExtensionController();
public PreferencesViewModel(IWindowManager windowManager, IEventAggregator events, ShellViewModel shell, PithosSettings settings)
{
_windowManager = windowManager;
_events = events;
DisplayName = "Pithos Preferences";
Shell = shell;
Settings=settings;
Accounts = new ObservableConcurrentCollection();
Accounts.AddFromEnumerable(settings.Accounts);
var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
_shortcutPath = Path.Combine(startupPath, "Pithos.lnk");
StartOnSystemStartup = File.Exists(_shortcutPath);
}
#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
#region Commands
public bool CanSelectiveSyncFolders
{
get { return CurrentAccount != null; }
}
public void SelectiveSyncFolders()
{
var monitor = Shell.Monitors[CurrentAccount.AccountName];
var folders=monitor.GetRootFolders();
var model = new SelectiveSynchViewModel(folders,_events,CurrentAccount);
if (_windowManager.ShowDialog(model) == true)
{
}
}
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);
}
private void SetStartupMode()
{
if (StartOnSystemStartup && !File.Exists(_shortcutPath))
{
CreateShortcut(_shortcutPath);
}
else if (!StartOnSystemStartup && File.Exists(_shortcutPath))
{
if (File.Exists(_shortcutPath))
File.Delete(_shortcutPath);
}
}
/* 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)
{
var newAccount = new AccountSettings
{
AccountName = wizard.AccountName,
ApiKey=wizard.Token,
RootPath=wizard.AccountPath,
IsActive=wizard.IsAccountActive,
UsePithos=true
};
Settings.Accounts.Add(newAccount);
(Accounts as IProducerConsumerCollection).TryAdd(newAccount);
CurrentAccount = newAccount;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(() => Settings);
}
}
public async void AddPithosAccount()
{
var credentials=await PithosAccount.RetrieveCredentialsAsync(Settings.PithosLoginUrl);
var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
if (account == null)
{
account=new AccountSettings{
AccountName=credentials.UserName,
ApiKey=credentials.Password,
UsePithos=true
};
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("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);
}
}
}
}