📄 findreplacedlg.cpp
字号:
//this file is part of notepad++
//Copyright (C)2003 Don HO ( donho@altern.org )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "FindReplaceDlg.h"
#include "ScintillaEditView.h"
#include "Notepad_plus_msgs.h"
#include "constant.h"
// need this header for SHBrowseForFolder
#include <Shlobj.h>
void addText2Combo(const char * txt2add, HWND hCombo)
{
if (!hCombo) return;
if (!strcmp(txt2add, "")) return;
char text[MAX_PATH];
int count = ::SendMessage(hCombo, CB_GETCOUNT, 0, 0);
bool hasFound = false;
int i = 0;
for ( ; i < count ; i++)
{
::SendMessage(hCombo, CB_GETLBTEXT, i, (LPARAM)text);
if (!strcmp(txt2add, text))
{
hasFound = true;
break;
}
}
if (!hasFound)
i = ::SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)txt2add);
::SendMessage(hCombo, CB_SETCURSEL, i, 0);
}
// Set a call back with the handle after init to set the path.
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/callbackfunctions/browsecallbackproc.asp
static int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData)
{
if (uMsg == BFFM_INITIALIZED)
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
return 0;
};
// important : to activate all styles
const int STYLING_MASK = 255;
void FindInFilesDlg::doDialog(bool isRTL)
{
if (!isCreated())
create(IDD_FINDINFILES_DLG, isRTL);
char dir[MAX_PATH];
::GetCurrentDirectory(sizeof(dir), dir);
::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, dir);
LangType lt;
::SendMessage(_hParent, WM_COMMAND, IDC_GETCURRENTDOCTYPE, (LPARAM)<);
const char *ext = NppParameters::getInstance()->getLangExtFromLangType(lt);
if (ext && ext[0])
{
string filtres = "";
vector<string> vStr;
cutString(ext, vStr);
for (size_t i = 0 ; i < vStr.size() ; i++)
{
filtres += "*.";
filtres += vStr[i] + " ";
}
::SetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filtres.c_str());
}
display();
}
BOOL CALLBACK FindInFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND :
{
switch (wParam)
{
case IDCANCEL :
display(false);
return TRUE;
case IDOK :
{
char filters[256];
char directory[MAX_PATH];
::GetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters, sizeof(filters));
addText2Combo(filters, ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO));
_filters = filters;
::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, sizeof(directory));
addText2Combo(directory, ::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO));
_directory = directory;
if (directory[strlen(directory)-1] != '\\')
_directory += "\\";
::SendMessage(_hParent, WM_COMMAND, IDC_FINDINFILES_LAUNCH, 0);
display(false);
return TRUE;
}
case IDD_FINDINFILES_BROWSE_BUTTON :
{
// This code was copied and slightly modifed from:
// http://www.bcbdev.com/faqs/faq62.htm
// SHBrowseForFolder returns a PIDL. The memory for the PIDL is
// allocated by the shell. Eventually, we will need to free this
// memory, so we need to get a pointer to the shell malloc COM
// object that will free the PIDL later on.
LPMALLOC pShellMalloc = 0;
if (::SHGetMalloc(&pShellMalloc) == NO_ERROR)
{
// If we were able to get the shell malloc object,
// then proceed by initializing the BROWSEINFO stuct
BROWSEINFO info;
memset(&info, 0, sizeof(info));
info.hwndOwner = _hSelf;
info.pidlRoot = NULL;
char szDisplayName[MAX_PATH];
info.pszDisplayName = szDisplayName;
string title = "Select a folder to search from";
info.lpszTitle = title.c_str();
info.ulFlags = 0;
info.lpfn = BrowseCallbackProc;
char directory[MAX_PATH];
::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, sizeof(directory));
info.lParam = reinterpret_cast<LPARAM>(directory);
// Execute the browsing dialog.
LPITEMIDLIST pidl = ::SHBrowseForFolder(&info);
// pidl will be null if they cancel the browse dialog.
// pidl will be not null when they select a folder.
if (pidl)
{
// Try to convert the pidl to a display string.
// Return is true if success.
char szDir[MAX_PATH];
if (::SHGetPathFromIDList(pidl, szDir))
// Set edit control to the directory path.
::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, szDir);
pShellMalloc->Free(pidl);
}
pShellMalloc->Release();
}
return TRUE;
}
}
}
}
return FALSE;
}
void FindReplaceDlg::create(int dialogID, bool isRTL)
{
StaticDialog::create(dialogID, isRTL);
_currentStatus = REPLACE;
initOptionsFromDlg();
if ((NppParameters::getInstance())->isTransparentAvailable())
{
::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_CHECK), SW_SHOW);
::ShowWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), SW_SHOW);
::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(20, 200));
::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETPOS, TRUE, 150);
if (!isCheckedOrNot(IDC_PERCENTAGE_SLIDER))
::EnableWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), FALSE);
}
RECT rect;
::GetWindowRect(_hSelf, &rect);
_findW = _replaceW = rect.right - rect.left;
_findH = _replaceH = rect.bottom - rect.top;
_findInFilesDlg.init(_hInst, _hSelf);
goToCenter();
}
void FindReplaceDlg::notify(SCNotification *notification)
{
switch (notification->nmhdr.code)
{
case SCN_DOUBLECLICK :
{
try {
// in getInfo() method the previous line is renew as current for next call
const FoundInfo &fInfo = _pFinder->getInfo();
int markedLine = _pFinder->getCurrentMarkedLine();
// now we clean the previous mark
if (markedLine != -1)
(*_ppEditView)->execute(SCI_MARKERDELETE, markedLine, MARK_SYMBOLE);
// After cleaning the previous mark, we can swich to another document
::SendMessage(_hParent, WM_DOOPEN, 0, (LPARAM)fInfo._fullPath.c_str());
(*_ppEditView)->execute(SCI_SETSEL, fInfo._start, fInfo._end);
// we set the current mark here
int nb = (*_ppEditView)->getCurrentLineNumber();
_pFinder->setCurrentMarkedLine(nb);
(*_ppEditView)->execute(SCI_MARKERADD, nb, MARK_SYMBOLE);
// Then we colourise the double clicked line
_pFinder->setFinderStyle();
//_pFinder->showMargin(ScintillaEditView::_SC_MARGE_FOLDER, false);
_pFinder->execute(SCI_SETLEXER, SCLEX_NULL);
_pFinder->execute(SCI_STYLESETEOLFILLED, SCE_UNIVERSAL_FOUND_STYLE, true);
int lno = _pFinder->getCurrentLineNumber();
int start = _pFinder->execute(SCI_POSITIONFROMLINE, lno);
int end = _pFinder->execute(SCI_GETLINEENDPOSITION, lno);
//
_pFinder->execute(SCI_STARTSTYLING, start, STYLING_MASK);
_pFinder->execute(SCI_SETSTYLING, end - start + 2, SCE_UNIVERSAL_FOUND_STYLE);
_pFinder->execute(SCI_COLOURISE,start, end + 1);
_pFinder->execute(SCI_SETCURRENTPOS, start);
_pFinder->execute(SCI_SETANCHOR, start);
} catch(...){
}
break;
}
default :
break;
}
}
BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG :
{
// Wrap arround active by default
::SendDlgItemMessage(_hSelf, IDWRAP, BM_SETCHECK, BST_CHECKED, 0);
return TRUE;
}
case WM_HSCROLL :
{
if ((HWND)lParam == ::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER))
{
int percent = ::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0);
(NppParameters::getInstance())->SetTransparent(_hSelf, percent);
}
return TRUE;
}
case WM_SIZE:
{
resizeFinder();
resizeStatusBar();
return FALSE;
}
case WM_NOTIFY:
{
notify(reinterpret_cast<SCNotification *>(lParam));
return FALSE;
}
case WM_ACTIVATE :
{
CharacterRange cr = (*_ppEditView)->getSelection();
bool isSelected = (cr.cpMax - cr.cpMin) != 0;
if (!isSelected)
{
::SendDlgItemMessage(_hSelf, IDC_IN_SELECTION_CHECK, BM_SETCHECK, BST_UNCHECKED, 0);
_isInSelection = false;
}
::EnableWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), isSelected);
return TRUE;
}
case WM_MODELESSDIALOG :
return ::SendMessage(_hParent, WM_MODELESSDIALOG, wParam, lParam);
case WM_COMMAND :
{
switch (wParam)
{
case IDCANCEL : // Close
display(false);
if (_findInFilesDlg.isCreated())
_findInFilesDlg.display(false);
return TRUE;
case IDOK : // Find Next
processFindNext();
return TRUE;
case IDREPLACE :
processReplace();
return TRUE;
case IDSWITCH :
_currentStatus = !_currentStatus;
doDialog(_currentStatus);
return TRUE;
case IDREPLACEALL :
{
(*_ppEditView)->execute(SCI_BEGINUNDOACTION);
int nbReplaced = processAll(REPLACE_ALL);
(*_ppEditView)->execute(SCI_ENDUNDOACTION);
char result[64];
if (nbReplaced < 0)
strcpy(result, "The regular expression to search is formed badly");
else
{
itoa(nbReplaced, result, 10);
strcat(result, " tokens are replaced.");
}
::MessageBox(_hSelf, result, "", MB_OK);
return TRUE;
}
case IDC_REPLACE_OPENEDFILES :
replaceAllInOpenedDocs();
return TRUE;
case IDC_FINDALL_OPENEDFILES :
findAllIn(ALL_OPEN_DOCS);
return TRUE;
case IDC_FINDINFILES :
_findInFilesDlg.doDialog(_isRTL);
return TRUE;
case IDC_GETCURRENTDOCTYPE :
*((LangType *)lParam) = (*_ppEditView)->getCurrentDocType();
return TRUE;
case IDC_FINDINFILES_LAUNCH : // Virtual Control which don't exist
{
findAllIn(FILES_IN_DIR);
return TRUE;
}
case IDCMARKALL :
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -