diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index b67d80f8..c9e34bad 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -617,6 +617,7 @@ LRESULT Notepad_plus::init(HWND hwnd) //--Init dialogs--// _findReplaceDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); + _findInFinderDlg.init(_pPublicInterface->getHinst(), hwnd); _incrementFindDlg.init(_pPublicInterface->getHinst(), hwnd, &_findReplaceDlg, _nativeLangSpeaker.isRTL()); _incrementFindDlg.addToRebar(&_rebarBottom); _goToLineDlg.init(_pPublicInterface->getHinst(), hwnd, &_pEditView); @@ -1501,7 +1502,9 @@ bool Notepad_plus::replaceInFiles() _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); _invisibleEditView.setCurrentBuffer(pBuf); - int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, FindReplaceDlg::_env, true, fileNames.at(i).c_str()); + FindersInfo findersInfo; + findersInfo._pFileName = fileNames.at(i).c_str(); + int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, FindReplaceDlg::_env, true, &findersInfo); nbTotal += nbReplaced; if (nbReplaced) { @@ -1535,11 +1538,87 @@ bool Notepad_plus::replaceInFiles() return true; } +bool Notepad_plus::findInFinderFiles(FindersInfo *findInFolderInfo) +{ + int nbTotal = 0; + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + vector patterns2Match; + _findReplaceDlg.getPatterns(patterns2Match); + if (patterns2Match.size() == 0) + { + _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); + _findReplaceDlg.getPatterns(patterns2Match); + } + + vector fileNames = findInFolderInfo->_pSourceFinder->getResultFilePaths(); + + findInFolderInfo->_pDestFinder->beginNewFilesSearch(); + findInFolderInfo->_pDestFinder->addSearchLine(findInFolderInfo->_findOption._str2Search.c_str()); + + Progress progress(_pPublicInterface->getHinst()); + + size_t filesCount = fileNames.size(); + size_t filesPerPercent = 1; + + if (filesCount > 1) + { + if (filesCount >= 200) + filesPerPercent = filesCount / 100; + progress.open(_findReplaceDlg.getHSelf(), TEXT("Find In Files progress...")); + } + + for (size_t i = 0, updateOnCount = filesPerPercent; i < filesCount; ++i) + { + if (progress.isCancelled()) break; + + bool closeBuf = false; + BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str()); + if (id == BUFFER_INVALID) + { + id = MainFileManager->loadFile(fileNames.at(i).c_str()); + closeBuf = true; + } + + if (id != BUFFER_INVALID) + { + Buffer * pBuf = MainFileManager->getBufferByID(id); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + int cp = _invisibleEditView.execute(SCI_GETCODEPAGE); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); + + findInFolderInfo->_pFileName = fileNames.at(i).c_str(); + nbTotal += _findReplaceDlg.processAll(ProcessFindInFinder, &(findInFolderInfo->_findOption), true, findInFolderInfo); + if (closeBuf) + MainFileManager->closeBuffer(id, _pEditView); + } + if (i == updateOnCount) + { + updateOnCount += filesPerPercent; + progress.setPercent((i * 100) / filesCount, fileNames.at(i).c_str()); + } + else + { + progress.setInfo(fileNames.at(i).c_str()); + } + } + progress.close(); + + findInFolderInfo->_pDestFinder->finishFilesSearch(nbTotal, findInFolderInfo->_findOption._isMatchLineNumber); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + return true; +} + bool Notepad_plus::findInFiles() { const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); - if (!dir2Search[0] || !::PathFileExists(dir2Search)) + if (not dir2Search[0] || not ::PathFileExists(dir2Search)) { return false; } @@ -1558,6 +1637,7 @@ bool Notepad_plus::findInFiles() _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); _findReplaceDlg.getPatterns(patterns2Match); } + vector fileNames; getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); @@ -1593,8 +1673,9 @@ bool Notepad_plus::findInFiles() _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); int cp = _invisibleEditView.execute(SCI_GETCODEPAGE); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); - - nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, true, fileNames.at(i).c_str()); + FindersInfo findersInfo; + findersInfo._pFileName = fileNames.at(i).c_str(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, true, &findersInfo); if (closeBuf) MainFileManager->closeBuffer(id, _pEditView); } @@ -1646,7 +1727,9 @@ bool Notepad_plus::findInOpenedFiles() _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); int cp = _invisibleEditView.execute(SCI_GETCODEPAGE); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); - nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, pBuf->getFullPathName()); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); } } @@ -1658,7 +1741,9 @@ bool Notepad_plus::findInOpenedFiles() _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); int cp = _invisibleEditView.execute(SCI_GETCODEPAGE); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); - nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, pBuf->getFullPathName()); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); } } @@ -1691,7 +1776,9 @@ bool Notepad_plus::findInCurrentFile() _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); int cp = _invisibleEditView.execute(SCI_GETCODEPAGE); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? cp : SC_CP_UTF8); - nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, pBuf->getFullPathName()); + FindersInfo findersInfo; + findersInfo._pFileName = pBuf->getFullPathName(); + nbTotal += _findReplaceDlg.processAll(ProcessFindAll, FindReplaceDlg::_env, isEntireDoc, &findersInfo); _findReplaceDlg.finishFilesSearch(nbTotal); diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index de2d9daf..bb9e6062 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -282,6 +282,7 @@ public: bool loadSession(Session & session, bool isSnapshotMode = false); void notifyBufferChanged(Buffer * buffer, int mask); + bool findInFinderFiles(FindersInfo *findInFolderInfo); bool findInFiles(); bool replaceInFiles(); void setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *filters); @@ -340,6 +341,8 @@ private: // Dialog FindReplaceDlg _findReplaceDlg; + FindInFinderDlg _findInFinderDlg; + FindIncrementDlg _incrementFindDlg; AboutDlg _aboutDlg; DebugInfoDlg _debugInfoDlg; diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index ea4b6ca2..3eb204cc 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -215,8 +215,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa case WM_FINDALL_INCURRENTDOC: { - findInCurrentFile(); - return TRUE; + return findInCurrentFile(); } case WM_FINDINFILES: @@ -224,6 +223,21 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa return findInFiles(); } + case WM_FINDALL_INCURRENTFINDER: + { + FindersInfo *findInFolderInfo = (FindersInfo *)wParam; + Finder * newFinder = _findReplaceDlg.createFinder(); + + findInFolderInfo->_pDestFinder = newFinder; + bool isOK = findInFinderFiles(findInFolderInfo); + return isOK; + } + /* + case NPPM_INTERNAL_REMOVEFINDER: + { + return _findReplaceDlg.removeFinder((Finder *)wParam); + } + */ case WM_REPLACEINFILES: { replaceInFiles(); @@ -249,6 +263,26 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa return TRUE; } + case NPPM_INTERNAL_FINDINFINDERDLG: + { + const int strSize = FINDREPLACE_MAXLENGTH; + TCHAR str[strSize]; + Finder *launcher = (Finder *)wParam; + + bool isFirstTime = not _findInFinderDlg.isCreated(); + + _findInFinderDlg.doDialog(launcher, _nativeLangSpeaker.isRTL()); + + _pEditView->getGenericSelectedText(str, strSize); + _findReplaceDlg.setSearchText(str); + setFindReplaceFolderFilter(NULL, NULL); + + if (isFirstTime) + _nativeLangSpeaker.changeFindReplaceDlgLang(_findReplaceDlg); + + return TRUE; + } + case NPPM_DOOPEN: case WM_DOOPEN: { diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index b952e278..d1d591ee 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -40,6 +40,29 @@ FindOption FindReplaceDlg::_options; #define SHIFTED 0x8000 +void addText2Combo(const TCHAR * txt2add, HWND hCombo) +{ + if (!hCombo) return; + if (!lstrcmp(txt2add, TEXT(""))) return; + + int i = 0; + + i = ::SendMessage(hCombo, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)txt2add); + if (i != CB_ERR) // found + { + ::SendMessage(hCombo, CB_DELETESTRING, i, 0); + } + + i = ::SendMessage(hCombo, CB_INSERTSTRING, 0, (LPARAM)txt2add); + ::SendMessage(hCombo, CB_SETCURSEL, i, 0); +}; + +generic_string getTextFromCombo(HWND hCombo) +{ + TCHAR str[FINDREPLACE_MAXLENGTH]; + ::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, (LPARAM)str); + return generic_string(str); +}; int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int length) { //query may equal to result, since it always gets smaller @@ -199,32 +222,6 @@ void Searching::displaySectionCentered(int posStart, int posEnd, ScintillaEditVi LONG_PTR FindReplaceDlg::originalFinderProc = NULL; -void FindReplaceDlg::addText2Combo(const TCHAR * txt2add, HWND hCombo, bool) -{ - if (!hCombo) return; - if (!lstrcmp(txt2add, TEXT(""))) return; - - int i = 0; - - i = ::SendMessage(hCombo, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)txt2add); - if (i != CB_ERR) // found - { - ::SendMessage(hCombo, CB_DELETESTRING, i, 0); - } - - i = ::SendMessage(hCombo, CB_INSERTSTRING, 0, (LPARAM)txt2add); - - ::SendMessage(hCombo, CB_SETCURSEL, i, 0); -} - -generic_string FindReplaceDlg::getTextFromCombo(HWND hCombo, bool) const -{ - TCHAR str[FINDREPLACE_MAXLENGTH]; - ::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, (LPARAM)str); - return generic_string(str); -} - - // important : to activate all styles const int STYLING_MASK = 255; @@ -233,7 +230,13 @@ FindReplaceDlg::~FindReplaceDlg() _tab.destroy(); if (_pFinder) delete _pFinder; - delete [] _uniFileName; + for (int n = _findersOfFinder.size() - 1; n >= 0; n--) + { + delete _findersOfFinder[n]; + _findersOfFinder.erase(_findersOfFinder.begin() + n); + } + + delete[] _uniFileName; } void FindReplaceDlg::create(int dialogID, bool isRTL) @@ -350,12 +353,11 @@ void FindReplaceDlg::fillFindHistory() void FindReplaceDlg::fillComboHistory(int id, const vector & strings) { - bool isUnicode = false; HWND hCombo = ::GetDlgItem(_hSelf, id); for (vector::const_reverse_iterator i = strings.rbegin() ; i != strings.rend(); ++i) { - addText2Combo(i->c_str(), hCombo, isUnicode); + addText2Combo(i->c_str(), hCombo); } ::SendMessage(hCombo, CB_SETCURSEL, 0, 0); // select first item } @@ -398,7 +400,13 @@ void FindReplaceDlg::updateCombos() updateCombo(IDFINDWHAT); } -FoundInfo Finder::EmptyFoundInfo(0, 0, TEXT("")); +void FindReplaceDlg::updateCombo(int comboID) +{ + HWND hCombo = ::GetDlgItem(_hSelf, comboID); + addText2Combo(getTextFromCombo(hCombo).c_str(), hCombo); +} + +FoundInfo Finder::EmptyFoundInfo(0, 0, 0, TEXT("")); SearchResultMarking Finder::EmptySearchResultMarking; bool Finder::notify(SCNotification *notification) @@ -512,6 +520,41 @@ void Finder::DeleteResult() assert(size_t(_scintView.execute(SCI_GETLINECOUNT)) == _pMainFoundInfos->size() + 1); } +vector Finder::getResultFilePaths() const +{ + vector paths; + size_t len = _pMainFoundInfos->size(); + for (size_t i = 0; i < len; ++i) + { + // make sure that path is not already in + generic_string & path2add = (*_pMainFoundInfos)[i]._fullPath; + bool found = path2add.empty(); + for (size_t j = 0; j < paths.size() && not found; ++j) + { + if (paths[j] == path2add) + found = true; + + } + if (not found) + paths.push_back(path2add); + } + return paths; +} + +bool Finder::canFind(const TCHAR *fileName, size_t lineNumber) const +{ + size_t len = _pMainFoundInfos->size(); + for (size_t i = 0; i < len; ++i) + { + if ((*_pMainFoundInfos)[i]._fullPath == fileName) + { + if (lineNumber == (*_pMainFoundInfos)[i]._lineNumber) + return true; + } + } + return false; +} + void Finder::gotoNextFoundResult(int direction) { int increment = direction < 0 ? -1 : 1; @@ -564,6 +607,67 @@ void Finder::gotoNextFoundResult(int direction) } } +void FindInFinderDlg::initFromOptions() +{ + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT_FIFOLDER); + addText2Combo(_options._str2Search.c_str(), hFindCombo); + + ::SendDlgItemMessage(_hSelf, IDC_MATCHLINENUM_CHECK_FIFOLDER, BM_SETCHECK, _options._isMatchLineNumber ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDWHOLEWORD_FIFOLDER, BM_SETCHECK, _options._isWholeWord ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDMATCHCASE_FIFOLDER, BM_SETCHECK, _options._isMatchCase ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDNORMAL_FIFOLDER, BM_SETCHECK, _options._searchType == FindNormal ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDEXTENDED_FIFOLDER, BM_SETCHECK, _options._searchType == FindExtended ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendDlgItemMessage(_hSelf, IDREGEXP_FIFOLDER, BM_SETCHECK, _options._searchType == FindRegex ? BST_CHECKED : BST_UNCHECKED, 0); + + ::SendDlgItemMessage(_hSelf, IDREDOTMATCHNL_FIFOLDER, BM_SETCHECK, _options._dotMatchesNewline ? BST_CHECKED : BST_UNCHECKED, 0); +} + +void FindInFinderDlg::writeOptions() +{ + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT_FIFOLDER); + _options._str2Search = getTextFromCombo(hFindCombo); + _options._isMatchLineNumber = isCheckedOrNot(IDC_MATCHLINENUM_CHECK_FIFOLDER); + _options._isWholeWord = isCheckedOrNot(IDWHOLEWORD_FIFOLDER); + _options._isMatchCase = isCheckedOrNot(IDMATCHCASE_FIFOLDER); + _options._searchType = isCheckedOrNot(IDREGEXP_FIFOLDER) ? FindRegex : isCheckedOrNot(IDEXTENDED_FIFOLDER) ? FindExtended : FindNormal; + + _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL_FIFOLDER); +} + +INT_PTR CALLBACK FindInFinderDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG: + initFromOptions(); + return TRUE; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + ::EndDialog(_hSelf, -1); + return TRUE; + + case IDOK: + writeOptions(); + ::EndDialog(_hSelf, -1); + FindersInfo findersInfo; + findersInfo._pSourceFinder = _pFinder2Search; + findersInfo._findOption = _options; + ::SendMessage(_hParent, WM_FINDALL_INCURRENTFINDER, (WPARAM)&findersInfo, 0); + return TRUE; + } + return FALSE; + } + default: + return FALSE; + } +} + + INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -705,10 +809,9 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM case IDOK : // Find Next : only for FIND_DLG and REPLACE_DLG { setStatusbarMessage(generic_string(), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); updateCombo(IDFINDWHAT); nppParamInst->_isFindReplacing = true; @@ -732,11 +835,10 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (_currentStatus == REPLACE_DLG) { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); - _options._str4Replace = getTextFromCombo(hReplaceCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); + _options._str4Replace = getTextFromCombo(hReplaceCombo); updateCombos(); nppParamInst->_isFindReplacing = true; @@ -752,10 +854,9 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (_currentStatus == FIND_DLG) { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); combo2ExtendedMode(IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); updateCombo(IDFINDWHAT); nppParamInst->_isFindReplacing = true; @@ -769,10 +870,9 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM case IDC_FINDALL_CURRENTFILE : { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); combo2ExtendedMode(IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); updateCombo(IDFINDWHAT); nppParamInst->_isFindReplacing = true; @@ -800,10 +900,9 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if ((lstrlen(directory) > 0) && (directory[lstrlen(directory)-1] != '\\')) _options._directory += TEXT("\\"); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); combo2ExtendedMode(IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); updateCombo(IDFINDWHAT); nppParamInst->_isFindReplacing = true; @@ -838,11 +937,10 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (::MessageBox(_hParent, msg.c_str(), TEXT("Are you sure?"), MB_OKCANCEL|MB_DEFBUTTON2) == IDOK) { - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); - _options._str4Replace = getTextFromCombo(hReplaceCombo, isUnicode); + _options._str4Replace = getTextFromCombo(hReplaceCombo); updateCombo(IDFINDWHAT); updateCombo(IDREPLACEWITH); @@ -860,11 +958,10 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (_currentStatus == REPLACE_DLG) { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); - _options._str4Replace = getTextFromCombo(hReplaceCombo, isUnicode); + _options._str4Replace = getTextFromCombo(hReplaceCombo); updateCombos(); nppParamInst->_isFindReplacing = true; @@ -888,11 +985,10 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM return TRUE; } - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); - _options._str4Replace = getTextFromCombo(hReplaceCombo, isUnicode); + _options._str4Replace = getTextFromCombo(hReplaceCombo); updateCombos(); nppParamInst->_isFindReplacing = true; @@ -927,10 +1023,9 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (_currentStatus == FIND_DLG) { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); updateCombo(IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); int nbCounted = processAll(ProcessCountAll, &_options); generic_string result = TEXT(""); @@ -959,9 +1054,8 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM if (_currentStatus == MARK_DLG) { setStatusbarMessage(TEXT(""), FSNoMessage); - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - _options._str2Search = getTextFromCombo(hFindCombo, isUnicode); + _options._str2Search = getTextFromCombo(hFindCombo); updateCombo(IDFINDWHAT); if (isMacroRecording) saveInMacro(wParam, FR_OP_FIND); @@ -1457,7 +1551,7 @@ int FindReplaceDlg::markAllInc(const FindOption *opt) return nbFound; } -int FindReplaceDlg::processAll(ProcessOperation op, const FindOption *opt, bool isEntire, const TCHAR *fileName, int colourStyleID) +int FindReplaceDlg::processAll(ProcessOperation op, const FindOption *opt, bool isEntire, const FindersInfo *pFindersInfo, int colourStyleID) { if (op == ProcessReplaceAll && (*_ppEditView)->getCurrentBuffer()->isReadOnly()) { @@ -1514,46 +1608,46 @@ int FindReplaceDlg::processAll(ProcessOperation op, const FindOption *opt, bool endPosition = docLength; } - return processRange(op, txt2find, txt2replace, startPosition, endPosition, fileName, pOptions, colourStyleID); + FindReplaceInfo findReplaceInfo; + findReplaceInfo._txt2find = txt2find; + findReplaceInfo._txt2replace = txt2replace; + findReplaceInfo._startRange = startPosition; + findReplaceInfo._endRange = endPosition; + return processRange(op, findReplaceInfo, pFindersInfo, pOptions, colourStyleID); } -int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, const TCHAR *txt2replace, int startRange, int endRange, const TCHAR *fileName, const FindOption *opt, int colourStyleID) +int FindReplaceDlg::processRange(ProcessOperation op, FindReplaceInfo & findReplaceInfo, const FindersInfo * pFindersInfo, const FindOption *opt, int colourStyleID) { int nbProcessed = 0; - if (!isCreated() && !txt2find) + if (!isCreated() && not findReplaceInfo._txt2find) return nbProcessed; if ((op == ProcessReplaceAll) && (*_ppEditView)->getCurrentBuffer()->isReadOnly()) return nbProcessed; - if (startRange == endRange) + if (findReplaceInfo._startRange == findReplaceInfo._endRange) return nbProcessed; - if (!fileName) - fileName = TEXT(""); - const FindOption *pOptions = opt?opt:_env; - //bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; - bool isUnicode = ((*_ppEditView)->execute(SCI_GETCODEPAGE) == SC_CP_UTF8); int stringSizeFind = 0; int stringSizeReplace = 0; TCHAR *pTextFind = NULL; - if (!txt2find) + if (not findReplaceInfo._txt2find) { HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); - generic_string str2Search = getTextFromCombo(hFindCombo, isUnicode); + generic_string str2Search = getTextFromCombo(hFindCombo); stringSizeFind = str2Search.length(); pTextFind = new TCHAR[stringSizeFind + 1]; lstrcpy(pTextFind, str2Search.c_str()); } else { - stringSizeFind = lstrlen(txt2find); + stringSizeFind = lstrlen(findReplaceInfo._txt2find); pTextFind = new TCHAR[stringSizeFind + 1]; - lstrcpy(pTextFind, txt2find); + lstrcpy(pTextFind, findReplaceInfo._txt2find); } if (!pTextFind[0]) @@ -1565,23 +1659,24 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con TCHAR *pTextReplace = NULL; if (op == ProcessReplaceAll) { - if (!txt2replace) + if (not findReplaceInfo._txt2replace) { HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); - generic_string str2Replace = getTextFromCombo(hReplaceCombo, isUnicode); + generic_string str2Replace = getTextFromCombo(hReplaceCombo); stringSizeReplace = str2Replace.length(); pTextReplace = new TCHAR[stringSizeReplace + 1]; lstrcpy(pTextReplace, str2Replace.c_str()); } else { - stringSizeReplace = lstrlen(txt2replace); + stringSizeReplace = lstrlen(findReplaceInfo._txt2replace); pTextReplace = new TCHAR[stringSizeReplace + 1]; - lstrcpy(pTextReplace, txt2replace); + lstrcpy(pTextReplace, findReplaceInfo._txt2replace); } } - if (pOptions->_searchType == FindExtended) { + if (pOptions->_searchType == FindExtended) + { stringSizeFind = Searching::convertExtendedToString(pTextFind, pTextFind, stringSizeFind); if (op == ProcessReplaceAll) stringSizeReplace = Searching::convertExtendedToString(pTextReplace, pTextReplace, stringSizeReplace); @@ -1617,7 +1712,7 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con while (targetStart != -1 && targetStart != -2) { - targetStart = (*_ppEditView)->searchInTarget(pTextFind, stringSizeFind, startRange, endRange); + targetStart = (*_ppEditView)->searchInTarget(pTextFind, stringSizeFind, findReplaceInfo._startRange, findReplaceInfo._endRange); // If we've not found anything, just break out of the loop if (targetStart == -1 || targetStart == -2) @@ -1625,7 +1720,7 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND)); - if (targetEnd > endRange) { //we found a result but outside our range, therefore do not process it + if (targetEnd > findReplaceInfo._endRange) { //we found a result but outside our range, therefore do not process it break; } @@ -1637,9 +1732,13 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con { case ProcessFindAll: { + const TCHAR *pFileName = TEXT(""); + if (pFindersInfo && pFindersInfo->_pFileName) + pFileName = pFindersInfo->_pFileName; + if (!findAllFileNameAdded) //add new filetitle in hits if we haven't already { - _pFinder->addFileNameTitle(fileName); + _pFinder->addFileNameTitle(pFileName); findAllFileNameAdded = true; } @@ -1664,11 +1763,58 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con SearchResultMarking srm; srm._start = start_mark; srm._end = end_mark; - _pFinder->add(FoundInfo(targetStart, targetEnd, fileName), srm, line.c_str(), lineNumber + 1); + _pFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); break; } + case ProcessFindInFinder: + { + if (not pFindersInfo || not pFindersInfo->_pSourceFinder || not pFindersInfo->_pDestFinder) + break; + + const TCHAR *pFileName = pFindersInfo->_pFileName ? pFindersInfo->_pFileName : TEXT(""); + + if (!findAllFileNameAdded) //add new filetitle in hits if we haven't already + { + pFindersInfo->_pDestFinder->addFileNameTitle(pFileName); + findAllFileNameAdded = true; + } + + int lineNumber = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, targetStart); + int lend = (*_ppEditView)->execute(SCI_GETLINEENDPOSITION, lineNumber); + int lstart = (*_ppEditView)->execute(SCI_POSITIONFROMLINE, lineNumber); + int nbChar = lend - lstart; + + // use the static buffer + TCHAR lineBuf[1024]; + + if (nbChar > 1024 - 3) + lend = lstart + 1020; + + int start_mark = targetStart - lstart; + int end_mark = targetEnd - lstart; + + (*_ppEditView)->getGenericText(lineBuf, 1024, lstart, lend, &start_mark, &end_mark); + + generic_string line = lineBuf; + line += TEXT("\r\n"); + SearchResultMarking srm; + srm._start = start_mark; + srm._end = end_mark; + + if (pOptions->_isMatchLineNumber) + { + if (pFindersInfo->_pSourceFinder->canFind(pFileName, lineNumber + 1)) + pFindersInfo->_pDestFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); + } + else + { + pFindersInfo->_pDestFinder->add(FoundInfo(targetStart, targetEnd, lineNumber + 1, pFileName), srm, line.c_str()); + } + break; + } + case ProcessReplaceAll: { int replacedLength; @@ -1755,23 +1901,34 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con // After the processing of the last string occurence the search loop should be stopped // This helps to avoid the endless replacement during the EOL ("$") searching - if( targetStart + foundTextLen == endRange ) + if (targetStart + foundTextLen == findReplaceInfo._endRange) break; - - - startRange = targetStart + foundTextLen + replaceDelta; //search from result onwards - endRange += replaceDelta; //adjust end of range in case of replace - - } - + findReplaceInfo._startRange = targetStart + foundTextLen + replaceDelta; //search from result onwards + findReplaceInfo._endRange += replaceDelta; //adjust end of range in case of replace + } delete [] pTextFind; delete [] pTextReplace; - if (nbProcessed > 0 && op == ProcessFindAll) - _pFinder->addFileHitCount(nbProcessed); + if (nbProcessed > 0) + { + Finder *pFinder = nullptr; + if (op == ProcessFindAll) + { + pFinder = _pFinder; + } + else if (op == ProcessFindInFinder) + { + if (pFindersInfo && pFindersInfo->_pDestFinder) + pFinder = pFindersInfo->_pDestFinder; + else + pFinder = _pFinder; + } + if (pFinder != nullptr) + pFinder->addFileHitCount(nbProcessed); + } return nbProcessed; } @@ -1787,6 +1944,7 @@ void FindReplaceDlg::findAllIn(InWhat op) { _pFinder = new Finder(); _pFinder->init(_hInst, _hSelf, _ppEditView); + _pFinder->setVolatiled(false); tTbData data = {0}; _pFinder->create(&data, false); @@ -1873,6 +2031,106 @@ void FindReplaceDlg::findAllIn(InWhat op) ::SendMessage(_hSelf, WM_NEXTDLGCTL, (WPARAM)::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO), TRUE); } +Finder * FindReplaceDlg::createFinder() +{ + Finder *pFinder = new Finder(); + + pFinder->init(_hInst, _hSelf, _ppEditView); + + tTbData data = { 0 }; + pFinder->create(&data, false); + ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, (WPARAM)pFinder->getHSelf()); + // define the default docking behaviour + data.uMask = DWS_DF_CONT_BOTTOM | DWS_ICONTAB | DWS_ADDINFO; + data.hIconTab = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_FIND_RESULT_ICON), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT); + data.pszAddInfo = _findAllResultStr; + + data.pszModuleName = TEXT("dummy"); + + // the dlgDlg should be the index of funcItem where the current function pointer is + // in this case is DOCKABLE_DEMO_INDEX + data.dlgID = 0; + ::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data); + + pFinder->_scintView.init(_hInst, pFinder->getHSelf()); + + // Subclass the ScintillaEditView for the Finder (Scintilla doesn't notify all key presses) + originalFinderProc = SetWindowLongPtr(pFinder->_scintView.getHSelf(), GWLP_WNDPROC, (LONG_PTR)finderProc); + + pFinder->setFinderReadOnly(true); + pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8); + pFinder->_scintView.execute(SCI_USEPOPUP, FALSE); + pFinder->_scintView.execute(SCI_SETUNDOCOLLECTION, false); //dont store any undo information + pFinder->_scintView.execute(SCI_SETCARETLINEVISIBLE, 1); + pFinder->_scintView.execute(SCI_SETCARETWIDTH, 0); + pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true); + + // get the width of FindDlg + RECT findRect; + ::GetWindowRect(pFinder->getHSelf(), &findRect); + + // overwrite some default settings + pFinder->_scintView.showMargin(ScintillaEditView::_SC_MARGE_SYBOLE, false); + pFinder->_scintView.setMakerStyle(FOLDER_STYLE_SIMPLE); + + pFinder->_scintView.display(); + pFinder->display(); + //::SendMessage(_hParent, NPPM_DMMHIDE, 0, (LPARAM)pFinder->getHSelf()); + ::UpdateWindow(_hParent); + //justCreated = true; + + pFinder->setFinderStyle(); + + // Send the address of _MarkingsStruct to the lexer + char ptrword[sizeof(void*) * 2 + 1]; + sprintf(ptrword, "%p", &pFinder->_MarkingsStruct); + pFinder->_scintView.execute(SCI_SETPROPERTY, (WPARAM)"@MarkingsStruct", (LPARAM)ptrword); + + _findersOfFinder.push_back(pFinder); + + ::SendMessage(pFinder->getHSelf(), WM_SIZE, 0, 0); + + // Show finder + ::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)pFinder->getHSelf()); + pFinder->_scintView.getFocus(); + + return pFinder; + + /* + { + if (_findAllResult == 1) + wsprintf(_findAllResultStr, TEXT("1 hit")); + else + wsprintf(_findAllResultStr, TEXT("%d hits"), _findAllResult); + if (_findAllResult) + { + focusOnFinder(); + } + else + { + // Show finder + ::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)pFinder->getHSelf()); + getFocus(); // no hits + } + } + else // error - search folder doesn't exist + ::SendMessage(_hSelf, WM_NEXTDLGCTL, (WPARAM)::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO), TRUE); + */ +} + +bool FindReplaceDlg::removeFinder(Finder *finder2remove) +{ + for (vector::iterator i = _findersOfFinder.begin(); i != _findersOfFinder.end(); ++i) + { + if (*i == finder2remove) + { + delete finder2remove; + _findersOfFinder.erase(i); + return true; + } + } + return false; +} void FindReplaceDlg::setSearchText(TCHAR * txt2find) { HWND hCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); @@ -2245,6 +2503,22 @@ void FindReplaceDlg::initOptionsFromDlg() _options._isInHiddenDir = isCheckedOrNot(IDD_FINDINFILES_INHIDDENDIR_CHECK); } +void FindInFinderDlg::doDialog(Finder *launcher, bool isRTL) +{ + _pFinder2Search = launcher; + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_FINDINFINDER_DLG, &pMyDlgTemplate); + ::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, (LPARAM)this); + ::GlobalFree(hMyDlgTemplate); + } + else + ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_FINDINFINDER_DLG), _hParent, dlgProc, (LPARAM)this); + +} + + void FindReplaceDlg::doDialog(DIALOG_TYPE whichType, bool isRTL, bool toShow) { if (!isCreated()) @@ -2441,33 +2715,34 @@ void Finder::addFileHitCount(int count) setFinderReadOnly(false); _scintView.insertGenericTextFrom(_lastFileHeaderPos, text); setFinderReadOnly(true); - ++nFoundFiles; + ++_nbFoundFiles; } -void Finder::addSearchHitCount(int count) +void Finder::addSearchHitCount(int count, bool isMatchLines) { - TCHAR text[50]; - if(count == 1 && nFoundFiles == 1) - wsprintf(text, TEXT(" (1 hit in 1 file)")); - else if(count == 1 && nFoundFiles != 1) - wsprintf(text, TEXT(" (1 hit in %i files)"), nFoundFiles); - else if(count != 1 && nFoundFiles == 1) - wsprintf(text, TEXT(" (%i hits in 1 file)"), count); - else if(count != 1 && nFoundFiles != 1) - wsprintf(text, TEXT(" (%i hits in %i files)"), count, nFoundFiles); + TCHAR *moreInfo = isMatchLines ? TEXT(" - Line Filter Mode: only display the filtered results") :TEXT(""); + TCHAR text[100]; + if(count == 1 && _nbFoundFiles == 1) + wsprintf(text, TEXT(" (1 hit in 1 file%s)"), moreInfo); + else if(count == 1 && _nbFoundFiles != 1) + wsprintf(text, TEXT(" (1 hit in %i files%s)"), _nbFoundFiles, moreInfo); + else if(count != 1 && _nbFoundFiles == 1) + wsprintf(text, TEXT(" (%i hits in 1 file%s)"), count, moreInfo); + else if(count != 1 && _nbFoundFiles != 1) + wsprintf(text, TEXT(" (%i hits in %i files%s)"), count, _nbFoundFiles, moreInfo); setFinderReadOnly(false); _scintView.insertGenericTextFrom(_lastSearchHeaderPos, text); setFinderReadOnly(true); } -void Finder::add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline, int lineNb) +void Finder::add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline) { _pMainFoundInfos->push_back(fi); generic_string str = TEXT("\tLine "); TCHAR lnb[16]; - wsprintf(lnb, TEXT("%d"), lineNb); + wsprintf(lnb, TEXT("%d"), fi._lineNumber); str += lnb; str += TEXT(": "); mi._start += str.length(); @@ -2583,13 +2858,13 @@ void Finder::beginNewFilesSearch() _scintView.execute(SCI_SETCURRENTPOS, 0); _pMainFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1; _pMainMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1; - nFoundFiles = 0; + _nbFoundFiles = 0; // fold all old searches (1st level only) _scintView.collapse(searchHeaderLevel - SC_FOLDLEVELBASE, fold_collapse); } -void Finder::finishFilesSearch(int count) +void Finder::finishFilesSearch(int count, bool isMatchLines) { std::vector* _pOldFoundInfos; std::vector* _pOldMarkings; @@ -2604,9 +2879,10 @@ void Finder::finishFilesSearch(int count) _pMainMarkings = _pOldMarkings; _MarkingsStruct._length = _pMainMarkings->size(); - _MarkingsStruct._markings = &((*_pMainMarkings)[0]); + if (_pMainMarkings->size() > 0) + _MarkingsStruct._markings = &((*_pMainMarkings)[0]); - addSearchHitCount(count); + addSearchHitCount(count, isMatchLines); _scintView.execute(SCI_SETSEL, 0, 0); _scintView.execute(SCI_SETLEXER, SCLEX_SEARCHRESULT); @@ -2674,6 +2950,24 @@ INT_PTR CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (wParam) { + case NPPM_INTERNAL_FINDINFINDERDLG: + { + ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_FINDINFINDERDLG, (WPARAM)this, 0); + return TRUE; + } + + case NPPM_INTERNAL_REMOVEFINDER: + { + if (_canBeVolatiled) + { + ::SendMessage(::GetParent(_hParent), NPPM_DMMHIDE, 0, (LPARAM)_hSelf); + setClosed(true); + + //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_REMOVEFINDER, (WPARAM)this, 0); + } + return TRUE; + } + case NPPM_INTERNAL_SCINTILLAFINFERCOLLAPSE : { _scintView.foldAll(fold_collapse); @@ -2725,6 +3019,10 @@ INT_PTR CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) ::GetCursorPos(&p); ContextMenu scintillaContextmenu; vector tmp; + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_FINDINFINDERDLG, TEXT("Find in this finder..."))); + if (_canBeVolatiled) + tmp.push_back(MenuItemUnit(NPPM_INTERNAL_REMOVEFINDER, TEXT("Close this finder"))); + tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOLLAPSE, TEXT("Collapse all"))); tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE, TEXT("Uncollapse all"))); tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); @@ -2881,8 +3179,7 @@ INT_PTR CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR 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); + generic_string str2Search = getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT)); if (updateSearch) { FindStatus findStatus = FSFound; diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h index b4f3f24a..a023928c 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h @@ -59,10 +59,11 @@ enum DIALOG_TYPE {FIND_DLG, REPLACE_DLG, FINDINFILES_DLG, MARK_DLG}; enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR, CURRENT_DOC}; struct FoundInfo { - FoundInfo(int start, int end, const TCHAR *fullPath) - : _start(start), _end(end), _fullPath(fullPath) {}; + FoundInfo(int start, int end, size_t lineNumber, const TCHAR *fullPath) + : _start(start), _end(end), _lineNumber(lineNumber), _fullPath(fullPath) {}; int _start; int _end; + size_t _lineNumber; generic_string _fullPath; }; @@ -73,32 +74,27 @@ struct TargetRange { enum SearchIncrementalType { NotIncremental, FirstIncremental, NextIncremental }; enum SearchType { FindNormal, FindExtended, FindRegex }; -enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt }; +enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt, ProcessFindInFinder }; struct FindOption { - bool _isWholeWord; - bool _isMatchCase; - bool _isWrapAround; - bool _whichDirection; - SearchIncrementalType _incrementalType; - SearchType _searchType; - bool _doPurge; - bool _doMarkLine; - bool _isInSelection; + bool _isWholeWord = true; + bool _isMatchCase = true; + bool _isWrapAround = true; + bool _whichDirection = DIR_DOWN; + SearchIncrementalType _incrementalType = NotIncremental; + SearchType _searchType = FindNormal; + bool _doPurge = false; + bool _doMarkLine = false; + bool _isInSelection = false; generic_string _str2Search; generic_string _str4Replace; generic_string _filters; generic_string _directory; - bool _isRecursive; - bool _isInHiddenDir; - bool _dotMatchesNewline; - FindOption() : _isWholeWord(true), _isMatchCase(true), _searchType(FindNormal),\ - _isWrapAround(true), _whichDirection(DIR_DOWN), _incrementalType(NotIncremental), - _doPurge(false), _doMarkLine(false), - _isInSelection(false), _isRecursive(true), _isInHiddenDir(false), - _dotMatchesNewline(false), - _filters(TEXT("")), _directory(TEXT("")) {}; + bool _isRecursive = true; + bool _isInHiddenDir = false; + bool _dotMatchesNewline = false; + bool _isMatchLineNumber = true; // only for Find in Folder }; //This class contains generic search functions as static functions for easy access @@ -139,17 +135,20 @@ public: void addSearchLine(const TCHAR *searchName); void addFileNameTitle(const TCHAR * fileName); void addFileHitCount(int count); - void addSearchHitCount(int count); - void add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline, int lineNb); + void addSearchHitCount(int count, bool isMatchLines = false); + void add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline); void setFinderStyle(); void removeAll(); void openAll(); void copy(); void beginNewFilesSearch(); - void finishFilesSearch(int count); + void finishFilesSearch(int count, bool isMatchLines = false); void gotoNextFoundResult(int direction); void GotoFoundLine(); void DeleteResult(); + std::vector getResultFilePaths() const; + bool canFind(const TCHAR *fileName, size_t lineNumber) const; + void setVolatiled(bool val) { _canBeVolatiled = val; }; protected : virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); @@ -169,11 +168,14 @@ private: SearchResultMarkings _MarkingsStruct; ScintillaEditView _scintView; - unsigned int nFoundFiles; + unsigned int _nbFoundFiles = 0; int _lastFileHeaderPos; int _lastSearchHeaderPos; + bool _canBeVolatiled = true; + + void setFinderReadOnly(bool isReadOnly) { _scintView.execute(SCI_SETREADONLY, isReadOnly); }; @@ -194,6 +196,40 @@ enum FindNextType { FINDNEXTTYPE_FINDNEXTFORREPLACE }; +struct FindReplaceInfo +{ + const TCHAR *_txt2find = nullptr; + const TCHAR *_txt2replace = nullptr; + int _startRange = -1; + int _endRange = -1; +}; + +struct FindersInfo +{ + Finder *_pSourceFinder = nullptr; + Finder *_pDestFinder = nullptr; + const TCHAR *_pFileName = nullptr; + + FindOption _findOption; +}; + +class FindInFinderDlg : public StaticDialog +{ +public: + void init(HINSTANCE hInst, HWND hPere) { + Window::init(hInst, hPere); + }; + void doDialog(Finder *launcher, bool isRTL = false); + FindOption & getOption() { return _options; } + +private: + Finder *_pFinder2Search = nullptr; + FindOption _options; + + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + void initFromOptions(); + void writeOptions(); +}; class FindReplaceDlg : public StaticDialog { @@ -225,13 +261,12 @@ public : bool processReplace(const TCHAR *txt2find, const TCHAR *txt2replace, const FindOption *options = NULL); int markAll(const TCHAR *txt2find, int styleID, bool isWholeWordSelected); - //int markAll2(const TCHAR *str2find); int markAllInc(const FindOption *opt); - int processAll(ProcessOperation op, const FindOption *opt, bool isEntire = false, const TCHAR *fileName = NULL, int colourStyleID = -1); -// int processAll(ProcessOperation op, const TCHAR *txt2find, const TCHAR *txt2replace, bool isEntire = false, const TCHAR *fileName = NULL, const FindOption *opt = NULL, int colourStyleID = -1); - int processRange(ProcessOperation op, const TCHAR *txt2find, const TCHAR *txt2replace, int startRange, int endRange, const TCHAR *fileName = NULL, const FindOption *opt = NULL, int colourStyleID = -1); + int processAll(ProcessOperation op, const FindOption *opt, bool isEntire = false, const FindersInfo *pFindersInfo = nullptr, int colourStyleID = -1); + int processRange(ProcessOperation op, FindReplaceInfo & findReplaceInfo, const FindersInfo *pFindersInfo, const FindOption *opt = NULL, int colourStyleID = -1); + void replaceAllInOpenedDocs(); void findAllIn(InWhat op); void setSearchText(TCHAR * txt2find); @@ -302,12 +337,11 @@ public : void execSavedCommand(int cmd, int intValue, generic_string stringValue); void setStatusbarMessage(const generic_string & msg, FindStatus staus); - + Finder * createFinder(); + bool removeFinder(Finder *finder2remove); protected : virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); - void addText2Combo(const TCHAR * txt2add, HWND comboID, bool isUTF8 = false); - generic_string getTextFromCombo(HWND hCombo, bool isUnicode = false) const; static LONG_PTR originalFinderProc; // Window procedure for the finder @@ -322,6 +356,10 @@ private : ScintillaEditView **_ppEditView; Finder *_pFinder; + + std::vector _findersOfFinder; + + bool _isRTL; int _findAllResult; @@ -358,11 +396,7 @@ private : } void updateCombos(); - void updateCombo(int comboID) { - bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit; - HWND hCombo = ::GetDlgItem(_hSelf, comboID); - addText2Combo(getTextFromCombo(hCombo, isUnicode).c_str(), hCombo, isUnicode); - }; + void updateCombo(int comboID); void fillFindHistory(); void fillComboHistory(int id, const std::vector & strings); int saveComboHistory(int id, int maxcount, std::vector & strings); diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc index 7eaa2446..351353ae 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc @@ -91,7 +91,6 @@ IDB_INCREMENTAL_BG BITMAP "../icons/incrementalBg.bmp" IDD_INCREMENT_FIND DIALOGEX 0, 0, 400, 20 STYLE DS_SYSMODAL | DS_CONTROL | DS_FIXEDSYS | WS_CHILD | WS_CLIPCHILDREN -//EXSTYLE WS_EX_TRANSPARENT FONT 8, TEXT("MS Shell Dlg") BEGIN PUSHBUTTON "X",IDCANCEL,2,3,16,14 @@ -113,4 +112,25 @@ BEGIN DEFPUSHBUTTON ">",IDC_INCFINDNXTOK,243,0,16,14, NOT WS_VISIBLE END +IDD_FINDINFINDER_DLG DIALOGEX 36, 44, 367, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Find in finder" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + RTEXT "&Find what :",IDFINDWHAT_STATIC_FIFOLDER,6,22,75,8 + COMBOBOX IDFINDWHAT_FIFOLDER,83,20,178,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + CONTROL "Search only in found lines",IDC_MATCHLINENUM_CHECK_FIFOLDER,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,66,99,16 + CONTROL "Match &whole word only",IDWHOLEWORD_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,88,140,15 + CONTROL "Match &case",IDMATCHCASE_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,100,140,15 + + GROUPBOX "Search Mode",IDC_MODE_STATIC_FIFOLDER,6,131,159,48 + CONTROL "&Normal",IDNORMAL_FIFOLDER,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,143,126,10 + CONTROL "E&xtended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED_FIFOLDER, "Button",BS_AUTORADIOBUTTON,12,155,145,10 + CONTROL "Re&gular expression",IDREGEXP_FIFOLDER,"Button",BS_AUTORADIOBUTTON,12,167,78,10 + CONTROL "&. matches newline",IDREDOTMATCHNL_FIFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,167,67,9 + PUSHBUTTON "Find all",IDOK,268,20,90,14,WS_GROUP + PUSHBUTTON "Close",IDCANCEL,268,38,90,14 +END + #endif //FIND_REPLACE_DLG_RC diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h index 6c7f3474..b8e11daf 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h @@ -122,4 +122,17 @@ #define IDREDOTMATCHNL 1703 #define IDF_REDOTMATCHNL 1024 + +#define IDD_FINDINFINDER_DLG 1710 +#define IDFINDWHAT_STATIC_FIFOLDER 1711 +#define IDFINDWHAT_FIFOLDER 1712 +#define IDC_MATCHLINENUM_CHECK_FIFOLDER 1713 +#define IDWHOLEWORD_FIFOLDER 1714 +#define IDMATCHCASE_FIFOLDER 1715 +#define IDC_MODE_STATIC_FIFOLDER 1716 +#define IDNORMAL_FIFOLDER 1717 +#define IDEXTENDED_FIFOLDER 1718 +#define IDREGEXP_FIFOLDER 1719 +#define IDREDOTMATCHNL_FIFOLDER 1720 + #endif //FINDREPLACE_DLG_H diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 55498de5..7e930a25 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -88,17 +88,18 @@ typedef void * SCINTILLA_PTR; #define WM_DOCK_USERDEFINE_DLG (SCINTILLA_USER + 1) #define WM_UNDOCK_USERDEFINE_DLG (SCINTILLA_USER + 2) -#define WM_CLOSE_USERDEFINE_DLG (SCINTILLA_USER + 3) -#define WM_REMOVE_USERLANG (SCINTILLA_USER + 4) -#define WM_RENAME_USERLANG (SCINTILLA_USER + 5) -#define WM_REPLACEALL_INOPENEDDOC (SCINTILLA_USER + 6) -#define WM_FINDALL_INOPENEDDOC (SCINTILLA_USER + 7) -#define WM_DOOPEN (SCINTILLA_USER + 8) -#define WM_FINDINFILES (SCINTILLA_USER + 9) -#define WM_REPLACEINFILES (SCINTILLA_USER + 10) -#define WM_FINDALL_INCURRENTDOC (SCINTILLA_USER + 11) -#define WM_FRSAVE_INT (SCINTILLA_USER + 12) -#define WM_FRSAVE_STR (SCINTILLA_USER + 13) +#define WM_CLOSE_USERDEFINE_DLG (SCINTILLA_USER + 3) +#define WM_REMOVE_USERLANG (SCINTILLA_USER + 4) +#define WM_RENAME_USERLANG (SCINTILLA_USER + 5) +#define WM_REPLACEALL_INOPENEDDOC (SCINTILLA_USER + 6) +#define WM_FINDALL_INOPENEDDOC (SCINTILLA_USER + 7) +#define WM_DOOPEN (SCINTILLA_USER + 8) +#define WM_FINDINFILES (SCINTILLA_USER + 9) +#define WM_REPLACEINFILES (SCINTILLA_USER + 10) +#define WM_FINDALL_INCURRENTDOC (SCINTILLA_USER + 11) +#define WM_FRSAVE_INT (SCINTILLA_USER + 12) +#define WM_FRSAVE_STR (SCINTILLA_USER + 13) +#define WM_FINDALL_INCURRENTFINDER (SCINTILLA_USER + 14) const int NB_FOLDER_STATE = 7; @@ -229,6 +230,7 @@ public: } } }; + virtual void destroy() { ::DestroyWindow(_hSelf); diff --git a/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp b/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp index c91f1841..db77d205 100644 --- a/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp +++ b/PowerEditor/src/ScitillaComponent/SmartHighlighter.cpp @@ -122,12 +122,19 @@ void SmartHighlighter::highlightView(ScintillaEditView * pHighlightView) prevDocLineChecked = docLine; startPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, docLine); endPos = (int)pHighlightView->execute(SCI_POSITIONFROMLINE, docLine+1); - if (endPos == -1) { //past EOF - endPos = (int)pHighlightView->getCurrentDocLen() - 1; - _pFRDlg->processRange(ProcessMarkAll_2, searchText, NULL, startPos, endPos, NULL, &fo); + FindReplaceInfo frInfo; + frInfo._txt2find = searchText; + frInfo._startRange = startPos; + frInfo._endRange = endPos; + if (endPos == -1) + { //past EOF + frInfo._endRange = (int)pHighlightView->getCurrentDocLen() - 1; + _pFRDlg->processRange(ProcessMarkAll_2, frInfo, NULL, &fo); break; - } else { - _pFRDlg->processRange(ProcessMarkAll_2, searchText, NULL, startPos, endPos, NULL, &fo); + } + else + { + _pFRDlg->processRange(ProcessMarkAll_2, frInfo, NULL, &fo); } } diff --git a/PowerEditor/src/WinControls/Window.h b/PowerEditor/src/WinControls/Window.h index 17f5b0ff..dbc105f7 100644 --- a/PowerEditor/src/WinControls/Window.h +++ b/PowerEditor/src/WinControls/Window.h @@ -110,7 +110,6 @@ public: HWND getHSelf() const { - //assert(_hSelf != 0); return _hSelf; } diff --git a/PowerEditor/src/resource.h b/PowerEditor/src/resource.h index b7c40344..fe133658 100644 --- a/PowerEditor/src/resource.h +++ b/PowerEditor/src/resource.h @@ -401,6 +401,8 @@ #define NPPM_INTERNAL_GETSCINTEDTVIEW (NOTEPADPLUS_USER_INTERNAL + 37) #define NPPM_INTERNAL_ENABLESNAPSHOT (NOTEPADPLUS_USER_INTERNAL + 38) #define NPPM_INTERNAL_SAVECURRENTSESSION (NOTEPADPLUS_USER_INTERNAL + 39) + #define NPPM_INTERNAL_FINDINFINDERDLG (NOTEPADPLUS_USER_INTERNAL + 40) + #define NPPM_INTERNAL_REMOVEFINDER (NOTEPADPLUS_USER_INTERNAL + 41) //wParam: 0