📄 findreplacedlg.svn-base
字号:
//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"
#include "common_func.h"
#include <uxtheme.h>
#include "UniConversion.h"
typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD);
void addText2Combo(const char * txt2add, HWND hCombo, bool isUTF8)
{
if (!hCombo) return;
if (!strcmp(txt2add, "")) return;
char text[MAX_PATH];
WCHAR textW[MAX_PATH*2];
int count = ::SendMessage(hCombo, CB_GETCOUNT, 0, 0);
bool hasFound = false;
int i = 0;
WCHAR wchars2Add[256];
if (isUTF8)
::MultiByteToWideChar(CP_UTF8, 0, txt2add, -1, wchars2Add, 256 / sizeof(WCHAR));
for ( ; i < count ; i++)
{
if (isUTF8)
{
::SendMessageW(hCombo, CB_GETLBTEXT, i, (LPARAM)textW);
if (!wcscmp(wchars2Add, textW))
{
hasFound = true;
break;
}
}
else
{
::SendMessage(hCombo, CB_GETLBTEXT, i, (LPARAM)text);
if (!strcmp(txt2add, text))
{
hasFound = true;
break;
}
}
}
if (!hasFound)
{
if (!isUTF8)
i = ::SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)txt2add);
else
{
i = ::SendMessageW(hCombo, CB_ADDSTRING, 0, (LPARAM)wchars2Add);
}
}
::SendMessage(hCombo, CB_SETCURSEL, i, 0);
}
string getTextFromCombo(HWND hCombo, bool isUnicode)
{
char str[MAX_PATH];
if (isUnicode)
{
WCHAR wchars[MAX_PATH];
::SendMessageW(hCombo, WM_GETTEXT, MAX_PATH, (LPARAM)wchars);
::WideCharToMultiByte(CP_UTF8, 0, wchars, -1, str, 256, NULL, NULL);
}
else
{
::SendMessage(hCombo, WM_GETTEXT, MAX_PATH, (LPARAM)str);
}
return string(str);
}
/*
// 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 FindReplaceDlg::create(int dialogID, bool isRTL)
{
StaticDialog::create(dialogID, isRTL);
_currentStatus = REPLACE_DLG;
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);
getClientRect(rect);
_tab.init(_hInst, _hSelf, false, false, true);
_tab.setFont("Tahoma", 13);
const char *find = "Find";
const char *replace = "Replace";
const char *findInFiles = "Find in files";
NppParameters::FindDlgTabTitiles & fdTitles = NppParameters::getInstance()->getFindDlgTabTitiles();
if (fdTitles.isWellFilled())
{
find = fdTitles._find.c_str();
replace = fdTitles._replace.c_str();
findInFiles = fdTitles._findInFiles.c_str();
}
_tab.insertAtEnd(find);
_tab.insertAtEnd(replace);
_tab.insertAtEnd(findInFiles);
_tab.reSizeTo(rect);
_tab.display();
ETDTProc enableDlgTheme = (ETDTProc)::SendMessage(_hParent, NPPM_GETENABLETHEMETEXTUREFUNC, 0, 0);
if (enableDlgTheme)
enableDlgTheme(_hSelf, ETDT_ENABLETAB);
goToCenter();
}
void FindReplaceDlg::updateCombos()
{
bool isUnicode = (*_ppEditView)->getCurrentBuffer().getUnicodeMode() != uni8Bit;
HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH);
addText2Combo(getTextFromCombo(hReplaceCombo, isUnicode).c_str(), hReplaceCombo, isUnicode);
HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT);
addText2Combo(getTextFromCombo(hFindCombo, isUnicode).c_str(), hFindCombo, isUnicode);
}
bool Finder::notify(SCNotification *notification)
{
switch (notification->nmhdr.code)
{
case SCN_MARGINCLICK:
{
if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER)
{
_scintView.marginClick(notification->position, notification->modifiers);
}
break;
}
case SCN_DOUBLECLICK :
{
try {
int currentPos = _scintView.execute(SCI_GETCURRENTPOS);
if (currentPos)
{
char prevChar = (char)_scintView.execute(SCI_GETCHARAT, currentPos - 1);
if (prevChar == 0x0A)
currentPos -= 2;
}
int lno = _scintView.execute(SCI_LINEFROMPOSITION, currentPos);
int start = _scintView.execute(SCI_POSITIONFROMLINE, lno);
int end = _scintView.execute(SCI_GETLINEENDPOSITION, lno);
if (_scintView.execute(SCI_GETFOLDLEVEL, lno) & SC_FOLDLEVELHEADERFLAG)
{
_scintView.execute(SCI_TOGGLEFOLD, lno);
_scintView.execute(SCI_SETCURRENTPOS, start);
_scintView.execute(SCI_SETANCHOR, start);
return false;
}
// in getInfo() method the previous line is renew as current for next call
const FoundInfo &fInfo = getInfo(lno);
int markedLine = 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
int cmd = getMode()==FILES_IN_DIR?WM_DOOPEN:NPPM_SWITCHTOFILE;
::SendMessage(::GetParent(_hParent), cmd, 0, (LPARAM)fInfo._fullPath.c_str());
(*_ppEditView)->execute(SCI_SETSEL, fInfo._start, fInfo._end);
// we set the current mark here
int nb = (*_ppEditView)->getCurrentLineNumber();
setCurrentMarkedLine(nb);
(*_ppEditView)->execute(SCI_MARKERADD, nb, MARK_SYMBOLE);
// Then we colourise the double clicked line
setFinderStyle();
_scintView.showMargin(ScintillaEditView::_SC_MARGE_FOLDER, true);
_scintView.execute(SCI_SETLEXER, SCLEX_NULL);
_scintView.execute(SCI_STYLESETEOLFILLED, SCE_SEARCHRESULT_KWORD3, true);
//
_scintView.execute(SCI_STARTSTYLING, start, STYLING_MASK);
_scintView.execute(SCI_SETSTYLING, end - start + 2, SCE_SEARCHRESULT_KWORD3);
_scintView.execute(SCI_COLOURISE, start, end + 1);
_scintView.execute(SCI_SETCURRENTPOS, start);
_scintView.execute(SCI_SETANCHOR, start);
return true;
} catch(...){
printStr("SCN_DOUBLECLICK problem");
}
break;
}
default :
break;
}
return false;
}
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);
if (_isRecursive)
::SendDlgItemMessage(_hSelf, IDD_FINDINFILES_RECURSIVE_CHECK, BM_SETCHECK, BST_CHECKED, 0);
RECT arc;
::GetWindowRect(::GetDlgItem(_hSelf, IDCANCEL), &arc);
_findInFilesClosePos.bottom = _replaceClosePos.bottom = _findClosePos.bottom = arc.bottom - arc.top;
_findInFilesClosePos.right = _replaceClosePos.right = _findClosePos.right = arc.right - arc.left;
POINT p;
p.x = arc.left;
p.y = arc.top;
::ScreenToClient(_hSelf, &p);
_replaceClosePos.left = p.x;
_replaceClosePos.top = p.y;
p = getLeftTopPoint(::GetDlgItem(_hSelf, IDREPLACE));
_findInFilesClosePos.left = p.x;
_findInFilesClosePos.top = p.y;
p = getLeftTopPoint(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES));
_findClosePos.left = p.x;
_findClosePos.top = p.y + 10;
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:
{
NMHDR *nmhdr = (NMHDR *)lParam;
if (nmhdr->code == TCN_SELCHANGE)
{
HWND tabHandle = _tab.getHSelf();
if (nmhdr->hwndFrom == tabHandle)
{
int indexClicked = int(::SendMessage(tabHandle, TCM_GETCURSEL, 0, 0));
doDialog((DIALOG_TYPE)indexClicked);
if ((DIALOG_TYPE)indexClicked == FINDINFILES_DLG)
{
char currentDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, currentDir);
setFindInFilesDirFilter(currentDir, NULL);
}
}
return TRUE;
}
break;
}
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 NPPM_MODELESSDIALOG :
return ::SendMessage(_hParent, NPPM_MODELESSDIALOG, wParam, lParam);
case WM_COMMAND :
{
switch (wParam)
{
case IDCANCEL : // Close
display(false);
return TRUE;
case IDOK : // Find Next
{
bool isUnicode = (*_ppEditView)->getCurrentBuffer().getUnicodeMode() != uni8Bit;
HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT);
string str2Search = getTextFromCombo(hFindCombo, isUnicode);
addText2Combo(str2Search.c_str(), hFindCombo, isUnicode);
processFindNext(str2Search.c_str());
}
return TRUE;
case IDREPLACE :
{
updateCombos();
processReplace();
return TRUE;
}
case IDREPLACEALL :
{
updateCombos();
(*_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 :
updateCombos();
replaceAllInOpenedDocs();
return TRUE;
case IDC_FINDALL_OPENEDFILES :
updateCombo(IDFINDWHAT);
findAllIn(ALL_OPEN_DOCS);
return TRUE;
case IDD_FINDINFILES_GOBACK_BUTTON :
doDialog(FIND_DLG);
return TRUE;
case IDC_GETCURRENTDOCTYPE :
*((LangType *)lParam) = (*_ppEditView)->getCurrentDocType();
return TRUE;
case IDCMARKALL :
{
updateCombo(IDFINDWHAT);
int nbMarked = processAll(MARK_ALL);
char result[64];
if (nbMarked < 0)
strcpy(result, "The regular expression to search is formed badly");
else
{
itoa(nbMarked, result, 10);
strcat(result, " tokens are found and marked");
}
::MessageBox(_hSelf, result, "", MB_OK);
return TRUE;
}
case IDC_CLEAR_ALL :
{
LangType lt = (*_ppEditView)->getCurrentDocType();
if (lt == L_TXT)
(*_ppEditView)->defineDocType(L_CPP);
(*_ppEditView)->defineDocType(lt);
(*_ppEditView)->execute(SCI_MARKERDELETEALL, MARK_SYMBOLE);
return TRUE;
}
case IDCCOUNTALL :
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -