2 // Copyright (c) 2010-2014 Yves Langisch. All rights reserved.
3 // http://cyberduck.ch/
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // Bug fixes, suggestions and comments should be sent to:
20 using System
.Collections
.Generic
;
21 using System
.Collections
.ObjectModel
;
22 using System
.Collections
.Specialized
;
24 using System
.Windows
.Forms
;
25 using BrightIdeasSoftware
;
26 using ch
.cyberduck
.core
;
27 using ch
.cyberduck
.core
.bonjour
;
28 using ch
.cyberduck
.core
.cdn
;
29 using ch
.cyberduck
.core
.editor
;
30 using ch
.cyberduck
.core
.exception
;
31 using ch
.cyberduck
.core
.features
;
32 using ch
.cyberduck
.core
.local
;
33 using ch
.cyberduck
.core
.pasteboard
;
34 using ch
.cyberduck
.core
.preferences
;
35 using ch
.cyberduck
.core
.serializer
;
36 using ch
.cyberduck
.core
.sftp
;
37 using ch
.cyberduck
.core
.ssl
;
38 using ch
.cyberduck
.core
.threading
;
39 using ch
.cyberduck
.core
.transfer
;
40 using ch
.cyberduck
.core
.worker
;
41 using ch
.cyberduck
.ui
.browser
;
42 using ch
.cyberduck
.ui
.comparator
;
43 using Ch
.Cyberduck
.Core
;
44 using Ch
.Cyberduck
.Core
.Local
;
45 using Ch
.Cyberduck
.Ui
.Controller
.Threading
;
46 using Ch
.Cyberduck
.Ui
.Winforms
;
47 using Ch
.Cyberduck
.Ui
.Winforms
.Taskdialog
;
50 using org
.apache
.log4j
;
52 using Application
= ch
.cyberduck
.core
.local
.Application
;
53 using Boolean
= java
.lang
.Boolean
;
54 using Exception
= System
.Exception
;
55 using Path
= ch
.cyberduck
.core
.Path
;
56 using String
= System
.String
;
57 using StringBuilder
= System
.Text
.StringBuilder
;
59 namespace Ch
.Cyberduck
.Ui
.Controller
61 public class BrowserController
: WindowController
<IBrowserView
>, TranscriptListener
, CollectionListener
,
64 public delegate void CallbackDelegate();
66 public delegate bool DialogCallbackDelegate(DialogResult result
);
68 internal static readonly Filter HiddenFilter
= new RegexFilter();
69 private static readonly Logger Log
= Logger
.getLogger(typeof (BrowserController
).FullName
);
70 private static readonly Filter NullFilter
= new NullFilter();
71 protected static string DEFAULT
= LocaleFactory
.localizedString("Default");
72 private readonly BookmarkCollection _bookmarkCollection
= BookmarkCollection
.defaultCollection();
73 private readonly BookmarkModel _bookmarkModel
;
74 private readonly TreeBrowserModel _browserModel
;
75 private readonly PathCache _cache
= new PathCache(PreferencesFactory
.get().getInteger("browser.cache.size"));
76 private readonly ListProgressListener _limitListener
;
77 private readonly Navigation _navigation
= new Navigation();
78 private readonly IList
<FileSystemWatcher
> _temporaryWatcher
= new List
<FileSystemWatcher
>();
79 private Comparator _comparator
= new NullComparator();
80 private String _dropFolder
; // holds the drop folder of the current drag operation
81 private InfoController _inspector
;
82 private BrowserView _lastBookmarkView
= BrowserView
.Bookmark
;
83 private PathPasteboard _pasteboard
;
84 private bool _showHiddenFiles
;
86 public BrowserController(IBrowserView view
)
90 ShowHiddenFiles
= PreferencesFactory
.get().getBoolean("browser.showHidden");
92 _limitListener
= new DialogLimitedListProgressListener(this);
93 _browserModel
= new TreeBrowserModel(this, _cache
, _limitListener
);
94 _bookmarkModel
= new BookmarkModel(this, _bookmarkCollection
);
95 View
.ViewClosedEvent
+= delegate { _bookmarkModel.Source = null; }
;
97 //default view is the bookmark view
98 ToggleView(BrowserView
.Bookmark
);
99 View
.StopActivityAnimation();
101 View
.SetComparator
+= View_SetComparator
;
102 View
.ChangeBrowserView
+= View_ChangeBrowserView
;
104 View
.QuickConnect
+= View_QuickConnect
;
105 View
.BrowserDoubleClicked
+= View_BrowserDoubleClicked
;
106 View
.BrowserSelectionChanged
+= View_BrowserSelectionChanged
;
107 View
.PathSelectionChanged
+= View_PathSelectionChanged
;
108 View
.EditEvent
+= View_EditEvent
;
109 View
.ItemsChanged
+= View_ItemsChanged
;
111 View
.ShowTransfers
+= View_ShowTransfers
;
113 View
.BrowserCanDrop
+= View_BrowserCanDrop
;
114 View
.HostCanDrop
+= View_HostCanDrop
;
115 View
.BrowserModelCanDrop
+= View_BrowserModelCanDrop
;
116 View
.HostModelCanDrop
+= View_HostModelCanDrop
;
117 View
.BrowserDropped
+= View_BrowserDropped
;
118 View
.HostDropped
+= View_HostDropped
;
119 View
.HostModelDropped
+= View_HostModelDropped
;
120 View
.BrowserModelDropped
+= View_BrowserModelDropped
;
121 View
.BrowserDrag
+= View_BrowserDrag
;
122 View
.HostDrag
+= View_HostDrag
;
123 View
.BrowserEndDrag
+= View_BrowserEndDrag
;
124 View
.HostEndDrag
+= View_HostEndDrag
;
125 View
.SearchFieldChanged
+= View_SearchFieldChanged
;
128 View
.ContextMenuEnabled
+= View_ContextMenuEnabled
;
130 #region Commands - File
132 View
.NewBrowser
+= View_NewBrowser
;
133 View
.ValidateNewBrowser
+= View_ValidateNewBrowser
;
134 View
.OpenConnection
+= View_OpenConnection
;
135 View
.ValidateOpenConnection
+= () => true;
136 View
.NewDownload
+= View_NewDownload
;
137 View
.ValidateNewDownload
+= () => false; //todo implement
138 View
.NewFolder
+= View_NewFolder
;
139 View
.ValidateNewFolder
+= View_ValidateNewFolder
;
140 View
.NewFile
+= View_NewFile
;
141 View
.ValidateNewFile
+= View_ValidateNewFile
;
142 View
.NewSymbolicLink
+= View_NewSymbolicLink
;
143 View
.ValidateNewSymbolicLink
+= View_ValidateNewSymbolicLink
;
144 View
.RenameFile
+= View_RenameFile
;
145 View
.ValidateRenameFile
+= View_ValidateRenameFile
;
146 View
.DuplicateFile
+= View_DuplicateFile
;
147 View
.ValidateDuplicateFile
+= View_ValidateDuplicateFile
;
148 View
.OpenUrl
+= View_OpenUrl
;
149 View
.ValidateOpenWebUrl
+= View_ValidateOpenWebUrl
;
150 View
.ValidateEditWith
+= View_ValidateEditWith
;
151 View
.ShowInspector
+= View_ShowInspector
;
152 View
.ValidateShowInspector
+= View_ValidateShowInspector
;
153 View
.Download
+= View_Download
;
154 View
.ValidateDownload
+= View_ValidateDownload
;
155 View
.DownloadAs
+= View_DownloadAs
;
156 View
.ValidateDownloadAs
+= View_ValidateDownloadAs
;
157 View
.DownloadTo
+= View_DownloadTo
;
158 View
.ValidateDownloadTo
+= View_ValidateDownload
; //use same validation handler
159 View
.Upload
+= View_Upload
;
160 View
.ValidateUpload
+= View_ValidateUpload
;
161 View
.Synchronize
+= View_Synchronize
;
162 View
.ValidateSynchronize
+= View_ValidateSynchronize
;
163 View
.Delete
+= View_Delete
;
164 View
.ValidateDelete
+= View_ValidateDelete
;
165 View
.RevertFile
+= View_RevertFile
;
166 View
.ValidateRevertFile
+= View_ValidateRevertFile
;
167 View
.GetArchives
+= View_GetArchives
;
168 View
.GetCopyUrls
+= View_GetCopyUrls
;
169 View
.GetOpenUrls
+= View_GetOpenUrls
;
170 View
.CreateArchive
+= View_CreateArchive
;
171 View
.ValidateCreateArchive
+= View_ValidateCreateArchive
;
172 View
.ExpandArchive
+= View_ExpandArchive
;
173 View
.ValidateExpandArchive
+= View_ValidateExpandArchive
;
177 #region Commands - Edit
179 View
.Cut
+= View_Cut
;
180 View
.ValidateCut
+= View_ValidateCut
;
181 View
.Copy
+= View_Copy
;
182 View
.ValidateCopy
+= View_ValidateCopy
;
183 View
.Paste
+= View_Paste
;
184 View
.ValidatePaste
+= View_ValidatePaste
;
185 View
.ShowPreferences
+= View_ShowPreferences
;
189 #region Commands - View
191 View
.ToggleToolbar
+= View_ToggleToolbar
;
192 View
.ShowHiddenFiles
+= View_ShowHiddenFiles
;
193 View
.ValidateTextEncoding
+= View_ValidateTextEncoding
;
194 View
.EncodingChanged
+= View_EncodingChanged
;
195 View
.ToggleLogDrawer
+= View_ToggleLogDrawer
;
199 #region Commands - Go
201 View
.RefreshBrowser
+= View_RefreshBrowser
;
202 View
.ValidateRefresh
+= View_ValidateRefresh
;
203 View
.GotoFolder
+= View_GotoFolder
;
204 View
.ValidateGotoFolder
+= View_ValidateGotoFolder
;
205 View
.HistoryBack
+= View_HistoryBack
;
206 View
.ValidateHistoryBack
+= View_ValidateHistoryBack
;
207 View
.HistoryForward
+= View_HistoryForward
;
208 View
.ValidateHistoryForward
+= View_ValidateHistoryForward
;
209 View
.FolderUp
+= View_FolderUp
;
210 View
.ValidateFolderUp
+= View_ValidateFolderUp
;
211 View
.FolderInside
+= View_FolderInside
;
212 View
.ValidateFolderInside
+= View_ValidateFolderInside
;
213 View
.Search
+= View_Search
;
214 View
.SendCustomCommand
+= View_SendCustomCommand
;
215 View
.ValidateSendCustomCommand
+= View_ValidateSendCustomCommand
;
216 View
.OpenInTerminal
+= View_OpenInTerminal
;
217 View
.ValidateOpenInTerminal
+= View_ValidateOpenInTerminal
;
218 View
.Stop
+= View_Disconnect
;
219 View
.ValidateStop
+= View_ValidateStop
;
220 View
.Disconnect
+= View_Disconnect
;
221 View
.ValidateDisconnect
+= View_ValidateDisconnect
;
225 #region Commands - Bookmark
227 View
.ToggleBookmarks
+= View_ToggleBookmarks
;
228 View
.SortBookmarksByHostname
+= View_SortBookmarksByHostname
;
229 View
.SortBookmarksByNickname
+= View_SortBookmarksByNickname
;
230 View
.SortBookmarksByProtocol
+= View_SortBookmarksByProtocol
;
232 View
.ConnectBookmark
+= View_ConnectBookmark
;
233 View
.ValidateConnectBookmark
+= View_ValidateConnectBookmark
;
234 View
.NewBookmark
+= View_NewBookmark
;
235 View
.ValidateNewBookmark
+= View_ValidateNewBookmark
;
236 View
.EditBookmark
+= View_EditBookmark
;
237 View
.ValidateEditBookmark
+= View_ValidateEditBookmark
;
238 View
.DeleteBookmark
+= View_DeleteBookmark
;
239 View
.ValidateDeleteBookmark
+= View_ValidateDeleteBookmark
;
240 View
.DuplicateBookmark
+= View_DuplicateBookmark
;
241 View
.ValidateDuplicateBookmark
+= View_ValidateDuplicateBookmark
;
245 #region Browser model delegates
247 View
.ModelCanExpandDelegate
= _browserModel
.CanExpand
;
248 View
.ModelChildrenGetterDelegate
= _browserModel
.ChildrenGetter
;
249 View
.ModelFilenameGetter
= _browserModel
.GetName
;
250 View
.ModelIconGetter
= _browserModel
.GetIcon
;
251 View
.ModelSizeGetter
= _browserModel
.GetSize
;
252 View
.ModelSizeAsStringGetter
= _browserModel
.GetSizeAsString
;
253 View
.ModelModifiedGetter
= _browserModel
.GetModified
;
254 View
.ModelModifiedAsStringGetter
= _browserModel
.GetModifiedAsString
;
255 View
.ModelOwnerGetter
= _browserModel
.GetOwner
;
256 View
.ModelGroupGetter
= _browserModel
.GetGroup
;
257 View
.ModelPermissionsGetter
= _browserModel
.GetPermission
;
258 View
.ModelKindGetter
= _browserModel
.GetKind
;
259 View
.ModelActiveGetter
= _browserModel
.GetActive
;
260 View
.ModelExtensionGetter
= _browserModel
.GetExtension
;
261 View
.ModelRegionGetter
= _browserModel
.GetRegion
;
262 View
.ModelVersionGetter
= _browserModel
.GetVersion
;
266 #region Bookmark model delegates
268 View
.BookmarkImageGetter
= _bookmarkModel
.GetBookmarkImage
;
269 View
.BookmarkNicknameGetter
= _bookmarkModel
.GetNickname
;
270 View
.BookmarkHostnameGetter
= _bookmarkModel
.GetHostname
;
271 View
.BookmarkUrlGetter
= _bookmarkModel
.GetUrl
;
272 View
.BookmarkNotesGetter
= _bookmarkModel
.GetNotes
;
273 View
.BookmarkStatusImageGetter
= _bookmarkModel
.GetBookmarkStatusImage
;
277 _bookmarkCollection
.addListener(this);
278 View
.ViewClosedEvent
+= delegate { _bookmarkCollection.removeListener(this); }
;
280 PopulateQuickConnect();
284 View
.ToolbarVisible
= PreferencesFactory
.get().getBoolean("browser.toolbar");
285 View
.LogDrawerVisible
= PreferencesFactory
.get().getBoolean("browser.transcript.open");
287 View
.GetEditorsForSelection
+= View_GetEditorsForSelection
;
288 View
.GetBookmarks
+= View_GetBookmarks
;
289 View
.GetHistory
+= View_GetHistory
;
290 View
.GetBonjourHosts
+= View_GetBonjourHosts
;
291 View
.ClearHistory
+= View_ClearHistory
;
292 View
.ShowCertificate
+= View_Certificate
;
294 View
.ValidatePathsCombobox
+= View_ValidatePathsCombobox
;
295 View
.ValidateSearchField
+= View_ValidateSearchField
;
297 View
.Exit
+= View_Exit
;
298 View
.SetBookmarkModel(_bookmarkCollection
, null);
301 public BrowserController() : this(ObjectFactory
.GetInstance
<IBrowserView
>())
306 /// The first selected path found or null if there is no selection
308 public Path SelectedPath
312 IList
<Path
> selectedPaths
= View
.SelectedPaths
;
313 if (selectedPaths
.Count
> 0)
315 return selectedPaths
[0];
321 public Path Workdir { get; set; }
327 /// All selected paths or an empty list if there is no selection
329 public IList
<Path
> SelectedPaths
335 return View
.SelectedPaths
;
337 return new List
<Path
>();
339 set { View.SelectedPaths = value; }
342 public bool ShowHiddenFiles
344 get { return _showHiddenFiles; }
347 FilenameFilter
= value ? NullFilter
: HiddenFilter
;
348 _showHiddenFiles
= value;
349 View
.HiddenFilesVisible
= _showHiddenFiles
;
353 public PathCache Cache
355 get { return _cache; }
358 public Filter FilenameFilter { get; set; }
360 public Comparator FilenameComparator
362 get { return _comparator; }
363 set { _comparator = value; }
366 public Session Session { get; private set; }
368 public void collectionLoaded()
370 AsyncDelegate mainAction
= delegate { ReloadBookmarks(); }
;
374 public void collectionItemAdded(object obj
)
376 AsyncDelegate mainAction
= delegate { PopulateQuickConnect(); }
;
380 public void collectionItemRemoved(object obj
)
382 AsyncDelegate mainAction
= delegate { PopulateQuickConnect(); }
;
386 public void collectionItemChanged(object obj
)
388 AsyncDelegate mainAction
= delegate { PopulateQuickConnect(); }
;
392 public override void message(string msg
)
395 if (Utils
.IsNotBlank(msg
))
401 if (View
.CurrentView
== BrowserView
.Bookmark
|| View
.CurrentView
== BrowserView
.History
||
402 View
.CurrentView
== BrowserView
.Bonjour
)
404 label
= String
.Format("{0} {1}", View
.NumberOfBookmarks
, LocaleFactory
.localizedString("Bookmarks"));
410 label
= String
.Format(LocaleFactory
.localizedString("{0} Files"), View
.NumberOfFiles
);
414 label
= String
.Empty
;
418 AsyncDelegate updateLabel
= delegate { View.StatusLabel = label; }
;
422 public override void log(bool request
, string transcript
)
424 if (View
.LogDrawerVisible
)
426 AsyncDelegate mainAction
= delegate { View.AddTranscriptEntry(request, transcript); }
;
431 private void View_NewSymbolicLink()
433 CreateSymlinkController slc
=
434 new CreateSymlinkController(ObjectFactory
.GetInstance
<ICreateSymlinkPromptView
>(), this);
438 private bool View_ValidateNewSymbolicLink()
440 return IsMounted() && Session
.getFeature(typeof (Symlink
)) != null && SelectedPaths
.Count
== 1;
443 private void View_SortBookmarksByProtocol()
445 BookmarkCollection
.defaultCollection().sortByProtocol();
449 private void View_SortBookmarksByNickname()
451 BookmarkCollection
.defaultCollection().sortByNickname();
455 private void View_SortBookmarksByHostname()
457 BookmarkCollection
.defaultCollection().sortByHostname();
461 private bool View_ValidateOpenInTerminal()
463 return IsMounted() && Session
is SFTPSession
&&
464 File
.Exists(PreferencesFactory
.get().getProperty("terminal.command.ssh"));
467 private void View_OpenInTerminal()
469 Host host
= Session
.getHost();
471 if (SelectedPaths
.Count
== 1)
473 Path selected
= SelectedPath
;
474 if (selected
.isDirectory())
483 new SshTerminalService().open(host
, workdir
);
486 private void View_SetComparator(BrowserComparator comparator
)
488 if (!comparator
.equals(_comparator
))
490 _comparator
= comparator
;
495 private IList
<Application
> View_GetEditorsForSelection()
497 Path p
= SelectedPath
;
502 return Utils
.ConvertFromJavaList
<Application
>(EditorFactory
.instance().getEditors(p
.getName()), null);
505 return new List
<Application
>();
508 private bool View_ValidateNewBrowser()
513 private List
<KeyValuePair
<String
, List
<String
>>> View_GetCopyUrls()
515 List
<KeyValuePair
<String
, List
<String
>>> items
= new List
<KeyValuePair
<String
, List
<String
>>>();
516 IList
<Path
> selected
= View
.SelectedPaths
;
517 if (selected
.Count
== 0)
519 items
.Add(new KeyValuePair
<string, List
<String
>>(LocaleFactory
.localizedString("None"),
520 new List
<string>()));
524 UrlProvider urlProvider
= ((UrlProvider
) Session
.getFeature(typeof (UrlProvider
)));
525 if (urlProvider
!= null)
527 for (int i
= 0; i
< urlProvider
.toUrl(SelectedPath
).size(); i
++)
529 DescriptiveUrl descUrl
= (DescriptiveUrl
) urlProvider
.toUrl(SelectedPath
).toArray()[i
];
530 KeyValuePair
<String
, List
<String
>> entry
=
531 new KeyValuePair
<string, List
<string>>(descUrl
.getHelp(), new List
<string>());
533 foreach (Path path
in selected
)
535 entry
.Value
.Add(((DescriptiveUrl
) urlProvider
.toUrl(path
).toArray()[i
]).getUrl());
539 UrlProvider distributionConfiguration
=
540 ((UrlProvider
) Session
.getFeature(typeof (DistributionConfiguration
)));
541 if (distributionConfiguration
!= null)
543 for (int i
= 0; i
< distributionConfiguration
.toUrl(SelectedPath
).size(); i
++)
545 DescriptiveUrl descUrl
=
546 (DescriptiveUrl
) distributionConfiguration
.toUrl(SelectedPath
).toArray()[i
];
547 KeyValuePair
<String
, List
<String
>> entry
=
548 new KeyValuePair
<string, List
<string>>(descUrl
.getHelp(), new List
<string>());
550 foreach (Path path
in selected
)
553 ((DescriptiveUrl
) distributionConfiguration
.toUrl(path
).toArray()[i
]).getUrl());
561 private bool IsBrowser()
563 return View
.CurrentView
== BrowserView
.File
;
566 private IList
<KeyValuePair
<string, List
<string>>> View_GetOpenUrls()
568 IList
<KeyValuePair
<String
, List
<String
>>> items
= new List
<KeyValuePair
<String
, List
<String
>>>();
569 IList
<Path
> selected
= View
.SelectedPaths
;
570 if (selected
.Count
== 0)
572 items
.Add(new KeyValuePair
<string, List
<String
>>(LocaleFactory
.localizedString("None"),
573 new List
<string>()));
577 DescriptiveUrlBag urls
=
578 ((UrlProvider
) Session
.getFeature(typeof (UrlProvider
))).toUrl(SelectedPath
)
579 .filter(DescriptiveUrl
.Type
.http
, DescriptiveUrl
.Type
.cname
, DescriptiveUrl
.Type
.cdn
,
580 DescriptiveUrl
.Type
.signed
, DescriptiveUrl
.Type
.authenticated
, DescriptiveUrl
.Type
.torrent
);
581 for (int i
= 0; i
< urls
.size(); i
++)
583 DescriptiveUrl descUrl
= (DescriptiveUrl
) urls
.toArray()[i
];
584 KeyValuePair
<String
, List
<String
>> entry
= new KeyValuePair
<string, List
<string>>(
585 descUrl
.getHelp(), new List
<string>());
588 foreach (Path path
in selected
)
590 entry
.Value
.Add(((DescriptiveUrl
) urls
.toArray()[i
]).getUrl());
597 public void UpdateBookmarks()
599 View
.UpdateBookmarks();
602 private bool View_ValidateDuplicateBookmark()
604 return _bookmarkModel
.Source
.allowsEdit() && View
.SelectedBookmarks
.Count
== 1;
607 private void View_DuplicateBookmark()
609 ToggleView(BrowserView
.Bookmark
);
610 Host duplicate
= new HostDictionary().deserialize(View
.SelectedBookmark
.serialize(SerializerFactory
.get()));
611 // Make sure a new UUID is asssigned for duplicate
612 duplicate
.setUuid(null);
613 AddBookmark(duplicate
);
616 private void View_HostModelDropped(ModelDropEventArgs dropargs
)
618 int sourceIndex
= _bookmarkModel
.Source
.indexOf(dropargs
.SourceModels
[0]);
619 int destIndex
= dropargs
.DropTargetIndex
;
620 if (dropargs
.DropTargetLocation
== DropTargetLocation
.BelowItem
)
624 if (dropargs
.Effect
== DragDropEffects
.Copy
)
627 new HostDictionary().deserialize(((Host
) dropargs
.SourceModels
[0]).serialize(SerializerFactory
.get()));
629 AddBookmark(host
, destIndex
);
631 if (dropargs
.Effect
== DragDropEffects
.Move
)
633 if (sourceIndex
< destIndex
)
637 foreach (Host promisedDragBookmark
in dropargs
.SourceModels
)
639 _bookmarkModel
.Source
.remove(promisedDragBookmark
);
640 if (destIndex
> _bookmarkModel
.Source
.size())
642 _bookmarkModel
.Source
.add(promisedDragBookmark
);
646 _bookmarkModel
.Source
.add(destIndex
, promisedDragBookmark
);
648 //view.selectRowIndexes(NSIndexSet.indexSetWithIndex(row), false);
649 //view.scrollRowToVisible(row);
654 private void View_HostModelCanDrop(ModelDropEventArgs args
)
656 if (!_bookmarkModel
.Source
.allowsEdit())
658 // Do not allow drags for non writable collections
659 args
.Effect
= DragDropEffects
.None
;
660 args
.DropTargetLocation
= DropTargetLocation
.None
;
663 switch (args
.DropTargetLocation
)
665 case DropTargetLocation
.BelowItem
:
666 case DropTargetLocation
.AboveItem
:
667 if (args
.SourceModels
.Count
> 1)
669 args
.Effect
= DragDropEffects
.Move
;
673 args
.Effect
= DragDropEffects
.None
;
674 args
.DropTargetLocation
= DropTargetLocation
.None
;
679 private void View_HostDropped(OlvDropEventArgs e
)
681 if (e
.DataObject
is DataObject
&& ((DataObject
) e
.DataObject
).ContainsFileDropList())
683 DataObject data
= (DataObject
) e
.DataObject
;
685 if (e
.DropTargetLocation
== DropTargetLocation
.Item
)
687 IList
<TransferItem
> roots
= new List
<TransferItem
>();
689 foreach (string filename
in data
.GetFileDropList())
691 //check if we received at least one non-duck file
692 if (!".duck".Equals(Utils
.GetSafeExtension(filename
)))
694 // The bookmark this file has been dropped onto
695 Host destination
= (Host
) e
.DropTargetItem
.RowObject
;
700 Local local
= LocalFactory
.get(filename
);
701 // Upload to the remote host this bookmark points to
705 new Path(PathNormalizer
.normalize(destination
.getDefaultPath(), true),
706 EnumSet
.of(AbstractPath
.Type
.directory
)), local
.getName(),
707 EnumSet
.of(AbstractPath
.Type
.file
)), local
));
712 UploadTransfer q
= new UploadTransfer(host
, Utils
.ConvertToJavaList(roots
));
713 // If anything has been added to the queue, then process the queue
714 if (q
.getRoots().size() > 0)
716 TransferController
.Instance
.StartTransfer(q
);
722 if (e
.DropTargetLocation
== DropTargetLocation
.AboveItem
)
724 Host destination
= (Host
) e
.DropTargetItem
.RowObject
;
725 foreach (string file
in data
.GetFileDropList())
727 _bookmarkModel
.Source
.add(_bookmarkModel
.Source
.indexOf(destination
),
728 HostReaderFactory
.get().read(LocalFactory
.get(file
)));
731 if (e
.DropTargetLocation
== DropTargetLocation
.BelowItem
)
733 Host destination
= (Host
) e
.DropTargetItem
.RowObject
;
734 foreach (string file
in data
.GetFileDropList())
736 _bookmarkModel
.Source
.add(_bookmarkModel
.Source
.indexOf(destination
) + 1,
737 HostReaderFactory
.get().read(LocalFactory
.get(file
)));
740 if (e
.DropTargetLocation
== DropTargetLocation
.Background
)
742 foreach (string file
in data
.GetFileDropList())
744 _bookmarkModel
.Source
.add(HostReaderFactory
.get().read(LocalFactory
.get(file
)));
750 private void View_HostCanDrop(OlvDropEventArgs args
)
752 if (!_bookmarkModel
.Source
.allowsEdit())
754 // Do not allow drags for non writable collections
755 args
.Effect
= DragDropEffects
.None
;
756 args
.DropTargetLocation
= DropTargetLocation
.None
;
760 DataObject dataObject
= (DataObject
) args
.DataObject
;
761 if (dataObject
.ContainsFileDropList())
763 //check if all files are .duck files
764 foreach (string file
in dataObject
.GetFileDropList())
766 string ext
= Utils
.GetSafeExtension(file
);
767 if (!".duck".Equals(ext
))
769 //if at least one non-duck file we prepare for uploading
770 args
.Effect
= DragDropEffects
.Copy
;
771 if (args
.DropTargetLocation
== DropTargetLocation
.Item
)
773 Host destination
= (Host
) args
.DropTargetItem
.RowObject
;
774 (args
.DataObject
as DataObject
).SetDropDescription((DropImageType
) args
.Effect
,
775 "Upload to %1", BookmarkNameProvider
.toString(destination
));
777 args
.DropTargetLocation
= DropTargetLocation
.Item
;
782 //at least one .duck file
783 args
.Effect
= DragDropEffects
.Copy
;
784 if (args
.DropTargetLocation
== DropTargetLocation
.Item
)
786 args
.DropTargetLocation
= DropTargetLocation
.Background
;
790 args
.Effect
= DragDropEffects
.None
;
793 private void View_HostEndDrag(DataObject data
)
795 RemoveTemporaryFiles(data
);
796 RemoveTemporaryFilesystemWatcher();
799 private string CreateAndWatchTemporaryFile(FileSystemEventHandler del
)
801 string tfile
= System
.IO
.Path
.Combine(System
.IO
.Path
.GetTempPath(), Guid
.NewGuid().ToString());
802 using (File
.Create(tfile
))
804 FileInfo tmpFile
= new FileInfo(tfile
);
805 tmpFile
.Attributes
|= FileAttributes
.Hidden
;
807 DriveInfo
[] allDrives
= DriveInfo
.GetDrives();
808 foreach (DriveInfo d
in allDrives
)
810 if (d
.IsReady
&& d
.DriveType
!= DriveType
.CDRom
)
814 FileSystemWatcher watcher
= new FileSystemWatcher(@d
.Name
, System
.IO
.Path
.GetFileName(tfile
));
816 watcher
.IncludeSubdirectories
= true;
817 watcher
.EnableRaisingEvents
= true;
818 watcher
.Created
+= del
;
820 _temporaryWatcher
.Add(watcher
);
824 Log
.info(string.Format("Cannot watch drive {0}", d
), e
);
831 private DataObject
View_HostDrag(ObjectListView list
)
833 DataObject data
= new DataObject(DataFormats
.FileDrop
,
836 CreateAndWatchTemporaryFile(delegate(object sender
, FileSystemEventArgs args
)
840 _dropFolder
= System
.IO
.Path
.GetDirectoryName(args
.FullPath
);
841 foreach (Host host
in
842 View
.SelectedBookmarks
)
844 string filename
= BookmarkNameProvider
.toString(host
) + ".duck";
846 System
.IO
.Path
.GetInvalidFileNameChars())
848 filename
= filename
.Replace(c
.ToString(), String
.Empty
);
851 Local file
= LocalFactory
.get(_dropFolder
, filename
);
852 HostWriterFactory
.get().write(host
, file
);
860 private void View_BrowserModelCanDrop(ModelDropEventArgs args
)
865 switch (args
.DropTargetLocation
)
867 case DropTargetLocation
.Item
:
868 destination
= (Path
) args
.DropTargetItem
.RowObject
;
869 if (!destination
.isDirectory())
872 destination
= destination
.getParent();
875 case DropTargetLocation
.Background
:
876 destination
= Workdir
;
879 args
.Effect
= DragDropEffects
.None
;
880 args
.DropTargetLocation
= DropTargetLocation
.None
;
883 Touch feature
= (Touch
) Session
.getFeature(typeof (Touch
));
884 if (!feature
.isSupported(destination
))
886 args
.Effect
= DragDropEffects
.None
;
887 args
.DropTargetLocation
= DropTargetLocation
.None
;
890 foreach (Path sourcePath
in args
.SourceModels
)
892 if (args
.ListView
== args
.SourceListView
)
894 // Use drag action from user
898 // If copying between sessions is supported
899 args
.Effect
= DragDropEffects
.Copy
;
901 if (sourcePath
.isDirectory() && sourcePath
.equals(destination
))
903 // Do not allow dragging onto myself.
904 args
.Effect
= DragDropEffects
.None
;
905 args
.DropTargetLocation
= DropTargetLocation
.None
;
908 if (sourcePath
.isDirectory() && destination
.isChild(sourcePath
))
910 // Do not allow dragging a directory into its own containing items
911 args
.Effect
= DragDropEffects
.None
;
912 args
.DropTargetLocation
= DropTargetLocation
.None
;
915 if (sourcePath
.isFile() && sourcePath
.getParent().equals(destination
))
917 // Moving file to the same destination makes no sense
918 args
.Effect
= DragDropEffects
.None
;
919 args
.DropTargetLocation
= DropTargetLocation
.None
;
923 if (Workdir
== destination
)
925 args
.DropTargetLocation
= DropTargetLocation
.Background
;
929 args
.DropTargetItem
= args
.ListView
.ModelToItem(destination
);
935 /// A file dragged within the browser has been received
937 /// <param name="dropargs"></param>
938 private void View_BrowserModelDropped(ModelDropEventArgs dropargs
)
941 switch (dropargs
.DropTargetLocation
)
943 case DropTargetLocation
.Item
:
944 destination
= (Path
) dropargs
.DropTargetItem
.RowObject
;
946 case DropTargetLocation
.Background
:
947 destination
= Workdir
;
953 if (null != destination
)
955 IDictionary
<Path
, Path
> files
= new Dictionary
<Path
, Path
>();
956 foreach (Path next
in dropargs
.SourceModels
)
958 Path renamed
= new Path(destination
, next
.getName(), next
.getType());
959 files
.Add(next
, renamed
);
963 if (dropargs
.Effect
== DragDropEffects
.Copy
)
965 foreach (BrowserController controller
in MainController
.Browsers
)
967 // Find source browser
968 if (controller
.View
.Browser
.Equals(dropargs
.SourceListView
))
971 new CopyTransfer(controller
.Session
.getHost(), Session
.getHost(),
972 Utils
.ConvertToJavaMap(files
)), new List
<Path
>(files
.Values
), false);
977 if (dropargs
.Effect
== DragDropEffects
.Move
)
979 // The file should be renamed
986 private void View_Download()
988 Download(SelectedPaths
, new DownloadDirectoryFinder().find(Session
.getHost()));
991 private bool View_ValidateRevertFile()
993 if (IsMounted() && SelectedPaths
.Count
== 1)
995 return Session
.getFeature(typeof (Versioning
)) != null;
1000 private void View_RevertFile()
1002 RevertPaths(SelectedPaths
);
1005 private void RevertPaths(IList
<Path
> files
)
1007 Background(new RevertAction(this, files
));
1010 private void View_ToggleBookmarks()
1012 if (View
.CurrentView
== BrowserView
.File
)
1014 View
.CurrentView
= _lastBookmarkView
;
1018 _lastBookmarkView
= View
.CurrentView
;
1019 View
.CurrentView
= BrowserView
.File
;
1023 private bool View_ValidateSearchField()
1025 return IsMounted() || View
.CurrentView
!= BrowserView
.File
;
1028 private bool View_ValidatePathsCombobox()
1033 private void View_ItemsChanged()
1038 private void View_Certificate()
1040 if (Session
is SSLSession
)
1042 SSLSession secured
= (SSLSession
) Session
;
1043 List certificates
= secured
.getAcceptedIssuers();
1044 CertificateStoreFactory
.get().display(certificates
);
1048 private void View_ClearHistory()
1050 HistoryCollection
.defaultCollection().clear();
1053 private List
<Host
> View_GetBonjourHosts()
1055 List
<Host
> b
= new List
<Host
>();
1056 foreach (Host h
in RendezvousCollection
.defaultCollection())
1063 private List
<Host
> View_GetHistory()
1065 List
<Host
> b
= new List
<Host
>();
1066 foreach (Host h
in HistoryCollection
.defaultCollection())
1073 private List
<Host
> View_GetBookmarks()
1075 List
<Host
> b
= new List
<Host
>();
1076 foreach (Host h
in BookmarkCollection
.defaultCollection())
1083 private void PopulateEncodings()
1085 List
<string> list
= new List
<string>();
1086 list
.AddRange(new DefaultCharsetProvider().availableCharsets());
1087 View
.PopulateEncodings(list
);
1088 View
.SelectedEncoding
= PreferencesFactory
.get().getProperty("browser.charset.encoding");
1091 private void View_EncodingChanged(object sender
, EncodingChangedArgs e
)
1093 string encoding
= e
.Encoding
;
1094 if (Utils
.IsBlank(encoding
))
1098 View
.SelectedEncoding
= encoding
;
1101 if (Session
.getEncoding().Equals(encoding
))
1105 Session
.getHost().setEncoding(encoding
);
1106 Mount(Session
.getHost());
1110 private void View_ConnectBookmark(object sender
, ConnectBookmarkArgs connectBookmarkArgs
)
1112 Mount(connectBookmarkArgs
.Bookmark
);
1115 private bool View_ValidateConnectBookmark()
1117 return View
.SelectedBookmarks
.Count
== 1;
1120 private bool View_ValidateDeleteBookmark()
1122 return _bookmarkModel
.Source
.allowsDelete() && View
.SelectedBookmarks
.Count
> 0;
1125 private bool View_ValidateEditBookmark()
1127 return _bookmarkModel
.Source
.allowsEdit() && View
.SelectedBookmarks
.Count
== 1;
1130 private bool View_ValidateNewBookmark()
1132 return _bookmarkModel
.Source
.allowsAdd();
1135 private void View_ChangeBrowserView(object sender
, ChangeBrowserViewArgs e
)
1140 private void View_EditBookmark()
1142 if (View
.SelectedBookmarks
.Count
== 1)
1144 BookmarkController
.Factory
.Create(View
.SelectedBookmark
).View
.Show(View
);
1148 private void View_NewBookmark()
1153 Path selected
= SelectedPath
;
1154 if (null == selected
|| !selected
.isDirectory())
1158 bookmark
= new HostDictionary().deserialize(Session
.getHost().serialize(SerializerFactory
.get()));
1159 bookmark
.setUuid(null);
1160 bookmark
.setDefaultPath(selected
.getAbsolute());
1166 ProtocolFactory
.forName(PreferencesFactory
.get().getProperty("connection.protocol.default")),
1167 PreferencesFactory
.get().getProperty("connection.hostname.default"),
1168 PreferencesFactory
.get().getInteger("connection.port.default"));
1170 ToggleView(BrowserView
.Bookmark
);
1171 AddBookmark(bookmark
);
1174 public void AddBookmark(Host item
)
1176 AddBookmark(item
, -1);
1179 private void AddBookmark(Host item
, int index
)
1181 _bookmarkModel
.Filter
= null;
1184 _bookmarkModel
.Source
.add(index
, item
);
1188 _bookmarkModel
.Source
.add(item
);
1190 View
.SelectBookmark(item
);
1191 View
.EnsureBookmarkVisible(item
);
1192 BookmarkController
.Factory
.Create(item
).View
.Show(View
);
1195 private void View_DeleteBookmark()
1197 List
<Host
> selected
= View
.SelectedBookmarks
;
1198 StringBuilder alertText
= new StringBuilder();
1200 foreach (Host host
in selected
)
1204 alertText
.Append("\n");
1206 alertText
.Append(Character
.toString('\u2022')).Append(" ").Append(BookmarkNameProvider
.toString(host
));
1213 DialogResult result
= QuestionBox(LocaleFactory
.localizedString("Delete Bookmark"),
1214 LocaleFactory
.localizedString("Do you want to delete the selected bookmark?"), alertText
.ToString(),
1215 String
.Format("{0}", LocaleFactory
.localizedString("Delete")), true);
1216 if (result
== DialogResult
.OK
)
1218 _bookmarkModel
.Source
.removeAll(Utils
.ConvertToJavaList(selected
));
1222 public override bool ViewShouldClose()
1227 private void View_OpenUrl()
1229 DescriptiveUrlBag list
;
1230 if (SelectedPaths
.Count
== 1)
1232 list
= ((UrlProvider
) Session
.getFeature(typeof (UrlProvider
))).toUrl(SelectedPath
);
1236 list
= ((UrlProvider
) Session
.getFeature(typeof (UrlProvider
))).toUrl(Workdir
);
1238 if (!list
.isEmpty())
1240 BrowserLauncherFactory
.get().open(list
.find(DescriptiveUrl
.Type
.http
).getUrl());
1244 private void View_SearchFieldChanged()
1246 if (View
.CurrentView
== BrowserView
.File
)
1248 SetPathFilter(View
.SearchString
);
1252 SetBookmarkFilter(View
.SearchString
);
1256 private void SetBookmarkFilter(string searchString
)
1258 if (Utils
.IsBlank(searchString
))
1260 View
.SearchString
= String
.Empty
;
1261 _bookmarkModel
.Filter
= null;
1265 _bookmarkModel
.Filter
= new BookmarkFilter(searchString
);
1270 private bool View_ValidateDisconnect()
1272 // disconnect/stop button update
1273 View
.ActivityRunning
= isActivityRunning();
1276 return isActivityRunning();
1278 return IsConnected();
1281 private bool View_ValidateStop()
1283 return isActivityRunning();
1286 private bool View_ValidateSendCustomCommand()
1288 return IsMounted() && Session
.getFeature(typeof (Command
)) != null;
1291 private bool View_ValidateFolderInside()
1293 return IsMounted() && SelectedPaths
.Count
> 0;
1296 private bool View_ValidateFolderUp()
1298 return IsMounted() && !Workdir
.isRoot();
1301 private bool View_ValidateHistoryForward()
1303 return IsMounted() && _navigation
.getForward().size() > 0;
1306 private bool View_ValidateHistoryBack()
1308 return IsMounted() && _navigation
.getBack().size() > 1;
1311 private bool View_ValidateGotoFolder()
1316 private bool View_ValidateRefresh()
1321 private void View_Disconnect()
1323 if (isActivityRunning())
1325 // Remove all pending actions)
1326 foreach (BackgroundAction action
in getActions().toArray(new BackgroundAction
[getActions().size()]))
1331 CallbackDelegate run
= delegate
1333 if (PreferencesFactory
.get().getBoolean("browser.disconnect.bookmarks.show"))
1335 ToggleView(BrowserView
.Bookmark
);
1339 ToggleView(BrowserView
.File
);
1346 * Unmount this session
1349 private void Disconnect(CallbackDelegate runnable
)
1351 InfoController infoController
= _inspector
;
1352 if (infoController
!= null)
1354 infoController
.View
.Close();
1358 Background(new DisconnectAction(this, runnable
));
1366 private void View_SendCustomCommand()
1368 new CommandController(this, Session
).View
.ShowDialog();
1371 private void View_Search()
1376 private void View_FolderInside()
1378 Path selected
= SelectedPath
;
1379 if (null == selected
)
1383 if (selected
.isDirectory())
1385 SetWorkdir(selected
);
1387 else if (selected
.isFile() || View
.SelectedPaths
.Count
> 1)
1389 if (PreferencesFactory
.get().getBoolean("browser.doubleclick.edit"))
1391 View_EditEvent(null);
1400 public void Download(IList
<Path
> downloads
, Local downloadFolder
)
1402 if (downloads
.Count
> 0)
1404 IList
<TransferItem
> items
= new List
<TransferItem
>();
1405 foreach (Path selected
in downloads
)
1407 items
.Add(new TransferItem(selected
, LocalFactory
.get(downloadFolder
, selected
.getName())));
1409 Transfer q
= new DownloadTransfer(Session
.getHost(), Utils
.ConvertToJavaList(items
));
1410 transfer(q
, new List
<Path
>());
1414 private void View_GotoFolder()
1416 GotoController gc
= new GotoController(ObjectFactory
.GetInstance
<IGotoPromptView
>(), this);
1420 private void View_RefreshBrowser()
1424 _cache
.invalidate(Workdir
);
1425 foreach (Path path
in View
.VisiblePaths
)
1427 if (null == path
) continue;
1428 _cache
.invalidate(path
);
1434 private bool View_ValidateTextEncoding()
1436 return IsMounted() && !isActivityRunning();
1439 private void View_ToggleLogDrawer()
1441 View
.LogDrawerVisible
= !View
.LogDrawerVisible
;
1442 PreferencesFactory
.get().setProperty("browser.transcript.open", View
.LogDrawerVisible
);
1445 private void View_ShowHiddenFiles()
1447 ShowHiddenFiles
= !ShowHiddenFiles
;
1454 private void View_ToggleToolbar()
1456 View
.ToolbarVisible
= !View
.ToolbarVisible
;
1457 PreferencesFactory
.get().setProperty("browser.toolbar", View
.ToolbarVisible
);
1460 private bool View_ValidatePaste()
1462 return IsBrowser() && IsMounted() && !_pasteboard
.isEmpty();
1465 private void View_Paste()
1467 IDictionary
<Path
, Path
> files
= new Dictionary
<Path
, Path
>();
1468 Path parent
= Workdir
;
1469 for (int i
= 0; i
< _pasteboard
.size(); i
++)
1471 Path next
= (Path
) _pasteboard
.get(i
);
1472 Path renamed
= new Path(parent
, next
.getName(), next
.getType());
1473 files
.Add(next
, renamed
);
1475 _pasteboard
.clear();
1476 if (_pasteboard
.isCut())
1480 if (_pasteboard
.isCopy())
1482 DuplicatePaths(files
);
1486 private bool View_ValidateCopy()
1488 return IsBrowser() && IsMounted() && SelectedPaths
.Count
> 0;
1491 private void View_Copy()
1493 _pasteboard
.clear();
1494 _pasteboard
.setCopy(true);
1495 foreach (Path p
in SelectedPaths
)
1497 // Writing data for private use when the item gets dragged to the transfer queue.
1502 private bool View_ValidateCut()
1504 return IsBrowser() && IsMounted() && SelectedPaths
.Count
> 0;
1507 private void View_Cut()
1509 _pasteboard
.clear();
1510 _pasteboard
.setCut(true);
1511 foreach (Path s
in SelectedPaths
)
1513 // Writing data for private use when the item gets dragged to the transfer queue.
1518 private void View_ShowPreferences()
1520 PreferencesController
.Instance
.View
.Show();
1523 private bool View_ContextMenuEnabled()
1525 //context menu is always enabled
1529 private void View_Exit()
1531 MainController
.Exit();
1534 private List
<string> View_GetArchives()
1536 List
<string> result
= new List
<string>();
1537 Archive
[] archives
= Archive
.getKnownArchives();
1538 foreach (Archive archive
in archives
)
1540 List selected
= Utils
.ConvertToJavaList(SelectedPaths
, null);
1541 result
.Add(archive
.getTitle(selected
));
1546 private bool View_ValidateExpandArchive()
1550 if (Session
.getFeature(typeof (Compress
)) == null)
1554 if (SelectedPaths
.Count
> 0)
1556 foreach (Path selected
in SelectedPaths
)
1558 if (selected
.isDirectory())
1562 if (!Archive
.isArchive(selected
.getName()))
1573 private void View_ExpandArchive()
1575 List
<Path
> expanded
= new List
<Path
>();
1576 foreach (Path selected
in SelectedPaths
)
1578 Archive archive
= Archive
.forName(selected
.getName());
1579 if (null == archive
)
1583 if (CheckOverwrite(Utils
.ConvertFromJavaList
<Path
>(archive
.getExpanded(new ArrayList {selected}
))))
1585 background(new UnarchiveAction(this, archive
, selected
, expanded
));
1590 private bool View_ValidateCreateArchive()
1594 if (Session
.getFeature(typeof (Compress
)) == null)
1598 if (SelectedPaths
.Count
> 0)
1600 foreach (Path selected
in SelectedPaths
)
1602 if (selected
.isFile() && Archive
.isArchive(selected
.getName()))
1604 // At least one file selected is already an archive. No distinct action possible
1614 private void View_CreateArchive(object sender
, CreateArchiveEventArgs createArchiveEventArgs
)
1616 Archive archive
= Archive
.forName(createArchiveEventArgs
.ArchiveName
);
1617 IList
<Path
> selected
= SelectedPaths
;
1618 if (CheckOverwrite(new List
<Path
> {archive.getArchive(Utils.ConvertToJavaList(selected))}
))
1620 background(new CreateArchiveAction(this, archive
, selected
));
1624 private bool View_ValidateDelete()
1626 return IsMounted() && SelectedPaths
.Count
> 0;
1629 private bool View_ValidateSynchronize()
1634 private void View_Synchronize()
1637 if (SelectedPaths
.Count
== 1 && SelectedPath
.isDirectory())
1639 selected
= SelectedPath
;
1646 View
.SynchronizeDialog(
1647 String
.Format(LocaleFactory
.localizedString("Synchronize {0} with"), selected
.getName()),
1648 new UploadDirectoryFinder().find(Session
.getHost()), null);
1651 Local target
= LocalFactory
.get(folder
);
1652 new UploadDirectoryFinder().save(Session
.getHost(), target
.getParent());
1653 transfer(new SyncTransfer(Session
.getHost(), new TransferItem(selected
, target
)));
1657 private bool View_ValidateNewFile()
1659 return IsMounted() &&
1660 ((Touch
) Session
.getFeature(typeof (Touch
))).isSupported(
1661 new UploadTargetFinder(Workdir
).find(SelectedPath
));
1664 private bool View_ValidateUpload()
1666 return IsMounted() &&
1667 ((Touch
) Session
.getFeature(typeof (Touch
))).isSupported(
1668 new UploadTargetFinder(Workdir
).find(SelectedPath
));
1671 private void View_Upload()
1673 // Due to the limited functionality of the OpenFileDialog class it is
1674 // currently not possible to select a folder. May be we should provide
1675 // a second menu item which allows to select a folder to upload
1676 string[] paths
= View
.UploadDialog(null);
1677 if (null == paths
|| paths
.Length
== 0) return;
1679 Path destination
= new UploadTargetFinder(Workdir
).find(SelectedPath
);
1680 List uploads
= Utils
.ConvertToJavaList(paths
, delegate(string path
)
1682 Local local
= LocalFactory
.get(path
);
1683 new UploadDirectoryFinder().save(Session
.getHost(), local
.getParent());
1686 new Path(destination
, local
.getName(),
1688 ? EnumSet
.of(AbstractPath
.Type
.directory
)
1689 : EnumSet
.of(AbstractPath
.Type
.file
)), local
);
1691 transfer(new UploadTransfer(Session
.getHost(), uploads
));
1694 private void View_DownloadTo()
1696 string folder
= View
.DownloadToDialog(LocaleFactory
.localizedString("Download To…"),
1697 new DownloadDirectoryFinder().find(Session
.getHost()), null);
1698 if (null != folder
&& SelectedPaths
.Count
> 0)
1700 Local target
= LocalFactory
.get(folder
);
1701 new DownloadDirectoryFinder().save(Session
.getHost(), target
);
1702 IList
<TransferItem
> downloads
= new List
<TransferItem
>();
1703 foreach (Path file
in SelectedPaths
)
1705 downloads
.Add(new TransferItem(file
, LocalFactory
.get(target
, file
.getName())));
1707 transfer(new DownloadTransfer(Session
.getHost(), Utils
.ConvertToJavaList(downloads
)), new List
<Path
>());
1711 private bool View_ValidateDownloadAs()
1713 return IsMounted() && SelectedPaths
.Count
== 1;
1716 private void View_DownloadAs()
1718 string filename
= View
.DownloadAsDialog(new DownloadDirectoryFinder().find(Session
.getHost()),
1719 SelectedPath
.getName());
1720 if (null != filename
)
1722 Local target
= LocalFactory
.get(filename
);
1723 Path selected
= SelectedPath
;
1724 new DownloadDirectoryFinder().save(Session
.getHost(), target
.getParent());
1725 IList
<TransferItem
> downloads
= new List
<TransferItem
>();
1726 downloads
.Add(new TransferItem(selected
, target
));
1727 transfer(new DownloadTransfer(Session
.getHost(), Utils
.ConvertToJavaList(downloads
)), new List
<Path
>());
1731 private bool View_ValidateDownload()
1733 return IsMounted() && SelectedPaths
.Count
> 0;
1736 private bool View_ValidateShowInspector()
1738 return IsMounted() && SelectedPaths
.Count
> 0;
1741 private bool View_ValidateOpenWebUrl()
1746 private bool View_ValidateEditWith()
1748 if (IsMounted() && SelectedPaths
.Count
> 0)
1750 foreach (Path selected
in SelectedPaths
)
1752 if (!IsEditable(selected
))
1762 /// <param name="selected"></param>
1763 /// <returns>True if the selected path is editable (not a directory)</returns>
1764 private bool IsEditable(Path selected
)
1766 if (Session
.getHost().getCredentials().isAnonymousLogin())
1770 return selected
.isFile();
1773 private bool View_ValidateDuplicateFile()
1775 return IsMounted() && SelectedPaths
.Count
== 1;
1778 private bool View_ValidateRenameFile()
1780 if (IsMounted() && SelectedPaths
.Count
== 1)
1782 if (null == SelectedPath
)
1786 return ((Move
) Session
.getFeature(typeof (Move
))).isSupported(SelectedPath
);
1791 private void View_NewDownload()
1793 throw new NotImplementedException();
1796 private void View_OpenConnection()
1798 ConnectionController c
= ConnectionController
.Instance(this);
1799 DialogResult result
= c
.View
.ShowDialog(View
);
1800 if (result
== DialogResult
.OK
)
1802 Mount(c
.ConfiguredHost
);
1806 private bool View_ValidateNewFolder()
1811 private void View_DuplicateFile()
1813 DuplicateFileController dc
=
1814 new DuplicateFileController(ObjectFactory
.GetInstance
<IDuplicateFilePromptView
>(), this);
1818 private void View_NewFile()
1820 CreateFileController fc
= new CreateFileController(ObjectFactory
.GetInstance
<ICreateFilePromptView
>(), this);
1824 private void View_Delete()
1826 DeletePaths(SelectedPaths
);
1829 private void View_NewFolder()
1831 Location feature
= (Location
) Session
.getFeature(typeof (Location
));
1832 FolderController fc
= new FolderController(ObjectFactory
.GetInstance
<INewFolderPromptView
>(), this,
1834 ? (IList
<Location
.Name
>) Utils
.ConvertFromJavaList
<Location
.Name
>(feature
.getLocations())
1835 : new List
<Location
.Name
>());
1839 private bool View_RenameFile(Path path
, string newName
)
1841 if (!String
.IsNullOrEmpty(newName
) && !newName
.Equals(path
.getName()))
1843 Path renamed
= new Path(path
.getParent(), newName
, path
.getType());
1844 RenamePath(path
, renamed
);
1849 private DataObject
View_BrowserDrag(ObjectListView listView
)
1851 DataObject data
= new DataObject(DataFormats
.FileDrop
,
1854 CreateAndWatchTemporaryFile(delegate(object sender
, FileSystemEventArgs args
)
1856 _dropFolder
= System
.IO
.Path
.GetDirectoryName(args
.FullPath
);
1857 Invoke(delegate { Download(SelectedPaths, LocalFactory.get(_dropFolder)); }
);
1863 private void RemoveTemporaryFilesystemWatcher()
1865 BeginInvoke(delegate
1867 foreach (FileSystemWatcher watcher
in _temporaryWatcher
)
1871 _temporaryWatcher
.Clear();
1875 private void RemoveTemporaryFiles(DataObject data
)
1877 if (data
.ContainsFileDropList())
1879 foreach (string tmpFile
in data
.GetFileDropList())
1883 if (File
.Exists(tmpFile
))
1885 File
.Delete(tmpFile
);
1887 if (null != _dropFolder
)
1889 string tmpDestFile
= System
.IO
.Path
.Combine(_dropFolder
, System
.IO
.Path
.GetFileName(tmpFile
));
1890 if (File
.Exists(tmpDestFile
))
1892 File
.Delete(tmpDestFile
);
1896 catch (IOException e
)
1898 Log
.error("Could not remove temporary files.", e
);
1904 private void View_BrowserEndDrag(DataObject data
)
1906 RemoveTemporaryFiles(data
);
1907 RemoveTemporaryFilesystemWatcher();
1910 private void View_BrowserDropped(OlvDropEventArgs e
)
1912 if (IsMounted() && e
.DataObject
is DataObject
&& ((DataObject
) e
.DataObject
).ContainsFileDropList())
1915 switch (e
.DropTargetLocation
)
1917 case DropTargetLocation
.Item
:
1918 destination
= (Path
) e
.DropTargetItem
.RowObject
;
1920 case DropTargetLocation
.Background
:
1921 destination
= Workdir
;
1928 StringCollection dropList
= (e
.DataObject
as DataObject
).GetFileDropList();
1929 if (dropList
.Count
> 0)
1931 IList
<TransferItem
> roots
= new List
<TransferItem
>();
1932 foreach (string file
in dropList
)
1934 Local local
= LocalFactory
.get(file
);
1937 new Path(destination
, local
.getName(),
1939 ? EnumSet
.of(AbstractPath
.Type
.directory
)
1940 : EnumSet
.of(AbstractPath
.Type
.file
)), local
));
1942 UploadDroppedPath(roots
, destination
);
1947 public void UploadDroppedPath(IList
<TransferItem
> roots
, Path destination
)
1951 UploadTransfer q
= new UploadTransfer(Session
.getHost(), Utils
.ConvertToJavaList(roots
));
1952 if (q
.getRoots().size() > 0)
1960 /// Check if we accept drag operation from an external program
1962 /// <param name="args"></param>
1963 private void View_BrowserCanDrop(OlvDropEventArgs args
)
1965 Log
.trace("Entering View_BrowserCanDrop with " + args
.Effect
);
1966 if (IsMounted() && !(args
.DataObject
is OLVDataObject
))
1968 if (args
.DataObject
is DataObject
&& ((DataObject
) args
.DataObject
).ContainsFileDropList())
1971 switch (args
.DropTargetLocation
)
1973 case DropTargetLocation
.Item
:
1974 destination
= (Path
) args
.DropTargetItem
.RowObject
;
1975 if (!destination
.isDirectory())
1977 //dragging over file
1978 destination
= destination
.getParent();
1981 case DropTargetLocation
.Background
:
1982 destination
= Workdir
;
1985 args
.Effect
= DragDropEffects
.None
;
1986 args
.DropTargetLocation
= DropTargetLocation
.None
;
1989 Touch feature
= (Touch
) Session
.getFeature(typeof (Touch
));
1990 if (!feature
.isSupported(destination
))
1992 Log
.trace("Session does not allow file creation");
1993 args
.Effect
= DragDropEffects
.None
;
1994 args
.DropTargetLocation
= DropTargetLocation
.None
;
1997 Log
.trace("Setting effect to copy");
1998 args
.Effect
= DragDropEffects
.Copy
;
1999 if (Workdir
== destination
)
2001 args
.DropTargetLocation
= DropTargetLocation
.Background
;
2005 args
.DropTargetItem
= args
.ListView
.ModelToItem(destination
);
2007 (args
.DataObject
as DataObject
).SetDropDescription((DropImageType
) args
.Effect
, "Copy to %1",
2008 destination
.getName());
2013 private void View_ShowTransfers()
2015 TransferController
.Instance
.View
.Show();
2018 private void View_ShowInspector()
2020 IList
<Path
> selected
= SelectedPaths
;
2021 if (selected
.Count
> 0)
2023 if (PreferencesFactory
.get().getBoolean("browser.info.inspector"))
2025 if (null == _inspector
|| _inspector
.View
.IsDisposed
)
2027 _inspector
= InfoController
.Factory
.Create(this, selected
);
2031 _inspector
.Files
= selected
;
2033 _inspector
.View
.Show(View
);
2037 InfoController c
= InfoController
.Factory
.Create(this, selected
);
2043 private void View_EditEvent(string exe
)
2045 foreach (Path selected
in SelectedPaths
)
2048 if (Utils
.IsBlank(exe
))
2050 editor
= EditorFactory
.instance().create(this, Session
, selected
);
2054 editor
= EditorFactory
.instance().create(this, Session
, new Application(exe
, null), selected
);
2060 public void edit(Editor editor
)
2062 this.background(new WorkerBackgroundAction(this, Session
,
2063 editor
.open(new DisabledApplicationQuitCallback(), new DisabledTransferErrorCallback(),
2064 new DefaultEditorListener(this, Session
, editor
))));
2067 private void UpdateEditIcon()
2069 Path selected
= SelectedPath
;
2070 if (null != selected
)
2072 if (IsEditable(selected
))
2074 Application app
= EditorFactory
.instance().getEditor(selected
.getName());
2075 string editCommand
= app
!= null ? app
.getIdentifier() : null;
2076 if (Utils
.IsNotBlank(editCommand
))
2081 IconCache
.Instance
.GetFileIconFromExecutable(
2082 WindowsApplicationLauncher
.GetExecutableCommand(editCommand
), IconCache
.IconSize
.Large
)
2086 catch (ObjectDisposedException
)
2092 View
.EditIcon
= IconCache
.Instance
.IconForName("pencil", 32);
2095 private void UpdateOpenIcon()
2097 View
.OpenIcon
= IconCache
.Instance
.GetDefaultBrowserIcon();
2100 private void View_BrowserSelectionChanged()
2104 // update inspector content if available
2105 IList
<Path
> selectedPaths
= SelectedPaths
;
2107 if (PreferencesFactory
.get().getBoolean("browser.info.inspector"))
2109 if (_inspector
!= null && _inspector
.Visible
)
2111 if (selectedPaths
.Count
> 0)
2113 _inspector
.Files
= selectedPaths
;
2119 private void View_PathSelectionChanged()
2121 string selected
= View
.SelectedComboboxPath
;
2122 if (selected
!= null)
2124 Path workdir
= Workdir
;
2126 while (!p
.getAbsolute().Equals(selected
))
2131 if (workdir
.getParent().equals(p
))
2133 SetWorkdir(p
, workdir
);
2142 private void View_FolderUp()
2144 Path previous
= Workdir
;
2145 SetWorkdir(previous
.getParent(), previous
);
2148 private void View_HistoryBack()
2150 Path selected
= _navigation
.back();
2151 if (selected
!= null)
2153 Path previous
= Workdir
;
2154 if (previous
.getParent().equals(selected
))
2156 SetWorkdir(selected
, previous
);
2160 SetWorkdir(selected
);
2165 private void View_HistoryForward()
2167 Path selected
= _navigation
.forward();
2168 if (selected
!= null)
2170 SetWorkdir(selected
);
2174 private void View_BrowserDoubleClicked()
2176 View_FolderInside();
2179 private void View_QuickConnect()
2181 if (string.IsNullOrEmpty(View
.QuickConnectValue
))
2185 string input
= View
.QuickConnectValue
.Trim();
2187 // First look for equivalent bookmarks
2188 BookmarkCollection bookmarkCollection
= BookmarkCollection
.defaultCollection();
2189 foreach (Host host
in bookmarkCollection
)
2191 if (BookmarkNameProvider
.toString(host
).Equals(input
))
2197 Mount(HostParser
.parse(input
));
2201 /// Open a new browser with the current selected folder as the working directory
2203 private void View_NewBrowser(object sender
, NewBrowserEventArgs newBrowserEventArgs
)
2205 if (newBrowserEventArgs
.SelectedAsWorkingDir
)
2207 Path selected
= SelectedPath
;
2208 if (null == selected
|| !selected
.isDirectory())
2212 BrowserController c
= MainController
.NewBrowser(true);
2214 Host host
= new HostDictionary().deserialize(Session
.getHost().serialize(SerializerFactory
.get()));
2215 host
.setDefaultPath(selected
.getAbsolute());
2220 BrowserController c
= MainController
.NewBrowser(true);
2221 MainController
.OpenDefaultBookmark(c
);
2225 protected void transfer(Transfer transfer
)
2227 this.transfer(transfer
, Utils
.ConvertFromJavaList(transfer
.getRoots(), delegate(object o
)
2229 TransferItem item
= (TransferItem
) o
;
2235 /// Transfers the files either using the queue or using
2236 /// the browser session if #connection.pool.max is 1
2238 /// <param name="transfer"></param>
2239 protected void transfer(Transfer transfer
, IList
<Path
> selected
)
2241 this.transfer(transfer
, selected
, Session
.getTransferType().equals(Host
.TransferType
.browser
));
2247 /// <param name="transfer"></param>
2248 /// <param name="destination"></param>
2249 /// <param name="useBrowserConnection"></param>
2250 public void transfer(Transfer transfer
, IList
<Path
> selected
, bool browser
)
2252 TransferCallback callback
= new ReloadTransferCallback(this, selected
);
2255 Background(new CallbackTransferBackgroundAction(callback
, this, new ProgressTransferAdapter(this), this,
2256 this, transfer
, new TransferOptions()));
2260 TransferController
.Instance
.StartTransfer(transfer
, new TransferOptions(), callback
);
2267 /// <returns>true if a connection is being opened or is already initialized</returns>
2268 public bool HasSession()
2270 return Session
!= null;
2273 public bool IsMounted()
2275 return HasSession() && Workdir
!= null;
2281 /// <param name="preserveSelection">All selected files should be reselected after reloading the view</param>
2282 public void ReloadData(bool preserveSelection
)
2284 if (preserveSelection
)
2286 //Remember the previously selected paths
2287 ReloadData(SelectedPaths
);
2291 ReloadData(new List
<Path
>());
2295 public void RefreshParentPath(Path changed
)
2297 RefreshParentPaths(new Collection
<Path
> {changed}
);
2300 public void RefreshParentPaths(IList
<Path
> changed
)
2302 RefreshParentPaths(changed
, new List
<Path
>());
2305 public override void start(BackgroundAction action
)
2307 Invoke(delegate { View.StartActivityAnimation(); }
);
2310 public override void stop(BackgroundAction action
)
2312 Invoke(delegate { View.StopActivityAnimation(); }
);
2315 public void RefreshParentPaths(IList
<Path
> changed
, IList
<Path
> selected
)
2317 bool rootRefreshed
= false; //prevent multiple root updates
2318 foreach (Path path
in changed
)
2320 _cache
.invalidate(path
.getParent());
2321 if (Workdir
.equals(path
.getParent()))
2327 View
.SetBrowserModel(_browserModel
.ChildrenGetter(Workdir
));
2328 rootRefreshed
= true;
2332 View
.RefreshBrowserObject(path
.getParent());
2335 SelectedPaths
= selected
;
2338 public void ReloadData(Path directory
, bool preserveSelection
)
2340 if (Workdir
.equals(directory
))
2346 View
.RefreshBrowserObject(directory
);
2350 protected void ReloadData(IList
<Path
> selected
)
2352 if (null != Workdir
)
2354 IEnumerable
<Path
> children
= _browserModel
.ChildrenGetter(Workdir
);
2355 //clear selection before resetting model. Otherwise we have weird selection effects.
2356 SelectedPaths
= new List
<Path
>();
2357 int savedIndex
= View
.TopItemIndex
;
2358 View
.BeginBrowserUpdate();
2359 View
.SetBrowserModel(null); // #7670
2360 View
.SetBrowserModel(children
);
2361 View
.TopItemIndex
= savedIndex
;
2362 SelectedPaths
= selected
;
2363 List
<Path
> toUpdate
= new List
<Path
>();
2364 foreach (Path path
in View
.VisiblePaths
)
2366 if (path
.isDirectory())
2371 View
.RefreshBrowserObjects(toUpdate
);
2372 View
.EndBrowserUpdate();
2376 View
.SetBrowserModel(null);
2378 SelectedPaths
= selected
;
2382 public void SetWorkdir(Path directory
)
2384 SetWorkdir(directory
, new List
<Path
>());
2387 public void SetWorkdir(Path directory
, Path selected
)
2389 SetWorkdir(directory
, new List
<Path
> {selected}
);
2393 /// Sets the current working directory. This will udpate the path selection dropdown button
2394 /// and also add this path to the browsing history. If the path cannot be a working directory (e.g. permission
2395 /// issues trying to enter the directory), reloading the browser view is canceled and the working directory
2398 /// <param name="directory">The new working directory to display or null to detach any working directory from the browser</param>
2399 /// <param name="selected"></param>
2400 public void SetWorkdir(Path directory
, List
<Path
> selected
)
2402 Workdir
= directory
;
2403 // Remove any custom file filter
2404 SetPathFilter(null);
2405 // Change to last selected browser view
2406 ReloadData(Workdir
!= null ? selected
: new List
<Path
>());
2407 SetNavigation(IsMounted());
2410 private void SetNavigation(bool enabled
)
2412 View
.SearchEnabled
= enabled
;
2415 View
.SearchString
= String
.Empty
;
2417 List
<string> paths
= new List
<string>();
2420 // Update the current working directory
2421 _navigation
.add(Workdir
);
2425 paths
.Add(p
.getAbsolute());
2427 } while (!p
.isRoot());
2428 View
.PopulatePaths(paths
);
2430 View
.ComboboxPathEnabled
= enabled
;
2431 View
.HistoryBackEnabled
= enabled
&& _navigation
.getBack().size() > 1;
2432 View
.HistoryForwardEnabled
= enabled
&& _navigation
.getForward().size() > 0;
2433 View
.ParentPathEnabled
= enabled
&& !Workdir
.isRoot();
2436 public void RefreshObject(Path path
, bool preserveSelection
)
2438 if (preserveSelection
)
2440 RefreshObject(path
, View
.SelectedPaths
);
2444 RefreshObject(path
, new List
<Path
>());
2448 public void RefreshObject(Path path
, IList
<Path
> selected
)
2450 if (Workdir
.Equals(path
))
2452 View
.SetBrowserModel(_browserModel
.ChildrenGetter(path
));
2456 if (!path
.isDirectory())
2458 View
.RefreshBrowserObject(path
.getParent());
2462 View
.RefreshBrowserObject(path
);
2465 SelectedPaths
= selected
;
2469 public void Mount(Host host
)
2471 if (Log
.isDebugEnabled())
2473 Log
.debug(string.Format("Mount session for {0}", host
));
2475 CallbackDelegate callbackDelegate
= delegate
2477 // The browser has no session, we are allowed to proceed
2478 // Initialize the browser with the new session attaching all listeners
2479 Session session
= Init(host
);
2480 background(new MountAction(this, session
, host
, _limitListener
));
2482 Unmount(callbackDelegate
);
2486 /// Initializes a session for the passed host. Setting up the listeners and adding any callback
2487 /// controllers needed for login, trust management and hostkey verification.
2489 /// <param name="host"></param>
2490 /// <returns>A session object bound to this browser controller</returns>
2491 private Session
Init(Host host
)
2493 Session
= SessionFactory
.create(host
,
2494 new KeychainX509TrustManager(new DefaultTrustManagerHostnameCallback(host
)),
2495 new KeychainX509KeyManager());
2497 View
.SelectedEncoding
= Session
.getEncoding();
2498 View
.ClearTranscript();
2499 _navigation
.clear();
2500 _pasteboard
= PathPasteboardFactory
.getPasteboard(Session
);
2504 // some simple caching as _session.isConnected() throws a ConnectionCanceledException if not connected
2509 /// <returns>true if mounted and the connection to the server is alive</returns>
2510 public bool IsConnected()
2514 return Session
.isConnected();
2519 public static bool ApplicationShouldTerminate()
2521 // Determine if there are any open connections
2522 foreach (BrowserController controller
in new List
<BrowserController
>(MainController
.Browsers
))
2524 BrowserController c
= controller
;
2525 if (!controller
.Unmount(delegate(DialogResult result
)
2527 if (DialogResult
.OK
== result
)
2535 return false; // Disconnect cancelled
2541 public bool Unmount()
2543 return Unmount(() => { }
);
2546 public bool Unmount(CallbackDelegate disconnected
)
2548 return Unmount(result
=>
2550 if (DialogResult
.OK
== result
)
2552 UnmountImpl(disconnected
);
2563 /// <param name="unmountImpl"></param>
2564 /// <param name="disconnected"></param>
2565 /// <returns>True if the unmount process is in progress or has been finished, false if cancelled</returns>
2566 public bool Unmount(DialogCallbackDelegate unmountImpl
, CallbackDelegate disconnected
)
2568 if (IsConnected() || isActivityRunning())
2570 if (PreferencesFactory
.get().getBoolean("browser.disconnect.confirm"))
2572 DialogResult result
= CommandBox(LocaleFactory
.localizedString("Disconnect"),
2573 String
.Format(LocaleFactory
.localizedString("Disconnect from {0}"),
2574 Session
.getHost().getHostname()),
2575 LocaleFactory
.localizedString("The connection will be closed."),
2576 String
.Format("{0}", LocaleFactory
.localizedString("Disconnect")), true,
2577 LocaleFactory
.localizedString("Don't ask again", "Configuration"), SysIcons
.Question
,
2578 delegate(int option
, bool verificationChecked
)
2580 if (verificationChecked
)
2582 // Never show again.
2583 PreferencesFactory
.get().setProperty("browser.disconnect.confirm", false);
2587 case 0: // Disconnect
2588 unmountImpl(DialogResult
.OK
);
2592 return DialogResult
.OK
== result
;
2595 UnmountImpl(disconnected
);
2596 // Unmount succeeded
2600 private void UnmountImpl(CallbackDelegate disconnected
)
2602 CallbackDelegate run
= delegate
2605 View
.WindowTitle
= PreferencesFactory
.get().getProperty("application.name");
2612 public void SetStatus()
2614 BackgroundAction current
= getActions().getCurrent();
2615 message(null != current
? current
.getActivity() : null);
2618 public void SetStatus(string label
)
2620 View
.StatusLabel
= label
;
2623 private void PopulateQuickConnect()
2625 List
<string> nicknames
= new List
<string>();
2626 foreach (Host host
in _bookmarkCollection
)
2628 nicknames
.Add(BookmarkNameProvider
.toString(host
));
2630 View
.PopulateQuickConnect(nicknames
);
2636 /// <param name="path">The existing file</param>
2637 /// <param name="renamed">The renamed file</param>
2638 protected internal void RenamePath(Path path
, Path renamed
)
2640 RenamePaths(new Dictionary
<Path
, Path
> {{path, renamed}}
);
2646 /// <param name="selected">
2647 /// A dictionary with the original files as the key and
2648 /// the destination files as the value
2650 protected internal void RenamePaths(IDictionary
<Path
, Path
> selected
)
2652 if (CheckMove(selected
))
2654 List
<Path
> changed
= new List
<Path
>();
2655 changed
.AddRange(selected
.Keys
);
2656 changed
.AddRange(selected
.Values
);
2657 MoveAction move
= new MoveAction(this, Utils
.ConvertToJavaMap(selected
), changed
);
2663 /// Displays a warning dialog about files to be moved
2665 /// <param name="selected">The files to check for existence</param>
2666 /// <param name="action"></param>
2667 private bool CheckMove(IDictionary
<Path
, Path
> selected
)
2669 if (PreferencesFactory
.get().getBoolean("browser.move.confirm"))
2671 StringBuilder alertText
=
2672 new StringBuilder(LocaleFactory
.localizedString("Do you want to move the selected files?"));
2674 StringBuilder content
= new StringBuilder();
2676 bool rename
= false;
2677 IEnumerator
<KeyValuePair
<Path
, Path
>> enumerator
= null;
2678 for (enumerator
= selected
.GetEnumerator(); i
< 10 && enumerator
.MoveNext();)
2680 KeyValuePair
<Path
, Path
> next
= enumerator
.Current
;
2681 if (next
.Key
.getParent().equals(next
.Value
.getParent()))
2686 content
.Append("\n" + Character
.toString('\u2022') + " " + next
.Key
.getName());
2689 if (enumerator
.MoveNext())
2691 content
.Append("\n" + Character
.toString('\u2022') + " ...)");
2693 bool result
= false;
2694 CommandBox(rename
? LocaleFactory
.localizedString("Rename") : LocaleFactory
.localizedString("Move"),
2695 alertText
.ToString(), content
.ToString(),
2696 String
.Format("{0}",
2697 rename
? LocaleFactory
.localizedString("Rename") : LocaleFactory
.localizedString("Move")), true,
2698 LocaleFactory
.localizedString("Don't ask again", "Configuration"), SysIcons
.Question
,
2699 delegate(int option
, bool verificationChecked
)
2701 if (verificationChecked
)
2703 // Never show again.
2704 PreferencesFactory
.get().setProperty("browser.move.confirm", false);
2708 result
= CheckOverwrite(selected
.Values
);
2713 return CheckOverwrite(selected
.Values
);
2717 /// Recursively deletes the files
2719 /// <param name="selected">The files selected in the browser to delete</param>
2720 public void DeletePaths(ICollection
<Path
> selected
)
2722 ICollection
<Path
> normalized
=
2723 Utils
.ConvertFromJavaList
<Path
>(PathNormalizer
.normalize(Utils
.ConvertToJavaList(selected
)));
2724 if (normalized
.Count
== 0)
2729 StringBuilder alertText
=
2731 LocaleFactory
.localizedString("Really delete the following files? This cannot be undone."));
2733 StringBuilder content
= new StringBuilder();
2735 IEnumerator
<Path
> enumerator
;
2736 for (enumerator
= selected
.GetEnumerator(); i
< 10 && enumerator
.MoveNext();)
2738 Path item
= enumerator
.Current
;
2739 if (i
> 0) content
.AppendLine();
2741 content
.Append(Character
.toString('\u2022') + " " + item
.getName());
2744 if (enumerator
.MoveNext())
2746 content
.Append("\n" + Character
.toString('\u2022') + " ...)");
2748 DialogResult r
= QuestionBox(LocaleFactory
.localizedString("Delete"), alertText
.ToString(),
2749 content
.ToString(), String
.Format("{0}", LocaleFactory
.localizedString("Delete")), true);
2750 if (r
== DialogResult
.OK
)
2752 DeletePathsImpl(normalized
);
2756 private void DeletePathsImpl(ICollection
<Path
> files
)
2758 background(new DeleteAction(this, LoginCallbackFactory
.get(this), Utils
.ConvertToJavaList(files
)));
2761 public void SetPathFilter(string searchString
)
2763 if (Utils
.IsBlank(searchString
))
2765 View
.SearchString
= String
.Empty
;
2766 // Revert to the last used default filter
2767 if (ShowHiddenFiles
)
2769 FilenameFilter
= new NullFilter();
2773 FilenameFilter
= new RegexFilter();
2778 // Setting up a custom filter for the directory listing
2779 FilenameFilter
= new CustomPathFilter(searchString
);
2785 /// Displays a warning dialog about already existing files
2787 /// <param name="selected">The files to check for existance</param>
2788 private bool CheckOverwrite(ICollection
<Path
> selected
)
2790 StringBuilder alertText
=
2792 LocaleFactory
.localizedString(
2793 "A file with the same name already exists. Do you want to replace the existing file?"));
2795 StringBuilder content
= new StringBuilder();
2797 IEnumerator
<Path
> enumerator
= null;
2798 bool shouldWarn
= false;
2799 for (enumerator
= selected
.GetEnumerator(); enumerator
.MoveNext();)
2801 Path item
= enumerator
.Current
;
2802 if (_cache
.get(item
.getParent()).contains(item
))
2807 content
.Append("\n" + Character
.toString('\u2022') + " " + item
.getName());
2815 content
.Append("\n" + Character
.toString('\u2022') + " ...)");
2819 DialogResult r
= QuestionBox(LocaleFactory
.localizedString("Overwrite"), alertText
.ToString(),
2820 content
.ToString(), String
.Format("{0}", LocaleFactory
.localizedString("Overwrite")), true);
2821 return r
== DialogResult
.OK
;
2832 /// <param name="source">The original file to duplicate</param>
2833 /// <param name="destination">The destination of the duplicated file</param>
2834 protected internal void DuplicatePath(Path source
, Path destination
)
2836 DuplicatePaths(new Dictionary
<Path
, Path
> {{source, destination}}
);
2842 /// <param name="selected">A dictionary with the original files as the key and the destination files as the value</param>
2843 ///<param name="browser"></param>
2844 protected internal void DuplicatePaths(IDictionary
<Path
, Path
> selected
)
2846 if (CheckOverwrite(selected
.Values
))
2848 CopyTransfer copy
= new CopyTransfer(Session
.getHost(), Session
.getHost(),
2849 Utils
.ConvertToJavaMap(selected
));
2850 List
<Path
> changed
= new List
<Path
>();
2851 changed
.AddRange(selected
.Values
);
2852 transfer(copy
, changed
, true);
2859 /// <param name="view">The view to show</param>
2860 public void ToggleView(BrowserView view
)
2862 Log
.debug("ToggleView:" + view
);
2863 if (View
.CurrentView
== view
) return;
2865 SetBookmarkFilter(null);
2868 case BrowserView
.File
:
2869 View
.CurrentView
= BrowserView
.File
;
2870 SetPathFilter(null);
2873 case BrowserView
.Bookmark
:
2874 View
.CurrentView
= BrowserView
.Bookmark
;
2875 _bookmarkModel
.Source
= BookmarkCollection
.defaultCollection();
2879 case BrowserView
.History
:
2880 View
.CurrentView
= BrowserView
.History
;
2881 _bookmarkModel
.Source
= HistoryCollection
.defaultCollection();
2885 case BrowserView
.Bonjour
:
2886 View
.CurrentView
= BrowserView
.Bonjour
;
2887 _bookmarkModel
.Source
= RendezvousCollection
.defaultCollection();
2894 private void SelectHost()
2898 View
.SelectBookmark(Session
.getHost());
2903 /// Reload bookmarks table from the currently selected model
2905 public void ReloadBookmarks()
2907 ReloadBookmarks(null);
2911 /// Reload bookmarks table from the currently selected model
2913 public void ReloadBookmarks(Host selected
)
2915 //Note: expensive for a big bookmark list (might need a refactoring)
2916 View
.SetBookmarkModel(_bookmarkModel
.Source
, selected
);
2920 private class BookmarkFilter
: HostFilter
2922 private readonly string _searchString
;
2924 public BookmarkFilter(String searchString
)
2926 _searchString
= searchString
;
2929 public bool accept(Host host
)
2931 return BookmarkNameProvider
.toString(host
).ToLower().Contains(_searchString
.ToLower()) ||
2932 (null == host
.getComment()
2934 : host
.getComment().ToLower().Contains(_searchString
.ToLower())) ||
2935 (null == host
.getCredentials().getUsername()
2937 : host
.getCredentials().getUsername().ToLower().Contains(_searchString
.ToLower())) ||
2938 host
.getHostname().ToLower().Contains(_searchString
.ToLower());
2942 private class CallbackTransferBackgroundAction
: TransferBackgroundAction
2944 private readonly TransferCallback _callback
;
2945 private readonly Transfer _transfer
;
2947 public CallbackTransferBackgroundAction(TransferCallback callback
, BrowserController controller
,
2948 TransferListener transferListener
, ProgressListener progressListener
,
2949 TranscriptListener transcriptListener
, Transfer transfer
, TransferOptions options
)
2951 controller
, controller
.Session
, controller
._cache
, transferListener
, progressListener
,
2952 transcriptListener
, transfer
, options
)
2954 _callback
= callback
;
2955 _transfer
= transfer
;
2958 public override void finish()
2960 if (_transfer
.isComplete())
2962 _callback
.complete(_transfer
);
2968 private class CreateArchiveAction
: BrowserControllerBackgroundAction
2970 private readonly Archive _archive
;
2971 private readonly IList
<Path
> _selected
;
2972 private readonly List _selectedJava
;
2974 public CreateArchiveAction(BrowserController controller
, Archive archive
, IList
<Path
> selected
)
2978 _selectedJava
= Utils
.ConvertToJavaList(selected
);
2979 _selected
= selected
;
2982 public override object run()
2984 ((Compress
) BrowserController
.Session
.getFeature(typeof (Compress
))).archive(_archive
,
2985 BrowserController
.Workdir
, _selectedJava
, BrowserController
, BrowserController
);
2989 public override string getActivity()
2991 return _archive
.getCompressCommand(BrowserController
.Workdir
, _selectedJava
);
2994 public override void cleanup()
2997 BrowserController
.RefreshParentPaths(_selected
, new List
<Path
> {_archive.getArchive(_selectedJava)}
);
3001 private class CustomPathFilter
: SearchFilter
, IModelFilter
3003 public CustomPathFilter(String searchString
) : base(searchString
)
3007 public bool Filter(object modelObject
)
3009 return accept(modelObject
);
3013 private class DeleteAction
: WorkerBackgroundAction
3015 public DeleteAction(BrowserController controller
, LoginCallback prompt
, List files
)
3016 : base(controller
, controller
.Session
, new InnerDeleteWorker(controller
, prompt
, files
))
3020 private class InnerDeleteWorker
: DeleteWorker
3022 private readonly BrowserController _controller
;
3023 private readonly List _files
;
3025 public InnerDeleteWorker(BrowserController controller
, LoginCallback prompt
, List files
)
3026 : base(controller
.Session
, prompt
, files
, controller
)
3028 _controller
= controller
;
3032 public override void cleanup(object result
)
3034 if (((Boolean
) result
).booleanValue())
3036 _controller
.RefreshParentPaths((IList
<Path
>) Utils
.ConvertFromJavaList
<Path
>(_files
));
3042 private class DisconnectAction
: WorkerBackgroundAction
3044 private readonly BrowserController _controller
;
3046 public DisconnectAction(BrowserController controller
, CallbackDelegate callback
)
3047 : base(controller
, controller
.Session
, controller
.Cache
, new InnerDisconnectWorker(controller
, callback
)
3050 _controller
= controller
;
3053 public override void prepare()
3055 if (null == _controller
.Session
)
3057 throw new ConnectionCanceledException();
3059 if (!_controller
.Session
.isConnected())
3061 throw new ConnectionCanceledException();
3066 private class InnerDisconnectWorker
: DisconnectWorker
3068 private readonly CallbackDelegate _callback
;
3070 public InnerDisconnectWorker(BrowserController controller
, CallbackDelegate callback
)
3071 : base(controller
.Session
)
3073 _callback
= callback
;
3076 public override void cleanup(object wd
)
3084 private class MountAction
: WorkerBackgroundAction
3086 private readonly BrowserController _controller
;
3087 private readonly Host _host
;
3089 public MountAction(BrowserController controller
, Session session
, Host host
, ListProgressListener listener
)
3090 : base(controller
, controller
.Session
, new InnerMountWorker(controller
, session
, listener
))
3092 _controller
= controller
;
3096 public override void init()
3099 _controller
.View
.WindowTitle
= BookmarkNameProvider
.toString(_host
, true);
3100 _controller
.View
.RefreshBookmark(_controller
.Session
.getHost());
3103 private class InnerMountWorker
: MountWorker
3105 private readonly BrowserController _controller
;
3106 private readonly Session _session
;
3108 public InnerMountWorker(BrowserController controller
, Session session
, ListProgressListener listener
)
3109 : base(session
, controller
._cache
, listener
)
3111 _controller
= controller
;
3115 public override void cleanup(object wd
)
3117 Path workdir
= (Path
) wd
;
3118 if (null == workdir
)
3120 _controller
.Unmount();
3124 // Set the working directory
3125 _controller
.SetWorkdir(workdir
);
3126 _controller
.View
.RefreshBookmark(_session
.getHost());
3127 _controller
.ToggleView(BrowserView
.File
);
3128 _controller
.View
.SecureConnection
= _session
is SSLSession
;
3129 _controller
.View
.CertBasedConnection
= _session
is SSLSession
;
3130 _controller
.View
.SecureConnectionVisible
= true;
3136 private class MoveAction
: WorkerBackgroundAction
3138 public MoveAction(BrowserController controller
, Map selected
, IList
<Path
> changed
)
3139 : base(controller
, controller
.Session
, new InnerMoveWorker(controller
, selected
, changed
))
3143 private class InnerMoveWorker
: MoveWorker
3145 private readonly IList
<Path
> _changed
;
3146 private readonly BrowserController _controller
;
3147 private readonly Map _files
;
3149 public InnerMoveWorker(BrowserController controller
, Map files
, IList
<Path
> changed
)
3150 : base(controller
.Session
, files
, controller
)
3152 _controller
= controller
;
3157 public override void cleanup(object result
)
3159 _controller
.RefreshParentPaths(_changed
,
3160 (IList
<Path
>) Utils
.ConvertFromJavaList
<Path
>(_files
.values()));
3165 private class ProgressTransferAdapter
: TransferAdapter
3167 private readonly BrowserController _controller
;
3169 public ProgressTransferAdapter(BrowserController controller
)
3171 _controller
= controller
;
3174 public override void progress(TransferProgress status
)
3176 _controller
.message(status
.getProgress());
3180 private class ReloadTransferCallback
: TransferCallback
3182 private readonly IList
<Path
> _changed
;
3183 private readonly BrowserController _controller
;
3185 public ReloadTransferCallback(BrowserController controller
, IList
<Path
> changed
)
3187 _controller
= controller
;
3191 public void complete(Transfer t
)
3193 _controller
.invoke(new ReloadAction(_controller
, _changed
));
3196 private class ReloadAction
: WindowMainAction
3198 private readonly IList
<Path
> _changed
;
3200 public ReloadAction(BrowserController c
, IList
<Path
> changed
) : base(c
)
3205 public override bool isValid()
3207 return base.isValid() && ((BrowserController
) Controller
).IsConnected();
3210 public override void run()
3212 ((BrowserController
) Controller
).RefreshParentPaths(_changed
, _changed
);
3217 private class RevertAction
: WorkerBackgroundAction
3219 public RevertAction(BrowserController controller
, IList
<Path
> files
)
3220 : base(controller
, controller
.Session
, new InnerRevertWorker(controller
, files
))
3224 private class InnerRevertWorker
: RevertWorker
3226 private readonly BrowserController _controller
;
3227 private readonly IList
<Path
> _files
;
3229 public InnerRevertWorker(BrowserController controller
, IList
<Path
> files
)
3230 : base(controller
.Session
, Utils
.ConvertToJavaList(files
))
3232 _controller
= controller
;
3236 public override void cleanup(object result
)
3238 _controller
.RefreshParentPaths(_files
);
3243 private class UnarchiveAction
: BrowserControllerBackgroundAction
3245 private readonly Archive _archive
;
3246 private readonly List
<Path
> _expanded
;
3247 private readonly Path _selected
;
3249 public UnarchiveAction(BrowserController controller
, Archive archive
, Path selected
, List
<Path
> expanded
)
3253 _expanded
= expanded
;
3254 _selected
= selected
;
3257 public override object run()
3259 ((Compress
) BrowserController
.Session
.getFeature(typeof (Compress
))).unarchive(_archive
, _selected
,
3260 BrowserController
, BrowserController
);
3264 public override string getActivity()
3266 return _archive
.getDecompressCommand(_selected
);
3269 public override void cleanup()
3272 _expanded
.AddRange(Utils
.ConvertFromJavaList
<Path
>(_archive
.getExpanded(new ArrayList {_selected}
)));
3273 BrowserController
.RefreshParentPaths(_expanded
, _expanded
);