Statistics
| Branch: | Revision:

root / trunk / Pithos.Client.WPF / Shell / ShellViewModel.cs @ 174bbb6e

History | View | Annotate | Download (29 kB)

1 255f5f86 Panagiotis Kanavos
#region
2 255f5f86 Panagiotis Kanavos
/* -----------------------------------------------------------------------
3 255f5f86 Panagiotis Kanavos
 * <copyright file="ShellViewModel.cs" company="GRNet">
4 255f5f86 Panagiotis Kanavos
 * 
5 255f5f86 Panagiotis Kanavos
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
6 255f5f86 Panagiotis Kanavos
 *
7 255f5f86 Panagiotis Kanavos
 * Redistribution and use in source and binary forms, with or
8 255f5f86 Panagiotis Kanavos
 * without modification, are permitted provided that the following
9 255f5f86 Panagiotis Kanavos
 * conditions are met:
10 255f5f86 Panagiotis Kanavos
 *
11 255f5f86 Panagiotis Kanavos
 *   1. Redistributions of source code must retain the above
12 255f5f86 Panagiotis Kanavos
 *      copyright notice, this list of conditions and the following
13 255f5f86 Panagiotis Kanavos
 *      disclaimer.
14 255f5f86 Panagiotis Kanavos
 *
15 255f5f86 Panagiotis Kanavos
 *   2. Redistributions in binary form must reproduce the above
16 255f5f86 Panagiotis Kanavos
 *      copyright notice, this list of conditions and the following
17 255f5f86 Panagiotis Kanavos
 *      disclaimer in the documentation and/or other materials
18 255f5f86 Panagiotis Kanavos
 *      provided with the distribution.
19 255f5f86 Panagiotis Kanavos
 *
20 255f5f86 Panagiotis Kanavos
 *
21 255f5f86 Panagiotis Kanavos
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22 255f5f86 Panagiotis Kanavos
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 255f5f86 Panagiotis Kanavos
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 255f5f86 Panagiotis Kanavos
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25 255f5f86 Panagiotis Kanavos
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 255f5f86 Panagiotis Kanavos
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 255f5f86 Panagiotis Kanavos
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 255f5f86 Panagiotis Kanavos
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 255f5f86 Panagiotis Kanavos
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 255f5f86 Panagiotis Kanavos
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 255f5f86 Panagiotis Kanavos
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 255f5f86 Panagiotis Kanavos
 * POSSIBILITY OF SUCH DAMAGE.
33 255f5f86 Panagiotis Kanavos
 *
34 255f5f86 Panagiotis Kanavos
 * The views and conclusions contained in the software and
35 255f5f86 Panagiotis Kanavos
 * documentation are those of the authors and should not be
36 255f5f86 Panagiotis Kanavos
 * interpreted as representing official policies, either expressed
37 255f5f86 Panagiotis Kanavos
 * or implied, of GRNET S.A.
38 255f5f86 Panagiotis Kanavos
 * </copyright>
39 255f5f86 Panagiotis Kanavos
 * -----------------------------------------------------------------------
40 255f5f86 Panagiotis Kanavos
 */
41 255f5f86 Panagiotis Kanavos
#endregion
42 255f5f86 Panagiotis Kanavos
using System.Collections.Concurrent;
43 c53aa229 Panagiotis Kanavos
using System.Diagnostics;
44 c28a075a Panagiotis Kanavos
using System.Diagnostics.Contracts;
45 c53aa229 Panagiotis Kanavos
using System.IO;
46 c28a075a Panagiotis Kanavos
using System.Net;
47 d17258c2 Panagiotis Kanavos
using System.Reflection;
48 c53aa229 Panagiotis Kanavos
using System.Runtime.InteropServices;
49 c53aa229 Panagiotis Kanavos
using System.ServiceModel;
50 c53aa229 Panagiotis Kanavos
using System.Threading.Tasks;
51 c53aa229 Panagiotis Kanavos
using System.Windows;
52 fb9d6e00 Panagiotis Kanavos
using System.Windows.Controls.Primitives;
53 9bae55d1 Panagiotis Kanavos
using Caliburn.Micro;
54 c53aa229 Panagiotis Kanavos
using Hardcodet.Wpf.TaskbarNotification;
55 c53aa229 Panagiotis Kanavos
using Pithos.Client.WPF.Configuration;
56 42800be8 Panagiotis Kanavos
using Pithos.Client.WPF.FileProperties;
57 65282d58 Panagiotis Kanavos
using Pithos.Client.WPF.Preferences;
58 d3a13891 Panagiotis Kanavos
using Pithos.Client.WPF.SelectiveSynch;
59 42800be8 Panagiotis Kanavos
using Pithos.Client.WPF.Services;
60 5cb9d74f Panagiotis Kanavos
using Pithos.Client.WPF.Shell;
61 c53aa229 Panagiotis Kanavos
using Pithos.Core;
62 29a6b387 Panagiotis Kanavos
using Pithos.Core.Agents;
63 c53aa229 Panagiotis Kanavos
using Pithos.Interfaces;
64 c53aa229 Panagiotis Kanavos
using System;
65 c53aa229 Panagiotis Kanavos
using System.Collections.Generic;
66 c53aa229 Panagiotis Kanavos
using System.Linq;
67 0bd56b7c Panagiotis Kanavos
using Pithos.Network;
68 c53aa229 Panagiotis Kanavos
using StatusService = Pithos.Client.WPF.Services.StatusService;
69 9bae55d1 Panagiotis Kanavos
70 9bae55d1 Panagiotis Kanavos
namespace Pithos.Client.WPF {
71 4ec636f6 Panagiotis Kanavos
	using System.ComponentModel.Composition;
72 9bae55d1 Panagiotis Kanavos
73 4ec636f6 Panagiotis Kanavos
	
74 cf761c0d Panagiotis Kanavos
	///<summary>
75 cf761c0d Panagiotis Kanavos
	/// The "shell" of the Pithos application displays the taskbar  icon, menu and notifications.
76 cf761c0d Panagiotis Kanavos
	/// The shell also hosts the status service called by shell extensions to retrieve file info
77 cf761c0d Panagiotis Kanavos
	///</summary>
78 cf761c0d Panagiotis Kanavos
	///<remarks>
79 cf761c0d Panagiotis Kanavos
	/// It is a strange "shell" as its main visible element is an icon instead of a window
80 cf761c0d Panagiotis Kanavos
	/// The shell subscribes to the following events:
81 cf761c0d Panagiotis Kanavos
	/// * Notification:  Raised by components that want to notify the user. Usually displayed in a balloon
82 cf761c0d Panagiotis Kanavos
	/// * SelectiveSynchChanges: Notifies that the user made changes to the selective synch folders for an account. Raised by the Selective Synch dialog. Located here because the monitors are here
83 cf761c0d Panagiotis Kanavos
	/// * ShowFilePropertiesEvent: Raised when a shell command requests the display of the file/container properties dialog
84 cf761c0d Panagiotis Kanavos
	///</remarks>		
85 cf761c0d Panagiotis Kanavos
	//TODO: CODE SMELL Why does the shell handle the SelectiveSynchChanges?
86 4ec636f6 Panagiotis Kanavos
	[Export(typeof(IShell))]
87 4ec636f6 Panagiotis Kanavos
	public class ShellViewModel : Screen, IStatusNotification, IShell,
88 4ec636f6 Panagiotis Kanavos
		IHandle<Notification>, IHandle<SelectiveSynchChanges>, IHandle<ShowFilePropertiesEvent>
89 4ec636f6 Panagiotis Kanavos
	{
90 6bcdd8e2 Panagiotis Kanavos
91 cf761c0d Panagiotis Kanavos
		//The Status Checker provides the current synch state
92 cf761c0d Panagiotis Kanavos
		//TODO: Could we remove the status checker and use events in its place?
93 4f6d51d4 Panagiotis Kanavos
		private readonly IStatusChecker _statusChecker;
94 4f6d51d4 Panagiotis Kanavos
		private readonly IEventAggregator _events;
95 c53aa229 Panagiotis Kanavos
96 4ec636f6 Panagiotis Kanavos
		public PithosSettings Settings { get; private set; }
97 c53aa229 Panagiotis Kanavos
98 4ec636f6 Panagiotis Kanavos
99 255f5f86 Panagiotis Kanavos
		private readonly ConcurrentDictionary<string, PithosMonitor> _monitors = new ConcurrentDictionary<string, PithosMonitor>();
100 cf761c0d Panagiotis Kanavos
		///<summary>
101 cf761c0d Panagiotis Kanavos
		/// Dictionary of account monitors, keyed by account
102 cf761c0d Panagiotis Kanavos
		///</summary>
103 cf761c0d Panagiotis Kanavos
		///<remarks>
104 cf761c0d Panagiotis Kanavos
		/// One monitor class is created for each account. The Shell needs access to the monitors to execute start/stop/pause commands,
105 cf761c0d Panagiotis Kanavos
		/// retrieve account and boject info		
106 cf761c0d Panagiotis Kanavos
		///</remarks>
107 cf761c0d Panagiotis Kanavos
		// TODO: Does the Shell REALLY need access to the monitors? Could we achieve the same results with a better design?
108 cf761c0d Panagiotis Kanavos
		// TODO: The monitors should be internal to Pithos.Core, even though exposing them makes coding of the Object and Container windows easier
109 255f5f86 Panagiotis Kanavos
		public ConcurrentDictionary<string, PithosMonitor> Monitors
110 4ec636f6 Panagiotis Kanavos
		{
111 4ec636f6 Panagiotis Kanavos
			get { return _monitors; }
112 4ec636f6 Panagiotis Kanavos
		}
113 c53aa229 Panagiotis Kanavos
114 cf761c0d Panagiotis Kanavos
115 255f5f86 Panagiotis Kanavos
		///<summary>
116 255f5f86 Panagiotis Kanavos
		/// The status service is used by Shell extensions to retrieve file status information
117 255f5f86 Panagiotis Kanavos
		///</summary>
118 255f5f86 Panagiotis Kanavos
		//TODO: CODE SMELL! This is the shell! While hosting in the shell makes executing start/stop commands easier, it is still a smell
119 255f5f86 Panagiotis Kanavos
		private ServiceHost _statusService;
120 c53aa229 Panagiotis Kanavos
121 cf761c0d Panagiotis Kanavos
		//Logging in the Pithos client is provided by log4net
122 db8a9589 Panagiotis Kanavos
        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
123 c53aa229 Panagiotis Kanavos
124 255f5f86 Panagiotis Kanavos
		//Lazily initialized File Version info. This is done once and lazily to avoid blocking the UI
125 7f5882da Panagiotis Kanavos
		private readonly Lazy<FileVersionInfo> _fileVersion;
126 422c9598 Panagiotis Kanavos
127 7f5882da Panagiotis Kanavos
	    private readonly PollAgent _pollAgent;
128 31c97141 Panagiotis Kanavos
129 cf761c0d Panagiotis Kanavos
		///<summary>
130 cf761c0d Panagiotis Kanavos
		/// The Shell depends on MEF to provide implementations for windowManager, events, the status checker service and the settings
131 cf761c0d Panagiotis Kanavos
		///</summary>
132 cf761c0d Panagiotis Kanavos
		///<remarks>
133 cf761c0d Panagiotis Kanavos
		/// The PithosSettings class encapsulates the app's settings to abstract their storage mechanism (App settings, a database or registry)
134 cf761c0d Panagiotis Kanavos
		///</remarks>
135 4ec636f6 Panagiotis Kanavos
		[ImportingConstructor]		
136 31c97141 Panagiotis Kanavos
		public ShellViewModel(IWindowManager windowManager, IEventAggregator events, IStatusChecker statusChecker, PithosSettings settings,PollAgent pollAgent)
137 4ec636f6 Panagiotis Kanavos
		{
138 4ec636f6 Panagiotis Kanavos
			try
139 4ec636f6 Panagiotis Kanavos
			{
140 d3a13891 Panagiotis Kanavos
141 4ec636f6 Panagiotis Kanavos
				_windowManager = windowManager;
142 cf761c0d Panagiotis Kanavos
				//CHECK: Caliburn doesn't need explicit command construction
143 4ec636f6 Panagiotis Kanavos
				//OpenPithosFolderCommand = new PithosCommand(OpenPithosFolder);
144 4ec636f6 Panagiotis Kanavos
				_statusChecker = statusChecker;
145 cf761c0d Panagiotis Kanavos
				//The event subst
146 4ec636f6 Panagiotis Kanavos
				_events = events;
147 4ec636f6 Panagiotis Kanavos
				_events.Subscribe(this);
148 c53aa229 Panagiotis Kanavos
149 31c97141 Panagiotis Kanavos
			    _pollAgent = pollAgent;
150 4ec636f6 Panagiotis Kanavos
				Settings = settings;
151 c53aa229 Panagiotis Kanavos
152 255f5f86 Panagiotis Kanavos
				Proxy.SetFromSettings(settings);
153 34bdb91d Panagiotis Kanavos
154 4ec636f6 Panagiotis Kanavos
				StatusMessage = "In Synch";
155 7e26c075 Panagiotis Kanavos
156 255f5f86 Panagiotis Kanavos
				_fileVersion=  new Lazy<FileVersionInfo>(() =>
157 255f5f86 Panagiotis Kanavos
				{
158 255f5f86 Panagiotis Kanavos
					Assembly assembly = Assembly.GetExecutingAssembly();
159 255f5f86 Panagiotis Kanavos
					var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
160 255f5f86 Panagiotis Kanavos
					return fileVersion;
161 255f5f86 Panagiotis Kanavos
				});
162 4ec636f6 Panagiotis Kanavos
				_accounts.CollectionChanged += (sender, e) =>
163 4ec636f6 Panagiotis Kanavos
												   {
164 4ec636f6 Panagiotis Kanavos
													   NotifyOfPropertyChange(() => OpenFolderCaption);
165 4ec636f6 Panagiotis Kanavos
													   NotifyOfPropertyChange(() => HasAccounts);
166 4ec636f6 Panagiotis Kanavos
												   };
167 6aa29f4f Panagiotis Kanavos
168 4ec636f6 Panagiotis Kanavos
			}
169 4ec636f6 Panagiotis Kanavos
			catch (Exception exc)
170 4ec636f6 Panagiotis Kanavos
			{
171 4ec636f6 Panagiotis Kanavos
				Log.Error("Error while starting the ShellViewModel",exc);
172 4ec636f6 Panagiotis Kanavos
				throw;
173 4ec636f6 Panagiotis Kanavos
			}
174 6bcdd8e2 Panagiotis Kanavos
175 4ec636f6 Panagiotis Kanavos
		}
176 c53aa229 Panagiotis Kanavos
177 6aa29f4f Panagiotis Kanavos
178 4ec636f6 Panagiotis Kanavos
		protected override void OnActivate()
179 4ec636f6 Panagiotis Kanavos
		{
180 4ec636f6 Panagiotis Kanavos
			base.OnActivate();
181 42800be8 Panagiotis Kanavos
182 255f5f86 Panagiotis Kanavos
			
183 34bdb91d Panagiotis Kanavos
184 4ec636f6 Panagiotis Kanavos
			StartMonitoring();                    
185 4ec636f6 Panagiotis Kanavos
		}
186 7b0a5fec Panagiotis Kanavos
187 42800be8 Panagiotis Kanavos
188 34bdb91d Panagiotis Kanavos
189 4f6d51d4 Panagiotis Kanavos
		private async void StartMonitoring()
190 4ec636f6 Panagiotis Kanavos
		{
191 4ec636f6 Panagiotis Kanavos
			try
192 4ec636f6 Panagiotis Kanavos
			{
193 4ec636f6 Panagiotis Kanavos
				var accounts = Settings.Accounts.Select(MonitorAccount);
194 4ec636f6 Panagiotis Kanavos
				await TaskEx.WhenAll(accounts);
195 4ec636f6 Panagiotis Kanavos
				_statusService = StatusService.Start();
196 692ec33b Panagiotis Kanavos
197 692ec33b Panagiotis Kanavos
/*
198 4ec636f6 Panagiotis Kanavos
				foreach (var account in Settings.Accounts)
199 4ec636f6 Panagiotis Kanavos
				{
200 4ec636f6 Panagiotis Kanavos
					await MonitorAccount(account);
201 4ec636f6 Panagiotis Kanavos
				}
202 692ec33b Panagiotis Kanavos
*/
203 4ec636f6 Panagiotis Kanavos
				
204 4ec636f6 Panagiotis Kanavos
			}
205 4ec636f6 Panagiotis Kanavos
			catch (AggregateException exc)
206 4ec636f6 Panagiotis Kanavos
			{
207 4ec636f6 Panagiotis Kanavos
				exc.Handle(e =>
208 4ec636f6 Panagiotis Kanavos
				{
209 4ec636f6 Panagiotis Kanavos
					Log.Error("Error while starting monitoring", e);
210 4ec636f6 Panagiotis Kanavos
					return true;
211 4ec636f6 Panagiotis Kanavos
				});
212 4ec636f6 Panagiotis Kanavos
				throw;
213 4ec636f6 Panagiotis Kanavos
			}
214 4ec636f6 Panagiotis Kanavos
		}
215 4ec636f6 Panagiotis Kanavos
216 4ec636f6 Panagiotis Kanavos
		protected override void OnDeactivate(bool close)
217 4ec636f6 Panagiotis Kanavos
		{
218 4ec636f6 Panagiotis Kanavos
			base.OnDeactivate(close);
219 4ec636f6 Panagiotis Kanavos
			if (close)
220 4ec636f6 Panagiotis Kanavos
			{
221 4ec636f6 Panagiotis Kanavos
				StatusService.Stop(_statusService);
222 4ec636f6 Panagiotis Kanavos
				_statusService = null;
223 4ec636f6 Panagiotis Kanavos
			}
224 4ec636f6 Panagiotis Kanavos
		}
225 4ec636f6 Panagiotis Kanavos
226 4ec636f6 Panagiotis Kanavos
		public Task MonitorAccount(AccountSettings account)
227 4ec636f6 Panagiotis Kanavos
		{
228 4ec636f6 Panagiotis Kanavos
			return Task.Factory.StartNew(() =>
229 4ec636f6 Panagiotis Kanavos
			{                                                
230 4f6d51d4 Panagiotis Kanavos
				PithosMonitor monitor;
231 4ec636f6 Panagiotis Kanavos
				var accountName = account.AccountName;
232 4ec636f6 Panagiotis Kanavos
233 4ec636f6 Panagiotis Kanavos
				if (_monitors.TryGetValue(accountName, out monitor))
234 4ec636f6 Panagiotis Kanavos
				{
235 4ec636f6 Panagiotis Kanavos
					//If the account is active
236 c636df1f Panagiotis Kanavos
                    if (account.IsActive)
237 c636df1f Panagiotis Kanavos
                    {
238 c636df1f Panagiotis Kanavos
                        //The Api Key may have changed throuth the Preferences dialog
239 c636df1f Panagiotis Kanavos
                        monitor.ApiKey = account.ApiKey;
240 c636df1f Panagiotis Kanavos
						Debug.Assert(monitor.StatusNotification == this,"An existing monitor should already have a StatusNotification service object");
241 c636df1f Panagiotis Kanavos
                        monitor.RootPath = account.RootPath;
242 c636df1f Panagiotis Kanavos
                        //Start the monitor. It's OK to start an already started monitor,
243 c636df1f Panagiotis Kanavos
                        //it will just ignore the call                        
244 c636df1f Panagiotis Kanavos
                        StartMonitor(monitor).Wait();
245 c636df1f Panagiotis Kanavos
                    }
246 c636df1f Panagiotis Kanavos
                    else
247 c636df1f Panagiotis Kanavos
                    {
248 c636df1f Panagiotis Kanavos
                        //If the account is inactive
249 c636df1f Panagiotis Kanavos
                        //Stop and remove the monitor
250 c636df1f Panagiotis Kanavos
                        RemoveMonitor(accountName);
251 c636df1f Panagiotis Kanavos
                    }
252 4ec636f6 Panagiotis Kanavos
					return;
253 4ec636f6 Panagiotis Kanavos
				}
254 4ec636f6 Panagiotis Kanavos
255 255f5f86 Panagiotis Kanavos
				
256 4ec636f6 Panagiotis Kanavos
				//Create a new monitor/ Can't use MEF here, it would return a single instance for all monitors
257 4ec636f6 Panagiotis Kanavos
				monitor = new PithosMonitor
258 4ec636f6 Panagiotis Kanavos
							  {
259 4ec636f6 Panagiotis Kanavos
								  UserName = accountName,
260 4ec636f6 Panagiotis Kanavos
								  ApiKey = account.ApiKey,                                  
261 4ec636f6 Panagiotis Kanavos
								  StatusNotification = this,
262 4ec636f6 Panagiotis Kanavos
								  RootPath = account.RootPath
263 4ec636f6 Panagiotis Kanavos
							  };
264 4ec636f6 Panagiotis Kanavos
				//PithosMonitor uses MEF so we need to resolve it
265 4ec636f6 Panagiotis Kanavos
				IoC.BuildUp(monitor);
266 4ec636f6 Panagiotis Kanavos
267 255f5f86 Panagiotis Kanavos
				monitor.AuthenticationUrl = account.ServerUrl;
268 4ec636f6 Panagiotis Kanavos
269 4ec636f6 Panagiotis Kanavos
				_monitors[accountName] = monitor;
270 4ec636f6 Panagiotis Kanavos
271 4ec636f6 Panagiotis Kanavos
				if (account.IsActive)
272 4ec636f6 Panagiotis Kanavos
				{
273 4ec636f6 Panagiotis Kanavos
					//Don't start a monitor if it doesn't have an account and ApiKey
274 4ec636f6 Panagiotis Kanavos
					if (String.IsNullOrWhiteSpace(monitor.UserName) ||
275 4ec636f6 Panagiotis Kanavos
						String.IsNullOrWhiteSpace(monitor.ApiKey))
276 4ec636f6 Panagiotis Kanavos
						return;
277 4ec636f6 Panagiotis Kanavos
					StartMonitor(monitor);
278 4ec636f6 Panagiotis Kanavos
				}
279 4ec636f6 Panagiotis Kanavos
			});
280 4ec636f6 Panagiotis Kanavos
		}
281 4ec636f6 Panagiotis Kanavos
282 4ec636f6 Panagiotis Kanavos
283 4ec636f6 Panagiotis Kanavos
		protected override void OnViewLoaded(object view)
284 4ec636f6 Panagiotis Kanavos
		{
285 4ec636f6 Panagiotis Kanavos
			UpdateStatus();
286 4ec636f6 Panagiotis Kanavos
			var window = (Window)view;            
287 4ec636f6 Panagiotis Kanavos
			TaskEx.Delay(1000).ContinueWith(t => Execute.OnUIThread(window.Hide));
288 4ec636f6 Panagiotis Kanavos
			base.OnViewLoaded(view);
289 4ec636f6 Panagiotis Kanavos
		}
290 4ec636f6 Panagiotis Kanavos
291 4ec636f6 Panagiotis Kanavos
292 4ec636f6 Panagiotis Kanavos
		#region Status Properties
293 4ec636f6 Panagiotis Kanavos
294 4ec636f6 Panagiotis Kanavos
		private string _statusMessage;
295 4ec636f6 Panagiotis Kanavos
		public string StatusMessage
296 4ec636f6 Panagiotis Kanavos
		{
297 4ec636f6 Panagiotis Kanavos
			get { return _statusMessage; }
298 4ec636f6 Panagiotis Kanavos
			set
299 4ec636f6 Panagiotis Kanavos
			{
300 4ec636f6 Panagiotis Kanavos
				_statusMessage = value;
301 4ec636f6 Panagiotis Kanavos
				NotifyOfPropertyChange(() => StatusMessage);
302 4ec636f6 Panagiotis Kanavos
			}
303 4ec636f6 Panagiotis Kanavos
		}
304 4ec636f6 Panagiotis Kanavos
305 4ec636f6 Panagiotis Kanavos
		private readonly ObservableConcurrentCollection<AccountInfo> _accounts = new ObservableConcurrentCollection<AccountInfo>();
306 4ec636f6 Panagiotis Kanavos
		public ObservableConcurrentCollection<AccountInfo> Accounts
307 4ec636f6 Panagiotis Kanavos
		{
308 4ec636f6 Panagiotis Kanavos
			get { return _accounts; }
309 4ec636f6 Panagiotis Kanavos
		}
310 4ec636f6 Panagiotis Kanavos
311 4ec636f6 Panagiotis Kanavos
		public bool HasAccounts
312 4ec636f6 Panagiotis Kanavos
		{
313 4ec636f6 Panagiotis Kanavos
			get { return _accounts.Count > 0; }
314 4ec636f6 Panagiotis Kanavos
		}
315 4ec636f6 Panagiotis Kanavos
316 4ec636f6 Panagiotis Kanavos
317 4ec636f6 Panagiotis Kanavos
		public string OpenFolderCaption
318 4ec636f6 Panagiotis Kanavos
		{
319 4ec636f6 Panagiotis Kanavos
			get
320 4ec636f6 Panagiotis Kanavos
			{
321 4ec636f6 Panagiotis Kanavos
				return (_accounts.Count == 0)
322 4ec636f6 Panagiotis Kanavos
						? "No Accounts Defined"
323 4ec636f6 Panagiotis Kanavos
						: "Open Pithos Folder";
324 4ec636f6 Panagiotis Kanavos
			}
325 4ec636f6 Panagiotis Kanavos
		}
326 4ec636f6 Panagiotis Kanavos
327 4ec636f6 Panagiotis Kanavos
		private string _pauseSyncCaption="Pause Synching";
328 4ec636f6 Panagiotis Kanavos
		public string PauseSyncCaption
329 4ec636f6 Panagiotis Kanavos
		{
330 4ec636f6 Panagiotis Kanavos
			get { return _pauseSyncCaption; }
331 4ec636f6 Panagiotis Kanavos
			set
332 4ec636f6 Panagiotis Kanavos
			{
333 4ec636f6 Panagiotis Kanavos
				_pauseSyncCaption = value;
334 4ec636f6 Panagiotis Kanavos
				NotifyOfPropertyChange(() => PauseSyncCaption);
335 4ec636f6 Panagiotis Kanavos
			}
336 4ec636f6 Panagiotis Kanavos
		}
337 4ec636f6 Panagiotis Kanavos
338 4ec636f6 Panagiotis Kanavos
		private readonly ObservableConcurrentCollection<FileEntry> _recentFiles = new ObservableConcurrentCollection<FileEntry>();
339 4ec636f6 Panagiotis Kanavos
		public ObservableConcurrentCollection<FileEntry> RecentFiles
340 4ec636f6 Panagiotis Kanavos
		{
341 4ec636f6 Panagiotis Kanavos
			get { return _recentFiles; }
342 4ec636f6 Panagiotis Kanavos
		}
343 4ec636f6 Panagiotis Kanavos
344 4ec636f6 Panagiotis Kanavos
345 4ec636f6 Panagiotis Kanavos
		private string _statusIcon="../Images/Pithos.ico";
346 4ec636f6 Panagiotis Kanavos
		public string StatusIcon
347 4ec636f6 Panagiotis Kanavos
		{
348 4ec636f6 Panagiotis Kanavos
			get { return _statusIcon; }
349 4ec636f6 Panagiotis Kanavos
			set
350 4ec636f6 Panagiotis Kanavos
			{
351 255f5f86 Panagiotis Kanavos
				//TODO: Ensure all status icons use the Pithos logo
352 4f6d51d4 Panagiotis Kanavos
				_statusIcon = value;
353 4ec636f6 Panagiotis Kanavos
				NotifyOfPropertyChange(() => StatusIcon);
354 4ec636f6 Panagiotis Kanavos
			}
355 4ec636f6 Panagiotis Kanavos
		}
356 4ec636f6 Panagiotis Kanavos
357 4ec636f6 Panagiotis Kanavos
		#endregion
358 4ec636f6 Panagiotis Kanavos
359 4ec636f6 Panagiotis Kanavos
		#region Commands
360 4ec636f6 Panagiotis Kanavos
361 f2d88248 Panagiotis Kanavos
        public void ShowPreferences()
362 f2d88248 Panagiotis Kanavos
        {
363 f2d88248 Panagiotis Kanavos
            ShowPreferences(null);
364 f2d88248 Panagiotis Kanavos
        }
365 f2d88248 Panagiotis Kanavos
366 f2d88248 Panagiotis Kanavos
		public void ShowPreferences(string currentTab)
367 4ec636f6 Panagiotis Kanavos
		{
368 1e26eceb Panagiotis Kanavos
			//Settings.Reload();
369 f2d88248 Panagiotis Kanavos
		    var preferences = new PreferencesViewModel(_windowManager, _events, this, Settings,currentTab);
370 f2d88248 Panagiotis Kanavos
		    _windowManager.ShowDialog(preferences);
371 4ec636f6 Panagiotis Kanavos
			
372 4ec636f6 Panagiotis Kanavos
		}
373 4ec636f6 Panagiotis Kanavos
374 4ec636f6 Panagiotis Kanavos
		public void AboutPithos()
375 4ec636f6 Panagiotis Kanavos
		{
376 4ec636f6 Panagiotis Kanavos
			var about = new AboutViewModel();
377 4ec636f6 Panagiotis Kanavos
			_windowManager.ShowWindow(about);
378 4ec636f6 Panagiotis Kanavos
		}
379 4ec636f6 Panagiotis Kanavos
380 4ec636f6 Panagiotis Kanavos
		public void SendFeedback()
381 4ec636f6 Panagiotis Kanavos
		{
382 4ec636f6 Panagiotis Kanavos
			var feedBack =  IoC.Get<FeedbackViewModel>();
383 4ec636f6 Panagiotis Kanavos
			_windowManager.ShowWindow(feedBack);
384 4ec636f6 Panagiotis Kanavos
		}
385 4ec636f6 Panagiotis Kanavos
386 4ec636f6 Panagiotis Kanavos
		//public PithosCommand OpenPithosFolderCommand { get; private set; }
387 4ec636f6 Panagiotis Kanavos
388 4ec636f6 Panagiotis Kanavos
		public void OpenPithosFolder()
389 4ec636f6 Panagiotis Kanavos
		{
390 4ec636f6 Panagiotis Kanavos
			var account = Settings.Accounts.FirstOrDefault(acc => acc.IsActive);
391 4ec636f6 Panagiotis Kanavos
			if (account == null)
392 4ec636f6 Panagiotis Kanavos
				return;
393 4ec636f6 Panagiotis Kanavos
			Process.Start(account.RootPath);
394 4ec636f6 Panagiotis Kanavos
		}
395 4ec636f6 Panagiotis Kanavos
396 4ec636f6 Panagiotis Kanavos
		public void OpenPithosFolder(AccountInfo account)
397 4ec636f6 Panagiotis Kanavos
		{
398 4ec636f6 Panagiotis Kanavos
			Process.Start(account.AccountPath);
399 4ec636f6 Panagiotis Kanavos
		}
400 4ec636f6 Panagiotis Kanavos
401 4ec636f6 Panagiotis Kanavos
		
402 f734ab5b Panagiotis Kanavos
/*
403 4ec636f6 Panagiotis Kanavos
		public void GoToSite()
404 4ec636f6 Panagiotis Kanavos
		{            
405 4ec636f6 Panagiotis Kanavos
			var site = Properties.Settings.Default.PithosSite;
406 4ec636f6 Panagiotis Kanavos
			Process.Start(site);            
407 4ec636f6 Panagiotis Kanavos
		}
408 f734ab5b Panagiotis Kanavos
*/
409 6aa29f4f Panagiotis Kanavos
410 4ec636f6 Panagiotis Kanavos
		public void GoToSite(AccountInfo account)
411 4ec636f6 Panagiotis Kanavos
		{
412 9d2c0fc0 Panagiotis Kanavos
		    var uri = account.SiteUri.Replace("http://","https://");            
413 9d2c0fc0 Panagiotis Kanavos
		    Process.Start(uri);
414 4ec636f6 Panagiotis Kanavos
		}
415 4ec636f6 Panagiotis Kanavos
416 9d2c0fc0 Panagiotis Kanavos
	    /// <summary>
417 7f5882da Panagiotis Kanavos
        /// Open an explorer window to the target path's directory
418 7f5882da Panagiotis Kanavos
        /// and select the file
419 7f5882da Panagiotis Kanavos
        /// </summary>
420 7f5882da Panagiotis Kanavos
        /// <param name="entry"></param>
421 7f5882da Panagiotis Kanavos
        public void GoToFile(FileEntry entry)
422 7f5882da Panagiotis Kanavos
        {
423 7f5882da Panagiotis Kanavos
            var fullPath = entry.FullPath;
424 7f5882da Panagiotis Kanavos
            if (!File.Exists(fullPath) && !Directory.Exists(fullPath))
425 7f5882da Panagiotis Kanavos
                return;
426 7f5882da Panagiotis Kanavos
            Process.Start("explorer.exe","/select, " + fullPath);
427 7f5882da Panagiotis Kanavos
        }
428 7f5882da Panagiotis Kanavos
429 db8a9589 Panagiotis Kanavos
        public void OpenLogPath()
430 db8a9589 Panagiotis Kanavos
        {
431 db8a9589 Panagiotis Kanavos
            var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
432 db8a9589 Panagiotis Kanavos
            var pithosDataPath = Path.Combine(appDataPath, "GRNET");
433 db8a9589 Panagiotis Kanavos
434 db8a9589 Panagiotis Kanavos
            Process.Start(pithosDataPath);
435 db8a9589 Panagiotis Kanavos
        }
436 db8a9589 Panagiotis Kanavos
        
437 db8a9589 Panagiotis Kanavos
        public void ShowFileProperties()
438 4ec636f6 Panagiotis Kanavos
		{
439 4ec636f6 Panagiotis Kanavos
			var account = Settings.Accounts.First(acc => acc.IsActive);            
440 4ec636f6 Panagiotis Kanavos
			var dir = new DirectoryInfo(account.RootPath + @"\pithos");
441 4ec636f6 Panagiotis Kanavos
			var files=dir.GetFiles();
442 4ec636f6 Panagiotis Kanavos
			var r=new Random();
443 4ec636f6 Panagiotis Kanavos
			var idx=r.Next(0, files.Length);
444 4ec636f6 Panagiotis Kanavos
			ShowFileProperties(files[idx].FullName);            
445 4ec636f6 Panagiotis Kanavos
		}
446 4ec636f6 Panagiotis Kanavos
447 4ec636f6 Panagiotis Kanavos
		public void ShowFileProperties(string filePath)
448 4ec636f6 Panagiotis Kanavos
		{
449 4ec636f6 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(filePath))
450 4ec636f6 Panagiotis Kanavos
				throw new ArgumentNullException("filePath");
451 4f6d51d4 Panagiotis Kanavos
			if (!File.Exists(filePath) && !Directory.Exists(filePath))
452 4ec636f6 Panagiotis Kanavos
				throw new ArgumentException(String.Format("Non existent file {0}",filePath),"filePath");
453 4ec636f6 Panagiotis Kanavos
			Contract.EndContractBlock();
454 4ec636f6 Panagiotis Kanavos
455 4ec636f6 Panagiotis Kanavos
			var pair=(from monitor in  Monitors
456 4ec636f6 Panagiotis Kanavos
							   where filePath.StartsWith(monitor.Value.RootPath, StringComparison.InvariantCultureIgnoreCase)
457 4ec636f6 Panagiotis Kanavos
								   select monitor).FirstOrDefault();
458 255f5f86 Panagiotis Kanavos
			var accountMonitor = pair.Value;
459 4ec636f6 Panagiotis Kanavos
460 4ec636f6 Panagiotis Kanavos
			if (accountMonitor == null)
461 4ec636f6 Panagiotis Kanavos
				return;
462 4ec636f6 Panagiotis Kanavos
463 4ec636f6 Panagiotis Kanavos
			var infoTask=Task.Factory.StartNew(()=>accountMonitor.GetObjectInfo(filePath));
464 4ec636f6 Panagiotis Kanavos
465 4ec636f6 Panagiotis Kanavos
			
466 4ec636f6 Panagiotis Kanavos
467 4ec636f6 Panagiotis Kanavos
			var fileProperties = new FilePropertiesViewModel(this, infoTask,filePath);
468 4ec636f6 Panagiotis Kanavos
			_windowManager.ShowWindow(fileProperties);
469 4ec636f6 Panagiotis Kanavos
		} 
470 4ec636f6 Panagiotis Kanavos
		
471 4ec636f6 Panagiotis Kanavos
		public void ShowContainerProperties()
472 4ec636f6 Panagiotis Kanavos
		{
473 4ec636f6 Panagiotis Kanavos
			var account = Settings.Accounts.First(acc => acc.IsActive);            
474 4ec636f6 Panagiotis Kanavos
			var dir = new DirectoryInfo(account.RootPath);
475 4ec636f6 Panagiotis Kanavos
			var fullName = (from folder in dir.EnumerateDirectories()
476 4ec636f6 Panagiotis Kanavos
							where (folder.Attributes & FileAttributes.Hidden) == 0
477 4ec636f6 Panagiotis Kanavos
							select folder.FullName).First();
478 4ec636f6 Panagiotis Kanavos
			ShowContainerProperties(fullName);            
479 4ec636f6 Panagiotis Kanavos
		}
480 4ec636f6 Panagiotis Kanavos
481 4ec636f6 Panagiotis Kanavos
		public void ShowContainerProperties(string filePath)
482 4ec636f6 Panagiotis Kanavos
		{
483 4ec636f6 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(filePath))
484 4ec636f6 Panagiotis Kanavos
				throw new ArgumentNullException("filePath");
485 4ec636f6 Panagiotis Kanavos
			if (!Directory.Exists(filePath))
486 4ec636f6 Panagiotis Kanavos
				throw new ArgumentException(String.Format("Non existent file {0}",filePath),"filePath");
487 4ec636f6 Panagiotis Kanavos
			Contract.EndContractBlock();
488 4ec636f6 Panagiotis Kanavos
489 4ec636f6 Panagiotis Kanavos
			var pair=(from monitor in  Monitors
490 4ec636f6 Panagiotis Kanavos
							   where filePath.StartsWith(monitor.Value.RootPath, StringComparison.InvariantCultureIgnoreCase)
491 4ec636f6 Panagiotis Kanavos
								   select monitor).FirstOrDefault();
492 255f5f86 Panagiotis Kanavos
			var accountMonitor = pair.Value;            
493 4ec636f6 Panagiotis Kanavos
			var info = accountMonitor.GetContainerInfo(filePath);
494 4ec636f6 Panagiotis Kanavos
495 4ec636f6 Panagiotis Kanavos
			
496 4ec636f6 Panagiotis Kanavos
497 4ec636f6 Panagiotis Kanavos
			var containerProperties = new ContainerPropertiesViewModel(this, info,filePath);
498 4ec636f6 Panagiotis Kanavos
			_windowManager.ShowWindow(containerProperties);
499 4ec636f6 Panagiotis Kanavos
		}
500 4ec636f6 Panagiotis Kanavos
501 255f5f86 Panagiotis Kanavos
		public void SynchNow()
502 255f5f86 Panagiotis Kanavos
		{
503 31c97141 Panagiotis Kanavos
			_pollAgent.SynchNow();
504 255f5f86 Panagiotis Kanavos
		}
505 133f83c2 Panagiotis Kanavos
506 4ec636f6 Panagiotis Kanavos
		public ObjectInfo RefreshObjectInfo(ObjectInfo currentInfo)
507 4ec636f6 Panagiotis Kanavos
		{
508 4ec636f6 Panagiotis Kanavos
			if (currentInfo==null)
509 4ec636f6 Panagiotis Kanavos
				throw new ArgumentNullException("currentInfo");
510 4ec636f6 Panagiotis Kanavos
			Contract.EndContractBlock();
511 4ec636f6 Panagiotis Kanavos
512 4ec636f6 Panagiotis Kanavos
			var monitor = Monitors[currentInfo.Account];
513 4ec636f6 Panagiotis Kanavos
			var newInfo=monitor.CloudClient.GetObjectInfo(currentInfo.Account, currentInfo.Container, currentInfo.Name);
514 4ec636f6 Panagiotis Kanavos
			return newInfo;
515 4ec636f6 Panagiotis Kanavos
		}
516 4ec636f6 Panagiotis Kanavos
517 4ec636f6 Panagiotis Kanavos
		public ContainerInfo RefreshContainerInfo(ContainerInfo container)
518 4ec636f6 Panagiotis Kanavos
		{
519 4ec636f6 Panagiotis Kanavos
			if (container == null)
520 4ec636f6 Panagiotis Kanavos
				throw new ArgumentNullException("container");
521 4ec636f6 Panagiotis Kanavos
			Contract.EndContractBlock();
522 4ec636f6 Panagiotis Kanavos
523 4ec636f6 Panagiotis Kanavos
			var monitor = Monitors[container.Account];
524 4ec636f6 Panagiotis Kanavos
			var newInfo = monitor.CloudClient.GetContainerInfo(container.Account, container.Name);
525 4ec636f6 Panagiotis Kanavos
			return newInfo;
526 4ec636f6 Panagiotis Kanavos
		}
527 4ec636f6 Panagiotis Kanavos
528 4ec636f6 Panagiotis Kanavos
529 4ec636f6 Panagiotis Kanavos
		public void ToggleSynching()
530 4ec636f6 Panagiotis Kanavos
		{
531 4ec636f6 Panagiotis Kanavos
			bool isPaused=false;
532 4ec636f6 Panagiotis Kanavos
			foreach (var pair in Monitors)
533 4ec636f6 Panagiotis Kanavos
			{
534 4ec636f6 Panagiotis Kanavos
				var monitor = pair.Value;
535 4ec636f6 Panagiotis Kanavos
				monitor.Pause = !monitor.Pause;
536 4ec636f6 Panagiotis Kanavos
				isPaused = monitor.Pause;
537 4ec636f6 Panagiotis Kanavos
			}
538 174bbb6e Panagiotis Kanavos
                        
539 4ec636f6 Panagiotis Kanavos
540 4ec636f6 Panagiotis Kanavos
			PauseSyncCaption = isPaused ? "Resume syncing" : "Pause syncing";
541 4ec636f6 Panagiotis Kanavos
			var iconKey = isPaused? "TraySyncPaused" : "TrayInSynch";
542 4ec636f6 Panagiotis Kanavos
			StatusIcon = String.Format(@"../Images/{0}.ico", iconKey);
543 4ec636f6 Panagiotis Kanavos
		}
544 4ec636f6 Panagiotis Kanavos
545 4ec636f6 Panagiotis Kanavos
		public void ExitPithos()
546 4ec636f6 Panagiotis Kanavos
		{
547 4ec636f6 Panagiotis Kanavos
			foreach (var pair in Monitors)
548 4ec636f6 Panagiotis Kanavos
			{
549 4ec636f6 Panagiotis Kanavos
				var monitor = pair.Value;
550 4ec636f6 Panagiotis Kanavos
				monitor.Stop();
551 4ec636f6 Panagiotis Kanavos
			}
552 4ec636f6 Panagiotis Kanavos
553 4ec636f6 Panagiotis Kanavos
			((Window)GetView()).Close();
554 4ec636f6 Panagiotis Kanavos
		}
555 4ec636f6 Panagiotis Kanavos
		#endregion
556 4ec636f6 Panagiotis Kanavos
557 4ec636f6 Panagiotis Kanavos
558 4f6d51d4 Panagiotis Kanavos
		private readonly Dictionary<PithosStatus, StatusInfo> _iconNames = new List<StatusInfo>
559 4ec636f6 Panagiotis Kanavos
			{
560 4ec636f6 Panagiotis Kanavos
				new StatusInfo(PithosStatus.InSynch, "All files up to date", "TrayInSynch"),
561 174bbb6e Panagiotis Kanavos
				new StatusInfo(PithosStatus.PollSyncing, "Polling Files", "TraySynching"),
562 174bbb6e Panagiotis Kanavos
                new StatusInfo(PithosStatus.LocalSyncing, "Syncing Files", "TraySynching"),
563 4ec636f6 Panagiotis Kanavos
				new StatusInfo(PithosStatus.SyncPaused, "Sync Paused", "TraySyncPaused")
564 4ec636f6 Panagiotis Kanavos
			}.ToDictionary(s => s.Status);
565 4ec636f6 Panagiotis Kanavos
566 4ec636f6 Panagiotis Kanavos
		readonly IWindowManager _windowManager;
567 255f5f86 Panagiotis Kanavos
		
568 174bbb6e Panagiotis Kanavos
        //private int _syncCount=0;
569 174bbb6e Panagiotis Kanavos
570 174bbb6e Panagiotis Kanavos
571 174bbb6e Panagiotis Kanavos
        private PithosStatus _pithosStatus = PithosStatus.Disconnected;
572 174bbb6e Panagiotis Kanavos
573 174bbb6e Panagiotis Kanavos
        public void SetPithosStatus(PithosStatus status)
574 174bbb6e Panagiotis Kanavos
        {
575 174bbb6e Panagiotis Kanavos
            if (_pithosStatus == PithosStatus.LocalSyncing && status == PithosStatus.PollComplete)
576 174bbb6e Panagiotis Kanavos
                return;
577 174bbb6e Panagiotis Kanavos
            if (_pithosStatus == PithosStatus.PollSyncing && status == PithosStatus.LocalComplete)
578 174bbb6e Panagiotis Kanavos
                return;
579 174bbb6e Panagiotis Kanavos
            if (status == PithosStatus.LocalComplete || status == PithosStatus.PollComplete)
580 174bbb6e Panagiotis Kanavos
                _pithosStatus = PithosStatus.InSynch;
581 174bbb6e Panagiotis Kanavos
            else
582 174bbb6e Panagiotis Kanavos
                _pithosStatus = status;
583 174bbb6e Panagiotis Kanavos
            UpdateStatus();
584 174bbb6e Panagiotis Kanavos
        }
585 174bbb6e Panagiotis Kanavos
586 174bbb6e Panagiotis Kanavos
        public void SetPithosStatus(PithosStatus status,string message)
587 174bbb6e Panagiotis Kanavos
        {
588 174bbb6e Panagiotis Kanavos
            StatusMessage = message;
589 174bbb6e Panagiotis Kanavos
            SetPithosStatus(status);
590 174bbb6e Panagiotis Kanavos
        }
591 174bbb6e Panagiotis Kanavos
592 174bbb6e Panagiotis Kanavos
593 c53aa229 Panagiotis Kanavos
594 cf761c0d Panagiotis Kanavos
		///<summary>
595 cf761c0d Panagiotis Kanavos
		/// Updates the visual status indicators of the application depending on status changes, e.g. icon, stat		
596 cf761c0d Panagiotis Kanavos
		///</summary>
597 4ec636f6 Panagiotis Kanavos
		public void UpdateStatus()
598 4ec636f6 Panagiotis Kanavos
		{
599 4ec636f6 Panagiotis Kanavos
600 174bbb6e Panagiotis Kanavos
			if (_iconNames.ContainsKey(_pithosStatus))
601 4ec636f6 Panagiotis Kanavos
			{
602 174bbb6e Panagiotis Kanavos
				var info = _iconNames[_pithosStatus];
603 4ec636f6 Panagiotis Kanavos
				StatusIcon = String.Format(@"../Images/{0}.ico", info.IconName);
604 4ec636f6 Panagiotis Kanavos
			}
605 174bbb6e Panagiotis Kanavos
606 174bbb6e Panagiotis Kanavos
            if (_pithosStatus == PithosStatus.InSynch)
607 174bbb6e Panagiotis Kanavos
                StatusMessage = "All files up to date";
608 4ec636f6 Panagiotis Kanavos
		}
609 4ec636f6 Panagiotis Kanavos
610 4ec636f6 Panagiotis Kanavos
611 4ec636f6 Panagiotis Kanavos
	   
612 4ec636f6 Panagiotis Kanavos
		private Task StartMonitor(PithosMonitor monitor,int retries=0)
613 4ec636f6 Panagiotis Kanavos
		{
614 4ec636f6 Panagiotis Kanavos
			return Task.Factory.StartNew(() =>
615 4ec636f6 Panagiotis Kanavos
			{
616 4ec636f6 Panagiotis Kanavos
				using (log4net.ThreadContext.Stacks["Monitor"].Push("Start"))
617 4ec636f6 Panagiotis Kanavos
				{
618 4ec636f6 Panagiotis Kanavos
					try
619 4ec636f6 Panagiotis Kanavos
					{
620 4ec636f6 Panagiotis Kanavos
						Log.InfoFormat("Start Monitoring {0}", monitor.UserName);
621 4ec636f6 Panagiotis Kanavos
622 4ec636f6 Panagiotis Kanavos
						monitor.Start();
623 4ec636f6 Panagiotis Kanavos
					}
624 4ec636f6 Panagiotis Kanavos
					catch (WebException exc)
625 4ec636f6 Panagiotis Kanavos
					{
626 4ec636f6 Panagiotis Kanavos
						if (AbandonRetry(monitor, retries))
627 4ec636f6 Panagiotis Kanavos
							return;
628 4ec636f6 Panagiotis Kanavos
629 255f5f86 Panagiotis Kanavos
						HttpStatusCode statusCode =HttpStatusCode.OK;
630 255f5f86 Panagiotis Kanavos
						var response = exc.Response as HttpWebResponse;
631 255f5f86 Panagiotis Kanavos
						if(response!=null)
632 255f5f86 Panagiotis Kanavos
							statusCode = response.StatusCode;
633 255f5f86 Panagiotis Kanavos
634 255f5f86 Panagiotis Kanavos
						switch (statusCode)
635 255f5f86 Panagiotis Kanavos
						{
636 255f5f86 Panagiotis Kanavos
							case HttpStatusCode.Unauthorized:
637 255f5f86 Panagiotis Kanavos
								var message = String.Format("API Key Expired for {0}. Starting Renewal",
638 255f5f86 Panagiotis Kanavos
															monitor.UserName);
639 255f5f86 Panagiotis Kanavos
								Log.Error(message, exc);
640 1e26eceb Panagiotis Kanavos
						        var account = Settings.Accounts.Find(acc => acc.AccountName == monitor.UserName);                                
641 1e26eceb Panagiotis Kanavos
						        account.IsExpired = true;
642 1e26eceb Panagiotis Kanavos
                                Notify(new ExpirationNotification(account));
643 1e26eceb Panagiotis Kanavos
								//TryAuthorize(monitor.UserName, retries).Wait();
644 255f5f86 Panagiotis Kanavos
								break;
645 255f5f86 Panagiotis Kanavos
							case HttpStatusCode.ProxyAuthenticationRequired:
646 255f5f86 Panagiotis Kanavos
								TryAuthenticateProxy(monitor,retries);
647 255f5f86 Panagiotis Kanavos
								break;
648 255f5f86 Panagiotis Kanavos
							default:
649 255f5f86 Panagiotis Kanavos
								TryLater(monitor, exc, retries);
650 255f5f86 Panagiotis Kanavos
								break;
651 255f5f86 Panagiotis Kanavos
						}
652 4ec636f6 Panagiotis Kanavos
					}
653 4ec636f6 Panagiotis Kanavos
					catch (Exception exc)
654 4ec636f6 Panagiotis Kanavos
					{
655 4ec636f6 Panagiotis Kanavos
						if (AbandonRetry(monitor, retries)) 
656 4ec636f6 Panagiotis Kanavos
							return;
657 4ec636f6 Panagiotis Kanavos
658 4ec636f6 Panagiotis Kanavos
						TryLater(monitor,exc,retries);
659 4ec636f6 Panagiotis Kanavos
					}
660 4ec636f6 Panagiotis Kanavos
				}
661 4ec636f6 Panagiotis Kanavos
			});
662 4ec636f6 Panagiotis Kanavos
		}
663 4ec636f6 Panagiotis Kanavos
664 255f5f86 Panagiotis Kanavos
		private void TryAuthenticateProxy(PithosMonitor monitor,int retries)
665 255f5f86 Panagiotis Kanavos
		{
666 255f5f86 Panagiotis Kanavos
			Execute.OnUIThread(() =>
667 255f5f86 Panagiotis Kanavos
								   {                                       
668 255f5f86 Panagiotis Kanavos
									   var proxyAccount = IoC.Get<ProxyAccountViewModel>();
669 7f5882da Panagiotis Kanavos
										proxyAccount.Settings = Settings;
670 255f5f86 Panagiotis Kanavos
									   if (true != _windowManager.ShowDialog(proxyAccount)) 
671 255f5f86 Panagiotis Kanavos
										   return;
672 255f5f86 Panagiotis Kanavos
									   StartMonitor(monitor, retries);
673 255f5f86 Panagiotis Kanavos
									   NotifyOfPropertyChange(() => Accounts);
674 255f5f86 Panagiotis Kanavos
								   });
675 255f5f86 Panagiotis Kanavos
		}
676 65282d58 Panagiotis Kanavos
677 255f5f86 Panagiotis Kanavos
		private bool AbandonRetry(PithosMonitor monitor, int retries)
678 4ec636f6 Panagiotis Kanavos
		{
679 4ec636f6 Panagiotis Kanavos
			if (retries > 1)
680 4ec636f6 Panagiotis Kanavos
			{
681 4ec636f6 Panagiotis Kanavos
				var message = String.Format("Monitoring of account {0} has failed too many times. Will not retry",
682 4ec636f6 Panagiotis Kanavos
											monitor.UserName);
683 4ec636f6 Panagiotis Kanavos
				_events.Publish(new Notification
684 4ec636f6 Panagiotis Kanavos
									{Title = "Account monitoring failed", Message = message, Level = TraceLevel.Error});
685 4ec636f6 Panagiotis Kanavos
				return true;
686 4ec636f6 Panagiotis Kanavos
			}
687 4ec636f6 Panagiotis Kanavos
			return false;
688 4ec636f6 Panagiotis Kanavos
		}
689 4ec636f6 Panagiotis Kanavos
690 4ec636f6 Panagiotis Kanavos
691 7f5882da Panagiotis Kanavos
	    private void TryLater(PithosMonitor monitor, Exception exc,int retries)
692 4ec636f6 Panagiotis Kanavos
		{
693 4ec636f6 Panagiotis Kanavos
			var message = String.Format("An exception occured. Can't start monitoring\nWill retry in 10 seconds");
694 4ec636f6 Panagiotis Kanavos
			Task.Factory.StartNewDelayed(10000, () => StartMonitor(monitor,retries+1));
695 4ec636f6 Panagiotis Kanavos
			_events.Publish(new Notification
696 4ec636f6 Panagiotis Kanavos
								{Title = "Error", Message = message, Level = TraceLevel.Error});
697 4ec636f6 Panagiotis Kanavos
			Log.Error(message, exc);
698 4ec636f6 Panagiotis Kanavos
		}
699 4ec636f6 Panagiotis Kanavos
700 4ec636f6 Panagiotis Kanavos
701 4ec636f6 Panagiotis Kanavos
		public void NotifyChange(string status, TraceLevel level=TraceLevel.Info)
702 4ec636f6 Panagiotis Kanavos
		{
703 4f6d51d4 Panagiotis Kanavos
			StatusMessage = status;
704 4ec636f6 Panagiotis Kanavos
			
705 4ec636f6 Panagiotis Kanavos
			_events.Publish(new Notification { Title = "Pithos", Message = status, Level = level });
706 4ec636f6 Panagiotis Kanavos
		}
707 4ec636f6 Panagiotis Kanavos
708 4ec636f6 Panagiotis Kanavos
		public void NotifyChangedFile(string filePath)
709 4ec636f6 Panagiotis Kanavos
		{
710 7f5882da Panagiotis Kanavos
            if (RecentFiles.Any(e => e.FullPath == filePath))
711 7f5882da Panagiotis Kanavos
                return;
712 7f5882da Panagiotis Kanavos
            
713 4f6d51d4 Panagiotis Kanavos
			IProducerConsumerCollection<FileEntry> files=RecentFiles;
714 4ec636f6 Panagiotis Kanavos
			FileEntry popped;
715 4ec636f6 Panagiotis Kanavos
			while (files.Count > 5)
716 4ec636f6 Panagiotis Kanavos
				files.TryTake(out popped);
717 7f5882da Panagiotis Kanavos
            var entry = new FileEntry { FullPath = filePath };
718 4ec636f6 Panagiotis Kanavos
			files.TryAdd(entry);
719 4ec636f6 Panagiotis Kanavos
		}
720 4ec636f6 Panagiotis Kanavos
721 4ec636f6 Panagiotis Kanavos
		public void NotifyAccount(AccountInfo account)
722 4ec636f6 Panagiotis Kanavos
		{
723 4ec636f6 Panagiotis Kanavos
			if (account== null)
724 4ec636f6 Panagiotis Kanavos
				return;
725 4ec636f6 Panagiotis Kanavos
			//TODO: What happens to an existing account whose Token has changed?
726 4ec636f6 Panagiotis Kanavos
			account.SiteUri= String.Format("{0}/ui/?token={1}&user={2}",
727 eae84ae8 Panagiotis Kanavos
				account.SiteUri, Uri.EscapeDataString(account.Token),
728 255f5f86 Panagiotis Kanavos
				Uri.EscapeDataString(account.UserName));
729 4ec636f6 Panagiotis Kanavos
730 4ec636f6 Panagiotis Kanavos
			if (Accounts.All(item => item.UserName != account.UserName))
731 4ec636f6 Panagiotis Kanavos
				Accounts.TryAdd(account);
732 4ec636f6 Panagiotis Kanavos
733 4ec636f6 Panagiotis Kanavos
		}
734 4ec636f6 Panagiotis Kanavos
735 255f5f86 Panagiotis Kanavos
		public void NotifyConflicts(IEnumerable<FileSystemInfo> conflictFiles, string message)
736 255f5f86 Panagiotis Kanavos
		{
737 255f5f86 Panagiotis Kanavos
			if (conflictFiles == null)
738 255f5f86 Panagiotis Kanavos
				return;
739 7f5882da Panagiotis Kanavos
		    //Convert to list to avoid multiple iterations
740 7f5882da Panagiotis Kanavos
            var files = conflictFiles.ToList();
741 7f5882da Panagiotis Kanavos
			if (files.Count==0)
742 255f5f86 Panagiotis Kanavos
				return;
743 e5b65606 Panagiotis Kanavos
744 255f5f86 Panagiotis Kanavos
			UpdateStatus();
745 255f5f86 Panagiotis Kanavos
			//TODO: Create a more specific message. For now, just show a warning
746 7f5882da Panagiotis Kanavos
			NotifyForFiles(files,message,TraceLevel.Warning);
747 9c6d3193 Panagiotis Kanavos
748 255f5f86 Panagiotis Kanavos
		}
749 9c6d3193 Panagiotis Kanavos
750 255f5f86 Panagiotis Kanavos
		public void NotifyForFiles(IEnumerable<FileSystemInfo> files, string message,TraceLevel level=TraceLevel.Info)
751 255f5f86 Panagiotis Kanavos
		{
752 255f5f86 Panagiotis Kanavos
			if (files == null)
753 255f5f86 Panagiotis Kanavos
				return;
754 255f5f86 Panagiotis Kanavos
			if (!files.Any())
755 255f5f86 Panagiotis Kanavos
				return;
756 9c6d3193 Panagiotis Kanavos
757 255f5f86 Panagiotis Kanavos
			StatusMessage = message;
758 9c6d3193 Panagiotis Kanavos
759 255f5f86 Panagiotis Kanavos
			_events.Publish(new Notification { Title = "Pithos", Message = message, Level = level});
760 255f5f86 Panagiotis Kanavos
		}
761 9c6d3193 Panagiotis Kanavos
762 255f5f86 Panagiotis Kanavos
		public void Notify(Notification notification)
763 255f5f86 Panagiotis Kanavos
		{
764 255f5f86 Panagiotis Kanavos
			_events.Publish(notification);
765 255f5f86 Panagiotis Kanavos
		}
766 e5b65606 Panagiotis Kanavos
767 4ec636f6 Panagiotis Kanavos
768 255f5f86 Panagiotis Kanavos
		public void RemoveMonitor(string accountName)
769 4ec636f6 Panagiotis Kanavos
		{
770 4ec636f6 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(accountName))
771 4ec636f6 Panagiotis Kanavos
				return;
772 4ec636f6 Panagiotis Kanavos
773 4ec636f6 Panagiotis Kanavos
			var accountInfo=_accounts.FirstOrDefault(account => account.UserName == accountName);
774 8e89b160 Panagiotis Kanavos
            if (accountInfo != null)
775 8e89b160 Panagiotis Kanavos
            {
776 8e89b160 Panagiotis Kanavos
                _accounts.TryRemove(accountInfo);
777 8e89b160 Panagiotis Kanavos
                _pollAgent.RemoveAccount(accountInfo);
778 8e89b160 Panagiotis Kanavos
            }
779 4ec636f6 Panagiotis Kanavos
780 8e89b160 Panagiotis Kanavos
		    PithosMonitor monitor;
781 4ec636f6 Panagiotis Kanavos
			if (Monitors.TryRemove(accountName, out monitor))
782 4ec636f6 Panagiotis Kanavos
			{
783 4ec636f6 Panagiotis Kanavos
				monitor.Stop();
784 7f5882da Panagiotis Kanavos
                //TODO: Also remove any pending actions for this account
785 7f5882da Panagiotis Kanavos
                //from the network queue                
786 4ec636f6 Panagiotis Kanavos
			}
787 4ec636f6 Panagiotis Kanavos
		}
788 4ec636f6 Panagiotis Kanavos
789 4ec636f6 Panagiotis Kanavos
		public void RefreshOverlays()
790 4ec636f6 Panagiotis Kanavos
		{
791 4ec636f6 Panagiotis Kanavos
			foreach (var pair in Monitors)
792 4ec636f6 Panagiotis Kanavos
			{
793 4ec636f6 Panagiotis Kanavos
				var monitor = pair.Value;
794 4ec636f6 Panagiotis Kanavos
795 4ec636f6 Panagiotis Kanavos
				var path = monitor.RootPath;
796 4ec636f6 Panagiotis Kanavos
797 4ec636f6 Panagiotis Kanavos
				if (String.IsNullOrWhiteSpace(path))
798 4ec636f6 Panagiotis Kanavos
					continue;
799 4ec636f6 Panagiotis Kanavos
800 4ec636f6 Panagiotis Kanavos
				if (!Directory.Exists(path) && !File.Exists(path))
801 4ec636f6 Panagiotis Kanavos
					continue;
802 4ec636f6 Panagiotis Kanavos
803 4ec636f6 Panagiotis Kanavos
				IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
804 4ec636f6 Panagiotis Kanavos
805 4ec636f6 Panagiotis Kanavos
				try
806 4ec636f6 Panagiotis Kanavos
				{
807 4ec636f6 Panagiotis Kanavos
					NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM,
808 4ec636f6 Panagiotis Kanavos
												 HChangeNotifyFlags.SHCNF_PATHW | HChangeNotifyFlags.SHCNF_FLUSHNOWAIT,
809 4ec636f6 Panagiotis Kanavos
												 pathPointer, IntPtr.Zero);
810 4ec636f6 Panagiotis Kanavos
				}
811 4ec636f6 Panagiotis Kanavos
				finally
812 4ec636f6 Panagiotis Kanavos
				{
813 4ec636f6 Panagiotis Kanavos
					Marshal.FreeHGlobal(pathPointer);
814 4ec636f6 Panagiotis Kanavos
				}
815 4ec636f6 Panagiotis Kanavos
			}
816 4ec636f6 Panagiotis Kanavos
		}
817 4ec636f6 Panagiotis Kanavos
818 4ec636f6 Panagiotis Kanavos
		#region Event Handlers
819 4ec636f6 Panagiotis Kanavos
		
820 4ec636f6 Panagiotis Kanavos
		public void Handle(SelectiveSynchChanges message)
821 4ec636f6 Panagiotis Kanavos
		{
822 4ec636f6 Panagiotis Kanavos
			var accountName = message.Account.AccountName;
823 4ec636f6 Panagiotis Kanavos
			PithosMonitor monitor;
824 4ec636f6 Panagiotis Kanavos
			if (_monitors.TryGetValue(accountName, out monitor))
825 4ec636f6 Panagiotis Kanavos
			{
826 759bd3c4 Panagiotis Kanavos
				monitor.SetSelectivePaths(message.Uris,message.Added,message.Removed);
827 4ec636f6 Panagiotis Kanavos
828 4ec636f6 Panagiotis Kanavos
			}
829 4ec636f6 Panagiotis Kanavos
			
830 4ec636f6 Panagiotis Kanavos
		}
831 4ec636f6 Panagiotis Kanavos
832 4ec636f6 Panagiotis Kanavos
833 7f5882da Panagiotis Kanavos
		private bool _pollStarted;
834 eae84ae8 Panagiotis Kanavos
835 255f5f86 Panagiotis Kanavos
		//SMELL: Doing so much work for notifications in the shell is wrong
836 255f5f86 Panagiotis Kanavos
		//The notifications should be moved to their own view/viewmodel pair
837 255f5f86 Panagiotis Kanavos
		//and different templates should be used for different message types
838 255f5f86 Panagiotis Kanavos
		//This will also allow the addition of extra functionality, eg. actions
839 255f5f86 Panagiotis Kanavos
		//
840 4ec636f6 Panagiotis Kanavos
		public void Handle(Notification notification)
841 4ec636f6 Panagiotis Kanavos
		{
842 255f5f86 Panagiotis Kanavos
			UpdateStatus();
843 e5b65606 Panagiotis Kanavos
844 4ec636f6 Panagiotis Kanavos
			if (!Settings.ShowDesktopNotifications)
845 4ec636f6 Panagiotis Kanavos
				return;
846 eae84ae8 Panagiotis Kanavos
847 255f5f86 Panagiotis Kanavos
			if (notification is PollNotification)
848 255f5f86 Panagiotis Kanavos
			{
849 255f5f86 Panagiotis Kanavos
				_pollStarted = true;
850 255f5f86 Panagiotis Kanavos
				return;
851 255f5f86 Panagiotis Kanavos
			}
852 255f5f86 Panagiotis Kanavos
			if (notification is CloudNotification)
853 255f5f86 Panagiotis Kanavos
			{
854 255f5f86 Panagiotis Kanavos
				if (!_pollStarted) 
855 255f5f86 Panagiotis Kanavos
					return;
856 255f5f86 Panagiotis Kanavos
				_pollStarted= false;
857 255f5f86 Panagiotis Kanavos
				notification.Title = "Pithos";
858 255f5f86 Panagiotis Kanavos
				notification.Message = "Start Synchronisation";
859 255f5f86 Panagiotis Kanavos
			}
860 255f5f86 Panagiotis Kanavos
861 6bcdd8e2 Panagiotis Kanavos
		    var progress = notification as ProgressNotification;
862 6bcdd8e2 Panagiotis Kanavos
		    if (progress != null)
863 6bcdd8e2 Panagiotis Kanavos
		    {
864 174bbb6e Panagiotis Kanavos
		        StatusMessage = String.Format("Pithos {0}\r\n{1} {2:p2} of {3} - {4}",
865 6bcdd8e2 Panagiotis Kanavos
		                                      _fileVersion.Value.FileVersion, 
866 6bcdd8e2 Panagiotis Kanavos
                                              progress.Action,
867 6bcdd8e2 Panagiotis Kanavos
		                                      progress.Block/(double)progress.TotalBlocks,
868 6bcdd8e2 Panagiotis Kanavos
		                                      progress.FileSize.ToByteSize(),
869 6bcdd8e2 Panagiotis Kanavos
		                                      progress.FileName);
870 6bcdd8e2 Panagiotis Kanavos
		        return;
871 6bcdd8e2 Panagiotis Kanavos
		    }
872 6bcdd8e2 Panagiotis Kanavos
873 174bbb6e Panagiotis Kanavos
		    var info = notification as StatusNotification;
874 174bbb6e Panagiotis Kanavos
            if (info != null)
875 174bbb6e Panagiotis Kanavos
            {
876 174bbb6e Panagiotis Kanavos
                StatusMessage = String.Format("Pithos {0}\r\n{1}",
877 174bbb6e Panagiotis Kanavos
                                              _fileVersion.Value.FileVersion,
878 174bbb6e Panagiotis Kanavos
                                              info.Title);
879 174bbb6e Panagiotis Kanavos
                return;
880 174bbb6e Panagiotis Kanavos
            }
881 255f5f86 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(notification.Message) && String.IsNullOrWhiteSpace(notification.Title))
882 255f5f86 Panagiotis Kanavos
				return;
883 2dc6f765 Panagiotis Kanavos
884 174bbb6e Panagiotis Kanavos
			ShowBalloonFor(notification);
885 4ec636f6 Panagiotis Kanavos
		}
886 174bbb6e Panagiotis Kanavos
887 174bbb6e Panagiotis Kanavos
	    private void ShowBalloonFor(Notification notification)
888 174bbb6e Panagiotis Kanavos
	    {
889 174bbb6e Panagiotis Kanavos
            Contract.Requires(notification!=null);
890 174bbb6e Panagiotis Kanavos
            
891 174bbb6e Panagiotis Kanavos
            if (!Settings.ShowDesktopNotifications) 
892 174bbb6e Panagiotis Kanavos
                return;
893 174bbb6e Panagiotis Kanavos
            
894 174bbb6e Panagiotis Kanavos
            BalloonIcon icon;
895 174bbb6e Panagiotis Kanavos
	        switch (notification.Level)
896 174bbb6e Panagiotis Kanavos
	        {
897 174bbb6e Panagiotis Kanavos
	            case TraceLevel.Info:
898 174bbb6e Panagiotis Kanavos
	            case TraceLevel.Verbose:
899 174bbb6e Panagiotis Kanavos
	                return;
900 174bbb6e Panagiotis Kanavos
                case TraceLevel.Error:
901 174bbb6e Panagiotis Kanavos
                    icon = BalloonIcon.Error;
902 174bbb6e Panagiotis Kanavos
                    break;
903 174bbb6e Panagiotis Kanavos
                case TraceLevel.Warning:
904 174bbb6e Panagiotis Kanavos
	                icon = BalloonIcon.Warning;
905 174bbb6e Panagiotis Kanavos
	                break;
906 174bbb6e Panagiotis Kanavos
	            default:
907 174bbb6e Panagiotis Kanavos
	                return;
908 174bbb6e Panagiotis Kanavos
	        }
909 174bbb6e Panagiotis Kanavos
910 174bbb6e Panagiotis Kanavos
	        var tv = (ShellView) GetView();
911 174bbb6e Panagiotis Kanavos
	        System.Action clickAction = null;
912 174bbb6e Panagiotis Kanavos
	        if (notification is ExpirationNotification)
913 174bbb6e Panagiotis Kanavos
	        {
914 174bbb6e Panagiotis Kanavos
	            clickAction = () => ShowPreferences("AccountTab");
915 174bbb6e Panagiotis Kanavos
	        }
916 174bbb6e Panagiotis Kanavos
	        var balloon = new PithosBalloon
917 174bbb6e Panagiotis Kanavos
	                          {
918 174bbb6e Panagiotis Kanavos
	                              Title = notification.Title,
919 174bbb6e Panagiotis Kanavos
	                              Message = notification.Message,
920 174bbb6e Panagiotis Kanavos
	                              Icon = icon,
921 174bbb6e Panagiotis Kanavos
	                              ClickAction = clickAction
922 174bbb6e Panagiotis Kanavos
	                          };
923 174bbb6e Panagiotis Kanavos
	        tv.TaskbarView.ShowCustomBalloon(balloon, PopupAnimation.Fade, 4000);
924 174bbb6e Panagiotis Kanavos
	    }
925 174bbb6e Panagiotis Kanavos
926 174bbb6e Panagiotis Kanavos
	    #endregion
927 4ec636f6 Panagiotis Kanavos
928 4ec636f6 Panagiotis Kanavos
		public void Handle(ShowFilePropertiesEvent message)
929 4ec636f6 Panagiotis Kanavos
		{
930 4ec636f6 Panagiotis Kanavos
			if (message == null)
931 4ec636f6 Panagiotis Kanavos
				throw new ArgumentNullException("message");
932 4ec636f6 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(message.FileName) )
933 4ec636f6 Panagiotis Kanavos
				throw new ArgumentException("message");
934 4ec636f6 Panagiotis Kanavos
			Contract.EndContractBlock();
935 4ec636f6 Panagiotis Kanavos
936 4ec636f6 Panagiotis Kanavos
			var fileName = message.FileName;
937 255f5f86 Panagiotis Kanavos
			//TODO: Display file properties for non-container folders
938 4ec636f6 Panagiotis Kanavos
			if (File.Exists(fileName))
939 255f5f86 Panagiotis Kanavos
				//Retrieve the full name with exact casing. Pithos names are case sensitive				
940 255f5f86 Panagiotis Kanavos
				ShowFileProperties(FileInfoExtensions.GetProperFilePathCapitalization(fileName));
941 4ec636f6 Panagiotis Kanavos
			else if (Directory.Exists(fileName))
942 255f5f86 Panagiotis Kanavos
				//Retrieve the full name with exact casing. Pithos names are case sensitive
943 4f6d51d4 Panagiotis Kanavos
			{
944 255f5f86 Panagiotis Kanavos
				var path = FileInfoExtensions.GetProperDirectoryCapitalization(fileName);
945 255f5f86 Panagiotis Kanavos
				if (IsContainer(path))
946 255f5f86 Panagiotis Kanavos
					ShowContainerProperties(path);
947 255f5f86 Panagiotis Kanavos
				else
948 255f5f86 Panagiotis Kanavos
					ShowFileProperties(path);
949 4f6d51d4 Panagiotis Kanavos
			}
950 4ec636f6 Panagiotis Kanavos
		}
951 4f6d51d4 Panagiotis Kanavos
952 255f5f86 Panagiotis Kanavos
		private bool IsContainer(string path)
953 255f5f86 Panagiotis Kanavos
		{
954 255f5f86 Panagiotis Kanavos
			var matchingFolders = from account in _accounts
955 255f5f86 Panagiotis Kanavos
								  from rootFolder in Directory.GetDirectories(account.AccountPath)
956 255f5f86 Panagiotis Kanavos
								  where rootFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase)
957 255f5f86 Panagiotis Kanavos
								  select rootFolder;
958 255f5f86 Panagiotis Kanavos
			return matchingFolders.Any();
959 255f5f86 Panagiotis Kanavos
		}
960 255f5f86 Panagiotis Kanavos
961 255f5f86 Panagiotis Kanavos
		public FileStatus GetFileStatus(string localFileName)
962 255f5f86 Panagiotis Kanavos
		{
963 255f5f86 Panagiotis Kanavos
			if (String.IsNullOrWhiteSpace(localFileName))
964 255f5f86 Panagiotis Kanavos
				throw new ArgumentNullException("localFileName");
965 255f5f86 Panagiotis Kanavos
			Contract.EndContractBlock();
966 255f5f86 Panagiotis Kanavos
			
967 255f5f86 Panagiotis Kanavos
			var statusKeeper = IoC.Get<IStatusKeeper>();
968 255f5f86 Panagiotis Kanavos
			var status=statusKeeper.GetFileStatus(localFileName);
969 255f5f86 Panagiotis Kanavos
			return status;
970 255f5f86 Panagiotis Kanavos
		}
971 4ec636f6 Panagiotis Kanavos
	}
972 9bae55d1 Panagiotis Kanavos
}