diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 19010fdc6..78852835d 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -1568,6 +1568,80 @@ DWORD WINAPI AsyncCancelFindInFiles(LPVOID NppHWND) return 0; } +bool Notepad_plus::replaceInFiles() +{ + bool isRecursive = _findReplaceDlg.isRecursive(); + bool isInHiddenDir = _findReplaceDlg.isInHiddenDir(); + int nbTotal = 0; + + ScintillaEditView *pOldView = _pEditView; + _pEditView = &_invisibleEditView; + Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER); + + const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); + + if (!dir2Search[0] || !::PathFileExists(dir2Search)) + { + return false; + } + + HANDLE CancelThreadHandle = ::CreateThread(NULL, 0, AsyncCancelFindInFiles, _hSelf, 0, NULL); + + vector patterns2Match; + if (_findReplaceDlg.getFilters() == TEXT("")) + _findReplaceDlg.setFindInFilesDirFilter(NULL, TEXT("*.*")); + _findReplaceDlg.getPatterns(patterns2Match); + vector fileNames; + + getMatchedFileNames(dir2Search, patterns2Match, fileNames, isRecursive, isInHiddenDir); + + bool dontClose = false; + for (size_t i = 0 ; i < fileNames.size() ; i++) + { + MSG msg; + if (PeekMessage(&msg, _hSelf, NPPM_INTERNAL_CANCEL_FIND_IN_FILES, NPPM_INTERNAL_CANCEL_FIND_IN_FILES, PM_REMOVE)) break; + + BufferID id = MainFileManager->getBufferFromName(fileNames.at(i).c_str()); + if (id != BUFFER_INVALID) + { + dontClose = true; + } + else + { + id = MainFileManager->loadFile(fileNames.at(i).c_str()); + dontClose = false; + } + + if (id != BUFFER_INVALID) + { + Buffer * pBuf = MainFileManager->getBufferByID(id); + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + _invisibleEditView.execute(SCI_SETCODEPAGE, pBuf->getUnicodeMode() == uni8Bit ? 0 : SC_CP_UTF8); + + int nbReplaced = _findReplaceDlg.processAll(ProcessReplaceAll, NULL, NULL, true, fileNames.at(i).c_str()); + nbTotal += nbReplaced; + if (nbReplaced) + { + MainFileManager->saveBuffer(id, pBuf->getFullPathName()); + } + + if (!dontClose) + MainFileManager->closeBuffer(id, _pEditView); + } + } + + TerminateThread(CancelThreadHandle, 0); + + _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc); + _pEditView = pOldView; + + TCHAR msg[128]; + wsprintf(msg, TEXT("%d occurences replaced"), nbTotal); + printStr(msg); + + return true; +} + bool Notepad_plus::findInFiles() { bool isRecursive = _findReplaceDlg.isRecursive(); @@ -7007,6 +7081,11 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa return TRUE; } + case WM_REPLACEINFILES : + { + replaceInFiles(); + return TRUE; + } case NPPM_LAUNCHFINDINFILESDLG : { const int strSize = 64; diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 2a6a3ad39..0be34532c 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -217,6 +217,7 @@ public: void notifyBufferChanged(Buffer * buffer, int mask); bool findInFiles(); + bool replaceInFiles(); static HWND gNppHWND; //static handle to Notepad++ window, NULL if non-existant private: diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index 7389e3241..31a4d9b9e 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -490,7 +490,7 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP _replaceClosePos.left = p.x; _replaceClosePos.top = p.y; - p = getLeftTopPoint(::GetDlgItem(_hSelf, IDREPLACE)); + p = getLeftTopPoint(::GetDlgItem(_hSelf, IDREPLACEALL)); _findInFilesClosePos.left = p.x; _findInFilesClosePos.top = p.y; @@ -640,6 +640,28 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP } return TRUE; + case IDD_FINDINFILES_REPLACEINFILES : + { + const int filterSize = 256; + TCHAR filters[filterSize]; + TCHAR directory[MAX_PATH]; + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters, filterSize); + addText2Combo(filters, ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO)); + _filters = filters; + + ::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, MAX_PATH); + addText2Combo(directory, ::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO)); + _directory = directory; + + if ((lstrlen(directory) > 0) && (directory[lstrlen(directory)-1] != '\\')) + _directory += TEXT("\\"); + + updateCombo(IDFINDWHAT); + updateCombo(IDREPLACEWITH); + ::SendMessage(_hParent, WM_REPLACEINFILES, 0, 0); + } + return TRUE; + case IDC_REPLACE_OPENEDFILES : { if (_currentStatus == REPLACE_DLG) @@ -1170,18 +1192,6 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con if ((targetStart != -1) && (op == ProcessFindAll)) //add new filetitle if this file results in hits { - /* Don't remember why : - const int fileNameLen = lstrlen(fileName); - - if (fileNameLen > _fileNameLenMax) - { - _fileNameLenMax = fileNameLen; - - delete [] _uniFileName; - _uniFileName = new char[(fileNameLen + 3) * 2 + 1]; - } - ascii_to_utf8(fileName, fileNameLen, _uniFileName); - */ _pFinder->addFileNameTitle(fileName); } while (targetStart != -1) @@ -1364,8 +1374,10 @@ void FindReplaceDlg::findAllIn(InWhat op) _pFinder->setMode(op); ::SendMessage(_pFinder->getHSelf(), WM_SIZE, 0, 0); - - ::SendMessage(_hParent, (op==ALL_OPEN_DOCS)?WM_FINDALL_INOPENEDDOC:WM_FINDINFILES, 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(); } @@ -1423,8 +1435,6 @@ void FindReplaceDlg::enableFindInFilesControls(bool isEnable) { // Hide Items ::ShowWindow(::GetDlgItem(_hSelf, IDWRAP), isEnable?SW_HIDE:SW_SHOW); - //::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDINFILES), isEnable?SW_HIDE:SW_SHOW); - ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEWITH), isEnable?SW_HIDE:SW_SHOW); ::ShowWindow(::GetDlgItem(_hSelf, IDCCOUNTALL), isEnable?SW_HIDE:SW_SHOW); ::ShowWindow(::GetDlgItem(_hSelf, IDC_FINDALL_OPENEDFILES), isEnable?SW_HIDE:SW_SHOW); ::ShowWindow(::GetDlgItem(_hSelf, IDOK), isEnable?SW_HIDE:SW_SHOW); @@ -1446,6 +1456,12 @@ void FindReplaceDlg::enableFindInFilesControls(bool isEnable) ::ShowWindow(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES), isEnable?SW_HIDE:SW_SHOW); // Show Items + if (isEnable) + { + ::ShowWindow(::GetDlgItem(_hSelf, ID_STATICTEXT_REPLACE), SW_SHOW); + ::ShowWindow(::GetDlgItem(_hSelf, IDREPLACEWITH), SW_SHOW); + } + ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_REPLACEINFILES), isEnable?SW_SHOW:SW_HIDE); ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_STATIC), isEnable?SW_SHOW:SW_HIDE); ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO), isEnable?SW_SHOW:SW_HIDE); ::ShowWindow(::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_STATIC), isEnable?SW_SHOW:SW_HIDE); diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h index a01df9b35..3343d23bd 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h @@ -36,9 +36,7 @@ enum DIALOG_TYPE {FIND_DLG, REPLACE_DLG, FINDINFILES_DLG}; //#define FIND_REPLACE_STR_MAX 256 -typedef bool InWhat; -#define ALL_OPEN_DOCS true -#define FILES_IN_DIR false +enum InWhat{ALL_OPEN_DOCS, FILES_IN_DIR}; struct FoundInfo { FoundInfo(int start, int end, const TCHAR *foundLine, const TCHAR *fullPath, size_t lineNum) diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc index a980abfce..bd8813b09 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc @@ -23,56 +23,52 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "FindReplaceDlg_rc.h" IDD_FIND_REPLACE_DLG DIALOGEX 36, 44, 321, 182 -//STYLE DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOOLWINDOW - CAPTION "Replace" -FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x0 +FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN RTEXT "Find what :",IDFINDWHAT_STATIC,6,22,75,8 COMBOBOX IDFINDWHAT,83,20,125,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP RTEXT "Replace with :",ID_STATICTEXT_REPLACE,6,40,75,8 COMBOBOX IDREPLACEWITH,83,39,125,50,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP - CONTROL "Mark Line",IDC_MARKLINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,38,88,10 - CONTROL "Style found token",IDC_STYLEFOUND_CHECK,"Button", BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,13,50,100,15 + CONTROL "Mark Line",IDC_MARKLINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,38,88,10 + CONTROL "Style found token",IDC_STYLEFOUND_CHECK,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,13,50,100,15 GROUPBOX "",IDC_FINDALL_STATIC,7,31,204,54 - CONTROL "Purge for each search",IDC_PURGE_CHECK,"Button", BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,13,64,99,16 - PUSHBUTTON "Find All",IDCMARKALL,131,40,75,14 + CONTROL "Purge for each search",IDC_PURGE_CHECK,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,13,64,99,16 + PUSHBUTTON "Find All",IDCMARKALL,131,40,75,14 GROUPBOX "",IDC_REPLACEINSELECTION,141,50,170,23 CONTROL "In selection",IDC_IN_SELECTION_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,59,59,10 - PUSHBUTTON "Clear",IDC_CLEAR_ALL,156,71,50,11, WS_TABSTOP - RTEXT "Filters :", IDD_FINDINFILES_FILTERS_STATIC,6,40,75,8 - COMBOBOX IDD_FINDINFILES_FILTERS_COMBO,83,39,125,150, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP - - RTEXT "Directory :",IDD_FINDINFILES_DIR_STATIC,7,58,40,8 - COMBOBOX IDD_FINDINFILES_DIR_COMBO,49,57,141,150, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDD_FINDINFILES_BROWSE_BUTTON,193,56,16,14 - CONTROL "In all sub-folders",IDD_FINDINFILES_RECURSIVE_CHECK, TEXT("Button"), BS_AUTOCHECKBOX | WS_TABSTOP,49,70,80,15 - CONTROL "In hidden folders",IDD_FINDINFILES_INHIDDENDIR_CHECK, TEXT("Button"), BS_AUTOCHECKBOX | WS_TABSTOP,129,70,80,15 - - CONTROL "Match &whole word only",IDWHOLEWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,6,88,110,15 - CONTROL "Match &case",IDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,100,110,15 + PUSHBUTTON "Clear",IDC_CLEAR_ALL,156,71,50,11 + RTEXT "Filters :",IDD_FINDINFILES_FILTERS_STATIC,27,59,53,8 + COMBOBOX IDD_FINDINFILES_FILTERS_COMBO,83,57,125,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + RTEXT "Directory :",IDD_FINDINFILES_DIR_STATIC,7,77,40,8 + COMBOBOX IDD_FINDINFILES_DIR_COMBO,49,75,141,150,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDD_FINDINFILES_BROWSE_BUTTON,193,74,16,14 + CONTROL "In all sub-folders",IDD_FINDINFILES_RECURSIVE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,218,73,80,15 + CONTROL "In hidden folders",IDD_FINDINFILES_INHIDDENDIR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,218,87,80,15 + CONTROL "Match &whole word only",IDWHOLEWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,88,104,15 + CONTROL "Match &case",IDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,100,82,15 CONTROL "Wra&p around",IDWRAP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,6,112,110,15 - - GROUPBOX "Search mode",IDC_MODE_STATIC,6,126,138,48 - CONTROL "&Normal",IDNORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,138,126,10 - CONTROL "&Extended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED,"Button",BS_AUTORADIOBUTTON,12, 150,126,10 - CONTROL "Regular e&xpression",IDREGEXP,"Button", BS_AUTORADIOBUTTON,12,162,126,10 - + GROUPBOX "Search mode",IDC_MODE_STATIC,6,126,138,48 + CONTROL "&Normal",IDNORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,138,126,10 + CONTROL "&Extended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED, + "Button",BS_AUTORADIOBUTTON,12,150,126,10 + CONTROL "Regular e&xpression",IDREGEXP,"Button",BS_AUTORADIOBUTTON,12,162,126,10 CONTROL "&Up",IDDIRECTIONUP,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,155,94,45,12 CONTROL "&Down",IDDIRECTIONDOWN,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,155,106,45,12 GROUPBOX "Direction",IDC_DIR_STATIC,150,86,60,34,WS_GROUP - - PUSHBUTTON "Find Next",IDOK,217,20,90,14,WS_GROUP | WS_TABSTOP - PUSHBUTTON "Count",IDCCOUNTALL,217,38,90,14, WS_TABSTOP - PUSHBUTTON "Find all in all opened documents",IDC_FINDALL_OPENEDFILES,217,56,90,21,BS_MULTILINE | WS_TABSTOP - PUSHBUTTON "&Replace",IDREPLACE,217,38,90,14, WS_TABSTOP - PUSHBUTTON "Replace &All",IDREPLACEALL,217,56,90,14, WS_TABSTOP - PUSHBUTTON "Replace all in all opened documents",IDC_REPLACE_OPENEDFILES,217,74,90,21,BS_MULTILINE | WS_TABSTOP - PUSHBUTTON "Find them all",IDD_FINDINFILES_FIND_BUTTON,217,20,90,14,WS_GROUP - PUSHBUTTON "Close",IDCANCEL,217,99,90,14, WS_TABSTOP - + PUSHBUTTON "Find Next",IDOK,217,20,90,14,WS_GROUP + PUSHBUTTON "Count",IDCCOUNTALL,217,38,90,14 + PUSHBUTTON "Replace in files",IDD_FINDINFILES_REPLACEINFILES,217,38,90,14 + PUSHBUTTON "Find all in all opened documents",IDC_FINDALL_OPENEDFILES,217,56,90,21,BS_MULTILINE + PUSHBUTTON "&Replace",IDREPLACE,217,38,90,14 + PUSHBUTTON "Replace &All",IDREPLACEALL,217,56,90,14 + PUSHBUTTON "Replace all in all opened documents",IDC_REPLACE_OPENEDFILES,217,74,90,21,BS_MULTILINE + PUSHBUTTON "Find them all",IDD_FINDINFILES_FIND_BUTTON,217,20,90,14,WS_GROUP + PUSHBUTTON "Close",IDCANCEL,217,99,90,14 GROUPBOX "Transparency",IDC_TRANSPARENT_GRPBOX,227,123,83,49 CONTROL "",IDC_TRANSPARENT_CHECK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,223,123,9,10 CONTROL "On lose focus",IDC_TRANSPARENT_LOSSFOCUS_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,237,135,69,10 diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h index 59fcb3925..0e0f83c3d 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h @@ -56,6 +56,7 @@ #define IDD_FINDINFILES_GOBACK_BUTTON 1657 #define IDD_FINDINFILES_RECURSIVE_CHECK 1658 #define IDD_FINDINFILES_INHIDDENDIR_CHECK 1659 +#define IDD_FINDINFILES_REPLACEINFILES 1660 #define IDD_FINDRESULT 1670 diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index e3e2215ec..75602fe58 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -61,6 +61,7 @@ typedef void * SCINTILLA_PTR; #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) const int NB_FOLDER_STATE = 7;