Added Reason column
[pithos-ms-client] / trunk / Pithos.Client.WPF / FileProperties / ConflictsViewModel.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.ComponentModel;
5 using System.ComponentModel.Composition;
6 using System.Diagnostics;
7 using System.IO;
8 using System.Linq;
9 using System.Text;
10 using Caliburn.Micro;
11 using Pithos.Client.WPF.Converters;
12 using Pithos.Core;
13 using Pithos.Interfaces;
14
15 namespace Pithos.Client.WPF.FileProperties
16 {
17     [TypeConverter(typeof(EnumTypeConverter))]
18     public enum ConflictAction
19     {
20         [Description("Defer Decision")]
21         Defer,
22         [Description("Keep Local")]
23         KeepLocal,
24         [Description("Keep Server")]
25         KeepServer,
26         [Description("Keep Both")]
27         KeepBoth,
28         [Description("Clear Record")]
29         ClearLocal
30     }
31
32     public class ConflictFile:PropertyChangedBase
33     {
34         private string _filePath;
35         public string FilePath
36         {
37             get { return _filePath; }
38             set
39             {
40                 _filePath = value;
41                 NotifyOfPropertyChange(()=>FilePath);
42             }
43         }
44
45         private string _reason;
46         public string Reason
47         {
48             get { return _reason; }
49             set
50             {
51                 _reason = value;
52                 NotifyOfPropertyChange(() => Reason);
53             }
54         }
55
56         private ConflictAction _action;
57         public ConflictAction Action
58         {
59             get { return _action; }
60             set
61             {
62                 _action = value;
63                 NotifyOfPropertyChange(()=>Action);
64             }
65         }
66
67         public DateTime LocalModified { get; set; }
68
69         public DateTime CloudModified { get; set; }
70
71         public void GoToFile()
72         {
73             if (!File.Exists(FilePath) && !Directory.Exists(FilePath))
74                 return;
75             Process.Start("explorer.exe", "/select, " + FilePath);
76         }
77     }
78     [Export(typeof(ConflictsViewModel))]
79     class ConflictsViewModel:Screen
80     {
81         [Import]
82         public IStatusKeeper StatusKeeper { get; set; }
83
84         [Import]
85         public IConflictResolver Resolver { get; set; }
86
87         private readonly ObservableCollection<ConflictFile> _conflicts;
88
89         public ObservableCollection<ConflictFile> Conflicts
90         {
91             get { return _conflicts; }
92         }
93
94         public string[]  Actions
95         {
96             get { return new[] {"Keep Local", "Keep Server", "Keep Both"}; }
97         }
98
99         public ConflictsViewModel()
100         {
101                         this.DisplayName="Conflicts";
102             var conflicts = from state in FileState.Queryable
103                             where state.FileStatus == FileStatus.Conflict ||
104                                   state.OverlayStatus == FileOverlayStatus.Conflict
105                             let info=FileInfoExtensions.FromPath(state.FilePath)
106                             select new ConflictFile {FilePath = state.FilePath,Reason=state.ConflictReason,LocalModified = info.LastWriteTime};          
107             _conflicts = new ObservableCollection<ConflictFile>(conflicts.ToList());
108             
109         }
110
111         /// <summary>
112         /// Open an explorer window to the target path's directory
113         /// and select the file
114         /// </summary>
115         /// <param name="entry"></param>
116         public void GoToFile(string fullPath)
117         {
118             if (!File.Exists(fullPath) && !Directory.Exists(fullPath))
119                 return;
120             Process.Start("explorer.exe", "/select, " + fullPath);
121         }
122
123         public void Apply()
124         {
125             var conflicts = from conflict in Conflicts
126                             where conflict.Action != ConflictAction.Defer
127                             select conflict;
128             Resolver.Resolve(conflicts);
129             
130             TryClose(true);
131         }
132
133         public void Cancel()
134         {
135             TryClose(false);
136         }
137
138         
139     }
140
141     internal interface IConflictResolver
142     {
143         void Resolve(IEnumerable<ConflictFile> conflicts);
144     }
145 }