⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findreplacedlg.svn-base

📁 Notepad++ is a generic source code editor (it tries to be anyway) and Notepad replacement written in
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
//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 + -