/// <summary> /// Changes the start of all child folder's paths to match the parent folder's path /// </summary> /// <param name="folder">The folder to change the children for</param> private void ChangeSubFolderPathsAndIndentations(FolderExpander folder) { if (!folder.HasSubFolders) return; List<FolderExpander> childFolders = ((StackPanel) folder.Content).Children.Cast<FolderExpander>().ToList(); string newStartOfPath = folder.Path; string[] temp = childFolders[0].Path.Split('/'); string oldStartOfPath = string.Join("/", temp.Take(temp.Length - 1)); foreach (FolderExpander childFolder in childFolders) { childFolder.Path = newStartOfPath + childFolder.Path.Substring(oldStartOfPath.Length); childFolder.Indentation = (childFolder.Path.Count(x => x == '/') - 1) * 10 + 10; ChangeSubFolderPathsAndIndentations(childFolder); } }
/// <summary> /// Moves folder above or below another /// </summary> /// <param name="e">Drag event</param> /// <param name="dropTarget">The folder it is being dropped on</param> /// <param name="wasDroppedAbove">True if the folder was dropped above</param> private void MoveFolderAboveOrBelow(DragEventArgs e, FolderExpander dropTarget, bool wasDroppedAbove) { FolderExpander folderBeingMoved = (FolderExpander) e.Data.GetData(typeof(FolderExpander)); if (folderBeingMoved == null) return; //Checks you arn't putting the folder in itself if (dropTarget.Path.StartsWith(folderBeingMoved.Path)) return; //Generates new path StackPanel movingInto = (StackPanel) dropTarget.Parent; string newPath; if (movingInto.Parent is FolderExpander) newPath = $"{((FolderExpander) movingInto.Parent).Path}/{folderBeingMoved.Header}"; else newPath = $"/{folderBeingMoved.Header}"; //Calculates if one should be subtracted based on if the removal of that folder affects the index bool subrtactOne = movingInto.Children.Contains(folderBeingMoved) && (movingInto.Children.IndexOf(folderBeingMoved) < movingInto.Children.IndexOf(dropTarget)); //Gets the new folder index int newIndex = movingInto.Children.IndexOf(dropTarget) + (wasDroppedAbove ? 0 : 1) + (subrtactOne ? -1 : 0); //Gets the number of default folders int numberOfDefaults = movingInto.Children.Cast<FolderExpander>().Count(x => x.Default); //Changes the folder path ChangeFolder(newPath, newIndex, numberOfDefaults, folderBeingMoved); }
/// <summary> /// Change the location and/or name of a folder /// </summary> /// <param name="newPath">New path for the folder</param> /// <param name="newPathIndex">The index for the folder in its new location</param> /// <param name="numberOfDefaults">Number of default folders at the start of the level the folder is in</param> /// <param name="folder">The FolderLabel or FolderExpander being moved</param> private void ChangeFolder(string newPath, int newPathIndex, int numberOfDefaults, FolderExpander folder) { _needsSaving = true; SaveInfo.Content = ""; string oldPath = folder.Path; string[] newPathParts = newPath.Split('/').Skip(1).ToArray(); /*First changes everything in the main data structure*/ //Finds and deletes the folder using the path Folder folderToModify = GetFolderFromPath(oldPath); if (oldPath.Count(x => x == '/') != 1) GetFolderFromPath(oldPath, 1).Children.Remove(folderToModify); else SafeData.Folders.Remove(folderToModify); //Recreates the folder at the new path if (newPath.Count(x => x == '/') != 1) GetFolderFromPath(newPath, 1).Children.Insert(newPathIndex - numberOfDefaults, folderToModify); else SafeData.Folders.Insert(newPathIndex - numberOfDefaults, folderToModify); folderToModify.Name = newPathParts.Last(); //Changes account path data foreach (Account account in AccountsObservableCollection) if (account.Path.StartsWith(oldPath)) account.Path = newPath + account.Path.Substring(oldPath.Length); /*Then changes the already existing folder controls*/ //Gets the folder FolderExpander folderBeingMoved = GetFolderExpanderFromPath(oldPath); FolderExpander folderBeingMovedParentFolder = ((StackPanel) folderBeingMoved.Parent).Parent as FolderExpander; //Removes the folder from its current location ((StackPanel) folderBeingMoved.Parent).Children.Remove(folderBeingMoved); //If the parent folder is now empty it removes the dropdown if ((folderBeingMovedParentFolder != null) && (((StackPanel) folderBeingMovedParentFolder.Content).Children.Count == 0)) { folderBeingMovedParentFolder.Content = null; folderBeingMovedParentFolder.HasSubFolders = false; folderBeingMovedParentFolder.IsExpanded = false; } //Gets where the folding is going to be moved to FolderExpander folderMovedInto = GetFolderExpanderFromPath("/" + string.Join("/", newPathParts.Take(newPathParts.Length - 1))); //Modifies the folder being dropped into if it had no subfolders before hand if (folderMovedInto != null) if (folderMovedInto.Content == null) { folderMovedInto.Content = new StackPanel(); folderMovedInto.HasSubFolders = true; } //Changes folder values and places it in its new location folderBeingMoved.Header = newPathParts.Last(); folderBeingMoved.Path = newPath; folderBeingMoved.Indentation = (newPath.Count(x => x == '/') - 1) * 10 + 10; if (folderMovedInto != null) ((StackPanel) folderMovedInto.Content).Children.Insert(newPathIndex, folderBeingMoved); else Folders.Children.Insert(newPathIndex, folderBeingMoved); //Changes the path of all the sub folders ChangeSubFolderPathsAndIndentations(folder); }
/// <summary> /// Creates a expander control from a folder input /// </summary> /// <param name="folder">Folder to create expander from</param> /// <param name="currentPath">The current path of the folder</param> /// <returns>Dropdown folder</returns> private Expander MakeDropDownFolder(Folder folder, string currentPath) { FolderExpander output = new FolderExpander { Path = currentPath, Header = folder.Name, Indentation = (currentPath.Count(x => x == '/') - 1) * 10 + 10, Style = (Style) FindResource("DropDownFolder"), HasSubFolders = true, IsExpanded = folder.Expanded }; StackPanel stackPanel = new StackPanel(); foreach (Folder childFolder in folder.Children) if (childFolder.Children.Count == 0) stackPanel.Children.Add(new FolderExpander { Path = $"{currentPath}/{childFolder.Name}", Header = childFolder.Name, Indentation = ($"{currentPath}/{childFolder.Name}".Count(x => x == '/') - 1) * 10 + 10, Style = (Style) FindResource("DropDownFolder"), HasSubFolders = false, IsExpanded = folder.Expanded }); else stackPanel.Children.Add(MakeDropDownFolder(childFolder, $"{currentPath}/{childFolder.Name}")); output.Content = stackPanel; return output; }