X-Git-Url: https://code.grnet.gr/git/pithos-ms-client/blobdiff_plain/2e3aee00fb1040ff2e876396974c92653c023ebb..cbefd298922d7c0b603d65c1dfbd1fda788250f3:/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
diff --git a/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs b/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
index da83649..01c99c3 100644
--- a/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
+++ b/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
@@ -1,488 +1,708 @@
-#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)
- {
- _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);
-
- }
-
-
- #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);
-
- }
- }
- }
-}
+#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.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Forms;
+using Caliburn.Micro;
+using Pithos.Client.WPF.Configuration;
+using Pithos.Client.WPF.Properties;
+using Pithos.Client.WPF.SelectiveSynch;
+using Pithos.Client.WPF.Utils;
+using Pithos.Core;
+using Pithos.Interfaces;
+using System;
+using System.Linq;
+using Pithos.Network;
+using MessageBox = System.Windows.MessageBox;
+using Screen = Caliburn.Micro.Screen;
+
+namespace Pithos.Client.WPF.Preferences
+{
+ ///
+ /// The preferences screen displays user and account settings and updates the PithosMonitor
+ /// classes when account settings change.
+ ///
+ ///
+ /// The class is a single ViewModel for all Preferences tabs. It can be broken in separate
+ /// ViewModels, one for each tab.
+ ///
+ [Export, PartCreationPolicy(CreationPolicy.Shared)]
+ public class PreferencesViewModel : Screen
+ {
+ private readonly IEventAggregator _events;
+
+ //Logging in the Pithos client is provided by log4net
+ private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ 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)
+ {
+ // ReSharper disable DoNotCallOverridableMethodsInConstructor
+ //Caliburn.Micro uses DisplayName for the view's title
+ DisplayName = "Pithos+ Preferences";
+ // ReSharper restore DoNotCallOverridableMethodsInConstructor
+
+ _windowManager = windowManager;
+ _events = events;
+
+ Shell = shell;
+
+ Settings=settings;
+ Accounts = new ObservableConcurrentCollection();
+ if (settings.Accounts == null)
+ {
+ settings.Accounts=new AccountsCollection();
+ settings.Save();
+ }
+ var accountVMs = from account in settings.Accounts
+ select new AccountViewModel(account);
+
+ Accounts.AddFromEnumerable(accountVMs);
+
+ 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",Resources.PreferencesViewModel_StartupDelay_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.AccountKey];
+
+
+ var model = new SelectiveSynchViewModel(_events,CurrentAccount.Account,CurrentAccount.ApiKey);
+ if (_windowManager.ShowDialog(model) == true)
+ {
+
+ }
+ }
+
+ /* private bool _networkTracing;
+ public bool NetworkTracing
+ {
+ get { return _networkTracing; }
+ set
+ {
+ _networkTracing = value;
+
+ }
+ }*/
+
+ public void RefreshApiKey()
+ {
+ //_events.Publish(new Notification { Title = "Authorization failed", Message = "Your API Key has probably expired. You will be directed to a page where you can renew it", Level = TraceLevel.Error });
+ if (CurrentAccount == null)
+ return;
+ try
+ {
+
+ var name = CurrentAccount.AccountName;
+
+ var loginUri = new Uri(new Uri(CurrentAccount.ServerUrl), "login");
+ var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString(),name);
+ if (credentials==null)
+ return;
+ //The server will return credentials for a different account, not just the current account
+ //We need to find the correct account first
+ var account = Accounts.First(act => act.AccountName == credentials.UserName && act.ServerUrl == CurrentAccount.ServerUrl);
+ account.ApiKey = credentials.Password;
+ account.IsExpired = false;
+ Settings.Save();
+ TaskEx.Delay(10000).ContinueWith(_ =>Shell.MonitorAccount(account.Account));
+ NotifyOfPropertyChange(() => Accounts);
+ }
+ catch (AggregateException exc)
+ {
+ string message = String.Format("API Key retrieval failed");
+ Log.Error(message, exc.InnerException);
+ _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
+ }
+ catch (Exception exc)
+ {
+ string message = String.Format("API Key retrieval failed");
+ Log.Error(message, exc);
+ _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
+ }
+
+ }
+
+
+ public void OpenLogPath()
+ {
+ Shell.OpenLogPath();
+ }
+
+ public void OpenLogConsole()
+ {
+ var logView=IoC.Get();
+ _windowManager.ShowWindow(logView);
+ }
+
+ public void SaveChanges()
+ {
+ DoSave();
+ TryClose(true);
+ }
+
+ public void RejectChanges()
+ {
+ Settings.Reload();
+ TryClose(false);
+ }
+
+ public void ApplyChanges()
+ {
+ DoSave();
+ }
+
+ private void DoSave()
+ {
+ //SetStartupMode();
+
+ //Ensure we save the settings changes first
+ foreach (var account in _accountsToRemove)
+ {
+ Settings.Accounts.Remove(account);
+ }
+
+ foreach (var account in _accountsToAdd)
+ {
+ Settings.Accounts.Add(account);
+ }
+
+ Settings.Save();
+
+
+ try
+ {
+ foreach (var account in _accountsToRemove)
+ {
+ Shell.RemoveMonitor(account.ServerUrl, account.AccountName);
+ Shell.RemoveAccountFromDatabase(account);
+ }
+
+ foreach (var account in Settings.Accounts)
+ {
+ Shell.MonitorAccount(account);
+ }
+ }
+ finally
+ {
+ _accountsToRemove.Clear();
+ _accountsToAdd.Clear();
+ }
+
+ NotifyOfPropertyChange(()=>Settings);
+
+ if (IgnoreCertificateErrors)
+ ServicePointManager.ServerCertificateValidationCallback= (sender,certificate,chain,errors)=> true;
+ else
+ {
+ ServicePointManager.ServerCertificateValidationCallback = null;
+ }
+ }
+
+ /* 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);
+ }
+ }
+*/
+
+
+ readonly List _accountsToAdd=new List();
+ public void AddAccount()
+ {
+ var wizard = new AddAccountViewModel();
+ if (_windowManager.ShowDialog(wizard) == true)
+ {
+ string selectedPath = wizard.AccountPath;
+ var initialRootPath = wizard.ShouldCreateOkeanosFolder?
+ Path.Combine(selectedPath, "Okeanos")
+ :selectedPath;
+ var actualRootPath= initialRootPath;
+ if (wizard.ShouldCreateOkeanosFolder)
+ {
+ int attempt = 1;
+ while (Directory.Exists(actualRootPath) || File.Exists(actualRootPath))
+ {
+ actualRootPath = String.Format("{0} {1}", initialRootPath, attempt++);
+ }
+ }
+
+
+
+ var account = Accounts.FirstOrDefault(act => act.AccountName == wizard.AccountName && act.ServerUrl == wizard.CurrentServer);
+ if (account != null)
+ {
+ if (MessageBox.Show("The account you specified already exists. Do you want to update it?", "The account exists") == MessageBoxResult.Yes)
+ {
+ account.ApiKey = wizard.Token;
+ account.IsExpired = false;
+ CurrentAccount = account;
+ }
+ }
+ else
+ {
+ var newAccount = new AccountSettings
+ {
+ AccountName = wizard.AccountName,
+ ServerUrl = wizard.CurrentServer,
+ ApiKey = wizard.Token,
+ RootPath = actualRootPath,
+ IsActive = wizard.IsAccountActive,
+ };
+
+
+ var client = new CloudFilesClient(newAccount.AccountName, newAccount.ApiKey)
+ {
+ AuthenticationUrl = newAccount.ServerUrl, UsePithos = true
+ };
+ client.Authenticate();
+
+
+ var containers = client.ListContainers(newAccount.AccountName);
+ var containerUris = from container in containers
+ select String.Format(@"{0}/v1/{1}/{2}",
+ newAccount.ServerUrl, newAccount.AccountName, container.Name);
+
+ newAccount.SelectiveFolders.AddRange(containerUris.ToArray());
+
+ var objectInfos = (from container in containers
+ from dir in client.ListObjects(newAccount.AccountName, container.Name)
+ where container.Name != "trash"
+ select dir).ToList();
+ var tree = objectInfos.ToTree();
+
+ var selected = (from root in tree
+ from child in root
+ select child.Uri.ToString()).ToArray();
+ newAccount.SelectiveFolders.AddRange(selected);
+
+
+ //TODO:Add the "pithos" container as a default selection
+
+ _accountsToAdd.Add(newAccount);
+ var accountVm = new AccountViewModel(newAccount);
+ (Accounts as IProducerConsumerCollection).TryAdd(accountVm);
+ CurrentAccount = accountVm;
+ }
+ NotifyOfPropertyChange(() => Accounts);
+ NotifyOfPropertyChange(() => Settings);
+ }
+
+
+
+ }
+
+/*
+ public void AddPithosAccount()
+ {
+ var credentials=PithosAccount.RetrieveCredentials(null);
+ if (credentials == null)
+ return;
+ var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
+ var accountVM = new AccountViewModel(account);
+ if (account == null)
+ {
+ account=new AccountSettings{
+ AccountName=credentials.UserName,
+ ApiKey=credentials.Password
+ };
+ Settings.Accounts.Add(account);
+ accountVM = new AccountViewModel(account);
+ (Accounts as IProducerConsumerCollection).TryAdd(accountVM);
+ }
+ else
+ {
+ account.ApiKey=credentials.Password;
+ }
+ //SelectedAccountIndex= Settings.Accounts.IndexOf(account);
+ CurrentAccount = accountVM;
+ NotifyOfPropertyChange(() => Accounts);
+ NotifyOfPropertyChange(()=>Settings);
+ }
+*/
+
+
+ readonly List _accountsToRemove = new List();
+ public void RemoveAccount()
+ {
+ Accounts.TryRemove(CurrentAccount);
+ _accountsToRemove.Add(CurrentAccount.Account);
+
+ CurrentAccount = null;
+ NotifyOfPropertyChange(() => Accounts);
+
+
+ //NotifyOfPropertyChange("Settings.Accounts");
+ }
+
+ public bool CanRemoveAccount
+ {
+ get { return (CurrentAccount != null); }
+ }
+
+ public bool CanClearAccountCache
+ {
+ get { return (CurrentAccount != null); }
+ }
+
+ public void ClearAccountCache()
+ {
+ if (MessageBoxResult.Yes == MessageBox.Show("You are about to delete all partially downloaded files from the account's cache.\n" +
+ " You will have to download all partially downloaded data again\n" +
+ "This change can not be undone\n\n" +
+ "Do you wish to delete all partially downloaded data?", "Warning! Clearing account cache",
+ MessageBoxButton.YesNo,MessageBoxImage.Question,MessageBoxResult.No))
+ {
+
+ var cachePath = Path.Combine(CurrentAccount.RootPath, FolderConstants.CacheFolder);
+ var dir = new DirectoryInfo(cachePath);
+ //The file may not exist if we just created the account
+ if (!dir.Exists)
+ return;
+ dir.EnumerateFiles().Apply(file=>file.Delete());
+ dir.EnumerateDirectories().Apply(folder => folder.Delete(true));
+ }
+ }
+
+
+ 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);
+ }
+ }
+
+ public bool DebugLoggingEnabled
+ {
+ get { return Settings.DebugLoggingEnabled; }
+ set {
+ Settings.DebugLoggingEnabled = value;
+ NotifyOfPropertyChange(()=>DebugLoggingEnabled);
+ }
+ }
+
+ public bool IgnoreCertificateErrors
+ {
+ get { return Settings.IgnoreCertificateErrors; }
+ set {
+ Settings.IgnoreCertificateErrors = value;
+ NotifyOfPropertyChange(() => IgnoreCertificateErrors);
+ }
+ }
+
+ #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 AccountViewModel _currentAccount;
+ private readonly IWindowManager _windowManager;
+ private readonly string _shortcutPath;
+
+
+
+ public AccountViewModel CurrentAccount
+ {
+ get { return _currentAccount; }
+ set
+ {
+ _currentAccount = value;
+ NotifyOfPropertyChange(()=>CurrentAccount);
+ NotifyOfPropertyChange(() => CanRemoveAccount);
+ NotifyOfPropertyChange(() => CanSelectiveSyncFolders);
+ NotifyOfPropertyChange(() => CanMoveAccountFolder);
+ NotifyOfPropertyChange(() => CanClearAccountCache);
+ }
+ }
+
+/*
+ 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.AccountKey, 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));
+
+ Log.InfoFormat("Deleting account folder {0}",oldPath);
+ Directory.Delete(oldPath, true);
+
+ //We also need to change the path of the existing file states
+ 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.Account);
+ //Finally, notify that the Settings, CurrentAccount have changed
+ NotifyOfPropertyChange(() => CurrentAccount);
+ NotifyOfPropertyChange(() => Settings);
+
+ }
+ }
+ }
+}