private List <object> GetFoundEntriesList(PwGroup g, Dictionary <PwEntry, int> dEntryIconIndex) { List <Object> l = new List <object>(); m_lEntryListColumns = new List <AceColumn>(); List <AceColumn> lColumns = null; if (m_miGetEntryFieldEx != null) { lColumns = KeePass.Program.Config.MainWindow.EntryListColumns; } else //add a basic set of columns { lColumns = new List <AceColumn>(); AddColumn(lColumns, AceColumnType.Title, false); AddColumn(lColumns, AceColumnType.UserName, false); AddColumn(lColumns, AceColumnType.Password, true); AddColumn(lColumns, AceColumnType.Url, false); AddColumn(lColumns, AceColumnType.Notes, false); } foreach (PwEntry pe in g.Entries) { PwGroup pg = pe.ParentGroup; if (pg != null) { if (l.Find(x => (x is ListViewGroup) && ((x as ListViewGroup).Tag == pg)) == null) { ListViewGroup lvg = new ListViewGroup(pg.GetFullPath(" - ", pg.ParentGroup == null)); lvg.Tag = pg; l.Add(lvg); } } ListViewItem lvi = new ListViewItem(); lvi.Tag = new object[] { pe, g }; lvi.Text = SearchHelp.GetDBName(pe); lvi.ImageIndex = dEntryIconIndex[pe]; ListViewItem.ListViewSubItem lvsi = null; //Show all columns that are shown in the entry list view if possible if (m_miGetEntryFieldEx != null) { for (int i = 0; i < lColumns.Count; i++) { lvsi = new ListViewItem.ListViewSubItem(); lvsi.Text = (string)m_miGetEntryFieldEx.Invoke(m_host.MainWindow, new object[] { pe, i, true, null }); if (!m_lEntryListColumns.Contains(lColumns[i])) { m_lEntryListColumns.Add(lColumns[i]); } lvi.SubItems.Add(lvsi); } } else //Show a basic set of columns { foreach (AceColumn c in lColumns) { lvsi = new ListViewItem.ListViewSubItem(); if (c.Type == AceColumnType.Title) { lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.TitleField); } if (c.Type == AceColumnType.UserName) { lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.UserNameField); } if (c.Type == AceColumnType.Password) { lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.PasswordField); } if (c.Type == AceColumnType.Url) { lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.UrlField); } if (c.Type == AceColumnType.Notes) { lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : KeePassLib.Utility.StrUtil.MultiToSingleLine(pe.Strings.ReadSafe(PwDefs.NotesField)); } //Deref data if required lvsi.Text = DerefString(lvsi.Text, pe); if (!m_lEntryListColumns.Contains(c)) { m_lEntryListColumns.Add(c); } lvi.SubItems.Add(lvsi); } ; }; l.Add(lvi); } return(l); }
private void OnClickFindEntry(object sender, EventArgs e) { string f = (sender as ToolStripItem).Name; FindInfo fi = SearchHelp.FindList.Find(x => x.Name == (sender as ToolStripItem).Name); if (CallStandardSearch(fi, (sender as ToolStripItem).Name)) { if (fi != null) { foreach (Delegate d in fi.StandardEventHandlers) { d.DynamicInvoke(new object[] { sender, e }); } } return; } PluginDebug.AddInfo("Call own find routine", 0, "Action: " + f); //Show status logger Form fOptDialog = null; IStatusLogger sl = StatusUtil.CreateStatusDialog(m_host.MainWindow, out fOptDialog, null, (KPRes.SearchingOp ?? "..."), true, false); m_host.MainWindow.UIBlockInteraction(true); m_aStandardLvInit = null; //Perform find for all open databases PwDatabase dbAll = MergeDatabases(); List <object> l = null; try { object[] parameters; if (fi.SearchType != SearchType.BuiltIn) { parameters = new object[] { dbAll, sl, null, fi } } ; else { parameters = new object[] { dbAll, sl, null } }; l = (List <object>)fi.StandardMethod.Invoke(m_host, parameters); m_aStandardLvInit = (Action <ListView>)parameters[2]; } catch (Exception ex) { l = null; PluginDebug.AddError("Call standard find routine", 0, "Action: " + f, "Reason for standard call: " + ex.Message); foreach (Delegate d in fi.StandardEventHandlers) { d.DynamicInvoke(new object[] { sender, e }); } } finally { dbAll.Close(); } m_host.MainWindow.UIBlockInteraction(false); sl.EndLogging(); if (l == null) { return; } //Fill db column ImageList il = new ImageList(); ImageList il2 = (ImageList)Tools.GetField("m_ilCurrentIcons", m_host.MainWindow); foreach (Image img in il2.Images) { il.Images.Add(img); } foreach (var o in l) { ListViewItem lvi = o as ListViewItem; if (lvi == null) { continue; } ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem(); if (lvi.Tag is PwEntry) { lvsi.Text = SearchHelp.GetDBName(lvi.Tag as PwEntry); PwEntry pe = lvi.Tag as PwEntry; PwDatabase db = m_host.MainWindow.DocumentManager.FindContainerOf(pe); if (!pe.CustomIconUuid.Equals(PwUuid.Zero)) { il.Images.Add(db.GetCustomIcon(pe.CustomIconUuid, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16))); lvi.ImageIndex = il.Images.Count - 1; } else { lvi.ImageIndex = (int)pe.IconId; } } else if (lvi.Tag is PwGroup) { PwGroup pg = lvi.Tag as PwGroup; lvsi.Text = SearchHelp.GetDBName(pg.Entries.GetAt(0)); } lvi.SubItems.Insert(0, lvsi); } if ((l.Count == 0) && !string.IsNullOrEmpty(fi.NothingFound)) { Tools.ShowInfo(fi.NothingFound); il.Dispose(); return; } //Show results ListViewForm dlg = new ListViewForm(); //Prepare ImageList (CustomIcons can be different per database) dlg.InitEx(fi.Title, fi.SubTitle, fi.Note, fi.img, l, il, InitListView); UIUtil.ShowDialogAndDestroy(dlg); if (dlg.DialogResult != DialogResult.OK) { return; } il.Dispose(); NavigateToSelectedEntry(dlg, false); }
private void OnSearchExecute(object sender, EventArgs e) { //Perform search in all open databases m_dDBGroups = new Dictionary <PwDatabase, PwGroup>(); PwGroup g = null; List <PwDatabase> lOpenDB = m_host.MainWindow.DocumentManager.GetOpenDatabases(); m_btnOK.Click -= OnSearchExecute; List <string> lMsg = new List <string>(); foreach (PwDatabase db in lOpenDB) { lMsg.Clear(); lMsg.Add("DB: " + db.IOConnectionInfo.Path); if ((m_sf != null) && (m_sf.SearchResultsGroup != null) && (m_sf.SearchResultsGroup.Entries != null)) { lMsg.Add("Previos search results cleared: " + true.ToString()); m_sf.SearchResultsGroup.Entries.Clear(); } m_sf.InitEx(db, db.RootGroup); FindInfo fi = SearchHelp.FindList.Find(x => x.Name == SearchHelp.SearchForm); if (fi.StandardEventHandlers.Count > 0) { using (MonoWorkaroundDialogResult mwaDR = new MonoWorkaroundDialogResult(sender)) { foreach (Delegate onclick in fi.StandardEventHandlers) { lMsg.Add("Calling method: " + onclick.Method.Name + " - " + onclick.Method.ReflectedType.Name); onclick.DynamicInvoke(new object[] { sender, e }); } } } else { lMsg.Add("Calling standard method"); m_btnOK.PerformClick(); } if ((m_sf.SearchResultsGroup == null) || (m_sf.SearchResultsGroup.Entries == null)) { lMsg.Add("Found entries: 0"); } else { lMsg.Add("Found entries: " + m_sf.SearchResultsGroup.Entries.UCount.ToString()); } //Do NOT use m_sf.SearchResultsGroup.CloneDeep //It makes the virtual SearchResultsGroup the //parent group of the found entries if (g == null) { g = new PwGroup(true, true, m_sf.SearchResultsGroup.Name, m_sf.SearchResultsGroup.IconId); } foreach (PwEntry pe in m_sf.SearchResultsGroup.Entries) { g.AddEntry(pe, false); } PluginDebug.AddInfo("Executing search", 0, lMsg.ToArray()); } //Don't continue if not even a single entry was found if ((g == null) || (g.GetEntriesCount(true) == 0)) { if (m_sf.DialogResult == DialogResult.None) { m_sf.DialogResult = DialogResult.OK; } return; } //Prepare ImageList (CustomIcons can be different per database) ImageList il = new ImageList(); ImageList il2 = (ImageList)Tools.GetField("m_ilCurrentIcons", m_host.MainWindow); foreach (Image img in il2.Images) { il.Images.Add(img); } Dictionary <PwEntry, int> dEntryIconIndex = new Dictionary <PwEntry, int>(); PwDatabase dbFirst = null; bool bMultipleDB = false; foreach (PwEntry pe in g.Entries) { PwDatabase db = m_host.MainWindow.DocumentManager.FindContainerOf(pe); if (db == null) { PluginDebug.AddError("Could not get database for entry", 0, pe.Uuid.ToHexString()); continue; } if (!m_dDBGroups.ContainsKey(db)) { m_dDBGroups[db] = new PwGroup(true, false, SearchHelp.GetDBName(pe), PwIcon.Folder) { IsVirtual = true } } ; m_dDBGroups[db].AddEntry(pe, false); if (dbFirst == null) { dbFirst = db; } bMultipleDB |= db != dbFirst; if (!pe.CustomIconUuid.Equals(PwUuid.Zero)) { il.Images.Add(db.GetCustomIcon(pe.CustomIconUuid, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16))); dEntryIconIndex[pe] = dEntryIconIndex.Count - 1; } else { dEntryIconIndex[pe] = (int)pe.IconId; } } //If all found entries are contained in the same database //simply activate this database (might not be active yet) and return if (!bMultipleDB) { PwGroup pgSF = (PwGroup)Tools.GetField("m_pgResultsGroup", m_sf); if (pgSF != null) { //clear list of found entries //otherwise duplicates might be shown if last searched db is the only one that is to be shown pgSF.Entries.Clear(); pgSF.Entries.Add(g.Entries); } else //KeePass 2.47 { pgSF = new PwGroup(true, true, g.Name, g.IconId); pgSF.IsVirtual = true; pgSF.Entries.Add(g.Entries); } PluginDebug.AddInfo("Found " + pgSF.Entries.UCount.ToString() + " entries in 1 database"); m_host.MainWindow.UpdateUI(false, m_host.MainWindow.DocumentManager.FindDocument(dbFirst), true, pgSF, false, null, false); il.Dispose(); m_sf.SearchResultsGroup.Entries.Clear(); m_sf.SearchResultsGroup.Entries.Add(pgSF.Entries); m_sf.DialogResult = DialogResult.OK; return; } //We found entries from at least 2 databases //Show the results in ListViewForm and close SearchForm try { PluginDebug.AddInfo("Found " + g.Entries.UCount.ToString() + " entries in multiple database"); m_sf.DialogResult = DialogResult.Abort; m_sf.Visible = false; m_sf.Close(); } catch (Exception ex) { PluginDebug.AddError("Error closing searchform", new string[] { ex.Message }); } m_aStandardLvInit = InitListViewMain; List <object> l = GetFoundEntriesList(g, dEntryIconIndex); ListViewForm dlg = new ListViewForm(); int iCount = l.FindAll(x => (x as ListViewItem) != null).Count; string sSubTitle = iCount == 1 ? KPRes.SearchEntriesFound1 : KPRes.SearchEntriesFound; sSubTitle = sSubTitle.Replace("{PARAM}", iCount.ToString()); dlg.InitEx(KPRes.Search, sSubTitle, null, null, l, il, InitListView); ShowMultiDBInfo(true); PluginDebug.AddInfo("Multi-DB results: Show", 0); if (dlg.ShowDialog(m_host.MainWindow) != DialogResult.OK) { PluginDebug.AddInfo("Multi-DB results: Shown", 0); UIUtil.DestroyForm(dlg); return; } PluginDebug.AddInfo("Multi-DB results: Show and navigate", 0); il.Dispose(); NavigateToSelectedEntry(dlg, true); PluginDebug.AddInfo("Multi-DB results: Dispose form", 0); UIUtil.DestroyForm(dlg); PluginDebug.AddInfo("Multi-DB results: Disposed form", 0); }