1 // -----------------------------------------------------------------------
2 // <copyright file="PreferencesViewModel.cs" company="Microsoft">
3 // TODO: Update copyright text.
5 // -----------------------------------------------------------------------
7 using System.Collections.Concurrent;
8 using System.ComponentModel.Composition;
10 using System.Reflection;
12 using System.Windows.Forms;
14 using IWshRuntimeLibrary;
15 using Pithos.Client.WPF.Configuration;
16 using Pithos.Client.WPF.Preferences;
17 using Pithos.Client.WPF.SelectiveSynch;
19 using Pithos.Interfaces;
20 using File = System.IO.File;
21 using Screen = Caliburn.Micro.Screen;
23 namespace Pithos.Client.WPF
27 using System.Threading.Tasks;
30 /// TODO: Update summary.
33 public class PreferencesViewModel : Screen
35 private IEventAggregator _events;
38 private PithosSettings _settings;
39 public PithosSettings Settings
41 get { return _settings; }
45 NotifyOfPropertyChange(()=>Settings);
49 private ObservableConcurrentCollection<AccountSettings> _accounts;
50 public ObservableConcurrentCollection<AccountSettings> Accounts
52 get { return _accounts; }
56 NotifyOfPropertyChange(()=>Accounts);
60 public bool StartOnSystemStartup { get; set; }
62 private static void CreateShortcut(string shortcutPath)
64 var wshShell = new WshShellClass();
65 var shortcut = (IWshRuntimeLibrary.IWshShortcut) wshShell.CreateShortcut(
68 var exePath = Assembly.GetExecutingAssembly().Location;
69 shortcut.TargetPath = exePath;
70 shortcut.WorkingDirectory = Path.GetDirectoryName(exePath);
71 shortcut.Description = "Pithos";
75 public ShellViewModel Shell { get; set; }
76 //ShellExtensionController _extensionController=new ShellExtensionController();
78 public PreferencesViewModel(IWindowManager windowManager, IEventAggregator events, ShellViewModel shell, PithosSettings settings)
80 _windowManager = windowManager;
83 DisplayName = "Pithos Preferences";
87 Accounts = new ObservableConcurrentCollection<AccountSettings>();
88 Accounts.AddFromEnumerable(settings.Accounts);
90 var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
91 _shortcutPath = Path.Combine(startupPath, "Pithos.lnk");
94 StartOnSystemStartup = File.Exists(_shortcutPath);
99 #region Preferences Properties
101 private bool _noProxy;
104 get { return _noProxy; }
108 NotifyOfPropertyChange(()=>NoProxy);
113 private bool _defaultProxy;
115 public bool DefaultProxy
117 get { return _defaultProxy; }
120 _defaultProxy = value;
121 NotifyOfPropertyChange(() => DefaultProxy);
126 private bool _manualProxy;
128 public bool ManualProxy
130 get { return _manualProxy; }
133 _manualProxy = value;
134 NotifyOfPropertyChange(() => ManualProxy);
142 public bool CanSelectiveSyncFolders
144 get { return CurrentAccount != null; }
147 public void SelectiveSyncFolders()
149 var monitor = Shell.Monitors[CurrentAccount.AccountName];
150 var folders=monitor.GetRootFolders();
152 var model = new SelectiveSynchViewModel(folders,_events,CurrentAccount);
153 if (_windowManager.ShowDialog(model) == true)
159 public void SaveChanges()
165 public void RejectChanges()
171 public void ApplyChanges()
176 private void DoSave()
182 foreach (var account in Settings.Accounts)
184 Shell.MonitorAccount(account);
187 NotifyOfPropertyChange(()=>Settings);
190 private void SetStartupMode()
192 if (StartOnSystemStartup && !File.Exists(_shortcutPath))
194 CreateShortcut(_shortcutPath);
196 else if (!StartOnSystemStartup && File.Exists(_shortcutPath))
198 if (File.Exists(_shortcutPath))
199 File.Delete(_shortcutPath);
203 /* public void ChangePithosFolder()
205 var browser = new FolderBrowserDialog();
206 browser.SelectedPath = Settings.PithosPath;
207 var result = browser.ShowDialog((IWin32Window)GetView());
208 if (result == DialogResult.OK)
210 var newPath = browser.SelectedPath;
211 var accountName = CurrentAccount.AccountName;
212 var monitor = Shell.Monitors[accountName];
215 Shell.Monitors.Remove(accountName);
217 Directory.Move(Settings.PithosPath, newPath);
218 Settings.PithosPath = newPath;
221 Shell.MonitorAccount(CurrentAccount);
223 NotifyOfPropertyChange(() => Settings);
227 public void AddAccount()
229 var wizard = new AddAccountViewModel();
230 if (_windowManager.ShowDialog(wizard) == true)
232 var newAccount = new AccountSettings
234 AccountName = wizard.AccountName,
236 RootPath=wizard.AccountPath,
237 IsActive=wizard.IsAccountActive,
240 Settings.Accounts.Add(newAccount);
241 (Accounts as IProducerConsumerCollection<AccountSettings>).TryAdd(newAccount);
242 CurrentAccount = newAccount;
243 NotifyOfPropertyChange(() => Accounts);
244 NotifyOfPropertyChange(() => Settings);
251 public async void AddPithosAccount()
253 var credentials=await PithosAccount.RetrieveCredentialsAsync(Settings.PithosLoginUrl);
254 var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
257 account=new AccountSettings{
258 AccountName=credentials.UserName,
259 ApiKey=credentials.Password,
262 Settings.Accounts.Add(account);
263 (Accounts as IProducerConsumerCollection<AccountSettings>).TryAdd(account);
267 account.ApiKey=credentials.Password;
269 //SelectedAccountIndex= Settings.Accounts.IndexOf(account);
270 CurrentAccount = account;
271 NotifyOfPropertyChange(() => Accounts);
272 NotifyOfPropertyChange(()=>Settings);
275 public void RemoveAccount()
277 var accountName = CurrentAccount.AccountName;
278 Settings.Accounts.Remove(CurrentAccount);
280 Accounts.TryRemove(CurrentAccount);
283 CurrentAccount = null;
284 //Accounts = Settings.Accounts;
286 Shell.RemoveMonitor(accountName);
288 //NotifyOfPropertyChange("Settings.Accounts");
291 public bool CanRemoveAccount
293 get { return (CurrentAccount != null); }
298 public bool ExtensionsActivated
300 get { return Settings.ExtensionsActivated; }
303 if (Settings.ExtensionsActivated == value)
306 Settings.ExtensionsActivated = value;
310 _extensionController.RegisterExtensions();
313 _extensionController.UnregisterExtensions();
316 NotifyOfPropertyChange(() => ExtensionsActivated);
323 /* private int _selectedAccountIndex;
324 public int SelectedAccountIndex
326 get { return _selectedAccountIndex; }
329 //var accountCount=Settings.Accounts.Count;
330 //if (accountCount == 0)
332 //if (0 <= value && value < accountCount)
333 // _selectedAccountIndex = value;
335 // _selectedAccountIndex = 0;
336 _selectedAccountIndex = value;
337 NotifyOfPropertyChange(() => CurrentAccount);
338 NotifyOfPropertyChange(() => CanRemoveAccount);
339 NotifyOfPropertyChange(()=>SelectedAccountIndex);
343 private AccountSettings _currentAccount;
344 private IWindowManager _windowManager;
345 private string _shortcutPath;
349 public AccountSettings CurrentAccount
351 get { return _currentAccount; }
354 _currentAccount = value;
355 NotifyOfPropertyChange(()=>CurrentAccount);
356 NotifyOfPropertyChange(() => CanRemoveAccount);
357 NotifyOfPropertyChange(() => CanSelectiveSyncFolders);
358 NotifyOfPropertyChange(() => CanMoveAccountFolder);
363 public AccountSettings CurrentAccount
366 if (0 <= SelectedAccountIndex && SelectedAccountIndex < Settings.Accounts.Count)
367 return Settings.Accounts[SelectedAccountIndex];
375 public bool CanMoveAccountFolder
377 get { return CurrentAccount != null; }
380 public void MoveAccountFolder()
383 using (var dlg = new FolderBrowserDialog())
385 var currentFolder = CurrentAccount.RootPath;
386 dlg.SelectedPath = currentFolder;
387 //Ask the user to select a folder
388 //Note: We need a parent window here, which we retrieve with GetView
389 var view = (Window)GetView();
390 if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
393 var newPath= dlg.SelectedPath;
394 //Find the account's monitor and stop it
395 PithosMonitor monitor;
396 if (Shell.Monitors.TryGetValue(CurrentAccount.AccountName, out monitor))
401 var oldPath = monitor.RootPath;
402 //The old directory may not exist eg. if we create an account for the first time
403 if (Directory.Exists(oldPath))
405 //If it does, do the move
407 //Now Create all of the directories
408 foreach (string dirPath in Directory.EnumerateDirectories(oldPath, "*",
409 SearchOption.AllDirectories))
410 Directory.CreateDirectory(dirPath.Replace(oldPath, newPath));
413 foreach (string newFilePath in Directory.EnumerateFiles(oldPath, "*.*",
414 SearchOption.AllDirectories))
415 File.Copy(newFilePath, newFilePath.Replace(oldPath, newPath));
417 Directory.Delete(oldPath, true);
419 //We also need to change the path of the existing file states
421 monitor.MoveFileStates(oldPath, newPath);
424 //Replace the old rootpath with the new
425 CurrentAccount.RootPath = newPath;
426 //TODO: This will save all settings changes. Too coarse grained, need to fix at a later date
428 //And start the monitor on the new RootPath
431 monitor.RootPath = newPath;
432 if (CurrentAccount.IsActive)
436 Shell.MonitorAccount(CurrentAccount);
437 //Finally, notify that the Settings, CurrentAccount have changed
438 NotifyOfPropertyChange(() => CurrentAccount);
439 NotifyOfPropertyChange(() => Settings);