Horizon – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Horizon.Utilities;
using Microsoft.WindowsAPICodePack.Dialogs;
using TrackedFolders;

namespace Horizon
{
    public partial class ManageFoldersForm : Form
    {
        #region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private readonly MainForm _mainForm;

        private readonly CancellationTokenSource _localCancellationTokenSource;

        private readonly CancellationToken _localCancellationToken;

        private readonly CancellationTokenSource _cancellationTokenSource;

        private readonly CancellationToken _cancellationToken;

        #endregion

        #region Constructors, Destructors and Finalizers

        public ManageFoldersForm()
        {
            InitializeComponent();
            Utilities.WindowState.FormTracker.Track(this);

            _localCancellationTokenSource = new CancellationTokenSource();
            _localCancellationToken = _localCancellationTokenSource.Token;

            dataGridView1.Columns["DelayColumn"].ValueType = typeof(int);
        }

        public ManageFoldersForm(MainForm mainForm, CancellationToken cancellationToken) : this()
        {
            _mainForm = mainForm;

            _cancellationTokenSource =
                CancellationTokenSource.CreateLinkedTokenSource(_localCancellationToken, cancellationToken);
            _cancellationToken = _cancellationTokenSource.Token;
        }

        /// <summary>
        ///     Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && components != null)
            {
                components.Dispose();
            }

            _localCancellationTokenSource.Cancel();

            base.Dispose(disposing);
        }

        #endregion

        #region Event Handlers

        private async void RecursiveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var row in dataGridView1.SelectedRows.OfType<DataGridViewRow>())
            {
                var path = (string)row.Cells["PathColumn"].Value;

                await _mainForm.TakeSnapshotRecursive(path);
            }
        }

        private async void SelectedDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var row in dataGridView1.SelectedRows.OfType<DataGridViewRow>())
            {
                var path = (string)row.Cells["PathColumn"].Value;

                await _mainForm.TakeSnapshot(path);
            }
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            var commonOpenFileDialog = new CommonOpenFileDialog
            {
                Multiselect = true,
                IsFolderPicker = true
            };

            if (commonOpenFileDialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                _mainForm.Configuration.LastFolder = commonOpenFileDialog.FileNames.FirstOrDefault();
                _mainForm.ChangedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
                    async () => await _mainForm.SaveConfiguration(), _cancellationToken);

                foreach (var name in commonOpenFileDialog.FileNames)
                {
                    if (!Directory.Exists(name))
                    {
                        continue;
                    }

                    var exists = false;
                    foreach (var folder in _mainForm.TrackedFolders.Folder)
                    {
                        if (folder.Path.IsPathEqual(name))
                        {
                            exists = true;
                        }

                        if (folder.Path.IsSubPathOf(name))
                        {
                            if (folder.Recursive)
                            {
                                exists = true;
                            }
                        }
                    }

                    if (!exists)
                    {
                        dataGridView1.InvokeIfRequired(async dataGridView =>
                        {
                            var folder = new Folder(commonOpenFileDialog.FileName, true);

                            var index = dataGridView.Rows.Add();

                            var enableCheckBox =
                                (DataGridViewCheckBoxCell)dataGridView.Rows[index].Cells["EnableColumn"];

                            enableCheckBox.Value = true;

                            dataGridView.Rows[index].Cells["PathColumn"].Value = commonOpenFileDialog.FileName;
                            dataGridView.Rows[index].Cells["DelayColumn"].Value = folder.Delay;

                            _mainForm.TrackedFolders.Folder.Add(folder);

                            await _mainForm.SaveFolders();
                        });
                    }
                }
            }
        }

        private async void Button2_Click(object sender, EventArgs e)
        {
            var removeRows = new List<DataGridViewRow>();
            foreach (var row in dataGridView1.SelectedRows.OfType<DataGridViewRow>())
            {
                var path = (string)row.Cells["PathColumn"].Value;
                var removeFolders = new List<Folder>();
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    if (path == folder.Path)
                    {
                        removeFolders.Add(folder);
                    }
                }

                foreach (var folder in removeFolders)
                {
                    _mainForm.TrackedFolders.Folder.Remove(folder);
                }

                removeRows.Add(row);
            }

            await _mainForm.SaveFolders();

            foreach (var row in removeRows)
            {
                dataGridView1.Rows.Remove(row);
            }
        }

        private void ManageFoldersForm_Load(object sender, EventArgs e)
        {
            dataGridView1.CellValueChanged -= DataGridView1_CellValueChanged;
            try
            {
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    var index = dataGridView1.Rows.Add();

                    var enableCheckBox =
                        (DataGridViewCheckBoxCell)dataGridView1.Rows[index].Cells["EnableColumn"];

                    enableCheckBox.Value = Directory.Exists(folder.Path);

                    dataGridView1.Rows[index].Cells["PathColumn"].Value = folder.Path;

                    var recursiveCheckBox =
                        (DataGridViewCheckBoxCell)dataGridView1.Rows[index].Cells["RecursiveColumn"];

                    recursiveCheckBox.Value = folder.Recursive;

                    dataGridView1.Rows[index].Cells["DelayColumn"].Value = folder.Delay;

                    if (folder.Color.ToArgb() != 0)
                    {
                        dataGridView1.Rows[index].DefaultCellStyle.BackColor = folder.Color;
                    }
                }
            }
            finally
            {
                dataGridView1.CellValueChanged += DataGridView1_CellValueChanged;
            }

            dataGridView1.Sort(dataGridView1.Columns["PathColumn"], ListSortDirection.Descending);
        }

        private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (dataGridView.CurrentCell is DataGridViewCheckBoxCell)
            {
                dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }

        private async void DataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            var row = dataGridView.SelectedRows.OfType<DataGridViewRow>().FirstOrDefault();
            if (row == null)
            {
                return;
            }

            var directory = (string)row.Cells["PathColumn"].Value;

            var commonOpenFileDialog = new CommonOpenFileDialog
            {
                Multiselect = true,
                IsFolderPicker = true,
                DefaultDirectory = directory
            };

            if (commonOpenFileDialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                foreach (var name in commonOpenFileDialog.FileNames)
                {
                    _mainForm.Configuration.LastFolder = name;
                    _mainForm.ChangedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
                        async () => await _mainForm.SaveConfiguration(), _cancellationToken);

                    if (!Directory.Exists(name))
                    {
                        continue;
                    }

                    var exists = false;
                    Folder processFolder = null;
                    foreach (var folder in _mainForm.TrackedFolders.Folder)
                    {
                        if (folder.Path == directory)
                        {
                            processFolder = folder;
                        }

                        if (folder.Path.IsPathEqual(name))
                        {
                            exists = true;
                            continue;
                        }

                        if (folder.Path.IsSubPathOf(name))
                        {
                            if (folder.Recursive)
                            {
                                exists = true;
                            }
                        }
                    }

                    if (!exists)
                    {
                        if (processFolder != null)
                        {
                            _mainForm.TrackedFolders.Folder.Remove(processFolder);
                            row.Cells["PathColumn"].Value = name;
                            processFolder.Path = name;
                            _mainForm.TrackedFolders.Folder.Add(processFolder);

                            await _mainForm.SaveFolders();
                        }
                    }
                }
            }
        }

        private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (dataGridView.CurrentCell is DataGridViewCheckBoxCell)
            {
                if (dataGridView.CurrentCell.IsInEditMode)
                {
                    if (dataGridView.IsCurrentCellDirty)
                    {
                        dataGridView.EndEdit();
                    }
                }
            }
        }

        private async void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (e.RowIndex == -1 || e.ColumnIndex == -1)
            {
                return;
            }

            switch (dataGridView.Columns[e.ColumnIndex].Name)
            {
                case "DelayColumn":
                    ProcessDelay(dataGridView.Rows[e.RowIndex]);
                    break;
                case "RecursiveColumn":
                    await ProcessRecursive(dataGridView.Rows[e.RowIndex]);

                    break;
                case "EnableColumn":
                    await ProcessEnable(dataGridView.Rows[e.RowIndex]);
                    break;
            }
        }

        private void DataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
                !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
            {
                return;
            }

            dataGridView.EndEdit();
        }

        private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
                !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
            {
                return;
            }

            dataGridView.EndEdit();
        }

        private async void DataGridView1_DragDrop(object sender, DragEventArgs e)
        {
            var dataGridView = (DataGridView)sender;

            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                return;
            }

            var files = (string[])e.Data.GetData(DataFormats.FileDrop);

            foreach (var name in files)
            {
                // Only accept directories.
                if (!Directory.Exists(name))
                {
                    continue;
                }

                var exists = false;
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    if (folder.Path.IsPathEqual(name))
                    {
                        exists = true;
                    }

                    if (folder.Path.IsSubPathOf(name))
                    {
                        if (folder.Recursive)
                        {
                            exists = true;
                        }
                    }
                }

                if (!exists)
                {
                    var folder = new Folder(name, true);

                    var index = dataGridView.Rows.Add();

                    var enableCheckBox =
                        (DataGridViewCheckBoxCell)dataGridView.Rows[index].Cells["EnableColumn"];

                    enableCheckBox.Value = true;

                    dataGridView.Rows[index].Cells["PathColumn"].Value = name;
                    dataGridView.Rows[index].Cells["DelayColumn"].Value = folder.Delay;
                    _mainForm.TrackedFolders.Folder.Add(folder);

                    await _mainForm.SaveFolders();
                }
            }
        }

        private void DataGridView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }

            e.Effect = DragDropEffects.None;
        }

        private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            // Do not allow errors.
        }

        private async void ColorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var toolStripMenuItem = (ToolStripMenuItem)sender;
            var color = toolStripMenuItem.BackColor;

            foreach (var row in dataGridView1.SelectedRows.OfType<DataGridViewRow>())
            {
                var path = (string)row.Cells["PathColumn"].Value;
                var processFolders = new List<Folder>();
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    if (path == folder.Path)
                    {
                        processFolders.Add(folder);
                    }
                }

                foreach (var folder in processFolders)
                {
                    _mainForm.TrackedFolders.Folder.Remove(folder);
                }

                foreach (var folder in processFolders)
                {
                    row.DefaultCellStyle.BackColor = color;
                    folder.Color = color;

                    _mainForm.TrackedFolders.Folder.Add(folder);

                    await _mainForm.SaveFolders();
                }
            }
        }

        private async void NoneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var row in dataGridView1.SelectedRows.OfType<DataGridViewRow>())
            {
                var path = (string)row.Cells["PathColumn"].Value;
                var processFolders = new List<Folder>();
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    if (path == folder.Path)
                    {
                        processFolders.Add(folder);
                    }
                }

                foreach (var folder in processFolders)
                {
                    _mainForm.TrackedFolders.Folder.Remove(folder);
                }

                foreach (var folder in processFolders)
                {
                    row.DefaultCellStyle.BackColor = Color.Empty;
                    folder.Color = Color.Empty;

                    _mainForm.TrackedFolders.Folder.Add(folder);

                    await _mainForm.SaveFolders();
                }
            }
        }

        #endregion

        #region Private Methods

        private async void ProcessDelay(DataGridViewRow row)
        {
            var path = (string)row.Cells["PathColumn"].Value;
            var delay = (int)row.Cells["DelayColumn"].Value;

            var modifyFolders = new List<Folder>();
            foreach (var folder in _mainForm.TrackedFolders.Folder)
            {
                if (path == folder.Path)
                {
                    modifyFolders.Add(folder);
                }
            }

            foreach (var folder in modifyFolders)
            {
                _mainForm.TrackedFolders.Folder.Remove(folder);
            }

            foreach (var folder in modifyFolders)
            {
                folder.Delay = delay;

                _mainForm.TrackedFolders.Folder.Add(folder);

                await _mainForm.SaveFolders();
            }
        }

        private async Task ProcessEnable(DataGridViewRow row)
        {
            var enableCheckBoxCell =
                (DataGridViewCheckBoxCell)row.Cells["EnableColumn"];

            var path = (string)row.Cells["PathColumn"].Value;
            var processFolders = new List<Folder>();
            foreach (var folder in _mainForm.TrackedFolders.Folder)
            {
                if (path == folder.Path)
                {
                    processFolders.Add(folder);
                }
            }

            foreach (var folder in processFolders)
            {
                _mainForm.TrackedFolders.Folder.Remove(folder);
            }

            foreach (var folder in processFolders)
            {
                folder.Enable = (bool)enableCheckBoxCell.Value;

                _mainForm.TrackedFolders.Folder.Add(folder);

                await _mainForm.SaveFolders();
            }
        }

        private async Task ProcessRecursive(DataGridViewRow row)
        {
            var recursiveCheckBoxCell =
                (DataGridViewCheckBoxCell)row.Cells["RecursiveColumn"];

            var path = (string)row.Cells["PathColumn"].Value;
            var processFolders = new List<Folder>();
            foreach (var folder in _mainForm.TrackedFolders.Folder)
            {
                if (path == folder.Path)
                {
                    processFolders.Add(folder);
                }
            }

            // Check that any folder is not included in the already existing list of folders.
            var removeProcess = new List<Folder>();
            foreach (var processFolder in processFolders)
            {
                foreach (var folder in _mainForm.TrackedFolders.Folder)
                {
                    if (!folder.Path.IsPathEqual(processFolder.Path) && 
                        folder.Path.IsSubPathOf(processFolder.Path))
                    {
                        removeProcess.Add(processFolder);
                    }
                }
            }

            foreach (var folder in removeProcess)
            {
                processFolders.Remove(folder);
            }

            // In case all folders are contained within other folder paths revert the checkmark.
            if (processFolders.Count == 0)
            {
                dataGridView1.CellValueChanged -= DataGridView1_CellValueChanged;
                try
                {
                    recursiveCheckBoxCell.Value = !(bool)recursiveCheckBoxCell.Value;
                }
                finally
                {
                    dataGridView1.CellValueChanged += DataGridView1_CellValueChanged;
                }

                return;
            }

            foreach (var folder in processFolders)
            {
                _mainForm.TrackedFolders.Folder.Remove(folder);
            }

            foreach (var folder in processFolders)
            {
                folder.Recursive = (bool)recursiveCheckBoxCell.Value;
                _mainForm.TrackedFolders.Folder.Add(folder);

                await _mainForm.SaveFolders();
            }
        }

        #endregion
    }
}

Generated by GNU Enscript 1.6.5.90.