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
}
}