/// <summary> /// Sync call to list directory contents /// </summary> /// <param name="session"></param> /// <param name="path"></param> /// <returns></returns> public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { ListDirectoryResult result; if (session == null || session.Username == null) { result = new ListDirectoryResult(path); result.ErrorMsg = "Session invalid"; result.StatusCode = ResultStatusCode.Error; } else { string targetPath = path.Path; if (targetPath == null || targetPath == ".") { targetPath = string.Format("/home/{0}", session.Username); Log.InfoFormat("Defaulting path: {0}->{1}", path.Path, targetPath); path.Path = targetPath; } PscpClient client = new PscpClient(this.Options, session); result = client.ListDirectory(path); } return result; }
public ListDirectoryResult ListDirectory(BrowserFileInfo path) { lock (this) { //return this.DoListDirectory(path); ListDirectoryResult result = new ListDirectoryResult(path); String ArgsPscp = ToArgs(this.Session, this.Session.Password, path.Path); RunPscp( result, ArgsPscp, CommandLineOptions.replacePassword(ArgsPscp, "XXXXX"), null, null, (lines) => { // successful list ScpLineParser parser = new ScpLineParser(); foreach (string rawLine in lines) { string line = rawLine.TrimEnd(); BrowserFileInfo fileInfo; if (parser.TryParseFileLine(line, out fileInfo)) { if (fileInfo.Name != ".") { fileInfo.Path = MakePath(path.Path, fileInfo.Name); result.Add(fileInfo); } } } }); return(result); } }
private void listViewFiles_KeyDown(object sender, KeyEventArgs e) { BrowserFileInfo bfi = null; switch (e.KeyCode) { case Keys.Enter: if (this.listViewFiles.SelectedItems.Count != 0) { bfi = (BrowserFileInfo)this.listViewFiles.SelectedItems[0].Tag; if (bfi.Type == FileType.Directory || bfi.Type == FileType.ParentDirectory) { this.Presenter.LoadDirectory(bfi); } } break; case Keys.Back: bfi = (BrowserFileInfo)this.listViewFiles.Items[0].Tag; if (bfi.Type == FileType.ParentDirectory) { this.Presenter.LoadDirectory(bfi); } break; } }
/// <summary> /// Sync call to list directory contents /// </summary> /// <param name="session"></param> /// <param name="path"></param> /// <returns></returns> public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { ListDirectoryResult result; if (session == null || session.Username == null) { result = new ListDirectoryResult(path) { ErrorMsg = "Session invalid", StatusCode = ResultStatusCode.Error }; } else { string targetPath = path.Path; if (targetPath == null || targetPath == ".") { targetPath = string.Format("/home/{0}", session.Username); Log.InfoFormat("Defaulting path: {0}->{1}", path.Path, targetPath); path.Path = targetPath; } PscpClient client = new PscpClient(this.Options, session); result = client.ListDirectory(path); } return(result); }
public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { // Source Target Result // 1) WindowsFile Local if not the same, File.Copy // 2) Local Local File.Copy // 3) Remote Local RemoteCopy bool canTransfer = true; if (target.Type == FileType.File || target.Type == FileType.ParentDirectory) { // can't drop on file or parent dir (..) canTransfer = false; } else if (target.Source == source.Source) { // can't drop local-on-local or remote-on-remote canTransfer = false; } else if (target.Path == source.Path) { // can't drop on self canTransfer = false; } /* Future...if/when local-on-local allowed * else if (source.Source == SourceType.Local) * { * // can't drop into own folder...no op * string sourceDir = Path.GetFullPath(Path.GetDirectoryName(source.Path)); * string targetDir = Path.GetFullPath(target.Path); * canTransfer = sourceDir != targetDir; * }*/ return(canTransfer); }
public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { // Source Target Result // 1) WindowsFile Local if not the same, File.Copy // 2) Local Local File.Copy // 3) Remote Local RemoteCopy bool canTransfer = true; if (target.Type == FileType.File || target.Type == FileType.ParentDirectory) { // can't drop on file or parent dir (..) canTransfer = false; } else if (target.Source == source.Source) { // can't drop local-on-local or remote-on-remote canTransfer = false; } else if (target.Path == source.Path) { // can't drop on self canTransfer = false; } /* Future...if/when local-on-local allowed else if (source.Source == SourceType.Local) { // can't drop into own folder...no op string sourceDir = Path.GetFullPath(Path.GetDirectoryName(source.Path)); string targetDir = Path.GetFullPath(target.Path); canTransfer = sourceDir != targetDir; }*/ return canTransfer; }
/// <summary> /// Copy files /// </summary> /// <param name="sourceFiles"></param> /// <param name="target"></param> /// <param name="callback"></param> /// <returns></returns> public FileTransferResult CopyFiles(List <BrowserFileInfo> sourceFiles, BrowserFileInfo target, TransferUpdateCallback callback) { lock (this) { // Known Issues: // - If a large exe (or other file that the OS will virus scan) is tranfered, the operation will timeout. // After completion, the OS seems to block on the final write (while scanning). During this time the process looks like it's // hanging and the timeout logic kicks in. Hacked in "completed" logic into inlineOut/Err handlers but this is awkward FileTransferResult result = new FileTransferResult(); string args = ToArgs(this.Session, this.Session.Password, sourceFiles, target); string argsToLog = ToArgs(this.Session, "XXXXX", sourceFiles, target); ScpLineParser parser = new ScpLineParser(); RunPscp( result, args, argsToLog, (line) => { bool completed = false; if (callback != null) { FileTransferStatus status; if (parser.TryParseTransferStatus(line, out status)) { completed = status.PercentComplete == 100; callback(completed, false, status); } } return(completed); }, null, null); return(result); } }
void LoadDirectory(BrowserFileInfo path, ListDirectoryResult result) { if (path.Path == null) { // special case for drives/mounts foreach (DriveInfo drive in DriveInfo.GetDrives()) { BrowserFileInfo bfiDrive = new BrowserFileInfo(drive); result.Add(bfiDrive); result.MountCount++; } } else if (Directory.Exists(path.Path)) { // get new files DirectoryInfo newDir = new DirectoryInfo(path.Path); // add back (..) entry, if relevant if (newDir.Parent != null) { // has valid parent dir BrowserFileInfo bfiParent = new BrowserFileInfo(newDir.Parent) { Name = "..", Type = FileType.ParentDirectory }; result.Add(bfiParent); } else { // hit top of root so list drives, special case of null path BrowserFileInfo bfiListDrives = new BrowserFileInfo { Path = null, Name = "..", Type = FileType.ParentDirectory, }; result.Add(bfiListDrives); } // dirs foreach (DirectoryInfo di in newDir.GetDirectories()) { BrowserFileInfo bfi = new BrowserFileInfo(di); result.Add(bfi); } // files foreach (FileInfo fi in newDir.GetFiles()) { BrowserFileInfo bfi = new BrowserFileInfo(fi); result.Add(bfi); } } else { result.SetError(string.Format("Directory doesn't exist: {0}", path.Path), null); } }
public static BrowserFileInfo NewDirectory(string dir) { BrowserFileInfo file = new BrowserFileInfo { Name = Path.GetFileName(dir), Path = dir, Type = FileType.Directory, Source = SourceType.Remote }; return file; }
private void listViewFiles_DoubleClick(object sender, EventArgs e) { if (this.listViewFiles.SelectedItems.Count != 0) { BrowserFileInfo bfi = (BrowserFileInfo)this.listViewFiles.SelectedItems[0].Tag; if (bfi.Type == FileType.Directory || bfi.Type == FileType.ParentDirectory) { this.Presenter.LoadDirectory(bfi); } } }
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BrowserFileInfo targetPath = (BrowserFileInfo)e.Argument; this.BackgroundWorker.ReportProgress(5, "Requesting files for " + targetPath.Path); ListDirectoryResult result = this.Model.ListDirectory(this.Session, targetPath); this.BackgroundWorker.ReportProgress(80, "Remote call complete: " + result.StatusCode); e.Result = result; }
public void Add(BrowserFileInfo fileInfo) { this.Files.Add(fileInfo); if (fileInfo.Type == FileType.File) { this.FileCount++; } else if (fileInfo.Type == FileType.Directory) { this.DirCount++; } }
public static BrowserFileInfo NewDirectory(string dir) { BrowserFileInfo file = new BrowserFileInfo { Name = Path.GetFileName(dir), Path = dir, Type = FileType.Directory, Source = SourceType.Remote }; return(file); }
public void Initialize(IBrowserPresenter presenter, BrowserFileInfo startingDir) { if (this.initialized) return; this.Presenter = presenter; this.Presenter.AuthRequest += (Presenter_AuthRequest); this.Bind(this.Presenter.ViewModel); this.Presenter.LoadDirectory(startingDir); this.ConfirmTransfer = true; this.initialized = true; }
public bool TryParseFileLine(string line, out BrowserFileInfo fileInfo) { bool success = false; if (line.StartsWith("Listing directory")) { // ignore header line and current dir fileInfo = null; } else { Match match = regExFileLine.Match(line); if (match.Success) { string name = match.Groups["FileName"].Value; fileInfo = new BrowserFileInfo { Name = name, Path = name, Owner = match.Groups["OwnerName"].Value, Group = match.Groups["GroupName"].Value, Permissions = match.Groups["Permissions"].Value, Source = SourceType.Remote }; fileInfo.Type = fileInfo.Name == ".." ? FileType.ParentDirectory : fileInfo.Permissions != null && fileInfo.Permissions.StartsWith("d") ? FileType.Directory : FileType.File; DateTime lastMod; if (TryParseTimestamp(match.Groups["Timestamp"].Value, out lastMod)) { fileInfo.LastModTime = lastMod; } int blocks; if (int.TryParse(match.Groups["BlockCount"].Value, out blocks)) { fileInfo.Size = blocks; } success = true; } else { Log.WarnFormat("Could not parse directory listing entry: '{0}'", line); fileInfo = null; } } return(success); }
public void LoadDirectory(BrowserFileInfo dir) { if (this.BackgroundWorker.IsBusy) { this.ViewModel.Status = "Busying loading directory"; } else { this.ViewModel.BrowserState = BrowserState.Working; Log.InfoFormat("LoadDirectory, path={0}", dir); this.BackgroundWorker.RunWorkerAsync(dir); } }
public void Initialize(IBrowserPresenter presenter, BrowserFileInfo startingDir) { if (initialized) { return; } Presenter = presenter; Presenter.AuthRequest += Presenter_AuthRequest; Bind(Presenter.ViewModel); Presenter.LoadDirectory(startingDir); ConfirmTransfer = true; initialized = true; }
public void Initialize(IBrowserPresenter presenter, BrowserFileInfo startingDir) { if (this.initialized) { return; } this.Presenter = presenter; this.Presenter.AuthRequest += (Presenter_AuthRequest); this.Bind(this.Presenter.ViewModel); this.Presenter.LoadDirectory(startingDir); this.ConfirmTransfer = true; this.initialized = true; }
public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { Log.InfoFormat("GetFilesForPath, path={0}", path.Path); ListDirectoryResult result = new ListDirectoryResult(path); try { LoadDirectory(path, result); } catch (Exception ex) { result.SetError(null, ex); Log.ErrorFormat("Error loading directory: {0}", ex.Message); } return result; }
public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { Log.InfoFormat("GetFilesForPath, path={0}", path.Path); ListDirectoryResult result = new ListDirectoryResult(path); try { LoadDirectory(path, result); } catch (Exception ex) { result.SetError(null, ex); Log.ErrorFormat("Error loading directory: {0}", ex.Message); } return(result); }
private void listViewFiles_DragEnter(object sender, DragEventArgs e) { // Check for copy allowed, payload = DataFormats.FileDrop or BrowserFileInfo bool copyAllowed = (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy; bool isFile = e.Data.GetDataPresent(DataFormats.FileDrop, false); bool isBrowserFile = e.Data.GetDataPresent(typeof(BrowserFileInfo[])); this.dragDropIsValid = copyAllowed && (isFile || isBrowserFile); // update effect e.Effect = dragDropIsValid ? DragDropEffects.Copy : DragDropEffects.None; // parse out payload if (this.dragDropIsValid) { this.dragDropFileTransfer = new FileTransferRequest { Session = this.Presenter.Session }; // Get source files (payload) if (e.Data.GetDataPresent(DataFormats.FileDrop)) { // windows files Array files = (Array)e.Data.GetData(DataFormats.FileDrop, false); foreach (string fileName in files) { BrowserFileInfo item = Directory.Exists(fileName) ? new BrowserFileInfo(new DirectoryInfo(fileName)) : new BrowserFileInfo(new FileInfo(fileName)); this.dragDropFileTransfer.SourceFiles.Add(item); } } else if (e.Data.GetDataPresent(typeof(BrowserFileInfo[]))) { // from another browser BrowserFileInfo[] files = (BrowserFileInfo[])e.Data.GetData(typeof(BrowserFileInfo[])); this.dragDropFileTransfer.SourceFiles.AddRange(files); } } Log.DebugFormat( "DragEnter: allowedEffect={0}, effect={1}, isFile={2}, isBrowserFile={3}", e.AllowedEffect, e.Effect, isFile, isBrowserFile); }
private void listViewFiles_DragOver(object sender, DragEventArgs e) { // Prevent event from firing too often if (!dragDropIsValid || (e.X == dragDropLastX && e.Y == dragDropLastY)) { return; } dragDropLastX = e.X; dragDropLastY = e.Y; // Get item under mouse ListView listView = (ListView)sender; Point p = listView.PointToClient(new Point(e.X, e.Y)); ListViewHitTestInfo hti = listView.HitTest(p.X, p.Y); BrowserFileInfo target = hti.Item != null ? (BrowserFileInfo)hti.Item.Tag : this.Presenter.CurrentPath; this.dragDropFileTransfer.TargetFile = target; // Clear selection and select item under mouse if folder listView.SelectedItems.Clear(); if (hti.Item != null && target.Type == FileType.Directory) { hti.Item.Selected = true; } // Validate source/targets and update effect // - Windows file to remote panel (do transfer) // - Windows file to Local (do transfer?) // - Local BrowserFileInfo to Remote (do transfer) // - Remote BrowserFileInfo to Local (do transfer) // Ask model if allowed? // - Local BrowserFileInfo to Local (not allowed) // - Remote BrowserFileInfo to Remote (not allowed) e.Effect = DragDropEffects.Copy; foreach (BrowserFileInfo source in this.dragDropFileTransfer.SourceFiles) { if (!this.Presenter.CanTransferFile(source, target)) { e.Effect = DragDropEffects.None; break; } } }
private void listViewFiles_ItemDrag(object sender, ItemDragEventArgs e) { ListView listView = (ListView)sender; List <BrowserFileInfo> items = new List <BrowserFileInfo>(); foreach (ListViewItem item in listView.SelectedItems) { BrowserFileInfo bfi = (BrowserFileInfo)item.Tag; if (bfi.Type == FileType.ParentDirectory) { // can't work with parent dir...bug out return; } items.Add(bfi); } DoDragDrop(items.ToArray(), DragDropEffects.Copy); }
/// <summary>Asynchronously loads the contents of a directory</summary> /// <param name="dir">The BrowserFileInfo object containing the path to the directory to load</param> public void LoadDirectory(BrowserFileInfo dir) { if (this.BackgroundWorker.IsBusy) { this.ViewModel.Status = "Busy loading directory"; } else { this.ViewModel.BrowserState = BrowserState.Working; if (dir != null) { Log.InfoFormat("LoadDirectory, path={0}", dir); this.BackgroundWorker.RunWorkerAsync(dir); } else { Log.Error("LoadDirectory Failed: target was null"); } } }
public int Compare(object x, object y) { ListViewItem lviX = (ListViewItem)x; ListViewItem lviY = (ListViewItem)y; BrowserFileInfo a = (BrowserFileInfo)lviX.Tag; BrowserFileInfo b = (BrowserFileInfo)lviY.Tag; // direction int dir = this.SortOrder == SortOrder.Descending ? -1 : 1; // identity if (a == b) { return(0); } // preference based on type int type = a.Type.CompareTo(b.Type); if (type != 0) { return(type); } // resolve based on field switch (this.Column) { case 1: return(dir * Comparer <long> .Default.Compare(a.Size, b.Size)); case 2: return(dir * Comparer <DateTime> .Default.Compare(a.LastModTime, b.LastModTime)); case 3: return(dir * Comparer <string> .Default.Compare(a.Permissions, b.Permissions)); case 4: return(dir * Comparer <string> .Default.Compare(a.Owner, b.Owner)); case 5: return(dir * Comparer <string> .Default.Compare(a.Group, b.Group)); } // default to using name return(dir * Comparer <string> .Default.Compare(a.Name, b.Name)); }
public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { return(true); }
public bool TryParseFileLine(string line, out BrowserFileInfo fileInfo) { bool success = false; if (line.StartsWith("Listing directory")) { // ignore header line and current dir fileInfo = null; } else { Match match = regExFileLine.Match(line); if (match.Success) { string name = match.Groups["FileName"].Value; fileInfo = new BrowserFileInfo { Name = name, Path = name, Owner = match.Groups["OwnerName"].Value, Group = match.Groups["GroupName"].Value, Permissions = match.Groups["Permissions"].Value, Source = SourceType.Remote }; fileInfo.Type = fileInfo.Name == ".." ? FileType.ParentDirectory : fileInfo.Permissions != null && fileInfo.Permissions.StartsWith("d") ? FileType.Directory : FileType.File; DateTime lastMod; if (TryParseTimestamp(match.Groups["Timestamp"].Value, out lastMod)) { fileInfo.LastModTime = lastMod; } int blocks; if (int.TryParse(match.Groups["BlockCount"].Value, out blocks)) { fileInfo.Size = blocks; } success = true; } else { Log.WarnFormat("Could not parse directory listing entry: '{0}'", line); fileInfo = null; } } return success; }
public BrowserView(IBrowserPresenter presenter, BrowserFileInfo startingDir) : this() { Initialize(presenter, startingDir); }
/// <summary>Verify a file can be transfered</summary> /// <param name="source">The Source file</param> /// <param name="target">The Destination file</param> /// <returns>true if the file can be transfered</returns> public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { return this.FileTransferPresenter.CanTransferFile(source, target); }
static string ToArgs(SessionData session, string password, List<BrowserFileInfo> source, BrowserFileInfo target) { StringBuilder sb = new StringBuilder(); sb.Append("-r -agent "); // default arguments if (!String.IsNullOrEmpty(session.PuttySession)) { sb.Append("-load \"").Append(session.PuttySession).Append("\" "); } if (!String.IsNullOrEmpty(password)) { sb.Append("-pw ").Append(password).Append(" "); } sb.AppendFormat("-P {0} ", session.Port); if (target.Source == SourceType.Remote) { // possible to send multiple files remotely at a time foreach(BrowserFileInfo file in source) { sb.AppendFormat("\"{0}\" ", file.Path); } sb.AppendFormat(" {0}@{1}:\"{2}\"", session.Username, session.Host, EscapeForUnix(target.Path)); } else { if (source.Count > 1) { Log.WarnFormat("Not possible to transfer multiple remote files locally at one time. Tranfering first only!"); } sb.AppendFormat(" {0}@{1}:\"{2}\" ", session.Username, session.Host, EscapeForUnix(source[0].Path)); sb.AppendFormat("\"{0}\"", target.Path); } return sb.ToString(); }
public ListDirectoryResult ListDirectory(BrowserFileInfo path) { lock (this) { //return this.DoListDirectory(path); ListDirectoryResult result = new ListDirectoryResult(path); RunPscp( result, ToArgs(this.Session, this.Session.Password, path.Path), ToArgs(this.Session, "XXXXX", path.Path), null, null, (lines) => { // successful list ScpLineParser parser = new ScpLineParser(); foreach (string rawLine in lines) { string line = rawLine.TrimEnd(); BrowserFileInfo fileInfo; if (parser.TryParseFileLine(line, out fileInfo)) { if (fileInfo.Name != ".") { fileInfo.Path = MakePath(path.Path, fileInfo.Name); result.Add(fileInfo); } } } }); return result; } }
public ListDirectoryResult(BrowserFileInfo path) { this.Path = path; this.Files = new List <BrowserFileInfo>(); }
/// <summary> /// Copy files /// </summary> /// <param name="sourceFiles"></param> /// <param name="target"></param> /// <param name="callback"></param> /// <returns></returns> public FileTransferResult CopyFiles(List<BrowserFileInfo> sourceFiles, BrowserFileInfo target, TransferUpdateCallback callback) { lock(this) { /// Known Issues: /// - If a large exe (or other file that the OS will virus scan) is tranfered, the operation will timeout. /// After completion, the OS seems to block on the final write (while scanning). During this time the process looks like it's /// hanging and the timeout logic kicks in. Hacked in "completed" logic into inlineOut/Err handlers but this is awkward FileTransferResult result = new FileTransferResult(); string args = ToArgs(this.Session, this.Session.Password, sourceFiles, target); string argsToLog = ToArgs(this.Session, "XXXXX", sourceFiles, target); ScpLineParser parser = new ScpLineParser(); RunPscp( result, args, argsToLog, (line) => { bool completed = false; if (callback != null) { FileTransferStatus status; if (parser.TryParseTransferStatus(line, out status)) { completed = status.PercentComplete == 100; callback(completed, false, status); } } return completed; }, null, null); return result; } }
public ListDirectoryResult(BrowserFileInfo path) { this.Path = path; this.Files = new List<BrowserFileInfo>(); }
public void LocalToRemote() { SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; List<BrowserFileInfo> sourceFiles = new List<BrowserFileInfo> { //new BrowserFileInfo(new FileInfo(Path.GetTempFileName())) new BrowserFileInfo(new FileInfo(ScpConfig.PscpLocation)) }; BrowserFileInfo target = new BrowserFileInfo { Path = string.Format("/home/{0}/", session.Username), Source = SourceType.Remote }; PscpOptions options = new PscpOptions { PscpLocation = ScpConfig.PscpLocation, TimeoutMs = 5000 }; PscpClient client = new PscpClient(options, session); PscpResult res = client.CopyFiles( sourceFiles, target, (complete, cancelAll, status) => { Log.InfoFormat( "complete={0}, cancelAll={1}, fileName={2}, pctComplete={3}", complete, cancelAll, status.Filename, status.PercentComplete); }); Log.InfoFormat("Result: {0}", res); /* ListDirectoryResult res = client.ListDirectory(new BrowserFileInfo { Path = "." }); Assert.AreEqual(ResultStatusCode.Success, res.StatusCode); Assert.Greater(res.Files.Count, 0); foreach (BrowserFileInfo file in res.Files) { Log.Info(file); } Log.InfoFormat("Result: {0}", res);*/ }
private static string ToArgs(SessionData session, string password, List <BrowserFileInfo> source, BrowserFileInfo target) { StringBuilder sb = new StringBuilder(); sb.Append("-r -agent "); // default arguments if (!String.IsNullOrEmpty(session.PuttySession)) { sb.Append("-load \"").Append(session.PuttySession).Append("\" "); } if (!String.IsNullOrEmpty(password)) { sb.Append("-pw ").Append(password).Append(" "); } sb.AppendFormat("-P {0} ", session.Port); if (target.Source == SourceType.Remote) { // possible to send multiple files remotely at a time foreach (BrowserFileInfo file in source) { sb.AppendFormat("\"{0}\" ", file.Path); } sb.AppendFormat(" {0}@{1}:\"{2}\"", session.Username, session.Host, target.Path); } else { if (source.Count > 1) { Log.WarnFormat("Not possible to transfer multiple remote files locally at one time. Transferring first file only!"); } sb.AppendFormat(" {0}@{1}:\"{2}\" ", session.Username, session.Host, source[0].Path); sb.AppendFormat("\"{0}\"", target.Path); } return(sb.ToString()); }
/// <summary>Verify a file can be transfered</summary> /// <param name="source">The Source file</param> /// <param name="target">The Destination file</param> /// <returns>true if the file can be transfered</returns> public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { return(this.FileTransferPresenter.CanTransferFile(source, target)); }
public bool CanTransferFile(BrowserFileInfo source, BrowserFileInfo target) { return true; }