X-Git-Url: https://code.grnet.gr/git/pithos-ms-client/blobdiff_plain/6aa29f4fca0f3d139c45c0392148f4d3a1bd8607..84a3db1b645b989f2c512b66ab8097deb7316b5a:/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 1a9602f..2857dc8 100644
--- a/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
+++ b/trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
@@ -1,39 +1,82 @@
-// -----------------------------------------------------------------------
-//
-// TODO: Update copyright text.
-//
-// -----------------------------------------------------------------------
+#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.ComponentModel.Composition;
+using System.Diagnostics;
using System.IO;
using System.Reflection;
+using System.Threading.Tasks;
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.Properties;
using Pithos.Client.WPF.SelectiveSynch;
using Pithos.Core;
using Pithos.Interfaces;
-using File = System.IO.File;
+using System;
+using System.Linq;
using Screen = Caliburn.Micro.Screen;
-namespace Pithos.Client.WPF
+namespace Pithos.Client.WPF.Preferences
{
- using System;
- using System.Linq;
- using System.Threading.Tasks;
-
///
- /// TODO: Update summary.
+ /// 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]
public class PreferencesViewModel : Screen
{
- private IEventAggregator _events;
+ 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
@@ -46,8 +89,8 @@ namespace Pithos.Client.WPF
}
}
- private ObservableConcurrentCollection _accounts;
- public ObservableConcurrentCollection Accounts
+ private ObservableConcurrentCollection _accounts;
+ public ObservableConcurrentCollection Accounts
{
get { return _accounts; }
set
@@ -59,33 +102,32 @@ namespace Pithos.Client.WPF
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)
+ 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;
- DisplayName = "Pithos Preferences";
Shell = shell;
-
+
Settings=settings;
- Accounts = new ObservableConcurrentCollection();
- Accounts.AddFromEnumerable(settings.Accounts);
+ 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");
@@ -93,9 +135,26 @@ namespace Pithos.Client.WPF
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;
@@ -136,6 +195,18 @@ namespace Pithos.Client.WPF
}
#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
@@ -147,15 +218,65 @@ namespace Pithos.Client.WPF
public void SelectiveSyncFolders()
{
var monitor = Shell.Monitors[CurrentAccount.AccountName];
- var folders=monitor.GetRootFolders();
+
- var model = new SelectiveSynchViewModel(folders,_events,CurrentAccount);
+ var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount.Account);
if (_windowManager.ShowDialog(model) == true)
{
}
}
+
+ 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 == ?? );
+ 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();
@@ -175,29 +296,42 @@ namespace Pithos.Client.WPF
private void DoSave()
{
- Settings.Save();
- SetStartupMode();
+ //SetStartupMode();
+ //Ensure we save the settings changes first
+ foreach (var account in _accountsToRemove)
+ {
+ Settings.Accounts.Remove(account);
+ }
- foreach (var account in Settings.Accounts)
- {
- Shell.MonitorAccount(account);
+ foreach (var account in _accountsToAdd)
+ {
+ Settings.Accounts.Add(account);
}
- NotifyOfPropertyChange(()=>Settings);
- }
+ Settings.Save();
- private void SetStartupMode()
- {
- if (StartOnSystemStartup && !File.Exists(_shortcutPath))
+
+ try
{
- CreateShortcut(_shortcutPath);
- }
- else if (!StartOnSystemStartup && File.Exists(_shortcutPath))
+ foreach (var account in _accountsToRemove)
+ {
+ Shell.RemoveMonitor(account.AccountName);
+ Shell.RemoveAccountFromDatabase(account);
+ }
+
+ foreach (var account in Settings.Accounts)
+ {
+ Shell.MonitorAccount(account);
+ }
+ }
+ finally
{
- if (File.Exists(_shortcutPath))
- File.Delete(_shortcutPath);
+ _accountsToRemove.Clear();
+ _accountsToAdd.Clear();
}
+
+ NotifyOfPropertyChange(()=>Settings);
}
/* public void ChangePithosFolder()
@@ -224,22 +358,41 @@ namespace Pithos.Client.WPF
}
}
*/
+
+
+ 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++);
+ }
+ }
+ ### Check that the account does not already exist
+
var newAccount = new AccountSettings
{
AccountName = wizard.AccountName,
+ ServerUrl=wizard.CurrentServer,
ApiKey=wizard.Token,
- RootPath=wizard.AccountPath,
- IsActive=wizard.IsAccountActive,
- UsePithos=true
+ RootPath = actualRootPath,
+ IsActive=wizard.IsAccountActive
};
- Settings.Accounts.Add(newAccount);
- (Accounts as IProducerConsumerCollection).TryAdd(newAccount);
- CurrentAccount = newAccount;
+ _accountsToAdd.Add(newAccount);
+ var accountVm = new AccountViewModel(newAccount);
+ (Accounts as IProducerConsumerCollection).TryAdd(accountVm);
+ CurrentAccount = accountVm;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(() => Settings);
}
@@ -248,44 +401,45 @@ namespace Pithos.Client.WPF
}
- public async void AddPithosAccount()
+/*
+ public void AddPithosAccount()
{
- var credentials=await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
+ 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,
- UsePithos=true
+ ApiKey=credentials.Password
};
Settings.Accounts.Add(account);
- (Accounts as IProducerConsumerCollection).TryAdd(account);
+ accountVM = new AccountViewModel(account);
+ (Accounts as IProducerConsumerCollection).TryAdd(accountVM);
}
else
{
account.ApiKey=credentials.Password;
}
//SelectedAccountIndex= Settings.Accounts.IndexOf(account);
- CurrentAccount = account;
+ CurrentAccount = accountVM;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(()=>Settings);
}
+*/
+
+ readonly List _accountsToRemove = new List();
public void RemoveAccount()
{
- var accountName = CurrentAccount.AccountName;
- Settings.Accounts.Remove(CurrentAccount);
-
Accounts.TryRemove(CurrentAccount);
-
-
+ _accountsToRemove.Add(CurrentAccount.Account);
+
CurrentAccount = null;
- //Accounts = Settings.Accounts;
- //Settings.Save();
- Shell.RemoveMonitor(accountName);
NotifyOfPropertyChange(() => Accounts);
- NotifyOfPropertyChange(() => Settings);
+
//NotifyOfPropertyChange("Settings.Accounts");
}
@@ -319,6 +473,14 @@ namespace Pithos.Client.WPF
}
}
+ public bool DebugLoggingEnabled
+ {
+ get { return Settings.DebugLoggingEnabled; }
+ set {
+ Settings.DebugLoggingEnabled = value;
+ NotifyOfPropertyChange(()=>DebugLoggingEnabled);
+ }
+ }
#endregion
@@ -342,13 +504,13 @@ namespace Pithos.Client.WPF
}
}*/
- private AccountSettings _currentAccount;
- private IWindowManager _windowManager;
- private string _shortcutPath;
+ private AccountViewModel _currentAccount;
+ private readonly IWindowManager _windowManager;
+ private readonly string _shortcutPath;
- public AccountSettings CurrentAccount
+ public AccountViewModel CurrentAccount
{
get { return _currentAccount; }
set
@@ -416,11 +578,11 @@ namespace Pithos.Client.WPF
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
- if (monitor != null)
- monitor.MoveFileStates(oldPath, newPath);
+ monitor.MoveFileStates(oldPath, newPath);
}
}
//Replace the old rootpath with the new
@@ -435,7 +597,7 @@ namespace Pithos.Client.WPF
monitor.Start();
}
else
- Shell.MonitorAccount(CurrentAccount);
+ Shell.MonitorAccount(CurrentAccount.Account);
//Finally, notify that the Settings, CurrentAccount have changed
NotifyOfPropertyChange(() => CurrentAccount);
NotifyOfPropertyChange(() => Settings);