private void TreeViewItem_Drop(object sender, DragEventArgs e) { PathItem targetItem = ActivePathItem; var formats = e.Data.GetFormats(); if (sender is TreeView) { // dropped into treeview open space } else { targetItem = (e.OriginalSource as FrameworkElement)?.DataContext as PathItem; if (targetItem == null) { return; } } e.Handled = true; if (formats.Contains("FileDrop")) { HandleDroppedFiles(e.Data.GetData("FileDrop") as string[]); return; } if (!targetItem.IsFolder) { targetItem = targetItem.Parent; } var path = e.Data.GetData(DataFormats.UnicodeText) as string; if (string.IsNullOrEmpty(path)) { return; } string newPath; var sourceItem = FolderStructure.FindPathItemByFilename(ActivePathItem, path); if (sourceItem == null) { // Handle dropped new files (from Explorer perhaps) if (File.Exists(path)) { newPath = Path.Combine(targetItem.FullPath, Path.GetFileName(path)); File.Copy(path, newPath); AppModel.Window.ShowStatusSuccess($"File copied."); } return; } newPath = Path.Combine(targetItem.FullPath, sourceItem.DisplayName); if (sourceItem.FullPath.Equals(newPath, StringComparison.InvariantCultureIgnoreCase)) { AppModel.Window.ShowStatusError($"File not moved.", mmApp.Configuration.StatusMessageTimeout); return; } try { File.Move(sourceItem.FullPath, newPath); } catch (Exception ex) { AppModel.Window.ShowStatusError($"Couldn't move file: {ex.Message}", mmApp.Configuration.StatusMessageTimeout); return; } targetItem.IsExpanded = true; // wait for file watcher to pick up the file Dispatcher.Delay(200, (p) => { var srceItem = FolderStructure.FindPathItemByFilename(ActivePathItem, p as string); if (srceItem == null) { return; } srceItem.IsSelected = true; }, newPath); AppModel.Window.ShowStatus($"File moved to: {newPath}", mmApp.Configuration.StatusMessageTimeout); }
private void FileWatcher_CreateOrDelete(object sender, FileSystemEventArgs e) { if (mmApp.Model == null || mmApp.Model.Window == null) { return; } if (!Directory.Exists(FolderPath)) { FolderPath = null; return; } var file = e.FullPath; if (string.IsNullOrEmpty(file)) { return; } if (e.ChangeType == WatcherChangeTypes.Deleted) { mmApp.Model.Window.Dispatcher.Invoke(() => { var pi = FolderStructure.FindPathItemByFilename(ActivePathItem, file); if (pi == null) { return; } pi.Parent.Files.Remove(pi); //Debug.WriteLine("After: " + pi.Parent.Files.Count + " " + file); }, DispatcherPriority.ApplicationIdle); } if (e.ChangeType == WatcherChangeTypes.Created) { mmApp.Model.Window.Dispatcher.Invoke(() => { // Skip ignored Extensions string[] extensions = null; if (!string.IsNullOrEmpty(mmApp.Model.Configuration.FolderBrowser.IgnoredFileExtensions)) { extensions = mmApp.Model.Configuration.FolderBrowser.IgnoredFileExtensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); } if (extensions != null && extensions.Any(ext => file.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))) { return; } var pi = FolderStructure.FindPathItemByFilename(ActivePathItem, file); if (pi != null) // Already exists in the tree { return; } // does the path exist? var parentPathItem = FolderStructure.FindPathItemByFilename(ActivePathItem, Path.GetDirectoryName(file)); // Path either doesn't exist or is not expanded yet so don't attach - opening will trigger if (parentPathItem == null || (parentPathItem.Files.Count == 1 && parentPathItem.Files[0] == PathItem.Empty)) { return; } bool isFolder = Directory.Exists(file); pi = new PathItem() { FullPath = file, IsFolder = isFolder, IsFile = !isFolder, Parent = parentPathItem }; pi.SetIcon(); FolderStructure.InsertPathItemInOrder(pi, parentPathItem); }, DispatcherPriority.ApplicationIdle); } }
/// <summary> /// Gets a folder hierarchy /// </summary> /// <param name="baseFolder"></param> /// <param name="parentPathItem"></param> /// <param name="skipFolders"></param> /// <returns></returns> public PathItem GetFilesAndFolders(string baseFolder, PathItem parentPathItem = null, string skipFolders = "node_modules,bower_components,packages,testresults,bin,obj", bool nonRecursive = false) { if (string.IsNullOrEmpty(baseFolder) || !Directory.Exists(baseFolder)) return new PathItem(); PathItem activeItem; if (parentPathItem == null) { activeItem = new PathItem { FullPath = baseFolder, IsFolder = true }; parentPathItem = activeItem; } else { activeItem = new PathItem { FullPath=baseFolder, IsFolder = true, Parent = parentPathItem}; parentPathItem.Files.Add(activeItem); } string[] folders = null; try { folders = Directory.GetDirectories(baseFolder); } catch { } if (folders != null) { foreach (var folder in folders) { var name = System.IO.Path.GetFileName(folder); if (!string.IsNullOrEmpty(name)) { if (name.StartsWith(".")) continue; // skip folders if (("," + skipFolders + ",").Contains("," + name.ToLower() + ",")) continue; } if (!nonRecursive) GetFilesAndFolders(folder, activeItem, skipFolders); else { activeItem.Files.Add(new PathItem { FullPath = folder, IsFolder = true, Parent = activeItem } ); } } } string[] files = null; try { files = Directory.GetFiles(baseFolder); } catch { } if (folders == null && nonRecursive) { foreach (var folder in folders) { } } if (files != null) { foreach (var file in files) { var item = new PathItem {FullPath = file, Parent = activeItem, IsFolder = false, IsFile = true}; if (mmApp.Configuration.FolderBrowser.ShowIcons) item.Icon = icons.GetIconFromFile(file); activeItem.Files.Add(item); } } return activeItem; }
/// <summary> /// Gets a folder hierarchy and attach to an existing folder item or /// </summary> /// <param name="baseFolder">The folder for which to retrieve files for</param> /// <param name="parentPathItem">The parent item to which the retrieved files are attached</param> /// <param name="ignoredFolders"></param> /// <returns></returns> public PathItem GetFilesAndFolders(string baseFolder, PathItem parentPathItem = null, string ignoredFolders = null, string ignoredFileExtensions = null, bool nonRecursive = false) { if (string.IsNullOrEmpty(baseFolder) || !Directory.Exists(baseFolder)) { return(new PathItem()); } baseFolder = ExpandPathEnvironmentVars(baseFolder); PathItem activeItem; bool isRootFolder = false; if (ignoredFolders == null) { ignoredFolders = mmApp.Configuration.FolderBrowser.IgnoredFolders; } if (ignoredFileExtensions == null) { ignoredFileExtensions = mmApp.Configuration.FolderBrowser.IgnoredFileExtensions; } if (parentPathItem == null) { isRootFolder = true; activeItem = new PathItem { FullPath = baseFolder, IsFolder = true }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { activeItem.SetIcon(); } } else { activeItem = parentPathItem; //new PathItem { FullPath=baseFolder, IsFolder = true, Parent = parentPathItem}; activeItem.Files.Clear(); // remove all items } string[] folders = null; try { folders = Directory.GetDirectories(baseFolder); } catch { } if (folders != null) { foreach (var folder in folders.OrderBy(f => f.ToLower())) { var name = Path.GetFileName(folder); if (!string.IsNullOrEmpty(name)) { if (name.StartsWith(".")) { continue; } // skip folders if (("," + ignoredFolders + ",").Contains("," + name.ToLower() + ",")) { continue; } } var folderPath = new PathItem { FullPath = folder, IsFolder = true, Parent = activeItem }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { folderPath.SetIcon(); } activeItem.Files.Add(folderPath); if (!nonRecursive) { GetFilesAndFolders(folder, folderPath, ignoredFolders); } else { folderPath.Files.Add(PathItem.Empty); } } } string[] files = null; try { files = Directory.GetFiles(baseFolder); } catch { } if (files != null) { // Skip Extensions string[] extensions = null; if (!string.IsNullOrEmpty(ignoredFileExtensions)) { extensions = ignoredFileExtensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); } foreach (var file in files.OrderBy(f => f.ToLower())) { if (extensions != null && extensions.Any(ext => file.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))) { continue; } var item = new PathItem { FullPath = file, Parent = activeItem, IsFolder = false, IsFile = true }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { item.Icon = IconList.GetIconFromFile(file); } activeItem.Files.Add(item); } } if (activeItem.FullPath.Length > 5 && isRootFolder) { var parentFolder = new PathItem { IsFolder = true, FullPath = ".." }; parentFolder.SetIcon(); activeItem.Files.Insert(0, parentFolder); } return(activeItem); }
/// <summary> /// Sets visibility of all items in the path item tree /// </summary> /// <param name="searchText">Text to search for or empty to reset list</param> /// <param name="pathItem"> /// A PathItem nstance to start from. /// /// typically the root node: FolderBrowser.ActivePathItem but can also /// be a child node to start the search from. /// </param> public void SetSearchVisibility(string searchText, PathItem pathItem, bool recursive) { if (pathItem?.Files == null) { return; } var folderBrowser = FolderBrowser; if (searchText == null) { searchText = string.Empty; } searchText = searchText.ToLower(); // no items below if (pathItem.Files.Count == 0 || pathItem.Files[0] == PathItem.Empty) { if (!recursive) { return; } // load items var files = GetFilesAndFolders(pathItem.FullPath, pathItem, nonRecursive: !recursive).Files; pathItem.Files = files; //foreach (var file in files) // pathItem.Files.Add(file); if (pathItem.Files.Count == 0) { pathItem.Files.Add(PathItem.Empty); } // required so change is detected by tree //pathItem.OnPropertyChanged(nameof(PathItem.Files)); } foreach (var pi in pathItem.Files) { if (pi.IsEmpty) // it's a placeholder only { continue; } if (string.IsNullOrEmpty(searchText)) { pi.IsVisible = true; pi.IsSelected = false; pi.IsExpanded = false; } else if (searchText == "..") { pi.IsVisible = false; } else if (pi.DisplayName.ToLower().Contains(searchText)) { pi.IsVisible = true; var parent = pi.Parent; // make sure parents are expanded while (parent != null) { parent.IsExpanded = true; parent.OnPropertyChanged(nameof(PathItem.IsExpanded)); parent.IsVisible = true; parent = parent.Parent; } } else { pi.IsVisible = false; } if (recursive && pi.IsFolder && pi.DisplayName != "..") { SetSearchVisibility(searchText, pi, recursive); } } }
/// <summary> /// Gets a folder hierarchy /// </summary> /// <param name="baseFolder"></param> /// <param name="parentPathItem"></param> /// <param name="skipFolders"></param> /// <returns></returns> public PathItem GetFilesAndFolders(string baseFolder, PathItem parentPathItem = null, string skipFolders = "node_modules,bower_components,packages,testresults,bin,obj") { if (string.IsNullOrEmpty(baseFolder) || !Directory.Exists(baseFolder)) { return(new PathItem()); } PathItem activeItem; if (parentPathItem == null) { activeItem = new PathItem { FullPath = baseFolder, IsFolder = true }; parentPathItem = activeItem; } else { activeItem = new PathItem { FullPath = baseFolder, IsFolder = true, Parent = parentPathItem }; parentPathItem.Files.Add(activeItem); } string[] folders = null; try { folders = Directory.GetDirectories(baseFolder); } catch { } if (folders != null) { foreach (var folder in folders) { var name = System.IO.Path.GetFileName(folder); if (!string.IsNullOrEmpty(name)) { if (name.StartsWith(".")) { continue; } // skip folders if (("," + skipFolders + ",").Contains("," + name.ToLower() + ",")) { continue; } } GetFilesAndFolders(folder, activeItem, skipFolders); } } string[] files = null; try { files = Directory.GetFiles(baseFolder); } catch { } if (files != null) { foreach (var file in files) { activeItem.Files.Add(new PathItem { FullPath = file, Parent = activeItem, IsFolder = false }); } } return(activeItem); }
/// <summary> /// Gets a folder hierarchy /// </summary> /// <param name="baseFolder"></param> /// <param name="parentPathItem"></param> /// <param name="skipFolders"></param> /// <returns></returns> public PathItem GetFilesAndFolders(string baseFolder, PathItem parentPathItem = null, string skipFolders = ".git,node_modules,bower_components,packages,testresults,bin,obj", bool nonRecursive = false) { if (string.IsNullOrEmpty(baseFolder) || !Directory.Exists(baseFolder)) { return(new PathItem()); } baseFolder = ExpandPathEnvironmentVars(baseFolder); PathItem activeItem; bool isRootFolder = false; if (parentPathItem == null) { isRootFolder = true; activeItem = new PathItem { FullPath = baseFolder, IsFolder = true }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { activeItem.SetIcon(); } } else { activeItem = new PathItem { FullPath = baseFolder, IsFolder = true, Parent = parentPathItem }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { activeItem.SetIcon(); } parentPathItem.Files.Add(activeItem); } string[] folders = null; try { folders = Directory.GetDirectories(baseFolder); } catch { } if (folders != null) { foreach (var folder in folders.OrderBy(f => f.ToLower())) { var name = Path.GetFileName(folder); if (!string.IsNullOrEmpty(name)) { if (name.StartsWith(".")) { continue; } // skip folders if (("," + skipFolders + ",").Contains("," + name.ToLower() + ",")) { continue; } } if (!nonRecursive) { GetFilesAndFolders(folder, activeItem, skipFolders); } else { var folderPath = new PathItem { FullPath = folder, IsFolder = true, Parent = activeItem }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { folderPath.SetIcon(); } folderPath.Files.Add(PathItem.Empty); activeItem.Files.Add(folderPath); } } } string[] files = null; try { files = Directory.GetFiles(baseFolder); } catch { } if (files != null) { foreach (var file in files.OrderBy(f => f.ToLower())) { var item = new PathItem { FullPath = file, Parent = activeItem, IsFolder = false, IsFile = true }; if (mmApp.Configuration.FolderBrowser.ShowIcons) { item.Icon = IconList.GetIconFromFile(file); } activeItem.Files.Add(item); } } if (activeItem.FullPath.Length > 5 && isRootFolder) { var parentFolder = new PathItem { IsFolder = true, FullPath = ".." }; parentFolder.SetIcon(); activeItem.Files.Insert(0, parentFolder); } return(activeItem); }