Revision 71374945
b/trunk/Pithos.OFM/CloudFilesView.xaml | ||
---|---|---|
4 | 4 |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
5 | 5 |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Pithos.OFM" |
6 | 6 |
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro" |
7 |
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=WPFToolkit.Extended" |
|
7 | 8 |
mc:Ignorable="d" |
8 | 9 |
d:DesignHeight="300" d:DesignWidth="300"> |
9 | 10 |
<Grid> |
10 |
<TreeView Name="CloudInfos" Grid.Row="1" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" |
|
11 |
<Grid.RowDefinitions> |
|
12 |
<RowDefinition Height="Auto"/> |
|
13 |
<RowDefinition/> |
|
14 |
<RowDefinition Height="Auto"/> |
|
15 |
</Grid.RowDefinitions> |
|
16 |
<TextBlock Grid.Row="0" >Pithos</TextBlock> |
|
17 |
<xctk:BusyIndicator Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsBusy="{Binding IsCloudBusy}" |
|
18 |
BusyContent="{Binding CloudBusyMessage}" > |
|
19 |
|
|
20 |
<TreeView Name="CloudInfos" Grid.Row="1" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" |
|
11 | 21 |
cal:Message.Attach="[Event SelectedItemChanged] = [Action SelectCloudFile($eventArgs)]"> |
12 | 22 |
<TreeView.ItemTemplate> |
13 | 23 |
<HierarchicalDataTemplate DataType="{x:Type local:ObjectRecord}" ItemsSource="{Binding Directories}"> |
... | ... | |
17 | 27 |
</HierarchicalDataTemplate> |
18 | 28 |
</TreeView.ItemTemplate> |
19 | 29 |
</TreeView> |
20 |
|
|
30 |
</xctk:BusyIndicator> |
|
21 | 31 |
</Grid> |
22 | 32 |
</UserControl> |
b/trunk/Pithos.OFM/CloudFilesViewModel.cs | ||
---|---|---|
1 | 1 |
using System; |
2 | 2 |
using System.Collections.Generic; |
3 |
using System.ComponentModel.Composition; |
|
3 | 4 |
using System.Linq; |
4 | 5 |
using System.Text; |
6 |
using System.Threading.Tasks; |
|
7 |
using System.Windows; |
|
8 |
using Caliburn.Micro; |
|
9 |
using Pithos.Network; |
|
5 | 10 |
|
6 | 11 |
namespace Pithos.OFM |
7 | 12 |
{ |
8 |
class CloudFilesViewModel |
|
13 |
[Export] |
|
14 |
public class CloudFilesViewModel:Screen |
|
9 | 15 |
{ |
16 |
public bool IsCloudBusy |
|
17 |
{ |
|
18 |
get { return _isCloudBusy; } |
|
19 |
set |
|
20 |
{ |
|
21 |
if (value.Equals(_isCloudBusy)) return; |
|
22 |
_isCloudBusy = value; |
|
23 |
NotifyOfPropertyChange(() => IsCloudBusy); |
|
24 |
} |
|
25 |
} |
|
26 |
|
|
27 |
public bool IsCloudSelected |
|
28 |
{ |
|
29 |
get { return _isCloudSelected; } |
|
30 |
set |
|
31 |
{ |
|
32 |
if (value.Equals(_isCloudSelected)) return; |
|
33 |
_isCloudSelected = value; |
|
34 |
NotifyOfPropertyChange(() => IsCloudSelected); |
|
35 |
} |
|
36 |
} |
|
37 |
|
|
38 |
private ObjectRecord _selectedCloudFile; |
|
39 |
|
|
40 |
public ObjectRecord SelectedCloudFile |
|
41 |
{ |
|
42 |
get { return _selectedCloudFile; } |
|
43 |
set |
|
44 |
{ |
|
45 |
if (Equals(value, _selectedCloudFile)) return; |
|
46 |
_selectedCloudFile = value; |
|
47 |
NotifyOfPropertyChange(() => SelectedCloudFile); |
|
48 |
NotifyOfPropertyChange(() => CanDownload); |
|
49 |
IsCloudSelected = true; |
|
50 |
} |
|
51 |
} |
|
52 |
|
|
53 |
public bool CanDownload { get { return SelectedCloudFile != null; } } |
|
54 |
|
|
55 |
public void SelectCloudFile(RoutedPropertyChangedEventArgs<object> file) |
|
56 |
{ |
|
57 |
SelectedCloudFile = (ObjectRecord)file.NewValue; |
|
58 |
} |
|
59 |
|
|
60 |
|
|
61 |
public async Task LoadCloudFiles(string accountName, string apiKey, string serverUrl) |
|
62 |
{ |
|
63 |
await TaskEx.Yield(); |
|
64 |
IsCloudBusy = true; |
|
65 |
CloudBusyMessage = "Checking Pithos ..."; |
|
66 |
var client = new CloudFilesClient(accountName, apiKey) { AuthenticationUrl = serverUrl, UsePithos = true }; |
|
67 |
await client.Authenticate().ConfigureAwait(false); |
|
68 |
|
|
69 |
var containerInfos = await client.ListContainers(accountName).ConfigureAwait(false); |
|
70 |
var infos = from container in containerInfos |
|
71 |
from info in client.ListObjects(accountName, container.Name) |
|
72 |
select info; |
|
73 |
//Force enumeration here to get all items. Otherwise we get only the containers |
|
74 |
//and the objects will be retrieved by the UI thread during binding |
|
75 |
var rootItem = new ObjectRecord() |
|
76 |
{ |
|
77 |
DisplayName = accountName, |
|
78 |
Directories = infos.ToTree() |
|
79 |
}; |
|
80 |
|
|
81 |
CloudInfos = rootItem; |
|
82 |
IsCloudBusy = false; |
|
83 |
} |
|
84 |
|
|
85 |
|
|
86 |
public string CloudBusyMessage |
|
87 |
{ |
|
88 |
get { return _cloudBusyMessage; } |
|
89 |
set |
|
90 |
{ |
|
91 |
if (value == _cloudBusyMessage) return; |
|
92 |
_cloudBusyMessage = value; |
|
93 |
NotifyOfPropertyChange(() => CloudBusyMessage); |
|
94 |
} |
|
95 |
} |
|
96 |
|
|
97 |
public IEnumerable<ObjectRecord> CloudInfos |
|
98 |
{ |
|
99 |
get { return _cloudInfos; } |
|
100 |
set |
|
101 |
{ |
|
102 |
if (Equals(value, _cloudInfos)) return; |
|
103 |
_cloudInfos = value; |
|
104 |
NotifyOfPropertyChange(() => CloudInfos); |
|
105 |
} |
|
106 |
} |
|
107 |
|
|
108 |
|
|
109 |
private IEnumerable<ObjectRecord> _cloudInfos; |
|
110 |
|
|
111 |
private bool _isCloudBusy; |
|
112 |
private string _cloudBusyMessage; |
|
113 |
private bool _isCloudSelected; |
|
114 |
|
|
115 |
|
|
10 | 116 |
} |
11 | 117 |
} |
b/trunk/Pithos.OFM/FileManagerView.xaml | ||
---|---|---|
74 | 74 |
<r:RibbonGroup Header="Accounts"> |
75 | 75 |
<r:RibbonComboBox IsEditable="True" Text="{Binding CurrentAccount.AccountName}" > |
76 | 76 |
<r:RibbonGallery SelectedItem="{Binding CurrentAccount}" DisplayMemberPath="AccountName"> |
77 |
<r:RibbonGalleryCategory ItemsSource="{Binding Accounts}" DisplayMemberPath="AccountName" ></r:RibbonGalleryCategory>
|
|
77 |
<r:RibbonGalleryCategory ItemsSource="{Binding Accounts}" DisplayMemberPath="DisplayName" ></r:RibbonGalleryCategory>
|
|
78 | 78 |
</r:RibbonGallery> |
79 | 79 |
</r:RibbonComboBox> |
80 | 80 |
</r:RibbonGroup> |
... | ... | |
96 | 96 |
<r:RibbonContextualTabGroup Header="Cloud Files" Visibility="{Binding IsCloudSelected, Converter={StaticResource BooleanToVisibilityConverter}}"></r:RibbonContextualTabGroup> |
97 | 97 |
</r:Ribbon.ContextualTabGroups> |
98 | 98 |
</r:Ribbon> |
99 |
<xctk:BusyIndicator Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsBusy="{Binding IsLocalBusy}" |
|
100 |
BusyContent="{Binding LocalBusyMessage}" > |
|
101 |
<TreeView Name="LocalFiles" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" |
|
102 |
cal:Message.Attach="[Event SelectedItemChanged] = [Action SelectLocalFile($eventArgs)]"> |
|
103 |
<TreeView.Resources> |
|
104 |
<HierarchicalDataTemplate DataType="{x:Type local:DirectoryRecord}" ItemsSource="{Binding Infos}"> |
|
105 |
<StackPanel Orientation="Horizontal"> |
|
106 |
<Image Source="Images/Icons/Folder.ico" MaxWidth="16" MaxHeight="16" Margin="1" Stretch="Uniform" /> |
|
107 |
<TextBlock x:Name="Name" Text="{Binding Info.Name}"/> |
|
108 |
</StackPanel> |
|
109 |
</HierarchicalDataTemplate> |
|
110 |
<HierarchicalDataTemplate DataType="{x:Type local:FileRecord}" > |
|
111 |
<StackPanel Orientation="Horizontal"> |
|
112 |
<TextBlock x:Name="Name" Margin="16,0,0,0" Text="{Binding Info.Name}"/> |
|
113 |
</StackPanel> |
|
114 |
</HierarchicalDataTemplate> |
|
115 |
</TreeView.Resources> |
|
116 |
</TreeView> |
|
117 |
</xctk:BusyIndicator> |
|
99 |
<ContentControl x:Name="LocalFiles" Grid.Row="1" Grid.Column="0" ></ContentControl> |
|
118 | 100 |
<GridSplitter VerticalAlignment="Stretch" Grid.Column="1" Grid.Row="1" Width="5" |
119 | 101 |
ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" |
120 | 102 |
></GridSplitter> |
121 |
<xctk:BusyIndicator Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsBusy="{Binding IsCloudBusy}" |
|
122 |
BusyContent="{Binding CloudBusyMessage}" > |
|
123 |
<TreeView Name="CloudInfos" Grid.Row="1" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" |
|
124 |
cal:Message.Attach="[Event SelectedItemChanged] = [Action SelectCloudFile($eventArgs)]"> |
|
125 |
<TreeView.ItemTemplate> |
|
126 |
<HierarchicalDataTemplate DataType="{x:Type local:ObjectRecord}" ItemsSource="{Binding Directories}"> |
|
127 |
<StackPanel Orientation="Horizontal"> |
|
128 |
<TextBlock x:Name="Name" Margin="5,0,0,0" Text="{Binding DisplayName}"/> |
|
129 |
</StackPanel> |
|
130 |
</HierarchicalDataTemplate> |
|
131 |
</TreeView.ItemTemplate> |
|
132 |
</TreeView> |
|
133 |
</xctk:BusyIndicator> |
|
103 |
<ContentControl x:Name="CloudFiles" Grid.Row="1" Grid.Column="2" ></ContentControl> |
|
134 | 104 |
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.ColumnSpan="3" Margin="5"> |
135 | 105 |
<TextBlock >Operation Progress ...</TextBlock><ProgressBar Margin =" 5,0" Value="20" HorizontalAlignment="Left" Width="150"></ProgressBar> |
136 | 106 |
</StackPanel> |
b/trunk/Pithos.OFM/FileManagerViewModel.cs | ||
---|---|---|
14 | 14 |
[Export, PartCreationPolicy(CreationPolicy.Shared)] |
15 | 15 |
public class FileManagerViewModel:Screen |
16 | 16 |
{ |
17 |
[Import] |
|
18 |
public CloudFilesViewModel CloudFiles { get; set; } |
|
17 | 19 |
|
20 |
[Import] |
|
21 |
public LocalFilesViewModel LocalFiles { get; set; } |
|
22 |
|
|
18 | 23 |
public IEnumerable<AccountSettings> Accounts |
19 | 24 |
{ |
20 | 25 |
get { return _accounts; } |
... | ... | |
37 | 42 |
} |
38 | 43 |
} |
39 | 44 |
|
45 |
public bool IsCloudSelected |
|
46 |
{ |
|
47 |
get { return CloudFiles.IsCloudSelected; } |
|
48 |
set |
|
49 |
{ |
|
50 |
if (value.Equals(CloudFiles.IsCloudSelected)) return; |
|
51 |
CloudFiles.IsCloudSelected = value; |
|
52 |
LocalFiles.IsLocalSelected = !value; |
|
53 |
NotifyOfPropertyChange(() => IsCloudSelected); |
|
54 |
} |
|
55 |
} |
|
56 |
|
|
57 |
public bool IsLocalSelected |
|
58 |
{ |
|
59 |
get { return LocalFiles.IsLocalSelected; } |
|
60 |
set |
|
61 |
{ |
|
62 |
if (value.Equals(LocalFiles.IsLocalSelected)) return; |
|
63 |
LocalFiles.IsLocalSelected = value; |
|
64 |
IsCloudSelected = !value; |
|
65 |
NotifyOfPropertyChange(() => IsLocalSelected); |
|
66 |
} |
|
67 |
} |
|
68 |
|
|
69 |
private IEnumerable<AccountSettings> _accounts; |
|
70 |
private string _title; |
|
71 |
|
|
40 | 72 |
private AccountSettings _currentAccount; |
41 | 73 |
|
42 | 74 |
private AccountSettings _currentLoadedAccount; |
... | ... | |
65 | 97 |
this.Title = String.Format("Pithos+ OFM - {0}", _currentAccount.AccountName); |
66 | 98 |
|
67 | 99 |
|
68 |
TaskEx.Run(() => LoadLocalFiles(_currentAccount.RootPath)); |
|
100 |
|
|
101 |
TaskEx.Run(() => LocalFiles.LoadLocalFiles(_currentAccount.RootPath)); |
|
69 | 102 |
TaskEx.Run( |
70 | 103 |
() => |
71 |
LoadCloudFiles(_currentAccount.AccountName, _currentAccount.ApiKey, _currentAccount.ServerUrl)); |
|
104 |
CloudFiles.LoadCloudFiles(_currentAccount.AccountName, _currentAccount.ApiKey, _currentAccount.ServerUrl));
|
|
72 | 105 |
} |
73 | 106 |
} |
74 | 107 |
} |
75 | 108 |
|
76 |
public IEnumerable<ObjectRecord> CloudInfos |
|
77 |
{ |
|
78 |
get { return _cloudInfos; } |
|
79 |
set |
|
80 |
{ |
|
81 |
if (Equals(value, _cloudInfos)) return; |
|
82 |
_cloudInfos = value; |
|
83 |
NotifyOfPropertyChange(() => CloudInfos); |
|
84 |
} |
|
85 |
} |
|
86 | 109 |
|
87 | 110 |
|
88 |
public bool IsLocalSelected |
|
89 |
{ |
|
90 |
get { return _isLocalSelected; } |
|
91 |
set |
|
92 |
{ |
|
93 |
if (value.Equals(_isLocalSelected)) return; |
|
94 |
_isLocalSelected = value; |
|
95 |
IsCloudSelected = !value; |
|
96 |
NotifyOfPropertyChange(() => IsLocalSelected); |
|
97 |
} |
|
98 |
} |
|
99 |
|
|
100 |
public FileSystemInfo CurrentLocalItem |
|
101 |
{ |
|
102 |
get { return _currentLocalItem; } |
|
103 |
set |
|
104 |
{ |
|
105 |
if (Equals(value, _currentLocalItem)) return; |
|
106 |
_currentLocalItem = value; |
|
107 |
NotifyOfPropertyChange(() => CurrentLocalItem); |
|
108 |
|
|
109 |
} |
|
110 |
} |
|
111 |
|
|
112 | 111 |
public FileManagerViewModel() |
113 | 112 |
{ |
114 | 113 |
DisplayName = "Pithos+ OFM"; |
115 |
_watcher = new FileSystemWatcher(); |
|
116 | 114 |
// _watcher.Created += (o, e) => NotifyOfPropertyChange(()=>LocalItems); |
117 | 115 |
// _watcher.Deleted += (o, e) => NotifyOfPropertyChange(() => LocalItems); |
118 | 116 |
// _watcher.Renamed += (o, e) => NotifyOfPropertyChange(() => LocalItems); |
119 | 117 |
} |
120 | 118 |
|
121 |
readonly FileSystemWatcher _watcher; |
|
122 |
private IEnumerable<DirectoryRecord> _localFiles; |
|
123 |
private FileSystemInfo _currentLocalItem; |
|
124 |
private IEnumerable<ObjectRecord> _cloudInfos; |
|
125 |
|
|
126 |
|
|
127 |
|
|
128 |
public IEnumerable<DirectoryRecord> LocalFiles |
|
129 |
{ |
|
130 |
get { return _localFiles; } |
|
131 |
set |
|
132 |
{ |
|
133 |
if (Equals(value, _localFiles)) return; |
|
134 |
_localFiles = value; |
|
135 |
NotifyOfPropertyChange(() => LocalFiles); |
|
136 |
} |
|
137 |
} |
|
138 |
|
|
139 |
private IInfoRecord _selectedLocalFile; |
|
140 |
|
|
141 |
public IInfoRecord SelectedLocalFile |
|
142 |
{ |
|
143 |
get { return _selectedLocalFile; } |
|
144 |
set |
|
145 |
{ |
|
146 |
if (Equals(value, _selectedLocalFile)) return; |
|
147 |
_selectedLocalFile = value; |
|
148 |
NotifyOfPropertyChange(() => SelectedLocalFile); |
|
149 |
NotifyOfPropertyChange(() => CanUpload); |
|
150 |
IsLocalSelected = true; |
|
151 |
} |
|
152 |
} |
|
153 |
|
|
154 |
public void SelectLocalFile(RoutedPropertyChangedEventArgs<object> file) |
|
155 |
{ |
|
156 |
SelectedLocalFile=(IInfoRecord) file.NewValue; |
|
157 |
} |
|
158 |
|
|
159 |
private void LoadLocalFiles(string path) |
|
160 |
{ |
|
161 |
IsLocalBusy = true; |
|
162 |
LocalBusyMessage = "Reading local files ..."; |
|
163 |
if (_watcher.Path != path) |
|
164 |
{ |
|
165 |
_watcher.Path = path; |
|
166 |
_watcher.EnableRaisingEvents = true; |
|
167 |
} |
|
168 |
|
|
169 |
var folder = new DirectoryInfo(Path.Combine(path,"pithos")); |
|
170 |
LocalFiles = new List<DirectoryRecord> |
|
171 |
{ |
|
172 |
new DirectoryRecord{DirInfo=folder} |
|
173 |
}; |
|
174 |
IsLocalBusy = false; |
|
175 |
|
|
176 |
} |
|
177 |
|
|
178 |
|
|
179 |
public bool IsCloudSelected |
|
180 |
{ |
|
181 |
get { return _isCloudSelected; } |
|
182 |
set |
|
183 |
{ |
|
184 |
if (value.Equals(_isCloudSelected)) return; |
|
185 |
_isCloudSelected = value; |
|
186 |
IsLocalSelected = !value; |
|
187 |
NotifyOfPropertyChange(() => IsCloudSelected); |
|
188 |
} |
|
189 |
} |
|
190 |
|
|
191 |
private ObjectRecord _selectedCloudFile; |
|
192 |
|
|
193 |
public ObjectRecord SelectedCloudFile |
|
194 |
{ |
|
195 |
get { return _selectedCloudFile; } |
|
196 |
set |
|
197 |
{ |
|
198 |
if (Equals(value, _selectedCloudFile)) return; |
|
199 |
_selectedCloudFile = value; |
|
200 |
NotifyOfPropertyChange(() => SelectedCloudFile); |
|
201 |
NotifyOfPropertyChange(() => CanDownload); |
|
202 |
IsCloudSelected = true; |
|
203 |
} |
|
204 |
} |
|
205 |
|
|
206 |
public void SelectCloudFile(RoutedPropertyChangedEventArgs<object> file) |
|
207 |
{ |
|
208 |
SelectedCloudFile = (ObjectRecord)file.NewValue; |
|
209 |
} |
|
210 |
|
|
211 |
|
|
212 |
|
|
213 |
private async Task LoadCloudFiles(string accountName, string apiKey, string serverUrl) |
|
214 |
{ |
|
215 |
await TaskEx.Yield(); |
|
216 |
IsCloudBusy = true; |
|
217 |
CloudBusyMessage = "Checking Pithos ..."; |
|
218 |
var client = new CloudFilesClient(accountName, apiKey) { AuthenticationUrl = serverUrl, UsePithos = true }; |
|
219 |
await client.Authenticate().ConfigureAwait(false); |
|
220 | 119 |
|
221 |
var containerInfos = await client.ListContainers(accountName).ConfigureAwait(false); |
|
222 |
var infos = from container in containerInfos |
|
223 |
from info in client.ListObjects(accountName, container.Name) |
|
224 |
select info; |
|
225 |
//Force enumeration here to get all items. Otherwise we get only the containers |
|
226 |
//and the objects will be retrieved by the UI thread during binding |
|
227 |
var rootItem = new ObjectRecord() |
|
228 |
{ |
|
229 |
DisplayName = accountName, |
|
230 |
Directories = infos.ToTree() |
|
231 |
}; |
|
232 |
|
|
233 |
CloudInfos = rootItem; |
|
234 |
IsCloudBusy = false; |
|
235 |
} |
|
236 |
|
|
237 |
private bool _isLocalBusy; |
|
238 |
private bool _isCloudBusy; |
|
239 |
private string _localBusyMessage; |
|
240 |
private string _cloudBusyMessage; |
|
241 |
private IEnumerable<AccountSettings> _accounts; |
|
242 |
private string _title; |
|
243 |
private bool _isLocalSelected; |
|
244 |
private bool _isCloudSelected; |
|
245 |
|
|
246 |
public bool IsCloudBusy |
|
247 |
{ |
|
248 |
get { return _isCloudBusy; } |
|
249 |
set |
|
250 |
{ |
|
251 |
if (value.Equals(_isCloudBusy)) return; |
|
252 |
_isCloudBusy = value; |
|
253 |
NotifyOfPropertyChange(() => IsCloudBusy); |
|
254 |
} |
|
255 |
} |
|
256 |
|
|
257 |
public bool IsLocalBusy |
|
258 |
{ |
|
259 |
get { return _isLocalBusy; } |
|
260 |
set |
|
261 |
{ |
|
262 |
if (value.Equals(_isLocalBusy)) return; |
|
263 |
_isLocalBusy = value; |
|
264 |
NotifyOfPropertyChange(() => IsLocalBusy); |
|
265 |
} |
|
266 |
} |
|
267 |
|
|
268 |
public string LocalBusyMessage |
|
269 |
{ |
|
270 |
get { return _localBusyMessage; } |
|
271 |
set |
|
272 |
{ |
|
273 |
if (value == _localBusyMessage) return; |
|
274 |
_localBusyMessage = value; |
|
275 |
NotifyOfPropertyChange(() => LocalBusyMessage); |
|
276 |
} |
|
277 |
} |
|
278 |
|
|
279 |
public string CloudBusyMessage |
|
280 |
{ |
|
281 |
get { return _cloudBusyMessage; } |
|
282 |
set |
|
283 |
{ |
|
284 |
if (value == _cloudBusyMessage) return; |
|
285 |
_cloudBusyMessage = value; |
|
286 |
NotifyOfPropertyChange(() => CloudBusyMessage); |
|
287 |
} |
|
288 |
} |
|
289 | 120 |
|
290 |
public bool CanUpload { get { return SelectedLocalFile != null; } }
|
|
121 |
public bool CanUpload { get { return LocalFiles.CanUpload; } }
|
|
291 | 122 |
|
292 | 123 |
public void Upload() |
293 | 124 |
{ |
294 | 125 |
|
295 | 126 |
} |
296 | 127 |
|
297 |
public bool CanDownload { get { return SelectedCloudFile != null; } }
|
|
128 |
public bool CanDownload { get { return CloudFiles.CanDownload; } }
|
|
298 | 129 |
|
299 | 130 |
public void Download() |
300 | 131 |
{ |
b/trunk/Pithos.OFM/LocalFilesView.xaml | ||
---|---|---|
1 |
<UserControl x:Class="Pithos.OFM.LocalFilesView" |
|
2 |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
3 |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
4 |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|
5 |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|
6 |
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=WPFToolkit.Extended" |
|
7 |
xmlns:local="clr-namespace:Pithos.OFM" xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro" |
|
8 |
mc:Ignorable="d" |
|
9 |
d:DesignHeight="300" d:DesignWidth="300"> |
|
10 |
<Grid> |
|
11 |
<Grid.RowDefinitions> |
|
12 |
<RowDefinition Height="Auto"/> |
|
13 |
<RowDefinition/> |
|
14 |
<RowDefinition Height="Auto"/> |
|
15 |
</Grid.RowDefinitions> |
|
16 |
|
|
17 |
<TextBlock Grid.Row="0">Local</TextBlock> |
|
18 |
<xctk:BusyIndicator Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsBusy="{Binding IsLocalBusy}" |
|
19 |
BusyContent="{Binding LocalBusyMessage}" > |
|
20 |
<TreeView Name="LocalFiles" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" |
|
21 |
cal:Message.Attach="[Event SelectedItemChanged] = [Action SelectLocalFile($eventArgs)]"> |
|
22 |
<TreeView.Resources> |
|
23 |
<HierarchicalDataTemplate DataType="{x:Type local:DirectoryRecord}" ItemsSource="{Binding Infos}"> |
|
24 |
<StackPanel Orientation="Horizontal"> |
|
25 |
<Image Source="Images/Icons/Folder.ico" MaxWidth="16" MaxHeight="16" Margin="1" Stretch="Uniform" /> |
|
26 |
<TextBlock x:Name="Name" Text="{Binding Info.Name}"/> |
|
27 |
</StackPanel> |
|
28 |
</HierarchicalDataTemplate> |
|
29 |
<HierarchicalDataTemplate DataType="{x:Type local:FileRecord}" > |
|
30 |
<StackPanel Orientation="Horizontal"> |
|
31 |
<TextBlock x:Name="Name" Margin="16,0,0,0" Text="{Binding Info.Name}"/> |
|
32 |
</StackPanel> |
|
33 |
</HierarchicalDataTemplate> |
|
34 |
</TreeView.Resources> |
|
35 |
</TreeView> |
|
36 |
</xctk:BusyIndicator> |
|
37 |
|
|
38 |
</Grid> |
|
39 |
</UserControl> |
b/trunk/Pithos.OFM/LocalFilesView.xaml.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Linq; |
|
4 |
using System.Text; |
|
5 |
using System.Windows; |
|
6 |
using System.Windows.Controls; |
|
7 |
using System.Windows.Data; |
|
8 |
using System.Windows.Documents; |
|
9 |
using System.Windows.Input; |
|
10 |
using System.Windows.Media; |
|
11 |
using System.Windows.Media.Imaging; |
|
12 |
using System.Windows.Navigation; |
|
13 |
using System.Windows.Shapes; |
|
14 |
|
|
15 |
namespace Pithos.OFM |
|
16 |
{ |
|
17 |
/// <summary> |
|
18 |
/// Interaction logic for LocalFilesView.xaml |
|
19 |
/// </summary> |
|
20 |
public partial class LocalFilesView : UserControl |
|
21 |
{ |
|
22 |
public LocalFilesView() |
|
23 |
{ |
|
24 |
InitializeComponent(); |
|
25 |
} |
|
26 |
} |
|
27 |
} |
b/trunk/Pithos.OFM/LocalFilesViewModel.cs | ||
---|---|---|
1 | 1 |
using System; |
2 | 2 |
using System.Collections.Generic; |
3 |
using System.ComponentModel.Composition; |
|
4 |
using System.IO; |
|
3 | 5 |
using System.Linq; |
4 | 6 |
using System.Text; |
7 |
using System.Windows; |
|
8 |
using Caliburn.Micro; |
|
9 |
using Pithos.Interfaces; |
|
5 | 10 |
|
6 | 11 |
namespace Pithos.OFM |
7 | 12 |
{ |
8 |
class LocalFilesViewModel |
|
13 |
[Export] |
|
14 |
public class LocalFilesViewModel:Screen |
|
9 | 15 |
{ |
16 |
private IEnumerable<DirectoryRecord> _localFiles; |
|
17 |
|
|
18 |
private FileSystemInfo _currentLocalItem; |
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
public IEnumerable<DirectoryRecord> LocalFiles |
|
23 |
{ |
|
24 |
get { return _localFiles; } |
|
25 |
set |
|
26 |
{ |
|
27 |
if (Equals(value, _localFiles)) return; |
|
28 |
_localFiles = value; |
|
29 |
NotifyOfPropertyChange(() => LocalFiles); |
|
30 |
} |
|
31 |
} |
|
32 |
|
|
33 |
private IInfoRecord _selectedLocalFile; |
|
34 |
|
|
35 |
public IInfoRecord SelectedLocalFile |
|
36 |
{ |
|
37 |
get { return _selectedLocalFile; } |
|
38 |
set |
|
39 |
{ |
|
40 |
if (Equals(value, _selectedLocalFile)) return; |
|
41 |
_selectedLocalFile = value; |
|
42 |
NotifyOfPropertyChange(() => SelectedLocalFile); |
|
43 |
NotifyOfPropertyChange(() => CanUpload); |
|
44 |
IsLocalSelected = true; |
|
45 |
} |
|
46 |
} |
|
47 |
|
|
48 |
public bool CanUpload { get { return SelectedLocalFile != null; } } |
|
49 |
|
|
50 |
|
|
51 |
|
|
52 |
|
|
53 |
private bool _isLocalBusy; |
|
54 |
private string _localBusyMessage; |
|
55 |
private bool _isLocalSelected; |
|
56 |
|
|
57 |
public void SelectLocalFile(RoutedPropertyChangedEventArgs<object> file) |
|
58 |
{ |
|
59 |
SelectedLocalFile = (IInfoRecord)file.NewValue; |
|
60 |
} |
|
61 |
|
|
62 |
|
|
63 |
public bool IsLocalBusy |
|
64 |
{ |
|
65 |
get { return _isLocalBusy; } |
|
66 |
set |
|
67 |
{ |
|
68 |
if (value.Equals(_isLocalBusy)) return; |
|
69 |
_isLocalBusy = value; |
|
70 |
NotifyOfPropertyChange(() => IsLocalBusy); |
|
71 |
} |
|
72 |
} |
|
73 |
|
|
74 |
public string LocalBusyMessage |
|
75 |
{ |
|
76 |
get { return _localBusyMessage; } |
|
77 |
set |
|
78 |
{ |
|
79 |
if (value == _localBusyMessage) return; |
|
80 |
_localBusyMessage = value; |
|
81 |
NotifyOfPropertyChange(() => LocalBusyMessage); |
|
82 |
} |
|
83 |
} |
|
84 |
|
|
85 |
public void LoadLocalFiles(string path) |
|
86 |
{ |
|
87 |
IsLocalBusy = true; |
|
88 |
LocalBusyMessage = "Reading local files ..."; |
|
89 |
if (_watcher.Path != path) |
|
90 |
{ |
|
91 |
_watcher.Path = path; |
|
92 |
_watcher.EnableRaisingEvents = true; |
|
93 |
} |
|
94 |
|
|
95 |
var folder = new DirectoryInfo(Path.Combine(path, "pithos")); |
|
96 |
LocalFiles = new List<DirectoryRecord> |
|
97 |
{ |
|
98 |
new DirectoryRecord{DirInfo=folder} |
|
99 |
}; |
|
100 |
IsLocalBusy = false; |
|
101 |
|
|
102 |
} |
|
103 |
|
|
104 |
readonly FileSystemWatcher _watcher; |
|
105 |
|
|
106 |
|
|
107 |
|
|
108 |
public bool IsLocalSelected |
|
109 |
{ |
|
110 |
get { return _isLocalSelected; } |
|
111 |
set |
|
112 |
{ |
|
113 |
if (value.Equals(_isLocalSelected)) return; |
|
114 |
_isLocalSelected = value; |
|
115 |
NotifyOfPropertyChange(() => IsLocalSelected); |
|
116 |
} |
|
117 |
} |
|
118 |
|
|
119 |
public FileSystemInfo CurrentLocalItem |
|
120 |
{ |
|
121 |
get { return _currentLocalItem; } |
|
122 |
set |
|
123 |
{ |
|
124 |
if (Equals(value, _currentLocalItem)) return; |
|
125 |
_currentLocalItem = value; |
|
126 |
NotifyOfPropertyChange(() => CurrentLocalItem); |
|
127 |
|
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
public LocalFilesViewModel() |
|
132 |
{ |
|
133 |
_watcher = new FileSystemWatcher(); |
|
134 |
|
|
135 |
} |
|
136 |
|
|
10 | 137 |
} |
11 | 138 |
} |
b/trunk/Pithos.OFM/Pithos.OFM.csproj | ||
---|---|---|
74 | 74 |
</Reference> |
75 | 75 |
</ItemGroup> |
76 | 76 |
<ItemGroup> |
77 |
<Compile Include="..\CommonAssemblyVersion.cs">
|
|
77 |
<Compile Include="..\CommonAssemblyVersion.cs"> |
|
78 | 78 |
<Link>AssemblyVersion.cs</Link> |
79 |
</Compile>
|
|
79 |
</Compile> |
|
80 | 80 |
<Compile Include="CloudFilesView.xaml.cs"> |
81 | 81 |
<DependentUpon>CloudFilesView.xaml</DependentUpon> |
82 | 82 |
</Compile> |
... | ... | |
90 | 90 |
<DependentUpon>OFM.xaml</DependentUpon> |
91 | 91 |
</Compile> |
92 | 92 |
<Compile Include="InfoRecord.cs" /> |
93 |
<Compile Include="LocalFilesView.xaml.cs"> |
|
94 |
<DependentUpon>LocalFilesView.xaml</DependentUpon> |
|
95 |
</Compile> |
|
93 | 96 |
<Compile Include="LocalFilesViewModel.cs" /> |
94 | 97 |
<Compile Include="ObjectRecord.cs" /> |
95 | 98 |
<Compile Include="OFM.cs" /> |
... | ... | |
108 | 111 |
<SubType>Designer</SubType> |
109 | 112 |
<Generator>MSBuild:Compile</Generator> |
110 | 113 |
</Page> |
114 |
<Page Include="LocalFilesView.xaml"> |
|
115 |
<SubType>Designer</SubType> |
|
116 |
<Generator>MSBuild:Compile</Generator> |
|
117 |
</Page> |
|
111 | 118 |
</ItemGroup> |
112 | 119 |
<ItemGroup> |
113 | 120 |
<None Include="pithos.snk" /> |
Also available in: Unified diff