[NEW_FEATURE] Enhance "Find in all opened files" and "Find in files" features.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository@410 f5eea248-9336-0410-98b8-ebc06183d4e3
pull/343/head^2
donho 2009-02-04 01:06:38 +00:00
parent 7d2eb78375
commit 7705e0b571
15 changed files with 503 additions and 344 deletions

View File

@ -268,6 +268,38 @@ const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT c
return _wideCharStr; return _wideCharStr;
} }
// "mstart" and "mend" are pointers to indexes in mbcs2Convert,
// which are converted to the corresponding indexes in the returned wchar_t string.
const wchar_t * WcharMbcsConvertor::char2wchar(const char * mbcs2Convert, UINT codepage, int *mstart, int *mend)
{
if (!_wideCharStr)
{
_wideCharStr = new wchar_t[initSize];
_wideCharAllocLen = initSize;
}
int len = MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, _wideCharStr, 0);
if (len > 0)
{
if (len > int(_wideCharAllocLen))
{
delete [] _wideCharStr;
_wideCharAllocLen = len;
_wideCharStr = new wchar_t[_wideCharAllocLen];
}
MultiByteToWideChar(codepage, 0, mbcs2Convert, -1, _wideCharStr, len);
*mstart = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mstart, _wideCharStr, 0);
*mend = MultiByteToWideChar(codepage, 0, mbcs2Convert, *mend, _wideCharStr, 0);
}
else
{
_wideCharStr[0] = 0;
*mstart = 0;
*mend = 0;
}
return _wideCharStr;
}
const char * WcharMbcsConvertor::wchar2char(const wchar_t * wcharStr2Convert, UINT codepage) const char * WcharMbcsConvertor::wchar2char(const wchar_t * wcharStr2Convert, UINT codepage)
{ {
if (!_multiByteStr) if (!_multiByteStr)

View File

@ -107,6 +107,7 @@ public:
static void destroyInstance() {delete _pSelf;}; static void destroyInstance() {delete _pSelf;};
const wchar_t * char2wchar(const char* mbStr, UINT codepage); const wchar_t * char2wchar(const char* mbStr, UINT codepage);
const wchar_t * char2wchar(const char * mbcs2Convert, UINT codepage, int *mstart, int *mend);
const char * wchar2char(const wchar_t* wcStr, UINT codepage); const char * wchar2char(const wchar_t* wcStr, UINT codepage);
protected: protected:

View File

@ -1426,9 +1426,9 @@ bool Notepad_plus::replaceAllFiles() {
if (nbTotal < 0) if (nbTotal < 0)
lstrcpy(result, TEXT("The regular expression to search is formed badly")); lstrcpy(result, TEXT("The regular expression to search is formed badly"));
else else
wsprintf(result, TEXT("%d occurrences were replaced."), nbTotal); wsprintf(result, TEXT("%d occurrences replaced."), nbTotal);
::MessageBox(_hSelf, result, TEXT(""), MB_OK); ::printStr(result);
return true; return true;
} }
@ -1570,6 +1570,12 @@ DWORD WINAPI AsyncCancelFindInFiles(LPVOID NppHWND)
bool Notepad_plus::replaceInFiles() bool Notepad_plus::replaceInFiles()
{ {
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
if (!dir2Search[0] || !::PathFileExists(dir2Search))
{
return false;
}
bool isRecursive = _findReplaceDlg.isRecursive(); bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir(); bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0; int nbTotal = 0;
@ -1577,15 +1583,9 @@ bool Notepad_plus::replaceInFiles()
ScintillaEditView *pOldView = _pEditView; ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView; _pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
Buffer * oldBuf = _invisibleEditView.getCurrentBuffer(); //for manually setting the buffer, so notifications can be handled properly
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); Buffer * pBuf = NULL;
HANDLE CancelThreadHandle = NULL;
if (!dir2Search[0] || !::PathFileExists(dir2Search))
{
return false;
}
HANDLE CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
vector<generic_string> patterns2Match; vector<generic_string> patterns2Match;
if (_findReplaceDlg.getFilters() == TEXT("")) if (_findReplaceDlg.getFilters() == TEXT(""))
@ -1595,6 +1595,9 @@ bool Notepad_plus::replaceInFiles()
getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir);
if (fileNames.size() > 1)
CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
bool dontClose = false; bool dontClose = false;
for (size_t i = 0 ; i < fileNames.size() ; i++) for (size_t i = 0 ; i < fileNames.size() ; i++)
{ {
@ -1617,6 +1620,7 @@ bool Notepad_plus::replaceInFiles()
Buffer * pBuf = MainFileManager->getBufferByID(id); Buffer * pBuf = MainFileManager->getBufferByID(id);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument());
_invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8);
_invisibleEditView._currentBuffer = pBuf;
int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, NULL, NULL, true, fileNames.at(i).c_str()); int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, NULL, NULL, true, fileNames.at(i).c_str());
nbTotal += nbReplaced; nbTotal += nbReplaced;
@ -1630,9 +1634,11 @@ bool Notepad_plus::replaceInFiles()
} }
} }
if (CancelThreadHandle)
TerminateThread(CancelThreadHandle, 0); TerminateThread(CancelThreadHandle, 0);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_invisibleEditView._currentBuffer = oldBuf;
_pEditView = pOldView; _pEditView = pOldView;
TCHAR msg[128]; TCHAR msg[128];
@ -1644,17 +1650,6 @@ bool Notepad_plus::replaceInFiles()
bool Notepad_plus::findInFiles() bool Notepad_plus::findInFiles()
{ {
bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0;
ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
if (!_findReplaceDlg.isFinderEmpty())
_findReplaceDlg.clearFinder();
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
if (!dir2Search[0] || !::PathFileExists(dir2Search)) if (!dir2Search[0] || !::PathFileExists(dir2Search))
@ -1662,7 +1657,13 @@ bool Notepad_plus::findInFiles()
return false; return false;
} }
HANDLE CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL); bool isRecursive = _findReplaceDlg.isRecursive();
bool isInHiddenDir = _findReplaceDlg.isInHiddenDir();
int nbTotal = 0;
ScintillaEditView *pOldView = _pEditView;
_pEditView = &_invisibleEditView;
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
HANDLE CancelThreadHandle = NULL;
vector<generic_string> patterns2Match; vector<generic_string> patterns2Match;
if (_findReplaceDlg.getFilters() == TEXT("")) if (_findReplaceDlg.getFilters() == TEXT(""))
@ -1670,15 +1671,12 @@ bool Notepad_plus::findInFiles()
_findReplaceDlg.getPatterns(patterns2Match); _findReplaceDlg.getPatterns(patterns2Match);
vector<generic_string> fileNames; vector<generic_string> fileNames;
_findReplaceDlg.putFindResultStr(TEXT("Scanning files to search..."));
_findReplaceDlg.refresh();
getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir);
TCHAR msg[128]; if (fileNames.size() > 1)
wsprintf(msg, TEXT("Found %d matching files"), fileNames.size()); CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL);
_findReplaceDlg.putFindResultStr((const TCHAR*)msg);
_findReplaceDlg.refresh(); _findReplaceDlg.beginNewFilesSearch();
bool dontClose = false; bool dontClose = false;
for (size_t i = 0 ; i < fileNames.size() ; i++) for (size_t i = 0 ; i < fileNames.size() ; i++)
@ -1703,25 +1701,22 @@ bool Notepad_plus::findInFiles()
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument());
_invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8); _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8);
generic_string str = TEXT("File: ");
str += fileNames.at(i);
_findReplaceDlg.putFindResultStr(str.c_str());
nbTotal += _findReplaceDlg.processAll(ProcessFindAll, NULL, NULL, true, fileNames.at(i).c_str()); nbTotal += _findReplaceDlg.processAll(ProcessFindAll, NULL, NULL, true, fileNames.at(i).c_str());
if (!dontClose) if (!dontClose)
MainFileManager->closeBuffer(id, _pEditView); MainFileManager->closeBuffer(id, _pEditView);
} }
} }
if (CancelThreadHandle)
TerminateThread(CancelThreadHandle, 0); TerminateThread(CancelThreadHandle, 0);
_findReplaceDlg.finishFilesSearch(nbTotal);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_pEditView = pOldView; _pEditView = pOldView;
wsprintf(msg, TEXT("%d hits"), nbTotal); _findReplaceDlg.putFindResult(nbTotal);
_findReplaceDlg.putFindResultStr((const TCHAR *)&msg); if (nbTotal) _findReplaceDlg.display(false);
_findReplaceDlg.refresh();
return true; return true;
} }
@ -1737,10 +1732,7 @@ bool Notepad_plus::findInOpenedFiles()
const bool isEntireDoc = true; const bool isEntireDoc = true;
if (!_findReplaceDlg.isFinderEmpty()) _findReplaceDlg.beginNewFilesSearch();
_findReplaceDlg.clearFinder();
_findReplaceDlg.setSearchWord2Finder();
if (_mainWindowStatus & WindowMainActive) if (_mainWindowStatus & WindowMainActive)
{ {
@ -1764,10 +1756,13 @@ bool Notepad_plus::findInOpenedFiles()
} }
} }
_findReplaceDlg.finishFilesSearch(nbTotal);
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
_pEditView = pOldView; _pEditView = pOldView;
_findReplaceDlg.putFindResult(nbTotal); _findReplaceDlg.putFindResult(nbTotal);
if (nbTotal) _findReplaceDlg.display(false);
return true; return true;
} }
@ -7079,8 +7074,7 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
case WM_FINDINFILES : case WM_FINDINFILES :
{ {
findInFiles(); return findInFiles();
return TRUE;
} }
case WM_REPLACEINFILES : case WM_REPLACEINFILES :

View File

@ -318,7 +318,7 @@ BEGIN
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Go to another view", IDM_VIEW_GOTO_ANOTHER_VIEW MENUITEM "Go to another view", IDM_VIEW_GOTO_ANOTHER_VIEW
MENUITEM "Clone to another view", IDM_VIEW_CLONE_TO_ANOTHER_VIEW MENUITEM "Clone to another view", IDM_VIEW_CLONE_TO_ANOTHER_VIEW
MENUITEM "Focus on other view", IDM_VIEW_SWITCHTO_OTHER_VIEW // working, but no need in menu MENUITEM "Focus on other view", IDM_VIEW_SWITCHTO_OTHER_VIEW
MENUITEM "Go to new instance", IDM_VIEW_GOTO_NEW_INSTANCE MENUITEM "Go to new instance", IDM_VIEW_GOTO_NEW_INSTANCE
MENUITEM "Open in new instance", IDM_VIEW_LOAD_IN_NEW_INSTANCE MENUITEM "Open in new instance", IDM_VIEW_LOAD_IN_NEW_INSTANCE
MENUITEM SEPARATOR MENUITEM SEPARATOR

View File

@ -147,6 +147,8 @@ void Searching::displaySectionCentered(int posStart, int posEnd, ScintillaEditVi
pEditView->execute(SCI_SETANCHOR, posStart); pEditView->execute(SCI_SETANCHOR, posStart);
} }
LONG FindReplaceDlg::originalFinderProc = NULL;
void FindReplaceDlg::addText2Combo(const TCHAR * txt2add, HWND hCombo, bool isUTF8) void FindReplaceDlg::addText2Combo(const TCHAR * txt2add, HWND hCombo, bool isUTF8)
{ {
if (!hCombo) return; if (!hCombo) return;
@ -378,87 +380,154 @@ void FindReplaceDlg::updateCombos()
updateCombo(IDFINDWHAT); updateCombo(IDFINDWHAT);
} }
FoundInfo Finder::EmptyFoundInfo(0, 0, TEXT(""));
SearchResultMarking Finder::EmptySearchResultMarking;
bool Finder::notify(SCNotification *notification) bool Finder::notify(SCNotification *notification)
{ {
switch (notification->nmhdr.code) switch (notification->nmhdr.code)
{ {
case SCN_MARGINCLICK: case SCN_MARGINCLICK:
{
if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER) if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER)
{ {
_scintView.marginClick(notification->position, notification->modifiers); _scintView.marginClick(notification->position, notification->modifiers);
} }
break; break;
}
case SCN_DOUBLECLICK : case SCN_DOUBLECLICK:
{ // remove selection from the finder
try { int pos = notification->position;
if (pos == INVALID_POSITION)
pos = _scintView.execute(SCI_GETLINEENDPOSITION, notification->line);
_scintView.execute(SCI_SETSEL, pos, pos);
GotoFoundLine();
break;
}
return false;
}
void Finder::GotoFoundLine()
{
int currentPos = _scintView.execute(SCI_GETCURRENTPOS); int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
if (currentPos)
{
TCHAR prevChar = (TCHAR)_scintView.execute(SCI_GETCHARAT, currentPos - 1);
if (prevChar == 0x0A)
currentPos -= 2;
}
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos); int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno); int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno); int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno);
if (start + 2 >= end) return; // avoid empty lines
if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG)
{ {
_scintView.execute(SCI_TOGGLEFOLD, lno); _scintView.execute(SCI_TOGGLEFOLD, lno);
_scintView.execute(SCI_SETCURRENTPOS, start); return;
_scintView.execute(SCI_SETANCHOR, start);
return false;
} }
// in getInfo() method the previous line is renew as current for next call const FoundInfo fInfo = *(_pMainFoundInfos->begin() + lno);
const FoundInfo &fInfo = getInfo(lno);
int markedLine = getCurrentMarkedLine(); // Switch to another document
::SendMessage(::GetParent(_hParent), WM_DOOPEN, 0, (LPARAM)fInfo._fullPath.c_str());
// now we clean the previous mark
if (markedLine != -1)
(*_ppEditView)->execute(SCI_MARKERDELETE, markedLine, MARK_BOOKMARK);
// After cleaning the previous mark, we can swich to another document
int cmd = getMode()==FILES_IN_DIR?WM_DOOPEN:NPPM_SWITCHTOFILE;
::SendMessage(::GetParent(_hParent), cmd, 0, (LPARAM)fInfo._fullPath.c_str());
Searching::displaySectionCentered(fInfo._start, fInfo._end, *_ppEditView); Searching::displaySectionCentered(fInfo._start, fInfo._end, *_ppEditView);
// we set the current mark here
int nb = (*_ppEditView)->getCurrentLineNumber();
setCurrentMarkedLine(nb);
(*_ppEditView)->execute(SCI_MARKERADD, nb, MARK_BOOKMARK);
// Then we colourise the double clicked line // Then we colourise the double clicked line
setFinderStyle(); setFinderStyle();
_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true); _scintView.execute(SCI_SETLEXER, SCLEX_NULL); // yuval - this line causes a bug!!! (last line suddenly belongs to file level header instead of having level=0x400)
_scintView.execute(SCI_SETLEXER, SCLEX_NULL); // later it affects DeleteResult and gotoNextFoundResult (assertions)!!
_scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_KWORD3, true); _scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HIGHLIGHT_LINE, true);
//
_scintView.execute(SCI_STARTSTYLING, start, STYLING_MASK); _scintView.execute(SCI_STARTSTYLING, start, STYLING_MASK);
_scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_KWORD3); _scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_HIGHLIGHT_LINE);
_scintView.execute(SCI_COLOURISE, start, end + 1); _scintView.execute(SCI_COLOURISE, start, end + 1);
_scintView.execute(SCI_SETCURRENTPOS, start); }
_scintView.execute(SCI_SETANCHOR, start);
return true;
} catch(...){ void Finder::DeleteResult()
printStr(TEXT("SCN_DOUBLECLICK problem")); {
int currentPos = _scintView.execute(SCI_GETCURRENTPOS); // yniq - add handling deletion of multiple lines?
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno);
if (start + 2 >= end) return; // avoid empty lines
if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) // delete a folder
{
int endline = _scintView.execute(SCI_GETLASTCHILD, lno, -1) + 1;
assert((size_t) endline <= _pMainFoundInfos->size());
_pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno, _pMainFoundInfos->begin() + endline); // remove found info
_pMainMarkings->erase(_pMainMarkings->begin() + lno, _pMainMarkings->begin() + endline);
int end = _scintView.execute(SCI_POSITIONFROMLINE, endline);
_scintView.execute(SCI_SETSEL, start, end);
setFinderReadOnly(false);
_scintView.execute(SCI_CLEAR);
setFinderReadOnly(true);
} }
break; else // delete one line
{
assert((size_t) lno < _pMainFoundInfos->size());
_pMainFoundInfos->erase(_pMainFoundInfos->begin() + lno); // remove found info
_pMainMarkings->erase(_pMainMarkings->begin() + lno);
setFinderReadOnly(false);
_scintView.execute(SCI_LINEDELETE);
setFinderReadOnly(true);
}
_MarkingsStruct._length = _pMainMarkings->size();
assert(_pMainFoundInfos->size() == _pMainMarkings->size());
assert(_scintView.execute(SCI_GETLINECOUNT) == _pMainFoundInfos->size() + 1);
}
void Finder::gotoNextFoundResult(int direction)
{
int increment = direction < 0 ? -1 : 1;
int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int total_lines = _scintView.execute(SCI_GETLINECOUNT);
if (total_lines <= 1) return;
if (lno == total_lines - 1) lno--; // last line doesn't belong to any search, use last search
int init_lno = lno;
int max_lno = _scintView.execute(SCI_GETLASTCHILD, lno, searchHeaderLevel);
assert(max_lno <= total_lines - 2);
// get the line number of the current search (searchHeaderLevel)
int level = _scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELNUMBERMASK;
int min_lno = lno;
while (level-- >= fileHeaderLevel)
{
min_lno = _scintView.execute(SCI_GETFOLDPARENT, min_lno);
assert(min_lno >= 0);
} }
default : if (min_lno < 0) min_lno = lno; // when lno is a search header line // yuval - remove this?
break;
assert(min_lno <= max_lno);
lno += increment;
if (lno > max_lno) lno = min_lno;
else if (lno < min_lno) lno = max_lno;
while (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG)
{
lno += increment;
if (lno > max_lno) lno = min_lno;
else if (lno < min_lno) lno = max_lno;
if (lno == init_lno) break;
}
if ((_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG) == 0)
{
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
_scintView.execute(SCI_SETSEL, start, start);
_scintView.execute(SCI_ENSUREVISIBLE, lno);
_scintView.execute(SCI_SCROLLCARET);
GotoFoundLine();
} }
return false;
} }
@ -861,6 +930,7 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
default : default :
break; break;
} }
break;
} }
} }
return FALSE; return FALSE;
@ -1219,7 +1289,10 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
if (nbChar > 1024 - 3) if (nbChar > 1024 - 3)
lend = lstart + 1020; lend = lstart + 1020;
(*_ppEditView)->getGenericText(lineBuf, lstart, lend); int start_mark = targetStart - lstart;
int end_mark = targetEnd - lstart;
(*_ppEditView)->getGenericText(lineBuf, lstart, lend, &start_mark, &end_mark);
generic_string line; generic_string line;
#ifdef UNICODE #ifdef UNICODE
line = lineBuf; line = lineBuf;
@ -1236,7 +1309,10 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
line = lineBuf; line = lineBuf;
#endif #endif
line += TEXT("\r\n"); line += TEXT("\r\n");
_pFinder->add(FoundInfo(targetStart, targetEnd, line.c_str(), fileName, _pFinder->_lineCounter), lineNumber + 1); SearchResultMarking srm;
srm._start = start_mark;
srm._end = end_mark;
_pFinder->add(FoundInfo(targetStart, targetEnd, fileName), srm, line.c_str(), lineNumber + 1);
break; break;
} }
@ -1312,6 +1388,9 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
delete [] pTextFind; delete [] pTextFind;
delete [] pTextReplace; delete [] pTextReplace;
if (nbProcessed > 0 && op == ProcessFindAll)
_pFinder->addFileHitCount(nbProcessed);
return nbProcessed; return nbProcessed;
} }
@ -1329,7 +1408,8 @@ void FindReplaceDlg::findAllIn(InWhat op)
_pFinder->init(_hInst, _hSelf, _ppEditView); _pFinder->init(_hInst, _hSelf, _ppEditView);
tTbData data = {0}; tTbData data = {0};
_pFinder->create(&data); _pFinder->create(&data, false);
::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, (WPARAM)_pFinder->getHSelf());
// define the default docking behaviour // define the default docking behaviour
data.uMask = DWS_DF_CONT_BOTTOM | DWS_ICONTAB | DWS_ADDINFO; 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.hIconTab = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_FIND_RESULT_ICON), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);
@ -1343,16 +1423,24 @@ void FindReplaceDlg::findAllIn(InWhat op)
::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data); ::SendMessage(_hParent, NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data);
_pFinder->_scintView.init(_hInst, _pFinder->getHSelf()); _pFinder->_scintView.init(_hInst, _pFinder->getHSelf());
// Subclass the ScintillaEditView for the Finder (Scintilla doesn't notify all key presses)
originalFinderProc = SetWindowLong( _pFinder->_scintView.getHSelf(), GWL_WNDPROC, (LONG) finderProc);
_pFinder->_scintView.performGlobalStyles();
_pFinder->setFinderReadOnly(true); _pFinder->setFinderReadOnly(true);
_pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8); _pFinder->_scintView.execute(SCI_SETCODEPAGE, SC_CP_DBCS);
_pFinder->_scintView.execute(SCI_USEPOPUP, FALSE); _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.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true);
//_statusBar.init(_hInst, _hSelf, 0); char ptrword[sizeof(void*)*2+1];
RECT findRect; sprintf(ptrword, "%p", &_pFinder->_MarkingsStruct);
_pFinder->_scintView.execute(SCI_SETKEYWORDS, 0, (LPARAM) ptrword);
//const int scintEditInitHeight = 130;
// get the width of FindDlg // get the width of FindDlg
RECT findRect;
::GetWindowRect(_pFinder->getHSelf(), &findRect); ::GetWindowRect(_pFinder->getHSelf(), &findRect);
// overwrite some default settings // overwrite some default settings
@ -1363,25 +1451,21 @@ void FindReplaceDlg::findAllIn(InWhat op)
_pFinder->display(); _pFinder->display();
} }
_pFinder->setFinderStyle(); _pFinder->setFinderStyle();
_pFinder->setMode(op);
::SendMessage(_pFinder->getHSelf(), WM_SIZE, 0, 0); ::SendMessage(_pFinder->getHSelf(), WM_SIZE, 0, 0);
if (op == ALL_OPEN_DOCS)
::SendMessage(_hParent, WM_FINDALL_INOPENEDDOC, 0, 0);
else if (op == FILES_IN_DIR)
::SendMessage(_hParent, WM_FINDINFILES, 0, 0);
refresh(); if (::SendMessage(_hParent, (op==ALL_OPEN_DOCS)?WM_FINDALL_INOPENEDDOC:WM_FINDINFILES, 0, 0))
} {
wsprintf(_findAllResultStr, TEXT("%d hits"), _findAllResult);
void FindReplaceDlg::putFindResultStr(const TCHAR *text) if (_findAllResult)
{ {
wsprintf(_findAllResultStr, TEXT("%s"), text); focusOnFinder();
} }
else
void FindReplaceDlg::refresh() getFocus(); // no hits
{ }
::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)_pFinder->getHSelf()); else // error - search folder doesn't exist
::SendMessage(_hSelf, WM_NEXTDLGCTL, (WPARAM)::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO), TRUE);
} }
void FindReplaceDlg::enableReplaceFunc(bool isEnable) void FindReplaceDlg::enableReplaceFunc(bool isEnable)
@ -1480,12 +1564,11 @@ void Finder::setFinderStyle()
styleDefault._colorStyle = COLORSTYLE_ALL; //All colors set styleDefault._colorStyle = COLORSTYLE_ALL; //All colors set
_scintView.setStyle(styleDefault); _scintView.setStyle(styleDefault);
} }
_scintView.execute(SCI_STYLECLEARALL); _scintView.execute(SCI_STYLECLEARALL);
_scintView.execute(SCI_SETSTYLEBITS, 5); _scintView.execute(SCI_SETSTYLEBITS, 5);
_scintView.setSearchResultLexer(); _scintView.setSearchResultLexer();
_scintView.execute(SCI_COLOURISE, 0, -1); _scintView.execute(SCI_COLOURISE, 0, -1);
_scintView.execute(SCI_SETEOLMODE, SC_EOL_LF); _scintView.execute(SCI_SETEOLMODE, SC_EOL_CRLF);
} }
BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
@ -1520,9 +1603,15 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
return TRUE; return TRUE;
} }
case NPPM_INTERNAL_SCINTILLAFINFERCLEARALL:
{
removeAll();
return TRUE;
}
default : default :
{ {
break; return FALSE;
} }
} }
} }
@ -1540,6 +1629,7 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
tmp.push_back(MenuItemUnit(0, TEXT("Separator"))); tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy"))); tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select All"))); tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select All")));
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCLEARALL, TEXT("Clear All")));
scintillaContextmenu.create(_hSelf, tmp); scintillaContextmenu.create(_hSelf, tmp);

View File

@ -39,13 +39,11 @@ enum DIALOG_TYPE {FIND_DLG, REPLACE_DLG, FINDINFILES_DLG};
enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR}; enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR};
struct FoundInfo { struct FoundInfo {
FoundInfo(int start, int end, const TCHAR *foundLine, const TCHAR *fullPath, size_t lineNum) FoundInfo(int start, int end, const TCHAR *fullPath)
: _start(start), _end(end), _foundLine(foundLine), _fullPath(fullPath), _scintLineNumber(lineNum){}; : _start(start), _end(end), _fullPath(fullPath) {};
int _start; int _start;
int _end; int _end;
std::generic_string _foundLine;
std::generic_string _fullPath; std::generic_string _fullPath;
size_t _scintLineNumber;
}; };
struct TargetRange { struct TargetRange {
@ -88,7 +86,10 @@ private:
class Finder : public DockingDlgInterface { class Finder : public DockingDlgInterface {
friend class FindReplaceDlg; friend class FindReplaceDlg;
public: public:
Finder() : DockingDlgInterface(IDD_FINDRESULT), _markedLine(-1), _lineCounter(0) {}; Finder() : DockingDlgInterface(IDD_FINDRESULT), _pMainFoundInfos(&_foundInfos1), _pMainMarkings(&_markings1) {
_MarkingsStruct._length = 0;
_MarkingsStruct._markings = NULL;
};
~Finder() { ~Finder() {
_scintView.destroy(); _scintView.destroy();
@ -98,100 +99,152 @@ public:
_ppEditView = ppEditView; _ppEditView = ppEditView;
}; };
void addFileNameTitle(const TCHAR * fileName) { void addSearchLine(const TCHAR *searchName) {
generic_string str = TEXT("["); generic_string str = TEXT("Search \"");
str += fileName; str += searchName;
str += TEXT("]\n"); str += TEXT("\"\r\n");
setFinderReadOnly(false); setFinderReadOnly(false);
_scintView.appandGenericText(str.c_str()); _scintView.addGenericText(str.c_str());
setFinderReadOnly(true); setFinderReadOnly(true);
_lineCounter++; _lastSearchHeaderPos = _scintView.execute(SCI_GETCURRENTPOS) - 2;
_pMainFoundInfos->push_back(EmptyFoundInfo);
_pMainMarkings->push_back(EmptySearchResultMarking);
}; };
void add(FoundInfo fi, int lineNb) { void addFileNameTitle(const TCHAR * fileName) {
_foundInfos.push_back(fi); generic_string str = TEXT(" ");
std::generic_string str = TEXT("Line "); str += fileName;
str += TEXT("\r\n");
setFinderReadOnly(false);
_scintView.addGenericText(str.c_str());
setFinderReadOnly(true);
_lastFileHeaderPos = _scintView.execute(SCI_GETCURRENTPOS) - 2;
_pMainFoundInfos->push_back(EmptyFoundInfo);
_pMainMarkings->push_back(EmptySearchResultMarking);
};
void addFileHitCount(int count) {
TCHAR text[20];
wsprintf(text, TEXT(" (%i hits)"), count);
setFinderReadOnly(false);
_scintView.insertGenericTextFrom(_lastFileHeaderPos, text);
setFinderReadOnly(true);
nFoundFiles++;
};
void addSearchHitCount(int count) {
TCHAR text[50];
wsprintf(text, TEXT(" (%i hits in %i files)"), count, nFoundFiles);
setFinderReadOnly(false);
_scintView.insertGenericTextFrom(_lastSearchHeaderPos, text);
setFinderReadOnly(true);
};
void add(FoundInfo fi, SearchResultMarking mi, const TCHAR* foundline, int lineNb) {
_pMainFoundInfos->push_back(fi);
_pMainMarkings->push_back(mi);
std::generic_string str = TEXT("\tLine ");
TCHAR lnb[16]; TCHAR lnb[16];
wsprintf(lnb, TEXT("%d"), lineNb); wsprintf(lnb, TEXT("%d"), lineNb);
str += lnb; str += lnb;
str += TEXT(" : "); str += TEXT(": ");
str += fi._foundLine; str += foundline;
size_t len = str.length(); if (str.length() >= SC_SEARCHRESULT_LINEBUFFERMAXLENGTH)
if (len >= SC_SEARCHRESULT_LINEBUFFERMAXLENGTH)
{ {
const TCHAR * endOfLongLine = TEXT("...\r\n"); const TCHAR * endOfLongLine = TEXT("...\r\n");
str = str.substr(0, SC_SEARCHRESULT_LINEBUFFERMAXLENGTH - lstrlen(endOfLongLine) - 1); str = str.substr(0, SC_SEARCHRESULT_LINEBUFFERMAXLENGTH - lstrlen(endOfLongLine) - 1);
str += endOfLongLine; str += endOfLongLine;
} }
else
{
// Make sure we have EOL. We might not have one for example when searching in non-text files.
// This can happen because Scintilla line endings (\n) are not the same as
// string line endings (\0). In this case we will see only a part of the line
// in the find result window.
if (str[len-1] != '\n')
str += TEXT("\n");
}
setFinderReadOnly(false); setFinderReadOnly(false);
_scintView.appandGenericText(str.c_str()); _scintView.addGenericText(str.c_str());
setFinderReadOnly(true); setFinderReadOnly(true);
_lineCounter++;
}; };
void setFinderStyle(); void setFinderStyle();
void removeAll() { void removeAll() {
_markedLine = -1; _pMainFoundInfos->clear();
_foundInfos.clear(); _pMainMarkings->clear();
setFinderReadOnly(false); setFinderReadOnly(false);
_scintView.execute(SCI_CLEARALL); _scintView.execute(SCI_CLEARALL);
setFinderReadOnly(true); setFinderReadOnly(true);
_lineCounter = 0;
}; };
FoundInfo & getInfo(int curLineNum) { void beginNewFilesSearch() {
int nbInfo = _foundInfos.size(); _scintView.execute(SCI_SETLEXER, SCLEX_NULL);
for (size_t i = (nbInfo <= curLineNum)?nbInfo -1:curLineNum ; i > 0 ; i--) _scintView.execute(SCI_SETCURRENTPOS, 0);
{ _pMainFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1;
if (_foundInfos[i]._scintLineNumber == curLineNum) _pMainMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1;
return _foundInfos[i]; nFoundFiles = 0;
}
return _foundInfos[0]; // should never be reached // fold all old searches (1st level only)
_scintView.collapse(searchHeaderLevel - SC_FOLDLEVELBASE, fold_collapse);
}; };
bool isEmpty() const { void finishFilesSearch(int count) {
return _foundInfos.empty(); std::vector<FoundInfo>* _pOldFoundInfos;
std::vector<SearchResultMarking>* _pOldMarkings;
_pOldFoundInfos = _pMainFoundInfos == &_foundInfos1 ? &_foundInfos2 : &_foundInfos1;
_pOldMarkings = _pMainMarkings == &_markings1 ? &_markings2 : &_markings1;
_pOldFoundInfos->insert(_pOldFoundInfos->begin(), _pMainFoundInfos->begin(), _pMainFoundInfos->end());
_pOldMarkings->insert(_pOldMarkings->begin(), _pMainMarkings->begin(), _pMainMarkings->end());
_pMainFoundInfos->clear();
_pMainMarkings->clear();
_pMainFoundInfos = _pOldFoundInfos;
_pMainMarkings = _pOldMarkings;
_MarkingsStruct._length = _pMainMarkings->size();
_MarkingsStruct._markings = &((*_pMainMarkings)[0]);
addSearchHitCount(count);
_scintView.execute(SCI_SETSEL, 0, 0);
_scintView.execute(SCI_SETLEXER, SCLEX_SEARCHRESULT);
}; };
int getCurrentMarkedLine() const {return _markedLine;};
void setCurrentMarkedLine(int line) {_markedLine = line;};
InWhat getMode() const {return _mode;};
void setMode(InWhat mode) {_mode = mode;};
void setSearchWord(const TCHAR *word2search) {
_scintView.setHiLiteResultWords(word2search);
};
void gotoNextFoundResult(int direction);
void GotoFoundLine();
void DeleteResult();
protected : protected :
virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
bool notify(SCNotification *notification); bool notify(SCNotification *notification);
private: private:
enum { searchHeaderLevel = SC_FOLDLEVELBASE + 1, fileHeaderLevel, resultLevel };
ScintillaEditView **_ppEditView; ScintillaEditView **_ppEditView;
std::vector<FoundInfo> _foundInfos; std::vector<FoundInfo> _foundInfos1;
std::vector<FoundInfo> _foundInfos2;
std::vector<FoundInfo>* _pMainFoundInfos;
std::vector<SearchResultMarking> _markings1;
std::vector<SearchResultMarking> _markings2;
std::vector<SearchResultMarking>* _pMainMarkings;
SearchResultMarkings _MarkingsStruct;
ScintillaEditView _scintView; ScintillaEditView _scintView;
int _markedLine; unsigned int nFoundFiles;
InWhat _mode;
size_t _lineCounter; int _lastFileHeaderPos;
int _lastSearchHeaderPos;
void setFinderReadOnly(bool isReadOnly) { void setFinderReadOnly(bool isReadOnly) {
_scintView.execute(SCI_SETREADONLY, isReadOnly); _scintView.execute(SCI_SETREADONLY, isReadOnly);
}; };
static FoundInfo EmptyFoundInfo;
static SearchResultMarking EmptySearchResultMarking;
}; };
//FindReplaceDialog: standard find/replace window //FindReplaceDialog: standard find/replace window
@ -275,27 +328,11 @@ public :
} }
::SendMessage(hCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1)); // select all text - fast edit ::SendMessage(hCombo, CB_SETEDITSEL, 0, MAKELPARAM(0, -1)); // select all text - fast edit
} }
void gotoNextFoundResult(int direction = 0) {if (_pFinder) _pFinder->gotoNextFoundResult(direction);};
bool isFinderEmpty() const {
return _pFinder->isEmpty();
};
void clearFinder() {
_pFinder->removeAll();
};
void putFindResult(int result) { void putFindResult(int result) {
_findAllResult = result; _findAllResult = result;
}; };
void putFindResultStr(const TCHAR *text);
void refresh();
void setSearchWord2Finder(){
generic_string str2Search = getText2search();
_pFinder->setSearchWord(str2Search.c_str());
};
const TCHAR * getDir2Search() const {return _directory.c_str();}; const TCHAR * getDir2Search() const {return _directory.c_str();};
void getPatterns(vector<generic_string> & patternVect); void getPatterns(vector<generic_string> & patternVect);
@ -333,11 +370,49 @@ public :
tie.pszText = (TCHAR *)name2change; tie.pszText = (TCHAR *)name2change;
TabCtrl_SetItem(_tab.getHSelf(), index, &tie); TabCtrl_SetItem(_tab.getHSelf(), index, &tie);
} }
void beginNewFilesSearch()
{
_pFinder->beginNewFilesSearch();
bool isUnicode = (*_ppEditView)->getCurrentBuffer()->getUnicodeMode() != uni8Bit;
_pFinder->addSearchLine(getText2search().c_str());
}
void finishFilesSearch(int count)
{
_pFinder->finishFilesSearch(count);
}
void focusOnFinder() {
// Show finder and set focus
if (_pFinder) {
::SendMessage(_hParent, NPPM_DMMSHOW, 0, (LPARAM)_pFinder->getHSelf());
_pFinder->_scintView.getFocus();
}
};
protected : protected :
virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
void addText2Combo(const TCHAR * txt2add, HWND comboID, bool isUTF8 = false); void addText2Combo(const TCHAR * txt2add, HWND comboID, bool isUTF8 = false);
generic_string getTextFromCombo(HWND hCombo, bool isUnicode = false) const; generic_string getTextFromCombo(HWND hCombo, bool isUnicode = false) const;
static LONG originalFinderProc;
// Window procedure for the finder
static LRESULT FAR PASCAL finderProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_KEYDOWN && (wParam == VK_DELETE || wParam == VK_RETURN))
{
ScintillaEditView *pScint = (ScintillaEditView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA));
Finder *pFinder = (Finder *)(::GetWindowLongPtr(pScint->getHParent(), GWL_USERDATA));
if (wParam == VK_RETURN)
pFinder->GotoFoundLine();
else // VK_DELETE
pFinder->DeleteResult();
return 0;
}
else
// Call default (original) window procedure
return CallWindowProc((WNDPROC) originalFinderProc, hwnd, message, wParam, lParam);
}
private : private :
DIALOG_TYPE _currentStatus; DIALOG_TYPE _currentStatus;
@ -390,7 +465,7 @@ private :
void setDefaultButton(int nID) void setDefaultButton(int nID)
{ {
#if 0 #if 0
// Where is a problem when you: // There is a problem when you:
// 1. open the find dialog // 1. open the find dialog
// 2. press the "close" buttom // 2. press the "close" buttom
// 3. open it again // 3. open it again

View File

@ -1451,6 +1451,23 @@ void ScintillaEditView::getGenericText(TCHAR *dest, int start, int end) const
#endif #endif
} }
// "mstart" and "mend" are pointers to indexes in the read string,
// which are converted to the corresponding indexes in the returned TCHAR string.
void ScintillaEditView::getGenericText(TCHAR *dest, int start, int end, int *mstart, int *mend) const
{
#ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
char *destA = new char[end - start + 1];
getText(destA, start, end);
unsigned int cp = execute(SCI_GETCODEPAGE);
const TCHAR *destW = wmc->char2wchar(destA, cp, mstart, mend);
lstrcpy(dest, destW);
delete [] destA;
#else
getText(dest, start, end);
#endif
}
void ScintillaEditView::insertGenericTextFrom(int position, const TCHAR *text2insert) const void ScintillaEditView::insertGenericTextFrom(int position, const TCHAR *text2insert) const
{ {
#ifdef UNICODE #ifdef UNICODE
@ -1530,6 +1547,18 @@ void ScintillaEditView::appandGenericText(const TCHAR * text2Append) const
#endif #endif
} }
void ScintillaEditView::addGenericText(const TCHAR * text2Append) const
{
#ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
unsigned int cp = execute(SCI_GETCODEPAGE);
const char *text2AppendA =wmc->wchar2char(text2Append, cp);
execute(SCI_ADDTEXT, strlen(text2AppendA), (LPARAM)text2AppendA);
#else
execute(SCI_ADDTEXT, strlen(text2AppendA), (LPARAM)text2AppendA);
#endif
}
int ScintillaEditView::replaceTarget(const TCHAR * str2replace, int fromTargetPos, int toTargetPos) const int ScintillaEditView::replaceTarget(const TCHAR * str2replace, int fromTargetPos, int toTargetPos) const
{ {
if (fromTargetPos != -1 || toTargetPos != -1) if (fromTargetPos != -1 || toTargetPos != -1)

View File

@ -167,6 +167,7 @@ public:
void getText(char *dest, int start, int end) const; void getText(char *dest, int start, int end) const;
void getGenericText(TCHAR *dest, int start, int end) const; void getGenericText(TCHAR *dest, int start, int end) const;
void getGenericText(TCHAR *dest, int start, int end, int *mstart, int *mend) const;
void insertGenericTextFrom(int position, const TCHAR *text2insert) const; void insertGenericTextFrom(int position, const TCHAR *text2insert) const;
void replaceSelWith(const char * replaceText); void replaceSelWith(const char * replaceText);
@ -179,6 +180,7 @@ public:
TCHAR * getGenericSelectedText(TCHAR * txt, int size, bool expand = true); TCHAR * getGenericSelectedText(TCHAR * txt, int size, bool expand = true);
int searchInTarget(const TCHAR * Text2Find, int fromPos, int toPos) const; int searchInTarget(const TCHAR * Text2Find, int fromPos, int toPos) const;
void appandGenericText(const TCHAR * text2Append) const; void appandGenericText(const TCHAR * text2Append) const;
void addGenericText(const TCHAR * text2Append) const;
int replaceTarget(const TCHAR * str2replace, int fromTargetPos = -1, int toTargetPos = -1) const; int replaceTarget(const TCHAR * str2replace, int fromTargetPos = -1, int toTargetPos = -1) const;
int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const; int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const;
void showAutoComletion(int lenEntered, const TCHAR * list); void showAutoComletion(int lenEntered, const TCHAR * list);
@ -701,8 +703,9 @@ protected:
}; };
void setSearchResultLexer() { void setSearchResultLexer() {
execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_HEARDER, true); execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_FILE_HEADER, true);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, LIST_1 | LIST_2 | LIST_3); execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_SEARCH_HEADER, true);
setLexer(SCLEX_SEARCHRESULT, L_SEARCHRESULT, 0);
}; };
bool isNeededFolderMarge(LangType typeDoc) const { bool isNeededFolderMarge(LangType typeDoc) const {

View File

@ -302,6 +302,8 @@
#define NPPM_INTERNAL_CANCEL_FIND_IN_FILES (NOTEPADPLUS_USER_INTERNAL + 24) #define NPPM_INTERNAL_CANCEL_FIND_IN_FILES (NOTEPADPLUS_USER_INTERNAL + 24)
#define NPPM_INTERNAL_RELOADNATIVELANG (NOTEPADPLUS_USER_INTERNAL + 25) #define NPPM_INTERNAL_RELOADNATIVELANG (NOTEPADPLUS_USER_INTERNAL + 25)
#define NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED (NOTEPADPLUS_USER_INTERNAL + 26) #define NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED (NOTEPADPLUS_USER_INTERNAL + 26)
#define NPPM_INTERNAL_SCINTILLAFINFERCLEARALL (NOTEPADPLUS_USER_INTERNAL + 27)
// See Notepad_plus_msgs.h // See Notepad_plus_msgs.h
//#define NOTEPADPLUS_USER (WM_USER + 1000) //#define NOTEPADPLUS_USER (WM_USER + 1000)

View File

@ -14,5 +14,7 @@
<Command name="Wikipedia Search" Ctrl="no" Alt="yes" Shift="no" Key="114">http://en.wikipedia.org/wiki/Special:Search?search=$(CURRENT_WORD)</Command> <Command name="Wikipedia Search" Ctrl="no" Alt="yes" Shift="no" Key="114">http://en.wikipedia.org/wiki/Special:Search?search=$(CURRENT_WORD)</Command>
<Command name="open file" Ctrl="no" Alt="yes" Shift="no" Key="116">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD)</Command> <Command name="open file" Ctrl="no" Alt="yes" Shift="no" Key="116">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD)</Command>
<Command name="open in another instance" Ctrl="no" Alt="yes" Shift="no" Key="117">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD) -nosession -multiInst</Command> <Command name="open in another instance" Ctrl="no" Alt="yes" Shift="no" Key="117">$(NPP_DIRECTORY)\notepad++.exe $(CURRENT_WORD) -nosession -multiInst</Command>
<Command name="Open containing folder" Ctrl="no" Alt="no" Shift="no" Key="0">explorer $(CURRENT_DIRECTORY)</Command>
<Command name="Open current dir cmd" Ctrl="no" Alt="no" Shift="no" Key="0">cmd /K cd $(CURRENT_DIRECTORY)</Command>
</UserDefinedCommands> </UserDefinedCommands>
</NotepadPlus> </NotepadPlus>

View File

@ -689,12 +689,11 @@
</LexerType> </LexerType>
<LexerType name="searchResult" desc="Search result" ext=""> <LexerType name="searchResult" desc="Search result" ext="">
<WordsStyle name="DEFAULT" styleID="0" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" /> <WordsStyle name="DEFAULT" styleID="0" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="SELECTED LINE" styleID="6" fgColor="FFFF80" bgColor="0000FF" fontName="" fontStyle="1" fontSize="" /> <WordsStyle name="SEARCH HEADER" styleID="1" fgColor="000080" bgColor="BBBBFF" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="HEARDER" styleID="1" fgColor="008000" bgColor="D5FFD5" fontName="" fontStyle="1" fontSize="" /> <WordsStyle name="FILE HEADER" styleID="2" fgColor="008000" bgColor="D5FFD5" fontName="" fontStyle="1" fontSize="" />
<WordsStyle name="NUMBER" styleID="2" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" /> <WordsStyle name="LINE NUMBER" styleID="3" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="HIT WORD" styleID="3" fgColor="FF0000" bgColor="FFFF80" fontName="" fontStyle="4" fontSize="" /> <WordsStyle name="HIT WORD" styleID="4" fgColor="FF0000" bgColor="FFFFBF" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="KEYWORD1" styleID="4" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="1" fontSize="" keywordClass="instre2">if else for while</WordsStyle> <WordsStyle name="SELECTED LINE" styleID="5" fgColor="FFFF80" bgColor="000080" fontName="" fontStyle="0" fontSize="" />
<WordsStyle name="KEYWORD2" styleID="5" fgColor="0080FF" bgColor="FFFFFF" fontName="" fontStyle="0" fontSize="" keywordClass="type1">bool long int char</WordsStyle>
</LexerType> </LexerType>
</LexerStyles> </LexerStyles>
<GlobalStyles> <GlobalStyles>

View File

@ -290,6 +290,10 @@
RelativePath="..\src\lastRecentFileList.cpp" RelativePath="..\src\lastRecentFileList.cpp"
> >
</File> </File>
<File
RelativePath="..\src\MISC\Exception\MiniDumper.cpp"
>
</File>
<File <File
RelativePath="..\src\Notepad_plus.cpp" RelativePath="..\src\Notepad_plus.cpp"
> >
@ -583,6 +587,10 @@
RelativePath="..\src\menuCmdID.h" RelativePath="..\src\menuCmdID.h"
> >
</File> </File>
<File
RelativePath="..\src\MISC\Exception\MiniDumper.h"
>
</File>
<File <File
RelativePath="..\src\Notepad_plus.h" RelativePath="..\src\Notepad_plus.h"
> >

View File

@ -170,12 +170,11 @@
#define SCE_D_COMMENTDOCKEYWORDERROR 17 #define SCE_D_COMMENTDOCKEYWORDERROR 17
#define SCE_SEARCHRESULT_DEFAULT 0 #define SCE_SEARCHRESULT_DEFAULT 0
#define SCE_SEARCHRESULT_HEARDER 1 #define SCE_SEARCHRESULT_SEARCH_HEADER 1
#define SCE_SEARCHRESULT_NUMBER 2 #define SCE_SEARCHRESULT_FILE_HEADER 2
#define SCE_SEARCHRESULT_WORD2SEARCH 3 #define SCE_SEARCHRESULT_LINE_NUMBER 3
#define SCE_SEARCHRESULT_KWORD1 4 #define SCE_SEARCHRESULT_WORD2SEARCH 4
#define SCE_SEARCHRESULT_KWORD2 5 #define SCE_SEARCHRESULT_HIGHLIGHT_LINE 5
#define SCE_SEARCHRESULT_KWORD3 6
#define SCE_OBJC_DIRECTIVE 20 #define SCE_OBJC_DIRECTIVE 20
#define SCE_OBJC_QUALIFIER 21 #define SCE_OBJC_QUALIFIER 21

View File

@ -828,6 +828,16 @@ struct SCNotification {
int y; // SCN_DWELLSTART, SCN_DWELLEND int y; // SCN_DWELLSTART, SCN_DWELLEND
}; };
struct SearchResultMarking {
long _start;
long _end;
};
struct SearchResultMarkings {
long _length;
SearchResultMarking *_markings;
};
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
} }
#endif #endif

View File

@ -24,6 +24,7 @@
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <vector>
#include "Platform.h" #include "Platform.h"
@ -33,6 +34,10 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
// The following definitions are a copy of the ones in FindReplaceDlg.h
static enum { searchHeaderLevel = SC_FOLDLEVELBASE + 1, fileHeaderLevel, resultLevel };
static inline bool AtEOL(Accessor &styler, unsigned int i) { static inline bool AtEOL(Accessor &styler, unsigned int i) {
return (styler[i] == '\n') || return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@ -42,143 +47,78 @@ static const char * const emptyWordListDesc[] = {
0 0
}; };
inline bool isSpaceChar(char ch) { static void ColouriseSearchResultLine(SearchResultMarkings* pMarkings, char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler, int linenum)
return ((ch == ' ') || (ch == ' '));
};
// return value : false if the end of line is reached, otherwise true
inline bool eatWhiteSpaces(const char *line, unsigned int & pos) {
if (pos >= strlen(line)) return false;
//int i = pos;
for ( ; line[pos] && isSpaceChar(line[pos]) ; pos++);
return (pos < strlen(line));
};
static void ColouriseSearchResultLine(WordList *keywordlists[], char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler)
{ {
// startLine and endPos are the absolute positions. // startLine and endPos are the absolute positions.
WordList &word2Search = *keywordlists[0]; if (lineBuffer[0] == ' ') // file header
WordList &keywords1 = *keywordlists[1];
WordList &keywords2 = *keywordlists[2];
WordList &keywords3 = *keywordlists[3];
if (lineBuffer[0] == '[')
{ {
styler.ColourTo(endPos, SCE_SEARCHRESULT_HEARDER); styler.ColourTo(endPos, SCE_SEARCHRESULT_FILE_HEADER);
} }
else else if (lineBuffer[0] == 'S') // search header
{
styler.ColourTo(endPos, SCE_SEARCHRESULT_SEARCH_HEADER);
}
else // line info
{ {
const unsigned int firstTokenLen = 4; const unsigned int firstTokenLen = 4;
unsigned int currentPos;
PLATFORM_ASSERT(lengthLine >= firstTokenLen + 2);
styler.ColourTo(startLine + firstTokenLen, SCE_SEARCHRESULT_DEFAULT); styler.ColourTo(startLine + firstTokenLen, SCE_SEARCHRESULT_DEFAULT);
unsigned int currentPos = firstTokenLen; for (currentPos = firstTokenLen; lineBuffer[currentPos] != ':' ; currentPos++) PLATFORM_ASSERT(currentPos < lengthLine);
for ( ; lineBuffer[currentPos] != ':' ; currentPos++); styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_LINE_NUMBER);
styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_NUMBER);
//StyleContext sc(startPos, length, initStyle, styler);
int currentStat = SCE_SEARCHRESULT_DEFAULT; int currentStat = SCE_SEARCHRESULT_DEFAULT;
PLATFORM_ASSERT(linenum < pMarkings->_length);
SearchResultMarking mi = pMarkings->_markings[linenum];
const int maxWordSize = 4096; currentPos += 2; // skip ": "
char word[maxWordSize]; unsigned int match_start = startLine + currentPos + mi._start - 1;
unsigned int match_end = startLine + currentPos + mi._end - 1;
bool isEndReached = eatWhiteSpaces(lineBuffer, currentPos); if (match_start <= endPos) {
styler.ColourTo(match_start, SCE_SEARCHRESULT_DEFAULT);
styler.ColourTo(startLine + currentPos - 1, SCE_SEARCHRESULT_DEFAULT); if (match_end <= endPos)
styler.ColourTo(match_end, SCE_SEARCHRESULT_WORD2SEARCH);
while (currentPos < lengthLine) else
{
for (int j = 0 ; j < maxWordSize ; currentPos++, j++)
{
if (currentPos >= lengthLine)
{
isEndReached = true;
break;
}
char ch = lineBuffer[currentPos];
if ((ch == ' ') || (ch == 0x0A) || (ch == 0x0D))
{
if (j == 0)
goto end;
word[j] = '\0';
if ((word2Search) && (word2Search.InList(word)))
{
currentStat = SCE_SEARCHRESULT_WORD2SEARCH; currentStat = SCE_SEARCHRESULT_WORD2SEARCH;
} }
else if ((keywords1) && (keywords1.InList(word))) styler.ColourTo(endPos, currentStat);
{
currentStat = SCE_SEARCHRESULT_KWORD1;
}
else if ((keywords2) && (keywords2.InList(word)))
{
currentStat = SCE_SEARCHRESULT_KWORD2;
}
else if ((keywords3) && (keywords3.InList(word)))
{
currentStat = SCE_SEARCHRESULT_KWORD3;
}
else
{
currentStat = SCE_SEARCHRESULT_DEFAULT;
}
styler.ColourTo(startLine + currentPos - 1, currentStat);
currentStat = SCE_SEARCHRESULT_DEFAULT;
isEndReached = !eatWhiteSpaces(lineBuffer, currentPos);
break;
}
else
word[j] = ch;
}
if (isEndReached)
{
styler.ColourTo(endPos, SCE_SEARCHRESULT_DEFAULT);
}
else
{
styler.ColourTo(startLine + currentPos - 1, currentStat);
}
}
end :
styler.ColourTo(endPos, SCE_SEARCHRESULT_DEFAULT);
} }
} }
static void ColouriseSearchResultDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { static void ColouriseSearchResultDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) {
char lineBuffer[SC_SEARCHRESULT_LINEBUFFERMAXLENGTH]; char lineBuffer[SC_SEARCHRESULT_LINEBUFFERMAXLENGTH];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
unsigned int linePos = 0; unsigned int linePos = 0;
unsigned int startLine = startPos; unsigned int startLine = startPos;
SearchResultMarkings* pMarkings = NULL;
sscanf(keywordlists[0]->words[0], "%p", &pMarkings);
PLATFORM_ASSERT(pMarkings);
for (unsigned int i = startPos; i < startPos + length; i++) { for (unsigned int i = startPos; i < startPos + length; i++) {
lineBuffer[linePos++] = styler[i]; lineBuffer[linePos++] = styler[i];
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
// End of line (or of line buffer) met, colourise it // End of line (or of line buffer) met, colourise it
lineBuffer[linePos] = '\0'; lineBuffer[linePos] = '\0';
ColouriseSearchResultLine(keywordlists, lineBuffer, linePos, startLine, i, styler); ColouriseSearchResultLine(pMarkings, lineBuffer, linePos, startLine, i, styler, styler.GetLine(startLine));
linePos = 0; linePos = 0;
startLine = i + 1; startLine = i + 1;
while (!AtEOL(styler, i)) i++; while (!AtEOL(styler, i)) i++;
} }
} }
if (linePos > 0) { // Last line does not have ending characters if (linePos > 0) { // Last line does not have ending characters
ColouriseSearchResultLine(keywordlists, lineBuffer, linePos, startLine, startPos + length - 1, styler); ColouriseSearchResultLine(pMarkings, lineBuffer, linePos, startLine, startPos + length - 1, styler, styler.GetLine(startLine));
} }
} }
// adaption by ksc, using the "} else {" trick of 1.53
// 030721
static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@ -188,7 +128,7 @@ static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList
char chNext = styler[startPos]; char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos); int styleNext = styler.StyleAt(startPos);
bool headerPoint = false; int headerPoint = 0;
int lev; int lev;
for (unsigned int i = startPos; i < endPos; i++) { for (unsigned int i = startPos; i < endPos; i++) {
@ -199,57 +139,32 @@ static void FoldSearchResultDoc(unsigned int startPos, int length, int, WordList
styleNext = styler.StyleAt(i + 1); styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\n') || (ch == '\r' && chNext != '\n'); bool atEOL = (ch == '\n') || (ch == '\r' && chNext != '\n');
if (style == SCE_SEARCHRESULT_HEARDER) if (style == SCE_SEARCHRESULT_FILE_HEADER)
{ {
headerPoint = true; headerPoint = fileHeaderLevel;
}
else if (style == SCE_SEARCHRESULT_SEARCH_HEADER)
{
headerPoint = searchHeaderLevel;
} }
if (atEOL) { if (atEOL) {
lev = SC_FOLDLEVELBASE; lev = headerPoint ? SC_FOLDLEVELHEADERFLAG + headerPoint : resultLevel;
headerPoint = 0;
if (lineCurrent > 0) {
int levelPrevious = styler.LevelAt(lineCurrent - 1);
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
lev = SC_FOLDLEVELBASE + 1;
} else {
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
}
}
if (headerPoint) {
lev = SC_FOLDLEVELBASE;
}
if (visibleChars == 0 && foldCompact) if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
if (headerPoint) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) { if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev); styler.SetLevel(lineCurrent, lev);
} }
lineCurrent++; lineCurrent++;
visibleChars = 0; visibleChars = 0;
headerPoint = false;
} }
if (!isspacechar(ch)) if (!isspacechar(ch))
visibleChars++; visibleChars++;
} }
styler.SetLevel(lineCurrent, SC_FOLDLEVELBASE);
if (lineCurrent > 0) {
int levelPrevious = styler.LevelAt(lineCurrent - 1);
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
lev = SC_FOLDLEVELBASE + 1;
} else {
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
}
} else {
lev = SC_FOLDLEVELBASE;
}
int flagsNext = styler.LevelAt(lineCurrent);
styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
} }
LexerModule lmSearchResult(SCLEX_SEARCHRESULT, ColouriseSearchResultDoc, "searchResult", FoldSearchResultDoc, emptyWordListDesc); LexerModule lmSearchResult(SCLEX_SEARCHRESULT, ColouriseSearchResultDoc, "searchResult", FoldSearchResultDoc, emptyWordListDesc);