KeePassTrueCryptMount / src / KeepassTrueCryptMount / KeepassTrueCryptMountExt.cs

/*
  Plugin for KeePass Password Safe - The Open-Source Password Manager
  KeePassTrueCryptMount
  Copyright (C) 2010-2013 Patrick Schaller

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

namespace KeePassTrueCryptMount
{
    /* 
     * It seems like a mistake, but the plugin namespace must the same
     * than the plugin class name (with suffix Ext), so no dots allowed. 
     * The assembly file must also have the name of the namespace.
     */

    using System;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;

    using KeePass.Plugins;

    public sealed class KeePassTrueCryptMountExt : Plugin
    {
        private IPluginHost pluginHost;
        private ToolStripMenuItem mnuEntryTrueCryptMount;
        private ToolStripMenuItem mnuToolsTrueCryptOptions;
        private MountMenuItemState mountMenuItemState;
        
        public KeePassTrueCryptMountExt()
        {
        }

        public override Image SmallIcon
        {
            get
            {
                return TrueCryptInfo.ExecutableExists(this.pluginHost.GetTrueCryptExecutable())
                    ? Resources.TrueCryptNormal
                    : Resources.TrueCryptError;
            }
        }

        public override string UpdateUrl
        {
            get
            {
                return @"https://bitbucket.org/schalpat/keepasstruecryptmount/downloads/version_manifest.txt";
            }
        }

        public override bool Initialize(IPluginHost host)
        {
            this.pluginHost = host;

            // insert the options menu item inside of the tools menu.
            var toolsMenuItem = this.pluginHost.MainWindow.ToolsMenu;

            this.mnuToolsTrueCryptOptions = new ToolStripMenuItem(LanguageTexts.TCOptionsMenuItemText + LanguageTexts.MenuItemOpenDialogSuffix);
            this.mnuToolsTrueCryptOptions.Image = Resources.TrueCryptNormal;
            this.mnuToolsTrueCryptOptions.Click += this.OnTrueCryptOptionsMenuItemClicked;

            toolsMenuItem.DropDownItems.Add(this.mnuToolsTrueCryptOptions);

            // insert the mount menu item inside of the entry menu.
            this.pluginHost.MainWindow.EntryContextMenu.KeyDown += this.OnEntryContextMenuKeyDown;
            this.pluginHost.MainWindow.EntryContextMenu.KeyUp += this.OnEntryContextMenuKeyUp;
            this.pluginHost.MainWindow.EntryContextMenu.Opened += this.OnEntryContextMenuOpened;
            this.mnuEntryTrueCryptMount = new ToolStripMenuItem();
            this.mnuEntryTrueCryptMount.ShortcutKeys = Keys.Control | Keys.T;
            this.mnuEntryTrueCryptMount.ShowShortcutKeys = true;
            this.mnuEntryTrueCryptMount.Click += this.OnTrueCryptMenuItemClicked;
            this.mnuEntryTrueCryptMount.Image = Resources.TrueCryptNormal;
            this.pluginHost.MainWindow.EntryContextMenu.Items.Insert(4, this.mnuEntryTrueCryptMount);
            this.mountMenuItemState = new MountMenuItemState(this.mnuEntryTrueCryptMount);
            this.mountMenuItemState.ChangeState(MountMenuItemStates.Invisible);
            this.mountMenuItemState.AlwaysVisible = this.pluginHost.GetTrueCryptMenuItemAlwaysVisible();

            this.SetTrueCryptMountMenuMenuAppearance();

            return true;
        }
        
        public override void Terminate()
        {
            this.pluginHost.MainWindow.ToolsMenu.DropDownItems.Remove(this.mnuToolsTrueCryptOptions);
            this.mnuToolsTrueCryptOptions.Click -= this.OnTrueCryptOptionsMenuItemClicked;
            this.mnuToolsTrueCryptOptions.Dispose();
            
            this.pluginHost.MainWindow.EntryContextMenu.KeyDown -= this.OnEntryContextMenuKeyDown;
            this.pluginHost.MainWindow.EntryContextMenu.KeyUp -= this.OnEntryContextMenuKeyUp;
            this.pluginHost.MainWindow.EntryContextMenu.Opened -= this.OnEntryContextMenuOpened;
            this.pluginHost.MainWindow.EntryContextMenu.Items.Remove(this.mnuEntryTrueCryptMount);
            this.mnuEntryTrueCryptMount.Click -= this.OnTrueCryptMenuItemClicked;
            this.mnuEntryTrueCryptMount.Dispose();
            base.Terminate();
        }

        private void OnEntryContextMenuKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
            {
                this.SetTrueCryptMountMenuItemAccessibility(true);
            }
        }
        
        private void OnEntryContextMenuKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
            {
                this.SetTrueCryptMountMenuItemAccessibility();
            }
        }

        private void OnEntryContextMenuOpened(object sender, EventArgs e)
        {
            this.SetTrueCryptMountMenuItemAccessibility();
        }

        private void OnTrueCryptMenuItemClicked(object sender, EventArgs e)
        {
            var entry = this.pluginHost.MainWindow.GetSelectedEntry(false);

            if (entry == null)
            {
                return;
            }

            if (this.mountMenuItemState.ShouldMountDialogShown)
            {
                var dialog = new TrueCryptMountForm()
                    .WithShowInTaskBar(false)
                    .WithStartPosition(FormStartPosition.CenterParent)
                    .ReadFrom(entry);

                var result = dialog.ShowDialog(this.pluginHost.MainWindow);

                if (result == DialogResult.Cancel)
                {
                    // exit here, save nothing, mount nothing
                    return;
                }

                // save settings
                if (dialog.ChangesApplied)
                {
                    dialog.WriteTo(entry);
                    entry.Touch(true);
                    this.pluginHost.Database.Modified = true;
                    this.pluginHost.MainWindow.UpdateUI(false, null, false, null, false, null, true);
                }
            }

            // do mount...
            new ProcessStartInfo(this.pluginHost.GetTrueCryptExecutable())
                .HideExecution()
                .WithCommandLine(entry.ToTrueCryptArguments())
                .Execute();
        }

        private void OnTrueCryptOptionsMenuItemClicked(object sender, EventArgs e)
        {
            // open the plugin options dialog.
            using (var optionsDialog = new TrueCryptOptionsForm(this.pluginHost))
            {
                optionsDialog.WithShowInTaskBar(false)
                             .WithStartPosition(FormStartPosition.CenterParent)
                             .ShowDialog(this.pluginHost.MainWindow);
            }

            this.mountMenuItemState.AlwaysVisible = this.pluginHost.GetTrueCryptMenuItemAlwaysVisible();

            this.SetTrueCryptMountMenuMenuAppearance();
        }

        /// <summary>
        /// Changes the appearance and accessibilty of the mount menu item after option change.
        /// </summary>
        private void SetTrueCryptMountMenuMenuAppearance()
        {
            // in case of missing executeable, disable the menu item and load another overlay image.
            if (!TrueCryptInfo.ExecutableExists(this.pluginHost.GetTrueCryptExecutable()))
            {
                this.mnuEntryTrueCryptMount.Enabled = false;
                this.mnuEntryTrueCryptMount.Image = Resources.TrueCryptError;
            }
            else
            {
                this.mnuEntryTrueCryptMount.Enabled = true;
                this.mnuEntryTrueCryptMount.Image = Resources.TrueCryptNormal;
            }
        }

        private void SetTrueCryptMountMenuItemAccessibility(bool shiftHold = false)
        {
            var state = this.mountMenuItemState.GetState(
                this.pluginHost.MainWindow.GetSelectedEntriesCount(),
                this.pluginHost.MainWindow.GetSelectedEntry(false),
                shiftHold);

            this.mountMenuItemState.ChangeState(state);
        }
    }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.