Skip to content

Commit 4578b9f

Browse files
committed
Add a *search as you type* option to filter found entries in Auto-Type Entry Selection form
1 parent f517dc3 commit 4578b9f

12 files changed

+205
-80
lines changed

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,24 @@ This KeePass plugin enhances KeePass' Auto-Type feature.
1818

1919
# Configuration
2020
Alternate Auto-Type integrates into KeePass' options form.\
21-
<img src="images/AlternateAutoType%20-%20Options.png" alt="Options" />
21+
<img src="images/AlternateAutoType%20-%20Options.png" alt="Options 1" />
22+
<img src="images/AlternateAutoType%20-%20Options%202.png" alt="Options 2" />
2223

23-
In the upper area you can configure the hotkeys Alternate Auto-Type will react on.
24-
In the lower area you can (de)activate the enhancements to the Auto-Type entry selection.
24+
In the first tab you can configure the hotkeys Alternate Auto-Type will react on.
25+
In the second tab you can (de)activate the enhancements to the Auto-Type entry selection.
2526
# Usage
27+
## Auto-Type hotkey configuration
28+
This tab basically mimics KeePass' integration tab with regards to hotkeys.
29+
You can define hotkeys for *Global Auto-Type* and *Global Auto-Type password only* in both tabs.
30+
31+
In addition, you can define whether *Global Auto-Type password only* will send an [Enter] key after the password was auto-typed.
32+
You can also define the hotkey for the Alternate Auto-Type specific sequence.
33+
34+
This is only possible on Windows.
2635
## Auto-Type entry selection enhancements
2736
While the Auto-Type entry selection is a great way to pick one of the matching candidates, it still lacks some features that this plugin adds.
2837

38+
- Search as you type allows filtering entries in the result list - can be helpful in case many entries are found
2939
- Sortable columns
3040
- Show database name if entries from more than one database are shown
3141
- Exclude entries in expired groups

Translations/AlternateAutoType.de.language.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Translation>
3-
<TranslationVersion>5</TranslationVersion>
3+
<!--
4+
Increment the TranslationVersion every time the translation file is updated
5+
Also update the version.info file
6+
-->
7+
<TranslationVersion>6</TranslationVersion>
48
<item>
59
<key>ErrorHotKeyAAT</key>
610
<value>{0} konnte nicht als Hotkey für Alternate Auto-Type registriert werden</value>
@@ -75,4 +79,8 @@
7579
Klicke '{1}', um einen weiteren Eintrag hinzuzufügen.
7680
Klicke '{2}', um nichts zu tun.</value>
7781
</item>
82+
<item>
83+
<key>SearchAsYouType</key>
84+
<value>Filtermöglichkeit für gefundene Einträge</value>
85+
</item>
7886
</Translation>

Translations/AlternateAutoType.template.language.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Translation>
3+
<!--
4+
Increment the TranslationVersion every time the translation file is updated
5+
Also update the version.info file
6+
-->
37
<TranslationVersion>0</TranslationVersion>
48
<item>
59
<key>ErrorHotKeyAAT</key>
@@ -75,4 +79,8 @@
7579
If you want to add another Auto-Type sequence, click '{1}'.
7680
If you want to skip these entries, please click '{2}'.</value>
7781
</item>
82+
<item>
83+
<key>SearchAsYouType</key>
84+
<value>Allow filtering of entries</value>
85+
</item>
7886
</Translation>
120 KB
Loading
56.7 KB
Loading

src/AlternateAutoType.cs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,14 @@ private void HotkeysDeactivate()
186186
private void OnWindowAdded(object sender, GwmWindowEventArgs e)
187187
{
188188
if (!(e.Form is AutoTypeCtxForm)) return;
189-
if (m_host.MainWindow.DocumentManager.GetOpenDatabases().Count < 1) return;
189+
int iOpenedDatabases = m_host.MainWindow.DocumentManager.GetOpenDatabases().Count;
190+
if (!Config.SearchAsYouType && iOpenedDatabases < 1) return;
190191
e.Form.Shown += OnAutoTypeFormShown;
191192

193+
if (iOpenedDatabases < 1) return;
192194
PluginDebug.AddInfo("Auto-Type entry selection window added", 0);
193195

196+
194197
List<AutoTypeCtx> lCtx = (List<AutoTypeCtx>)Tools.GetField("m_lCtxs", e.Form);
195198
if (lCtx == null) return;
196199
// Adjust content
@@ -253,8 +256,17 @@ private void OnWindowRemoved(object sender, GwmWindowEventArgs e)
253256

254257
private void OnAutoTypeFormShown(object sender, EventArgs e)
255258
{
256-
Form f = sender as AutoTypeCtxForm;
259+
if (m_host.MainWindow.DocumentManager.GetOpenDatabases().Count >= 1) InitializeAutoTypeListView(sender, e);
260+
261+
if (Config.SearchAsYouType) AddSearchfield(sender as AutoTypeCtxForm);
262+
}
263+
264+
private void InitializeAutoTypeListView(object sender, EventArgs e)
265+
{
266+
AutoTypeCtxForm f = sender as AutoTypeCtxForm;
257267
if (f == null) return;
268+
//AddSearchfield(f);
269+
if (m_host.MainWindow.DocumentManager.GetOpenDatabases().Count < 1) return;
258270
ListView lv = Tools.GetControl("m_lvItems", f) as ListView;
259271
PluginDebug.AddInfo("Auto-Type entry selection window shown", 0);
260272
if ((lv != null) && (lv.Items.Count == 0) && !KeePass.Program.Config.Integration.AutoTypeAlwaysShowSelDialog)
@@ -343,7 +355,62 @@ private void OnAutoTypeFormShown(object sender, EventArgs e)
343355
catch (Exception) { }
344356
}
345357

346-
private void AutoTypeForm_ShowGroups_CheckedChanged(object sender, EventArgs e)
358+
private class _SearchAsYouTypeData
359+
{
360+
internal ListView ShownEntries;
361+
internal List<ListViewItem> AllEntries;
362+
}
363+
private void AddSearchfield(AutoTypeCtxForm f)
364+
{
365+
var lvShownEntries = Tools.GetControl("m_lvItems", f) as ListView;
366+
if (lvShownEntries == null)
367+
{
368+
PluginDebug.AddError("Could not locate m_lvItems, search-as-you-type field not added");
369+
return;
370+
}
371+
var c = lvShownEntries.Parent;
372+
Label lSearch = new Label();
373+
TextBox tbSearch = new TextBox();
374+
c.Controls.Add(lSearch);
375+
c.Controls.Add(tbSearch);
376+
lSearch.Text = KeePass.Resources.KPRes.FindEntries;
377+
lSearch.AutoSize = true;
378+
tbSearch.Left = lvShownEntries.Left + lSearch.Width + DpiUtil.ScaleIntX(10);
379+
lSearch.Left = lvShownEntries.Left;
380+
tbSearch.Top = lvShownEntries.Top;
381+
lSearch.Top = lvShownEntries.Top + tbSearch.Height / 2 - lSearch.Height / 2;
382+
tbSearch.Width = lvShownEntries.Width / 2;
383+
List<ListViewItem> lvAllEntries = new List<ListViewItem>(lvShownEntries.Items.Cast< ListViewItem>());
384+
tbSearch.Tag = new _SearchAsYouTypeData() { AllEntries = lvAllEntries, ShownEntries = lvShownEntries };
385+
tbSearch.TextChanged += OnFilterSearchResults;
386+
int iGap = DpiUtil.ScaleIntY(10);
387+
int iHeight = lvShownEntries.Height;
388+
tbSearch.Dock = lvShownEntries.Dock = DockStyle.None;
389+
lvShownEntries.Top += tbSearch.Height + iGap -1;
390+
lvShownEntries.Height = iHeight - tbSearch.Height - iGap;
391+
}
392+
393+
private void OnFilterSearchResults(object sender, EventArgs e)
394+
{
395+
TextBox tbSearch = sender as TextBox;
396+
if (tbSearch == null) return;
397+
_SearchAsYouTypeData st = tbSearch.Tag as _SearchAsYouTypeData;
398+
if (st == null) return;
399+
string s = tbSearch.Text.ToLowerInvariant();
400+
st.ShownEntries.BeginUpdate();
401+
st.ShownEntries.Items.Clear();
402+
st.ShownEntries.Items.AddRange(st.AllEntries.Where(x =>
403+
x.Text.ToLowerInvariant().Contains(s) // Entry title
404+
||
405+
x.SubItems[1].Text.ToLowerInvariant().Contains(s) // User name
406+
).ToArray());
407+
st.ShownEntries.EndUpdate();
408+
if (!st.ShownEntries.ShowGroups) return;
409+
int column = st.ShownEntries.Columns.IndexOf(m_SortColumn);
410+
AdjustGroups(st.ShownEntries, column);
411+
}
412+
413+
private void AutoTypeForm_ShowGroups_CheckedChanged(object sender, EventArgs e)
347414
{
348415
Form f = (sender as Control).FindForm();
349416
ListView lv = Tools.GetControl("m_lvItems", f) as ListView;
@@ -597,6 +664,7 @@ private void OptionsFormShown(object sender, Tools.OptionsFormsEventArgs e)
597664
options.cbSpecialColumnsRespectPWEnter.Checked = Config.SpecialColumnsRespectPWEnter;
598665
options.cbKeepATOpen.Checked = Config.KeepATOpen;
599666
options.cbExcludeExpiredGroups.Checked = Config.ExcludeExpiredGroups;
667+
options.cbSearchAsYouType.Checked = Config.SearchAsYouType;
600668
e.form.Shown += options.OptionsForm_Shown;
601669
Tools.AddPluginToOptionsForm(this, options);
602670
}
@@ -623,6 +691,7 @@ private void OptionsForm_Closed(object sender, Tools.OptionsFormsEventArgs e)
623691
Config.SpecialColumnsRespectPWEnter = options.cbSpecialColumnsRespectPWEnter.Checked;
624692
Config.KeepATOpen = options.cbKeepATOpen.Checked;
625693
Config.ExcludeExpiredGroups = options.cbExcludeExpiredGroups.Checked;
694+
Config.SearchAsYouType = options.cbSearchAsYouType.Checked;
626695

627696
if ((Config.AATHotkey != Keys.None) || (Config.PWOnlyHotkey != Keys.None))
628697
HotkeysActivate();

src/Config.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ static Config()
4242
}
4343
}
4444

45+
public static bool SearchAsYouType
46+
{
47+
get { return Program.Config.CustomConfig.GetBool(m_SearchAsYouType, true); }
48+
set { Program.Config.CustomConfig.SetBool(m_SearchAsYouType, value); }
49+
}
4550
public static bool AddDBColumn
4651
{
4752
get { return Program.Config.CustomConfig.GetBool(m_AddDBColumnConfig, false); }
@@ -134,6 +139,7 @@ public static bool ExcludeExpiredGroups
134139
private static string m_AATHotkeyConfig = "AlternateAutoType.AATHotkey";
135140
private static string m_PWOnlyHotkeyConfig = "AlternateAutoType.PWOnlyHotkey";
136141
private static string m_PWEnterConfig = "AlternateAutoType.PWEnter";
142+
private static string m_SearchAsYouType = "AlternateAutoType.SearchAsYouType";
137143
private static string m_AddDBColumnConfig = "AlternateAutoType.AddDBColumn";
138144
private static string m_ColumnsSortableConfig = "AlternateAutoType.ColumnsSortable";
139145
private static string m_ColumnsRememberSorting = "AlternateAutoType.ColumnsRememberSorting";

0 commit comments

Comments
 (0)