#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); } } } }