diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 6d56856d7..432c5ba1c 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -2572,6 +2572,12 @@ void Notepad_plus::specialCmd(int id) } } +BOOL Notepad_plus::processIncrFindAccel(MSG *msg) const +{ + if (!::IsChild(_incrementFindDlg.getHSelf(), ::GetFocus())) + return FALSE; + return ::TranslateAccelerator(_incrementFindDlg.getHSelf(), _accelerator.getIncrFindAccTable(), msg); +} void Notepad_plus::setLanguage(LangType langType) { //Add logic to prevent changing a language when a document is shared between two views diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index b16ad81e8..62d7d7a81 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -519,6 +519,8 @@ private: void setLanguage(LangType langType); enum LangType menuID2LangType(int cmdID); + BOOL processIncrFindAccel(MSG *msg) const; + void checkMenuItem(int itemID, bool willBeChecked) const { ::CheckMenuItem(_mainMenuHandle, itemID, MF_BYCOMMAND | (willBeChecked?MF_CHECKED:MF_UNCHECKED)); }; diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index 12e41eb32..afaae5dd6 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -269,6 +269,9 @@ bool Notepad_plus_Window::isDlgsMsg(MSG *msg) const { for (size_t i = 0, len = _notepad_plus_plus_core._hModelessDlgs.size(); i < len; ++i) { + if (_notepad_plus_plus_core.processIncrFindAccel(msg)) + return true; + if (::IsDialogMessageW(_notepad_plus_plus_core._hModelessDlgs[i], msg)) return true; } diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index 82b22b49d..fc7bfc136 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -2698,7 +2698,7 @@ void FindIncrementDlg::display(bool toShow) const _pRebar->setIDVisible(_rbBand.wID, toShow); } -BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -2718,8 +2718,12 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) case WM_COMMAND : { - bool isUnicode = (*(_pFRDlg->_ppEditView))->getCurrentBuffer()->getUnicodeMode() != uni8Bit; - FindStatus findStatus = FSFound; + bool updateSearch = false; + bool forward = true; + bool advance = false; + bool updateHiLight = false; + bool updateCase = false; + switch (LOWORD(wParam)) { case IDCANCEL : @@ -2730,85 +2734,77 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) display(false); return TRUE; - case IDC_INCFINDPREVOK : - case IDC_INCFINDNXTOK : - case IDOK : + case IDM_SEARCH_FINDINCREMENT: // Accel table: Start incremental search + // if focus is on a some other control, return it to the edit field + if (::GetFocus() != ::GetDlgItem(_hSelf, IDC_INCFINDTEXT)) + { + ::PostMessage(_hSelf, WM_NEXTDLGCTL, (WPARAM)::GetDlgItem(_hSelf, IDC_INCFINDTEXT), TRUE); + return TRUE; + } + // otherwise, repeat the search + case IDM_SEARCH_FINDPREV: // Accel table: find prev + case IDM_SEARCH_FINDNEXT: // Accel table: find next + case IDC_INCFINDPREVOK: + case IDC_INCFINDNXTOK: + case IDOK: + updateSearch = true; + advance = true; + forward = (LOWORD(wParam) == IDC_INCFINDNXTOK) || + (LOWORD(wParam) == IDM_SEARCH_FINDNEXT) || + (LOWORD(wParam) == IDM_SEARCH_FINDINCREMENT) || + ((LOWORD(wParam) == IDOK) && !(GetKeyState(VK_SHIFT) & SHIFTED)); + break; + + case IDC_INCFINDMATCHCASE: + updateSearch = true; + updateCase = true; + updateHiLight = true; + break; + + case IDC_INCFINDHILITEALL: + updateHiLight = true; + break; + + case IDC_INCFINDTEXT: + if (HIWORD(wParam) == EN_CHANGE) + { + updateSearch = true; + break; + } + // treat other edit notifications as unhandled + default: + return DefWindowProc(getHSelf(), message, wParam, lParam); + } + FindOption fo; + fo._isWholeWord = false; + fo._incrementalType = advance ? NextIncremental : FirstIncremental; + fo._whichDirection = forward ? DIR_DOWN : DIR_UP; + fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); + + bool isUnicode = (*(_pFRDlg->_ppEditView))->getCurrentBuffer()->getUnicodeMode() != uni8Bit; + generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); + if (updateSearch) + { + FindStatus findStatus = FSFound; + bool isFound = _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); + setFindStatus(findStatus); + // If case-sensitivity changed (to Match=yes), there may have been a matched selection that + // now does not match; so if Not Found, clear selection and put caret at beginning of what was + // selected (no change, if there was no selection) + if (updateCase && !isFound) { - FindOption fo; - fo._isWholeWord = false; - fo._incrementalType = NextIncremental; - fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); - if (LOWORD(wParam) == IDC_INCFINDPREVOK) - fo._whichDirection = DIR_UP; - else if (LOWORD(wParam) == IDOK) - { - SHORT nVirtKey = GetKeyState(VK_SHIFT); - if (nVirtKey & SHIFTED) - fo._whichDirection = DIR_UP; - } - - generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); - setFindStatus(findStatus); + CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); + (*(_pFRDlg->_ppEditView))->execute(SCI_SETSEL, (WPARAM)-1, range.cpMin); } - return TRUE; - - case IDC_INCFINDTEXT : - { - switch(HIWORD(wParam)) - { - case EN_CHANGE : - { - FindOption fo; - fo._isWholeWord = false; - fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); - fo._incrementalType = FirstIncremental; - - generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); - setFindStatus(findStatus); - } - return TRUE; - - case EN_KILLFOCUS : - case EN_SETFOCUS : - break; - } - } - return TRUE; - - case IDC_INCFINDMATCHCASE: - { - FindOption fo; - fo._isWholeWord = false; - fo._incrementalType = FirstIncremental; - fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); - - generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - bool isFound = _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); - setFindStatus(findStatus); - if (!isFound) - { - CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); - (*(_pFRDlg->_ppEditView))->execute(SCI_SETSEL, (WPARAM)-1, range.cpMin); - } - } - - case IDC_INCFINDHILITEALL : - { - FindOption fo; - fo._isWholeWord = false; - fo._incrementalType = FirstIncremental; - fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); - - generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - bool isHiLieAll = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_GETCHECK, 0, 0)); - if (str2Search == TEXT("")) - isHiLieAll = false; - markSelectedTextInc(isHiLieAll, &fo); - } - return TRUE; } + + if (updateHiLight) + { + bool highlight = !str2Search.empty() && + (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_GETCHECK, 0, 0)); + markSelectedTextInc(highlight, &fo); + } + return TRUE; } case WM_ERASEBKGND: @@ -2825,7 +2821,7 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) break; } } - return FALSE; + return DefWindowProc(getHSelf(), message, wParam, lParam); } void FindIncrementDlg::markSelectedTextInc(bool enable, FindOption *opt) diff --git a/PowerEditor/src/WinControls/shortcut/shortcut.cpp b/PowerEditor/src/WinControls/shortcut/shortcut.cpp index ae9c87177..d5c14bac2 100644 --- a/PowerEditor/src/WinControls/shortcut/shortcut.cpp +++ b/PowerEditor/src/WinControls/shortcut/shortcut.cpp @@ -35,6 +35,8 @@ #include "Notepad_plus_Window.h" #include "keys.h" +#include + const int KEY_STR_LEN = 16; struct KeyIDNAME { @@ -452,6 +454,7 @@ BOOL CALLBACK Shortcut::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) // return true if one of CommandShortcuts is deleted. Otherwise false. void Accelerator::updateShortcuts() { + const std::array IFAccIds = { IDM_SEARCH_FINDNEXT, IDM_SEARCH_FINDPREV, IDM_SEARCH_FINDINCREMENT }; NppParameters *pNppParam = NppParameters::getInstance(); vector & shortcuts = pNppParam->getUserShortcuts(); @@ -467,6 +470,7 @@ void Accelerator::updateShortcuts() if (_pAccelArray) delete [] _pAccelArray; _pAccelArray = new ACCEL[nbMenu+nbMacro+nbUserCmd+nbPluginCmd]; + vector IFAcc; int offset = 0; size_t i = 0; @@ -476,6 +480,9 @@ void Accelerator::updateShortcuts() _pAccelArray[offset].cmd = (WORD)(shortcuts[i].getID()); _pAccelArray[offset].fVirt = shortcuts[i].getAcceleratorModifiers(); _pAccelArray[offset].key = shortcuts[i].getKeyCombo()._key; + // Special extra handling for shortcuts shared by Incremental Find dialog + if (std::find(IFAccIds.begin(), IFAccIds.end(), shortcuts[i].getID()) != IFAccIds.end()) + IFAcc.push_back(_pAccelArray[offset]); ++offset; } } @@ -510,7 +517,15 @@ void Accelerator::updateShortcuts() _nbAccelItems = offset; updateFullMenu(); - reNew(); //update the table + + //update the table + if (_hAccTable) + ::DestroyAcceleratorTable(_hAccTable); + _hAccTable = ::CreateAcceleratorTable(_pAccelArray, _nbAccelItems); + if (_hIncFindAccTab) + ::DestroyAcceleratorTable(_hIncFindAccTab); + _hIncFindAccTab = ::CreateAcceleratorTable(IFAcc.data(), IFAcc.size()); + return; } diff --git a/PowerEditor/src/WinControls/shortcut/shortcut.h b/PowerEditor/src/WinControls/shortcut/shortcut.h index 91f6bb267..58a875e8b 100644 --- a/PowerEditor/src/WinControls/shortcut/shortcut.h +++ b/PowerEditor/src/WinControls/shortcut/shortcut.h @@ -342,10 +342,12 @@ private : class Accelerator { //Handles accelerator keys for Notepad++ menu, including custom commands friend class ShortcutMapper; public: - Accelerator():_hAccelMenu(NULL), _hMenuParent(NULL), _hAccTable(NULL), _pAccelArray(NULL), _nbAccelItems(0){}; - ~Accelerator(){ + Accelerator() :_hAccelMenu(NULL), _hMenuParent(NULL), _hAccTable(NULL), _hIncFindAccTab(NULL), _pAccelArray(NULL), _nbAccelItems(0){}; + ~Accelerator() { if (_hAccTable) ::DestroyAcceleratorTable(_hAccTable); + if (_hIncFindAccTab) + ::DestroyAcceleratorTable(_hIncFindAccTab); if (_pAccelArray) delete [] _pAccelArray; }; @@ -355,6 +357,7 @@ public: updateShortcuts(); }; HACCEL getAccTable() const {return _hAccTable;}; + HACCEL getIncrFindAccTable() const { return _hIncFindAccTab; }; void updateShortcuts(); void updateFullMenu(); @@ -363,14 +366,10 @@ private: HMENU _hAccelMenu; HWND _hMenuParent; HACCEL _hAccTable; + HACCEL _hIncFindAccTab; ACCEL *_pAccelArray; int _nbAccelItems; - void reNew() { - if(_hAccTable) - ::DestroyAcceleratorTable(_hAccTable); - _hAccTable = ::CreateAcceleratorTable(_pAccelArray, _nbAccelItems); - }; void updateMenuItemByCommand(CommandShortcut csc); };