From a76784a5613a6cb4bc62860712720c4887b536fa Mon Sep 17 00:00:00 2001 From: izzy20044 Date: Tue, 5 May 2026 17:37:11 -0700 Subject: [PATCH] Add "Go to Entry" right-click action in search results When a search/filter is active, right-clicking a result now offers a "Go to Entry" command that clears the active filter and scrolls/selects the same clip in the unfiltered chronological list. The row position is computed via a single SQL COUNT(*) query against Main, mirroring FillList's default ORDER BY (stickyClipOrder DESC, bIsGroup ASC, clipOrder DESC). This avoids loading every row into memory, which matters on large databases (tested at ~25 GB). The handler also pumps the message queue while waiting for the loader thread's m_SearchingEvent, since list-load completion is reported via PostMessage(NM_SET_LIST_COUNT) which would otherwise be starved by a synchronous WaitForSingleObject. Menu item is enabled only while the search box is non-empty. --- CP_Main.rc | 1 + resource.h | 3 +- src/QPasteWnd.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++++++ src/QPasteWnd.h | 2 + 4 files changed, 142 insertions(+), 1 deletion(-) diff --git a/CP_Main.rc b/CP_Main.rc index 934ee12b..ad25ab69 100644 --- a/CP_Main.rc +++ b/CP_Main.rc @@ -515,6 +515,7 @@ BEGIN MENUITEM "Compare", ID_COMPARE_COMPARE END MENUITEM "Filter On Selected Clip", ID_MENU_FILTERON + MENUITEM "Go to Entry", ID_MENU_GOTOENTRY MENUITEM SEPARATOR MENUITEM "Delete Entry", 32801 MENUITEM SEPARATOR diff --git a/resource.h b/resource.h index e4340ca2..585cd0f6 100644 --- a/resource.h +++ b/resource.h @@ -873,6 +873,7 @@ #define ID_IMPORT_EXPORTTOWEBSEARCH 32997 #define ID_SPECIALPASTE_PASTENEWGUID 32998 #define ID_SPECIALPASTE_POSIXIFY_PATHS 32999 +#define ID_MENU_GOTOENTRY 33000 // Next default values for new objects // @@ -880,7 +881,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 394 -#define _APS_NEXT_COMMAND_VALUE 32999 +#define _APS_NEXT_COMMAND_VALUE 33001 #define _APS_NEXT_CONTROL_VALUE 2174 #define _APS_NEXT_SYMED_VALUE 104 #endif diff --git a/src/QPasteWnd.cpp b/src/QPasteWnd.cpp index 438d155d..7a2903a1 100644 --- a/src/QPasteWnd.cpp +++ b/src/QPasteWnd.cpp @@ -264,6 +264,8 @@ BEGIN_MESSAGE_MAP(CQPasteWnd, CWndEx) ON_UPDATE_COMMAND_UI(ID_CLIPORDER_MOVETOTOP, &CQPasteWnd::OnUpdateCliporderMovetotop) ON_COMMAND(ID_MENU_FILTERON, &CQPasteWnd::OnMenuFilteron) ON_UPDATE_COMMAND_UI(ID_MENU_FILTERON, &CQPasteWnd::OnUpdateMenuFilteron) + ON_COMMAND(ID_MENU_GOTOENTRY, &CQPasteWnd::OnMenuGoToEntry) + ON_UPDATE_COMMAND_UI(ID_MENU_GOTOENTRY, &CQPasteWnd::OnUpdateMenuGoToEntry) ON_BN_CLICKED(ON_TOP_WARNING, OnAlwaysOnTopClicked) //ON_WM_CTLCOLOR() ON_COMMAND(ID_SPECIALPASTE_UPPERCASE, &CQPasteWnd::OnSpecialpasteUppercase) @@ -6915,6 +6917,141 @@ void CQPasteWnd::OnUpdateMenuFilteron(CCmdUI* pCmdUI) UpdateMenuShortCut(pCmdUI, ActionEnums::FILTER_ON_SELECTED_CLIP); } +void CQPasteWnd::OnMenuGoToEntry() +{ + ARRAY IDs; + m_lstHeader.GetSelectionItemData(IDs); + if (IDs.GetSize() <= 0) + { + return; + } + + long targetID = IDs[0]; + + int targetSticky = 0; + int targetIsGroup = 0; + int targetClipOrder = 0; + long targetParent = -1; + bool gotKey = false; + try + { + CppSQLite3Query q = theApp.m_db.execQueryEx( + _T("SELECT stickyClipOrder, bIsGroup, clipOrder, lParentID FROM Main WHERE lID = %d"), + targetID); + if (!q.eof()) + { + targetSticky = q.getIntField(_T("stickyClipOrder")); + targetIsGroup = q.getIntField(_T("bIsGroup")); + targetClipOrder = q.getIntField(_T("clipOrder")); + targetParent = q.getIntField(_T("lParentID")); + gotKey = true; + } + } + catch (CppSQLite3Exception&) + { + } + + if (!gotKey) + { + return; + } + + CString filter; + if (CGetSetOptions::m_bShowAllClipsInMainList) + { + if (CGetSetOptions::GetShowGroupsInMainList()) + filter = _T("((Main.bIsGroup = 1 AND Main.lParentID = -1) OR Main.bIsGroup = 0)"); + else + filter = _T("(Main.bIsGroup = 0)"); + } + else + { + filter = _T("((Main.bIsGroup = 1 AND Main.lParentID = -1) OR (Main.bIsGroup = 0 AND Main.lParentID = -1))"); + } + + int targetIndex = -1; + try + { + CString rankSql; + rankSql.Format( + _T("SELECT COUNT(*) FROM Main WHERE %s AND (") + _T("(stickyClipOrder > %d) OR ") + _T("(stickyClipOrder = %d AND bIsGroup < %d) OR ") + _T("(stickyClipOrder = %d AND bIsGroup = %d AND clipOrder > %d))"), + (LPCTSTR)filter, + targetSticky, + targetSticky, targetIsGroup, + targetSticky, targetIsGroup, targetClipOrder); + + targetIndex = theApp.m_db.execScalar(rankSql); + } + catch (CppSQLite3Exception&) + { + targetIndex = -1; + } + + theApp.m_FocusID = targetID; + + if (theApp.m_GroupID >= 0 && targetParent != theApp.m_GroupID) + { + theApp.EnterGroupID(-1); + } + + m_bHandleSearchTextChange = false; + m_search.SetWindowText(_T("")); + m_bHandleSearchTextChange = true; + + FillList(_T("")); + + // The list loader thread reports completion via PostMessage(NM_SET_LIST_COUNT), + // so we must pump messages while waiting or that handler never runs. + DWORD waitStart = GetTickCount(); + while (WaitForSingleObject(m_thread.m_SearchingEvent, 0) == WAIT_TIMEOUT) + { + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (GetTickCount() - waitStart > 5000) + break; + Sleep(10); + } + + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + int totalRows = m_lstHeader.GetItemCount(); + + if (targetIndex < 0 || targetIndex >= totalRows) + { + MoveControls(); + SelectFocusID(); + m_lstHeader.SetFocus(); + return; + } + + MoveControls(); + + m_lstHeader.EnsureVisible(targetIndex, FALSE); + m_lstHeader.SetListPos(targetIndex); + m_lstHeader.SetFocus(); + + Log(StrF(_T("GoToEntry: scrolled to index %d of %d"), targetIndex, totalRows)); +} + +void CQPasteWnd::OnUpdateMenuGoToEntry(CCmdUI* pCmdUI) +{ + CString csSearch; + m_search.GetWindowText(csSearch); + pCmdUI->Enable(!csSearch.IsEmpty()); +} + void CQPasteWnd::OnAlwaysOnTopClicked() { DoAction(ActionEnums::TOGGLESHOWPERSISTANT); diff --git a/src/QPasteWnd.h b/src/QPasteWnd.h index 3627fe67..a5d69c34 100644 --- a/src/QPasteWnd.h +++ b/src/QPasteWnd.h @@ -511,6 +511,8 @@ class CQPasteWnd: public CWndEx afx_msg void OnUpdateCliporderMovetotop(CCmdUI *pCmdUI); afx_msg void OnMenuFilteron(); afx_msg void OnUpdateMenuFilteron(CCmdUI *pCmdUI); + afx_msg void OnMenuGoToEntry(); + afx_msg void OnUpdateMenuGoToEntry(CCmdUI *pCmdUI); afx_msg void OnAlwaysOnTopClicked(); //afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnSpecialpasteUppercase();