root / trunk / Pithos.Client.WPF / FileProperties / ContainerPropertiesViewModel.cs @ 4671d606
History | View | Annotate | Download (13.3 kB)
1 |
#region |
---|---|
2 |
/* ----------------------------------------------------------------------- |
3 |
* <copyright file="ContainerPropertiesViewModel.cs" company="GRNet"> |
4 |
* |
5 |
* Copyright 2011-2012 GRNET S.A. All rights reserved. |
6 |
* |
7 |
* Redistribution and use in source and binary forms, with or |
8 |
* without modification, are permitted provided that the following |
9 |
* conditions are met: |
10 |
* |
11 |
* 1. Redistributions of source code must retain the above |
12 |
* copyright notice, this list of conditions and the following |
13 |
* disclaimer. |
14 |
* |
15 |
* 2. Redistributions in binary form must reproduce the above |
16 |
* copyright notice, this list of conditions and the following |
17 |
* disclaimer in the documentation and/or other materials |
18 |
* provided with the distribution. |
19 |
* |
20 |
* |
21 |
* THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
22 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
25 |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 |
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
29 |
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
31 |
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 |
* POSSIBILITY OF SUCH DAMAGE. |
33 |
* |
34 |
* The views and conclusions contained in the software and |
35 |
* documentation are those of the authors and should not be |
36 |
* interpreted as representing official policies, either expressed |
37 |
* or implied, of GRNET S.A. |
38 |
* </copyright> |
39 |
* ----------------------------------------------------------------------- |
40 |
*/ |
41 |
#endregion |
42 |
using System; |
43 |
using System.Collections.Concurrent; |
44 |
using System.Collections.Generic; |
45 |
using System.Collections.ObjectModel; |
46 |
using System.ComponentModel.Composition; |
47 |
using System.Diagnostics.Contracts; |
48 |
using System.IO; |
49 |
using System.Linq; |
50 |
using System.Net; |
51 |
using System.Text; |
52 |
using System.Threading.Tasks; |
53 |
using System.Windows; |
54 |
using Caliburn.Micro; |
55 |
using Pithos.Network; |
56 |
|
57 |
namespace Pithos.Client.WPF.FileProperties |
58 |
{ |
59 |
[Export(typeof(ContainerPropertiesViewModel))] |
60 |
public class ContainerPropertiesViewModel:Screen |
61 |
{ |
62 |
private string _containerName; |
63 |
|
64 |
/// <summary> |
65 |
/// Name of the displayed container |
66 |
/// </summary> |
67 |
public string ContainerName |
68 |
{ |
69 |
get { return _containerName; } |
70 |
set |
71 |
{ |
72 |
_containerName = value; |
73 |
NotifyOfPropertyChange(()=>ContainerName); |
74 |
} |
75 |
} |
76 |
|
77 |
private string _title; |
78 |
/// <summary> |
79 |
/// Window title |
80 |
/// </summary> |
81 |
public string Title |
82 |
{ |
83 |
get { return _title; } |
84 |
set |
85 |
{ |
86 |
_title = value; |
87 |
NotifyOfPropertyChange(() => Title); |
88 |
} |
89 |
} |
90 |
|
91 |
private long _count; |
92 |
|
93 |
/// <summary> |
94 |
/// Count of files in the container |
95 |
/// </summary> |
96 |
public long Count |
97 |
{ |
98 |
get { return _count; } |
99 |
set |
100 |
{ |
101 |
_count = value; |
102 |
NotifyOfPropertyChange(() => Count); |
103 |
} |
104 |
} |
105 |
|
106 |
private DateTime _modified; |
107 |
|
108 |
/// <summary> |
109 |
/// Date of last modification |
110 |
/// </summary> |
111 |
public DateTime Modified |
112 |
{ |
113 |
get { return _modified; } |
114 |
set |
115 |
{ |
116 |
_modified = value; |
117 |
NotifyOfPropertyChange(() => Modified); |
118 |
} |
119 |
} |
120 |
|
121 |
private string _size; |
122 |
|
123 |
/// <summary> |
124 |
/// Total size of the container in bytes |
125 |
/// </summary> |
126 |
public string Size |
127 |
{ |
128 |
get { return _size; } |
129 |
set |
130 |
{ |
131 |
_size = value; |
132 |
NotifyOfPropertyChange(() => Size); |
133 |
} |
134 |
} |
135 |
|
136 |
private string _shortSize; |
137 |
|
138 |
/// <summary> |
139 |
/// Total size of the container formatted in KB,MB etc |
140 |
/// </summary> |
141 |
public string ShortSize |
142 |
{ |
143 |
get { return _shortSize; } |
144 |
set |
145 |
{ |
146 |
_shortSize = value; |
147 |
NotifyOfPropertyChange(() => ShortSize); |
148 |
} |
149 |
} |
150 |
|
151 |
private int _blockSize; |
152 |
|
153 |
/// <summary> |
154 |
/// Block size used by the container |
155 |
/// </summary> |
156 |
public int BlockSize |
157 |
{ |
158 |
get { return _blockSize; } |
159 |
set |
160 |
{ |
161 |
_blockSize = value; |
162 |
NotifyOfPropertyChange(() => BlockSize); |
163 |
} |
164 |
} |
165 |
|
166 |
private string _blockHash; |
167 |
|
168 |
/// <summary> |
169 |
/// Hash algorithm used to calculate block hashes |
170 |
/// </summary> |
171 |
public string BlockHash |
172 |
{ |
173 |
get { return _blockHash; } |
174 |
set |
175 |
{ |
176 |
_blockHash = value; |
177 |
NotifyOfPropertyChange(() => BlockHash); |
178 |
} |
179 |
} |
180 |
|
181 |
private ShellViewModel _shell; |
182 |
|
183 |
/// <summary> |
184 |
/// Reference to the parent Shell |
185 |
/// </summary> |
186 |
protected ShellViewModel Shell |
187 |
{ |
188 |
get { return _shell; } |
189 |
set |
190 |
{ |
191 |
_shell = value; |
192 |
NotifyOfPropertyChange(() => Shell); |
193 |
} |
194 |
} |
195 |
|
196 |
private ContainerInfo _container; |
197 |
/// <summary> |
198 |
/// The displayed ContainerInfo |
199 |
/// </summary> |
200 |
protected ContainerInfo Container |
201 |
{ |
202 |
get { return _container; } |
203 |
set |
204 |
{ |
205 |
_container = value; |
206 |
|
207 |
|
208 |
|
209 |
LoadFromDictionary(Tags, value.Tags); |
210 |
TagsChanged = false; |
211 |
//LoadFromDictionary(Policies, value.Policies); |
212 |
|
213 |
if (value.Policies.ContainsKey("Versioning")) |
214 |
{ |
215 |
Versioning version; |
216 |
if (Enum.TryParse(value.Policies["Versioning"], out version)) |
217 |
{ |
218 |
SelectedVersion = version; |
219 |
} |
220 |
} |
221 |
|
222 |
if (value.Policies.ContainsKey("Quota")) |
223 |
{ |
224 |
int quota; |
225 |
if (int.TryParse(value.Policies["Quota"], out quota)) |
226 |
{ |
227 |
Quota=quota; |
228 |
} |
229 |
} |
230 |
|
231 |
Title = String.Format("{0} Properties", _container.Name); |
232 |
Count = value.Count; |
233 |
ShortSize = value.Bytes.ToByteSize(); |
234 |
Size = String.Format("{0} ({1:N0} bytes)", ShortSize, value.Bytes); |
235 |
Modified = value.Last_Modified; |
236 |
BlockSize = value.BlockSize; |
237 |
BlockHash = value.BlockHash; |
238 |
ContainerName = Uri.UnescapeDataString(value.Name.Split('/').Last()); |
239 |
|
240 |
NotifyOfPropertyChange(() => Container); |
241 |
IsBusy = false; |
242 |
} |
243 |
} |
244 |
|
245 |
private int _quota; |
246 |
public int Quota |
247 |
{ |
248 |
get { return _quota; } |
249 |
set |
250 |
{ |
251 |
if (value < 0) |
252 |
throw new ArgumentOutOfRangeException("Quota"); |
253 |
|
254 |
_quota = value; |
255 |
NotifyOfPropertyChange(() => Quota); |
256 |
} |
257 |
} |
258 |
|
259 |
|
260 |
|
261 |
private Versioning[] _versions={Versioning.manual,Versioning.auto,Versioning.none}; |
262 |
public Versioning[] Versions |
263 |
{ |
264 |
get { return _versions; } |
265 |
} |
266 |
|
267 |
|
268 |
private Versioning _selectedVersion; |
269 |
public Versioning SelectedVersion |
270 |
{ |
271 |
get { return _selectedVersion; } |
272 |
set { |
273 |
_selectedVersion = value; |
274 |
NotifyOfPropertyChange(()=>SelectedVersion); |
275 |
} |
276 |
} |
277 |
|
278 |
private void LoadFromDictionary(ICollection<MetaValue> collection,Dictionary<string,string> source ) |
279 |
{ |
280 |
collection.Clear(); |
281 |
var items = from item in source |
282 |
select new MetaValue(item.Key, item.Value); |
283 |
|
284 |
items.Apply(collection.Add); |
285 |
} |
286 |
|
287 |
private MetaValue _currentTag; |
288 |
public MetaValue CurrentTag |
289 |
{ |
290 |
get { return _currentTag; } |
291 |
set |
292 |
{ |
293 |
_currentTag = (value == null) ? new MetaValue() : value.Clone(); |
294 |
_currentTag.PropertyChanged += (o, e) => NotifyOfPropertyChange(() => CanAddTag); |
295 |
|
296 |
NotifyOfPropertyChange(() => CurrentTag); |
297 |
NotifyOfPropertyChange(() => CanAddTag); |
298 |
} |
299 |
} |
300 |
|
301 |
private readonly ObservableCollection<MetaValue> _tags; |
302 |
public ObservableCollection<MetaValue> Tags |
303 |
{ |
304 |
get { return _tags; } |
305 |
} |
306 |
|
307 |
public bool CanAddTag |
308 |
{ |
309 |
get { return !String.IsNullOrWhiteSpace(CurrentTag.Name); } |
310 |
} |
311 |
|
312 |
public void AddTag() |
313 |
{ |
314 |
var existingTag = Tags.FirstOrDefault(tag => tag.Name == CurrentTag.Name); |
315 |
if (existingTag == null) |
316 |
Tags.Add(CurrentTag.Clone()); |
317 |
else |
318 |
{ |
319 |
existingTag.Value = CurrentTag.Value; |
320 |
} |
321 |
} |
322 |
|
323 |
/* private readonly ObservableCollection<MetaValue> _policies; |
324 |
public ObservableCollection<MetaValue> Policies |
325 |
{ |
326 |
get { return _policies; } |
327 |
}*/ |
328 |
|
329 |
private bool _tagsChanged; |
330 |
public bool TagsChanged |
331 |
{ |
332 |
get { return _tagsChanged; } |
333 |
private set |
334 |
{ |
335 |
_tagsChanged = value; |
336 |
NotifyOfPropertyChange(()=>TagsChanged); |
337 |
NotifyOfPropertyChange(() => CanApplyChanges); |
338 |
} |
339 |
} |
340 |
|
341 |
//public bool PoliciesChanged { get; private set; } |
342 |
|
343 |
private bool _isBusy=true; |
344 |
public bool IsBusy |
345 |
{ |
346 |
get { return _isBusy; } |
347 |
set |
348 |
{ |
349 |
_isBusy = value; |
350 |
NotifyOfPropertyChange(()=>IsBusy); |
351 |
} |
352 |
} |
353 |
|
354 |
public ContainerPropertiesViewModel(ShellViewModel shell, Task<ContainerInfo> container, string localFolderName) |
355 |
{ |
356 |
if (shell==null) |
357 |
throw new ArgumentNullException("shell"); |
358 |
if (container==null) |
359 |
throw new ArgumentNullException("container"); |
360 |
if (String.IsNullOrWhiteSpace(localFolderName)) |
361 |
throw new ArgumentNullException("localFolderName"); |
362 |
Contract.EndContractBlock(); |
363 |
|
364 |
_tags = new ObservableCollection<MetaValue>(); |
365 |
_tags.CollectionChanged += (sender, evt) => { TagsChanged = true; }; |
366 |
|
367 |
CurrentTag=new MetaValue(); |
368 |
/*_policies = new ObservableCollection<MetaValue>(); |
369 |
_policies.CollectionChanged += (sender, evt) => { PoliciesChanged = true; }; |
370 |
*/ |
371 |
|
372 |
var name = Path.GetFileName(localFolderName); |
373 |
DisplayName = String.Format("{0} Container Properties", name); |
374 |
|
375 |
Shell = shell; |
376 |
ContainerName = localFolderName; |
377 |
container.ContinueWith(t =>{ |
378 |
if (t.IsFaulted) |
379 |
{ |
380 |
IsBusy = false; |
381 |
Execute.OnUIThread(() => ShowError(t.Exception)); |
382 |
this.TryClose(); |
383 |
|
384 |
} |
385 |
else |
386 |
Execute.OnUIThread(()=>Container = t.Result); |
387 |
}); |
388 |
} |
389 |
|
390 |
private void ShowError(AggregateException exception) |
391 |
{ |
392 |
MessageView view=null; |
393 |
if (exception.InnerException is RetryException) |
394 |
view=new MessageView(exception.InnerException as RetryException); |
395 |
else if (exception.InnerException is WebException) |
396 |
view = new MessageView(exception.InnerException as WebException); |
397 |
else |
398 |
view = new MessageView(exception.InnerException); |
399 |
view.ShowDialog(); |
400 |
} |
401 |
|
402 |
public void Reload() |
403 |
{ |
404 |
Container = Shell.RefreshContainerInfo(Container); |
405 |
} |
406 |
|
407 |
public override void CanClose(Action<bool> callback) |
408 |
{ |
409 |
base.CanClose(callback); |
410 |
} |
411 |
|
412 |
public void SaveChanges() |
413 |
{ |
414 |
DoSave(); |
415 |
TryClose(); |
416 |
} |
417 |
|
418 |
public void RejectChanges() |
419 |
{ |
420 |
TryClose(); |
421 |
} |
422 |
|
423 |
public void ApplyChanges() |
424 |
{ |
425 |
DoSave(); |
426 |
} |
427 |
|
428 |
public bool CanApplyChanges |
429 |
{ |
430 |
get { return TagsChanged; } |
431 |
} |
432 |
|
433 |
private void DoSave() |
434 |
{ |
435 |
|
436 |
if (TagsChanged) |
437 |
{ |
438 |
Container.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value); |
439 |
var monitor = Shell.Monitors[Container.AccountKey]; |
440 |
monitor.CloudClient.UpdateMetadata(Container); |
441 |
} |
442 |
|
443 |
//Container.Policies["Quota"] = Quota.ToString(); |
444 |
//Container.Policies["Versioning"] = Enum.GetName(typeof (Versioning), SelectedVersion); |
445 |
|
446 |
/* |
447 |
if (PoliciesChanged) |
448 |
{ |
449 |
Container.Policies = this.Policies.ToDictionary(policy=> policy.Name, tag => tag.Value); |
450 |
} |
451 |
*/ |
452 |
|
453 |
|
454 |
} |
455 |
|
456 |
} |
457 |
|
458 |
|
459 |
} |