using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; using MsgMapper.Properties; using MsgReader.Outlook; namespace MsgMapper { public partial class MainForm : Form { // This delegate enables asynchronous calls for setting // the text property on a TextBox control. delegate void SetListBoxCallback(string text); #region Fields /// /// Contains our notifyicon on the taskbar /// private readonly NotifyIcon _trayIcon; /// /// A list with one or more FileSystemWatchers /// private List _fileSystemWatcher; /// /// Flag used to signal the method to really exit /// private bool _exit; /// /// The object that does all our properties mapping /// private readonly Reader _reader = new Reader(); #endregion #region MainForm public MainForm() { InitializeComponent(); var trayMenu = new ContextMenu(); trayMenu.MenuItems.Add("Show", OnShow); trayMenu.MenuItems.Add("Resync", OnResync); trayMenu.MenuItems.Add("Exit", OnExit); // Create a tray icon _trayIcon = new NotifyIcon { // ReSharper disable once LocalizableElement Text = "MSG properties to extended file properties mapper", Icon = new Icon(Icon, 40, 40), ContextMenu = trayMenu, Visible = true }; } #endregion #region _fileSystemWatcher_Created /// /// This method is called when a new object is created in a watched folder /// /// /// void _fileSystemWatcher_Created(object sender, FileSystemEventArgs e) { var msgFile = string.Empty; try { msgFile = e.FullPath; _reader.SetExtendedFileAttributesWithMsgProperties(msgFile); Thread.Sleep(250); Log("Mapped properties for file '" + msgFile + "'"); } catch (Exception exception) { Log("Mapping failed for file '" + Path.GetFileName(msgFile) + "', error: " + exception.Message); } } #endregion #region OnShow /// /// This method is triggered when a user selects the item called Show /// /// /// private void OnShow(object sender, EventArgs e) { Show(); } #endregion #region OnResync /// /// This method is triggered when a user selects the item called Resync /// /// /// private void OnResync(object sender, EventArgs e) { if ( MessageBox.Show( // ReSharper disable LocalizableElement "Are you sure you want to resync all the folers? This can take some time when you have huge amounts of Outlook message files", "Resync folders", MessageBoxButtons.YesNo) == DialogResult.Yes) // ReSharper restore LocalizableElement { Show(); foreach (DataGridViewRow row in FoldersDataGridView.Rows) { if (row.Cells[0].Value == null) continue; var folder = row.Cells[0].Value.ToString(); Log("Resyncing folder '" + folder + "'"); var msgFiles = Directory.GetFiles(folder, "*.msg", SearchOption.AllDirectories); foreach (var msgFile in msgFiles) { _reader.SetExtendedFileAttributesWithMsgProperties(msgFile); Log("Mapped properties for the file '" + msgFile + "'"); } } Log("Done"); } } #endregion #region OnExit /// /// This method is triggered when a user selects the item called Exit /// /// /// private void OnExit(object sender, EventArgs e) { SaveFolders(); _exit = true; Application.Exit(); } #endregion #region OnLoad /// /// This method is triggered when the form loads for the first time /// /// protected override void OnLoad(EventArgs e) { Visible = false; // Hide form window. ShowInTaskbar = false; // Remove from taskbar. LoadFolders(); base.OnLoad(e); } #endregion #region Log /// /// Writes messages to the /// /// private void Log(string message) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (InvokeRequired) { var callback = new SetListBoxCallback(Log); Invoke(callback, new object[] {message}); } else { StatusListBox.Items.Add(message); StatusListBox.SelectedIndex = StatusListBox.Items.Count - 1; } } #endregion #region LoadFolders /// /// This will load all the selected folders and add them to the filesystem watcher /// private void LoadFolders() { var foldersString = (string) Settings.Default["Folders"]; try { if (string.IsNullOrEmpty(foldersString)) { Show(); } else { var folders = Folders.LoadFromString(foldersString); _fileSystemWatcher = new List(); FoldersDataGridView.Rows.Clear(); foreach (var folder in folders) { // ReSharper disable once PossiblyMistakenUseOfParamsMethod if (Directory.Exists(folder.Path)) { FoldersDataGridView.Rows.Add(folder.Path); var fileSystemWatcher = new FileSystemWatcher(); fileSystemWatcher.Path = folder.Path; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.Filter = "*.msg"; fileSystemWatcher.Created += _fileSystemWatcher_Created; fileSystemWatcher.EnableRaisingEvents = true; _fileSystemWatcher.Add(fileSystemWatcher); Log("Watching folder '" + folder.Path + "'"); } else { Log("Ignoring folder '" + folder.Path + "' because it does not exists anymore"); } } } } catch (Exception e) { MessageBox.Show(e.Message, "Error...", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region SaveFolders /// /// This will save all the selected folders to the object /// private void SaveFolders() { var folders = new Folders(); foreach (DataGridViewRow row in FoldersDataGridView.Rows) { if(row.Cells[0].Value == null) continue; folders.Add(row.Cells[0].Value.ToString()); } // Save setting Settings.Default["Folders"] = folders.SerializeToString(); Settings.Default.Save(); } #endregion #region MainForm_FormClosing /// /// This method is triggered when a user tries to close the application. When a users presses the X (top right) /// on the form the form is just hidden. When the method is triggered through the method the /// form will be closed and the application with exit /// /// /// private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (_exit) return; // Do not close the form, just hide it... except when we close from the OnExit method Hide(); e.Cancel = true; } #endregion #region FolderExists /// /// This method checks if the is already present in the /// /// /// private bool FolderExists(string folder) { foreach (var row in FoldersDataGridView.Rows) if (String.Equals(row.ToString(), folder, StringComparison.InvariantCultureIgnoreCase)) return true; return false; } #endregion #region AddFolderButton_Click /// /// This method adds a folder to the /// /// /// private void AddFolderButton_Click(object sender, EventArgs e) { var folderBrowserDialog = new FolderBrowserDialog(); if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { // ReSharper disable once PossiblyMistakenUseOfParamsMethod if (FolderExists(folderBrowserDialog.SelectedPath)) MessageBox.Show("The folder '" + folderBrowserDialog.SelectedPath + "' is already added"); else FoldersDataGridView.Rows.Add(folderBrowserDialog.SelectedPath); SaveFolders(); LoadFolders(); } } #endregion } }