using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.IO; using System.Linq; using System.Drawing; using System.Threading.Tasks; using System.Windows.Forms; namespace DataOrganizer { public partial class FileManager : Form { private List Profiles { get; set; } = new List(); private List FolderGroups { get; set; } = new List(); private Snapshot ActiveSnapshot { get; set; } private Snapshot ComparisionSnapshot { get; set; } private Dictionary DiffTreeNodes { get; set; } = new Dictionary(); public FileManager() { InitializeComponent(); ScanSelectedFolderGroupButton.Click += ScanSelectedFolderGroupButton_Click; SelectProfileComboBoxMainMenu.SelectedIndexChanged += SelectProfileComboBoxMainMenu_SelectedIndexChanged; SelectFolderGroupComboBoxMainMenu.SelectedIndexChanged += SelectFolderGroupComboBoxMainMenu_SelectedIndexChanged; CompareAgainstProfileComboBox.SelectedIndexChanged += CompareAgainstProfileComboBox_SelectedIndexChanged; CompareAgainstFolderGroupComboBox.SelectedIndexChanged += CompareAgainstFolderGroupComboBox_SelectedIndexChanged; CompareButton.Click += CompareButton_Click; DiffViewTreeView.NodeMouseClick += DiffViewTreeView_NodeMouseClick; PopulateProfileComboBox(); } private void DiffViewTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (!ActiveSnapshot.TopLevelFolders.ContainsKey(e.Node.Name)) return; SelectedFolderViewGroupTreeView.Nodes.Clear(); ComparisionFolderViewTreeView.Nodes.Clear(); var folderA = ActiveSnapshot.Directories[e.Node.Name]; var folderB = ComparisionSnapshot.Directories[e.Node.Name]; SelectedFolderViewGroupTreeView.Nodes.Add(BuildTreeNode(folderA)); ComparisionFolderViewTreeView.Nodes.Add(BuildTreeNode(folderB)); } private void ScanSelectedFolderGroupButton_Click(object sender, EventArgs e) { var folderGroup = GetSelectedFolderGroup(); var files = GetAllFilesFromDirectory(new DirectoryInfo(folderGroup.Path)); var snapshot = new Snapshot(files, folderGroup); foreach (var folder in snapshot.Root.Folders.Values) DiffViewTreeView.Nodes.Add(BuildTreeNode(folder)); CommitFilesChangesButton.Enabled = true; MoveNewFilesButton.Enabled = true; if (ActiveSnapshot.Files.Count == 0) CommitFirstTimeScaneToDatabase(snapshot); //TODO: reload the form to have these changes active in the global snapshot } private void CommitFirstTimeScaneToDatabase(Snapshot snapshot) { var db = new DB(); db.InsertNewFileRecord(snapshot.Files.Values.ToList(), GetSelectedProfile().Id, GetSelectedFolderGroup().Id, GetSelectedFolderGroup().Path); ClearForm(); UpdateStatusLabel($"Committed {snapshot.Files.Count} records to the database."); } private void CompareButton_Click(object sender, EventArgs e) { var db = new DB(); var p = GetProfileToCompare(); var f = GetFolderGroupToCompare(); var renames = new List(); ComparisionSnapshot = new Snapshot(db.GetFilesForProfileByFolderGroup(p.Id, f.Id), f); var diff = ActiveSnapshot.Diff(ComparisionSnapshot); foreach (var folder in ActiveSnapshot.Directories.Values) { if (!folder.IsRootFolder) { var noRoot = folder.FullPath.Remove(0, ActiveSnapshot.Root.FullPath.Length + 1); var w = Path.Combine(f.Path, noRoot); if (ComparisionSnapshot.Directories.ContainsKey(w)) { renames.AddRange(ActiveSnapshot.FindFileRenames(folder, ComparisionSnapshot.Directories[w])); } } else { var compareRoot = ComparisionSnapshot.Directories.Single(x => x.Value.IsRootFolder).Value; renames.AddRange(ActiveSnapshot.FindFileRenames(folder, compareRoot)); } } foreach (var rename in renames) { DiffViewTreeView.Nodes.Add($"From: {rename.From.Name}"); DiffViewTreeView.Nodes.Add($"To: {rename.To.Name}"); } var dupCount = 0; //foreach(var folder in ActiveSnapshot.TopLevelFolders.Keys) //{ // foreach(var dup in ActiveSnapshot.FindDuplicates(ActiveSnapshot.Directories[folder])) // { // var node = new TreeNode($"{dup.File.Name} ({dup.Duplicates.Count})") { ToolTipText = dup.File.FullPath }; // foreach(var d in dup.Duplicates) // { // node.Nodes.Add(new TreeNode(d.Name) { ToolTipText = d.FullPath }); // dupCount++; // } // DiffViewTreeView.Nodes.Add(node); // } //} UpdateStatusLabel($"Found {dupCount} duplicate files."); //foreach(var file in diff.NewFiles) // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingInsert); //foreach (var file in diff.ModifiedFiles) // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingUpdate); //foreach (var file in diff.DeletedFiles) // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingDelete); } private void AddFileSnapshotToDiffView(FileSnapshot file, DB.FolderGroup folderGroup, FileSnapshot.FileStatus fileStatus = FileSnapshot.FileStatus.None) { var folder = file.ParentFolder; while (folder != null) { if (folder.FullPath == folderGroup.Path) break; var n = new TreeNode(folder.Name) { Name = folder.FullPath }; if (!DiffTreeNodes.ContainsKey(n.Name)) { if(folder.Parent != null && folder.Parent.FullPath == folderGroup.Path) { DiffViewTreeView.Nodes.Add(n); } DiffTreeNodes.Add(n.Name, n); } folder = folder.Parent; } var node = new TreeNode(file.Name) { Name = file.FullPath }; DiffTreeNodes.Add(file.FullPath, node); DiffTreeNodes[file.ParentFolder.FullPath].Nodes.Add(node); switch (fileStatus) { case FileSnapshot.FileStatus.PendingInsert: node.BackColor = Color.LightBlue; break; case FileSnapshot.FileStatus.PendingUpdate: node.BackColor = Color.Orange; node.ForeColor = Color.White; break; case FileSnapshot.FileStatus.PendingDelete: node.BackColor = Color.Red; break; } } private void CompareAgainstProfileComboBox_SelectedIndexChanged(object sender, EventArgs e) { ClearDiffResults(); CompareAgainstFolderGroupComboBox.Items.Clear(); var profile = GetProfileToCompare(); foreach(var folder in profile.FolderGroups) CompareAgainstFolderGroupComboBox.Items.Add(folder.Name); if(profile.FolderGroups.Count > 0) CompareAgainstFolderGroupComboBox.SelectedIndex = 0; } private void CompareAgainstFolderGroupComboBox_SelectedIndexChanged(object sender, EventArgs e) { ClearDiffResults(); CompareButton.Enabled = ActiveSnapshot.Files.Count > 0; ComparisionFolderViewGroupBox.Text = $"Folder View of {GetProfileToCompare().Name}:"; } private void SelectFolderGroupComboBoxMainMenu_SelectedIndexChanged(object sender, EventArgs e) { ClearForm(true); var db = new DB(); var folderGroup = GetSelectedFolderGroup(); var files = db.GetFilesForProfileByFolderGroup(GetSelectedProfile().Id, folderGroup.Id); ActiveSnapshot = new Snapshot(files, folderGroup); //foreach (var orgFolder in ActiveSnapshot.Root.Folders.Values) //{ // FolderGroupTreeView.Nodes.Add(BuildTreeNode(orgFolder)); //} CompareButton.Enabled = files.Count > 0; if (CompareAgainstFolderGroupComboBox.FindString(folderGroup.Name) != -1) CompareAgainstFolderGroupComboBox.SelectedIndex = CompareAgainstFolderGroupComboBox.FindString(folderGroup.Name); if (files.Count == 0) ScanSelectedFolderGroupButton.Text = "Scan Folder Group"; SelectedProfileDataLabel.Text = $"Loaded snapshot data for {files.Count} file(s)."; SelectedGroupFolderViewGroupBox.Text = $"Folder View of {GetSelectedProfile().Name}:"; } private TreeNode BuildTreeNode(Folder folder) { var node = new TreeNode(folder.Name) { Name = folder.FullPath }; foreach(var dir in folder.Folders.Values) { node.Nodes.Add(BuildTreeNode(dir)); } foreach(var file in folder.Files.Values) { node.Nodes.Add(new TreeNode(file.Name) { Name = file.FullPath }); } return node; } private List GetAllFilesFromDirectory(DirectoryInfo directory) { var files = new List(); files.AddRange(directory.EnumerateFiles()); foreach (var dir in directory.EnumerateDirectories()) { UpdateStatusLabel($"Scanning Directory {dir.Name}..."); files.AddRange(GetAllFilesFromDirectory(dir)); } return files; } private void SelectProfileComboBoxMainMenu_SelectedIndexChanged(object sender, EventArgs e) { ClearForm(); FolderGroups = GetSelectedProfile().FolderGroups; SelectFolderGroupComboBoxMainMenu.Items.Clear(); CompareAgainstProfileComboBox.Items.Clear(); foreach (var folder in FolderGroups) SelectFolderGroupComboBoxMainMenu.Items.Add(folder.Name); if (FolderGroups.Count > 0) SelectFolderGroupComboBoxMainMenu.SelectedIndex = 0; if(Profiles.Count > 1) { foreach(var profile in Profiles) if(profile.Name != SelectProfileComboBoxMainMenu.Text) CompareAgainstProfileComboBox.Items.Add(profile.Name); CompareAgainstProfileComboBox.SelectedIndex = 0; } } private void ClearForm(bool isFolderGroupChange = false) { DiffViewTreeView.Nodes.Clear(); if (!isFolderGroupChange) { CompareAgainstProfileComboBox.Items.Clear(); CompareAgainstFolderGroupComboBox.Items.Clear(); } CompareButton.Enabled = false; ScanSelectedFolderGroupButton.Text = "Scan for Changes"; MoveNewFilesButton.Enabled = false; CommitFilesChangesButton.Enabled = false; SelectedGroupFolderViewGroupBox.Text = string.Empty; SelectedFolderViewGroupTreeView.Nodes.Clear(); ComparisionFolderViewGroupBox.Text = string.Empty; ComparisionFolderViewTreeView.Nodes.Clear(); } private void ClearDiffResults() { DiffViewTreeView.Nodes.Clear(); } private void PopulateProfileComboBox() { var db = new DB(); Profiles = db.GetProfiles(); SelectProfileComboBoxMainMenu.Items.Clear(); foreach(var profile in Profiles) SelectProfileComboBoxMainMenu.Items.Add(profile.Name); if (Profiles.Count > 0) { if(Profiles.Count(x => x.MachineName == Environment.MachineName) == 1) SelectProfileComboBoxMainMenu.SelectedIndex = Profiles.FindIndex(x => x.MachineName == Environment.MachineName); else SelectProfileComboBoxMainMenu.SelectedIndex = 0; } } private void RefreshForm() { ClearForm(); PopulateProfileComboBox(); } private DB.Profile GetSelectedProfile() { return Profiles[SelectProfileComboBoxMainMenu.SelectedIndex]; } private DB.FolderGroup GetSelectedFolderGroup() { return FolderGroups[SelectFolderGroupComboBoxMainMenu.SelectedIndex]; } private DB.Profile GetProfileToCompare() { return Profiles.First(x => x.Name == CompareAgainstProfileComboBox.Text); } private DB.FolderGroup GetFolderGroupToCompare() { return GetProfileToCompare().FolderGroups.First(x => x.Name == CompareAgainstFolderGroupComboBox.Text); } private void ProfilesManageMainMenu_Click(object sender, EventArgs e) { var form = new ProfileManager(); form.ShowDialog(); RefreshForm(); } private void NamingPatternsManageMainMenu_Click(object sender, EventArgs e) { var form = new NamingConventionManager(); form.ShowDialog(); } private void UpdateStatusLabel(string message) { StatusLabel.Text = message; statusStrip1.Refresh(); } private void button1_Click(object sender, EventArgs e) { var form = new FolderBrowserDialog(); if(form.ShowDialog() == DialogResult.OK) { textBox1.Text = form.SelectedPath; } } private void button2_Click(object sender, EventArgs e) { //Compare } } }