diff --git a/KeePassTrayIconLockState/DatabaseOpenState.cs b/KeePassTrayIconLockState/DatabaseOpenState.cs index c770230..a167a89 100644 --- a/KeePassTrayIconLockState/DatabaseOpenState.cs +++ b/KeePassTrayIconLockState/DatabaseOpenState.cs @@ -1,11 +1,9 @@ -namespace KeePassTrayIconLockState { +namespace KeePassTrayIconLockState; - internal enum DatabaseOpenState { +internal enum DatabaseOpenState { - CLOSED, - OPENING, - OPEN - - } + CLOSED, + OPENING, + OPEN } \ No newline at end of file diff --git a/KeePassTrayIconLockState/KeePassTrayIconLockState.csproj b/KeePassTrayIconLockState/KeePassTrayIconLockState.csproj index 932cfa5..9e4e8e5 100644 --- a/KeePassTrayIconLockState/KeePassTrayIconLockState.csproj +++ b/KeePassTrayIconLockState/KeePassTrayIconLockState.csproj @@ -34,12 +34,15 @@ latest + + ..\..\darknet\darknet\bin\Debug\net452\DarkNet.dll + ..\..\..\..\..\..\Programs\Security\KeePass\KeePass.exe False - ..\..\KoKo\KoKo\bin\Release\net45\KoKo.dll + ..\..\KoKo\KoKo\bin\Release\net452\KoKo.dll @@ -83,5 +86,11 @@ + + + + + + \ No newline at end of file diff --git a/KeePassTrayIconLockState/KeePassTrayIconLockStateExt.cs b/KeePassTrayIconLockState/KeePassTrayIconLockStateExt.cs index b0ddc5d..74f5220 100644 --- a/KeePassTrayIconLockState/KeePassTrayIconLockStateExt.cs +++ b/KeePassTrayIconLockState/KeePassTrayIconLockStateExt.cs @@ -5,99 +5,115 @@ using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; +using Dark.Net; using KeePass.Plugins; using KeePass.Resources; using KoKo.Property; -namespace KeePassTrayIconLockState { - - // ReSharper disable once UnusedType.Global - public class KeePassTrayIconLockStateExt: Plugin { - - internal static readonly TimeSpan STARTUP_DURATION = TimeSpan.FromMilliseconds(2000); - - private readonly StoredProperty databaseOpenState = new(); - - private IPluginHost keePassHost = null!; - private Property trayIcon = null!; - - public override Image SmallIcon => Resources.plugin_image; - public override string UpdateUrl { get; } = @"https://raw.githubusercontent.com/Aldaviva/KeePassTrayIconLockState/master/KeePassTrayIconLockState/version.txt"; - - public override bool Initialize(IPluginHost host) { - keePassHost = host; - - keePassHost.MainWindow.FileOpened += delegate { databaseOpenState.Value = DatabaseOpenState.OPEN; }; - keePassHost.MainWindow.FileClosed += delegate { databaseOpenState.Value = DatabaseOpenState.CLOSED; }; - - ToolStripItemCollection statusBarItems = keePassHost.MainWindow.Controls.OfType().First().Items; - ToolStripItem statusBarInfo = statusBarItems[1]; - ToolStripItem progressBar = statusBarItems[2]; - Property statusBarText = new NativeReadableProperty(statusBarInfo, nameof(ToolStripItem.Text), nameof(ToolStripItem.TextChanged)); - Property isProgressBarVisible = new NativeReadableProperty(progressBar, nameof(ToolStripItem.Visible), nameof(ToolStripItem.VisibleChanged)); - - statusBarText.PropertyChanged += (_, args) => { - if (args.NewValue == KPRes.OpeningDatabase2) { - /* - * When the status bar text changes to "Opening database...", set the db open state to OPENING. - */ - databaseOpenState.Value = DatabaseOpenState.OPENING; - } - }; - - isProgressBarVisible.PropertyChanged += (_, args) => { - if (!args.NewValue && databaseOpenState.Value == DatabaseOpenState.OPENING) { - /* - * When the database is being opened and the progress bar gets hidden, it means the database was finished being decrypted, but was it successful or unsuccessful? - * Sadly there is no good way to tell, so instead we wait 100 ms for the FileOpen event to be fired. - * If it is fired, the db open state moves from OPENING to OPEN (above). - * Otherwise, assume that the database failed to decrypt and set the db open state to CLOSED. - */ - Task.Delay(100).ContinueWith(_ => { - if (databaseOpenState.Value == DatabaseOpenState.OPENING) { // failed to decrypt, otherwise this would have been set to OPEN by the FileOpen event above. - databaseOpenState.Value = DatabaseOpenState.CLOSED; - } - }); - - } else if (args.NewValue && databaseOpenState.Value == DatabaseOpenState.CLOSED && statusBarText.Value == KPRes.OpeningDatabase2) { - /* - * When the database is closed and the status bar says "Opening database..." and the progress bar gets shown, it means the user already failed the previous decryption - * attempt and is retrying after submitting another password, so set the db opening state to OPENING. - */ - databaseOpenState.Value = DatabaseOpenState.OPENING; - } - }; - - trayIcon = DerivedProperty.Create(databaseOpenState, openState => new TrayIcon(getIcon(openState), openState != DatabaseOpenState.CLOSED)); - - trayIcon.PropertyChanged += (_, _) => renderTrayIcon(); - - /* - * KeePass sets its own icon at some indeterminate time after startup, so repeatedly set our own icon every 8 ms for 2 seconds to make sure our icon isn't overridden. - */ - Timer startupTimer = new() { Enabled = true, Interval = 8 }; - startupTimer.Tick += delegate { renderTrayIcon(); }; - Task.Delay(STARTUP_DURATION).ContinueWith(_ => startupTimer.Stop()); - renderTrayIcon(); - - return true; - } - - private void renderTrayIcon() { - TrayIcon iconToRender = trayIcon.Value; - NotifyIcon keepassIcon = keePassHost.MainWindow.MainNotifyIcon; - - keepassIcon.Icon = iconToRender.image; - keepassIcon.Visible = iconToRender.isVisible; - } - - private static Icon getIcon(DatabaseOpenState databaseOpenState) => databaseOpenState switch { - DatabaseOpenState.CLOSED => Resources.locked, - DatabaseOpenState.OPENING => Resources.unlocking, - DatabaseOpenState.OPEN => Resources.unlocked, - _ => throw new ArgumentOutOfRangeException(nameof(databaseOpenState), databaseOpenState, nameof(getIcon)) +namespace KeePassTrayIconLockState; + +// ReSharper disable once UnusedType.Global +public class KeePassTrayIconLockStateExt: Plugin { + + internal static readonly TimeSpan STARTUP_DURATION = TimeSpan.FromMilliseconds(2000); + + private readonly StoredProperty databaseOpenState = new(); + private readonly IDarkNet darkNet = new DarkNet(); + + private IPluginHost keePassHost = null!; + private Property trayIcon = null!; + private Property taskbarIsDarkTheme = null!; + + public override Image SmallIcon => Resources.plugin_image; + public override string UpdateUrl { get; } = @"https://raw.githubusercontent.com/Aldaviva/KeePassTrayIconLockState/master/KeePassTrayIconLockState/version.txt"; + + public override bool Initialize(IPluginHost host) { + keePassHost = host; + + keePassHost.MainWindow.FileOpened += delegate { databaseOpenState.Value = DatabaseOpenState.OPEN; }; + keePassHost.MainWindow.FileClosed += delegate { databaseOpenState.Value = DatabaseOpenState.CLOSED; }; + + ToolStripItemCollection statusBarItems = keePassHost.MainWindow.Controls.OfType().First().Items; + ToolStripItem statusBarInfo = statusBarItems[1]; + ToolStripItem progressBar = statusBarItems[2]; + Property statusBarText = new NativeReadableProperty(statusBarInfo, nameof(ToolStripItem.Text), nameof(ToolStripItem.TextChanged)); + Property isProgressBarVisible = new NativeReadableProperty(progressBar, nameof(ToolStripItem.Visible), nameof(ToolStripItem.VisibleChanged)); + + statusBarText.PropertyChanged += (_, args) => { + if (args.NewValue == KPRes.OpeningDatabase2) { + /* + * When the status bar text changes to "Opening database...", set the db open state to OPENING. + */ + databaseOpenState.Value = DatabaseOpenState.OPENING; + } }; + isProgressBarVisible.PropertyChanged += (_, args) => { + if (!args.NewValue && databaseOpenState.Value == DatabaseOpenState.OPENING) { + /* + * When the database is being opened and the progress bar gets hidden, it means the database was finished being decrypted, but was it successful or unsuccessful? + * Sadly there is no good way to tell, so instead we wait 100 ms for the FileOpen event to be fired. + * If it is fired, the db open state moves from OPENING to OPEN (above). + * Otherwise, assume that the database failed to decrypt and set the db open state to CLOSED. + */ + Task.Delay(100).ContinueWith(_ => { + if (databaseOpenState.Value == DatabaseOpenState.OPENING) { // failed to decrypt, otherwise this would have been set to OPEN by the FileOpen event above. + databaseOpenState.Value = DatabaseOpenState.CLOSED; + } + }); + + } else if (args.NewValue && databaseOpenState.Value == DatabaseOpenState.CLOSED && statusBarText.Value == KPRes.OpeningDatabase2) { + /* + * When the database is closed and the status bar says "Opening database..." and the progress bar gets shown, it means the user already failed the previous decryption + * attempt and is retrying after submitting another password, so set the db opening state to OPENING. + */ + databaseOpenState.Value = DatabaseOpenState.OPENING; + } + }; + + taskbarIsDarkTheme = new NativeReadableProperty(darkNet, nameof(IDarkNet.UserTaskbarThemeIsDark), nameof(IDarkNet.UserTaskbarThemeIsDarkChanged)); + + trayIcon = DerivedProperty.Create(databaseOpenState, taskbarIsDarkTheme, + (openState, isDarkTheme) => new TrayIcon(getIcon(openState, isDarkTheme), openState != DatabaseOpenState.CLOSED)); + + trayIcon.PropertyChanged += delegate { renderTrayIcon(); }; + + /* + * KeePass sets its own icon at some indeterminate time after startup, so repeatedly set our own icon every 8 ms for 2 seconds to make sure our icon isn't overridden. + */ + Timer startupTimer = new() { Enabled = true, Interval = 8 }; + startupTimer.Tick += delegate { renderTrayIcon(); }; + Task.Delay(STARTUP_DURATION).ContinueWith(_ => startupTimer.Dispose()); + renderTrayIcon(); + + return true; + } + + private void renderTrayIcon() { + TrayIcon iconToRender = trayIcon.Value; + NotifyIcon keepassIcon = keePassHost.MainWindow.MainNotifyIcon; + + keepassIcon.Icon = iconToRender.image; + keepassIcon.Visible = iconToRender.isVisible; + } + + private static Icon getIcon(DatabaseOpenState databaseOpenState, bool isDarkTheme) { + Icon iconResource = databaseOpenState switch { + DatabaseOpenState.CLOSED when isDarkTheme => Resources.locked, + DatabaseOpenState.CLOSED => Resources.locked, + DatabaseOpenState.OPENING when isDarkTheme => Resources.unlocking, + DatabaseOpenState.OPENING => Resources.unlocking_light, + DatabaseOpenState.OPEN when isDarkTheme => Resources.unlocked, + DatabaseOpenState.OPEN => Resources.unlocked_light, + _ => throw new ArgumentOutOfRangeException(nameof(databaseOpenState), databaseOpenState, nameof(getIcon)) + }; + Icon sizedIconResource = new(iconResource, SystemInformation.SmallIconSize); + return sizedIconResource; + } + + public override void Terminate() { + darkNet.Dispose(); + base.Terminate(); } } \ No newline at end of file diff --git a/KeePassTrayIconLockState/Properties/AssemblyInfo.cs b/KeePassTrayIconLockState/Properties/AssemblyInfo.cs index 39a9a05..16726ad 100644 --- a/KeePassTrayIconLockState/Properties/AssemblyInfo.cs +++ b/KeePassTrayIconLockState/Properties/AssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Ben Hutchison")] [assembly: AssemblyProduct("KeePass Plugin")] -[assembly: AssemblyCopyright("Copyright © Ben Hutchison 2020")] +[assembly: AssemblyCopyright("© 2022 Ben Hutchison")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -17,7 +17,7 @@ // Remember to also update version.txt when changing these version attributes so that online update checking works. // https://keepass.info/help/v2_dev/plg_index.html#upd -[assembly: AssemblyVersion("1.0.2.0")] -[assembly: AssemblyFileVersion("1.0.2.0")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] [assembly: InternalsVisibleTo("Test")] \ No newline at end of file diff --git a/KeePassTrayIconLockState/Resources.Designer.cs b/KeePassTrayIconLockState/Resources.Designer.cs index 492e4f9..b6dfd8e 100644 --- a/KeePassTrayIconLockState/Resources.Designer.cs +++ b/KeePassTrayIconLockState/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace KeePassTrayIconLockState { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -90,6 +90,16 @@ internal static System.Drawing.Icon unlocked { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon unlocked_light { + get { + object obj = ResourceManager.GetObject("unlocked_light", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// @@ -99,5 +109,15 @@ internal static System.Drawing.Icon unlocking { return ((System.Drawing.Icon)(obj)); } } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon unlocking_light { + get { + object obj = ResourceManager.GetObject("unlocking_light", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } } } diff --git a/KeePassTrayIconLockState/Resources.resx b/KeePassTrayIconLockState/Resources.resx index 6c7922b..f804b1b 100644 --- a/KeePassTrayIconLockState/Resources.resx +++ b/KeePassTrayIconLockState/Resources.resx @@ -127,7 +127,13 @@ Resources\unlocked.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + Resources\unlocked-light.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + resources\unlocking.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + resources\unlocking-light.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/KeePassTrayIconLockState/Resources/unlocked-light.ico b/KeePassTrayIconLockState/Resources/unlocked-light.ico new file mode 100644 index 0000000..ba5bcf0 Binary files /dev/null and b/KeePassTrayIconLockState/Resources/unlocked-light.ico differ diff --git a/KeePassTrayIconLockState/Resources/unlocked.ico b/KeePassTrayIconLockState/Resources/unlocked.ico index bd2a9fc..2da54c1 100644 Binary files a/KeePassTrayIconLockState/Resources/unlocked.ico and b/KeePassTrayIconLockState/Resources/unlocked.ico differ diff --git a/KeePassTrayIconLockState/Resources/unlocking-light.ico b/KeePassTrayIconLockState/Resources/unlocking-light.ico new file mode 100644 index 0000000..acdc719 Binary files /dev/null and b/KeePassTrayIconLockState/Resources/unlocking-light.ico differ diff --git a/KeePassTrayIconLockState/Resources/unlocking.ico b/KeePassTrayIconLockState/Resources/unlocking.ico index bec0276..b47e5ed 100644 Binary files a/KeePassTrayIconLockState/Resources/unlocking.ico and b/KeePassTrayIconLockState/Resources/unlocking.ico differ diff --git a/KeePassTrayIconLockState/TrayIcon.cs b/KeePassTrayIconLockState/TrayIcon.cs index 093e6ec..165423f 100644 --- a/KeePassTrayIconLockState/TrayIcon.cs +++ b/KeePassTrayIconLockState/TrayIcon.cs @@ -2,40 +2,38 @@ using System.Drawing; -namespace KeePassTrayIconLockState { +namespace KeePassTrayIconLockState; - internal readonly struct TrayIcon { +internal readonly struct TrayIcon { - internal readonly Icon image; - internal readonly bool isVisible; + internal readonly Icon image; + internal readonly bool isVisible; - public TrayIcon(Icon image, bool isVisible) { - this.image = image; - this.isVisible = isVisible; - } - - private bool Equals(TrayIcon other) { - return image.Equals(other.image) && isVisible == other.isVisible; - } + public TrayIcon(Icon image, bool isVisible) { + this.image = image; + this.isVisible = isVisible; + } - public override bool Equals(object? obj) { - return obj is TrayIcon other && Equals(other); - } + public bool Equals(TrayIcon other) { + return image.Equals(other.image) && isVisible == other.isVisible; + } - public override int GetHashCode() { - unchecked { - return (image.GetHashCode() * 397) ^ isVisible.GetHashCode(); - } - } + public override bool Equals(object? obj) { + return obj is TrayIcon other && Equals(other); + } - public static bool operator ==(TrayIcon left, TrayIcon right) { - return left.Equals(right); + public override int GetHashCode() { + unchecked { + return (image.GetHashCode() * 397) ^ isVisible.GetHashCode(); } + } - public static bool operator !=(TrayIcon left, TrayIcon right) { - return !left.Equals(right); - } + public static bool operator ==(TrayIcon left, TrayIcon right) { + return left.Equals(right); + } + public static bool operator !=(TrayIcon left, TrayIcon right) { + return !left.Equals(right); } } \ No newline at end of file diff --git a/KeePassTrayIconLockState/version.txt b/KeePassTrayIconLockState/version.txt index 0c6cfc0..904d494 100644 --- a/KeePassTrayIconLockState/version.txt +++ b/KeePassTrayIconLockState/version.txt @@ -1,3 +1,3 @@ : -KeePassTrayIconLockState:1.0.2 +KeePassTrayIconLockState:1.1.0 : \ No newline at end of file