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

📄 notepad_plus.cpp.internaldockingdlg.svn-base

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

#include <shlwapi.h>
#include "Notepad_plus.h"
#include "SysMsg.h"
#include "FileDialog.h"
#include "resource.h"
#include "printer.h"
#include "FileNameStringSplitter.h"
#include "lesDlgs.h"
#include "Utf8_16.h"
#include "regExtDlg.h"
#include "RunDlg.h"
#include "ShortcutMapper.h"
#include "preferenceDlg.h"
#include "TaskListDlg.h"
#include <time.h>
#include <algorithm>

const char Notepad_plus::_className[32] = NOTEPAD_PP_CLASS_NAME;

int docTabIconIDs[] = {IDI_SAVED_ICON, IDI_UNSAVED_ICON, IDI_READONLY_ICON};
enum tb_stat {tb_saved, tb_unsaved, tb_ro};

struct SortTaskListPred
{
	ScintillaEditView *_views[2];

	SortTaskListPred(ScintillaEditView &p, ScintillaEditView &s)
	{
		_views[MAIN_VIEW] = &p;
		_views[SUB_VIEW] = &s;
	}

	bool operator()(const TaskLstFnStatus &l, const TaskLstFnStatus &r) const {
		return _views[l._iView]->getBufferAt(l._docIndex).getRecentTag() > _views[r._iView]->getBufferAt(r._docIndex).getRecentTag();
	}
};

Notepad_plus::Notepad_plus(): Window(), _mainWindowStatus(0), _pDocTab(NULL), _pEditView(NULL),
	_pMainSplitter(NULL), _isfullScreen(false),
    _recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false),\
	_isCmdScModified(false), _isMacrosScModified(false), _isUserCmdScModified(false),\
	_isScintillaKeyModified(false), _isRTL(false)
{

	TiXmlDocument *nativeLangDocRoot = (NppParameters::getInstance())->getNativeLang();
	if (nativeLangDocRoot)
	{
		_nativeLang =  nativeLangDocRoot->FirstChild("NotepadPlus");
		if (_nativeLang)
		{
			_nativeLang = _nativeLang->FirstChild("Native-Langue");
			if (_nativeLang)
			{
				TiXmlElement *element = _nativeLang->ToElement();
				const char *rtl = element->Attribute("RTL");
				if (rtl)
					_isRTL = (strcmp(rtl, "yes") == 0);
			}	
		}
	}
	else
		_nativeLang = NULL;
	
	TiXmlDocument *toolIconsDocRoot = (NppParameters::getInstance())->getToolIcons();
	if (toolIconsDocRoot)
	{
		_toolIcons =  toolIconsDocRoot->FirstChild("NotepadPlus");
		if (_toolIcons)
		{
			if ((_toolIcons = _toolIcons->FirstChild("ToolBarIcons")))
			{
				if ((_toolIcons = _toolIcons->FirstChild("Theme")))
				{
					const char *themeDir = (_toolIcons->ToElement())->Attribute("pathPrefix");

					for (TiXmlNode *childNode = _toolIcons->FirstChildElement("Icon");
						 childNode ;
						 childNode = childNode->NextSibling("Icon") )
					{
						int iIcon;
						const char *res = (childNode->ToElement())->Attribute("id", &iIcon);
						if (res)
						{
							TiXmlNode *grandChildNode = childNode->FirstChildElement("normal");
							if (grandChildNode)
							{
								TiXmlNode *valueNode = grandChildNode->FirstChild();
								//putain, enfin!!!
								if (valueNode)
								{
									string locator = themeDir?themeDir:"";
									
									locator += valueNode->Value();
									_customIconVect.push_back(iconLocator(0, iIcon, locator));
								}
							}

							grandChildNode = childNode->FirstChildElement("hover");
							if (grandChildNode)
							{
								TiXmlNode *valueNode = grandChildNode->FirstChild();
								//putain, enfin!!!
								if (valueNode)
								{
									string locator = themeDir?themeDir:"";
									
									locator += valueNode->Value();
									_customIconVect.push_back(iconLocator(1, iIcon, locator));
								}
							}

							grandChildNode = childNode->FirstChildElement("disabled");
							if (grandChildNode)
							{
								TiXmlNode *valueNode = grandChildNode->FirstChild();
								//putain, enfin!!!
								if (valueNode)
								{
									string locator = themeDir?themeDir:"";
									
									locator += valueNode->Value();
									_customIconVect.push_back(iconLocator(2, iIcon, locator));
								}
							}
						}
					}
				}
			}
		}
	}
	else
		_toolIcons = NULL;
}


void Notepad_plus::init(HINSTANCE hInst, HWND parent, const char *cmdLine)
{
	Window::init(hInst, parent);
    
	WNDCLASS nppClass;

	nppClass.style = CS_BYTEALIGNWINDOW | CS_DBLCLKS;//CS_HREDRAW | CS_VREDRAW;
	nppClass.lpfnWndProc = Notepad_plus_Proc;
	nppClass.cbClsExtra = 0;
	nppClass.cbWndExtra = 0;
	nppClass.hInstance = _hInst;
	nppClass.hIcon = ::LoadIcon(_hInst, MAKEINTRESOURCE(IDI_M30ICON));
	nppClass.hCursor = NULL;
	nppClass.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));
	nppClass.lpszMenuName = MAKEINTRESOURCE(IDR_M30_MENU);
	nppClass.lpszClassName = _className;

	if (!::RegisterClass(&nppClass))
	{
		systemMessage("System Err");
		throw int(98);
	}

	RECT workAreaRect;
	::SystemParametersInfo(SPI_GETWORKAREA,0,&workAreaRect,0);

	const NppGUI & nppGUI = (NppParameters::getInstance())->getNppGUI();

	_hSelf = ::CreateWindowEx(
					WS_EX_ACCEPTFILES | (_isRTL?WS_EX_LAYOUTRTL:0),\
					_className,\
					"Notepad++",\
					WS_OVERLAPPEDWINDOW	| WS_CLIPCHILDREN,\
					// CreateWindowEx bug : set all 0 to walk arround the pb
					0, 0, 0, 0,\
					_hParent,\
					NULL,\
					_hInst,\
					(LPVOID)this); // pass the ptr of this instantiated object
                                   // for retrive it in Notepad_plus_Proc from 
                                   // the CREATESTRUCT.lpCreateParams afterward.

	if (!_hSelf)
	{
		systemMessage("System Err");
		throw int(777);
	}

	// the routine ShowWindow should be called here immediately
	// Otherwise (if we call it after opening the files) the Scintilla
	// View contained the opened document will shift down one line.
	::MoveWindow(_hSelf, nppGUI._appPos.left + workAreaRect.left, nppGUI._appPos.top + workAreaRect.top, nppGUI._appPos.right, nppGUI._appPos.bottom, TRUE);
	::ShowWindow(_hSelf, nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW);

	if (nppGUI._rememberLastSession)
	{
		Session lastSession = (NppParameters::getInstance())->getSession();
		ScintillaEditView *cureentEditView = getCurrentEditView();
		for (size_t i = 0 ; i < lastSession._files.size() ; )
		{
			const char *pFn = lastSession._files[i]._fileName.c_str();
			if (PathFileExists(pFn))
			{
				doOpen(pFn);
				cureentEditView->getCurrentBuffer().setPosition(lastSession._files[i]);
				cureentEditView->restoreCurrentPos(lastSession._files[i]);

				for (size_t j = 0 ; j < lastSession._files[i].marks.size() ; j++)
					bookmarkAdd(lastSession._files[i].marks[j]);

				i++;
			}
			else
			{
				vector<sessionFileInfo>::iterator posIt = lastSession._files.begin() + i;
				lastSession._files.erase(posIt);
			}
		}

		if (lastSession._actifIndex < lastSession._files.size())
			_mainDocTab.activate(lastSession._actifIndex);
	}

    if (cmdLine)
    {
		LangType lt = (NppParameters::getInstance())->getDefLang();
		int ln = (NppParameters::getInstance())->getLineNumber2go(); 

		if (PathFileExists(cmdLine))
		{
			doOpen(cmdLine);
				
			if (lt != L_TXT)
				_pEditView->setCurrentDocType(lt);
			if (ln > 0)
                _pEditView->execute(SCI_GOTOLINE, ln-1);
		}
		else
		{
			FileNameStringSplitter fnss(cmdLine);
			char *pFn = NULL;
			
			for (int i = 0 ; i < fnss.size() ; i++)
			{
				pFn = (char *)fnss.getFileName(i);
				doOpen((const char *)pFn);
				
				if (lt != L_TXT)
					_pEditView->setCurrentDocType(lt);
				if (ln > 0)
					_pEditView->execute(SCI_GOTOLINE, ln-1);
			}
		}
		// restore the doc type to L_TXT
		(NppParameters::getInstance())->setDefLang(L_TXT);
		
    }

	::GetModuleFileName(NULL, _nppPath, MAX_PATH);

	setTitleWith(_pEditView->getCurrentTitle());

	setLangStatus(_pEditView->getCurrentDocType());
	checkDocState();

	// Notify plugins that Notepad++ is ready
	SCNotification scnN;
	scnN.nmhdr.code = NPPN_READY;
	scnN.nmhdr.hwndFrom = _hSelf;
	scnN.nmhdr.idFrom = 0;
	_pluginsManager.notify(&scnN);	
}

bool Notepad_plus::doSimpleOpen(const char *fileName)
{
	Utf8_16_Read UnicodeConvertor;

	FILE *fp = fopen(fileName, "rb");
    
	if (fp)
	{
		_pEditView->execute(SCI_CLEARALL, 0);
		_pEditView->setCurrentTitle(fileName);

		char data[blockSize];

		size_t lenFile = fread(data, 1, sizeof(data), fp);
		bool isNotEmpty = (lenFile != 0);

		while (lenFile > 0) 
		{
			lenFile = UnicodeConvertor.convert(data, lenFile);
			_pEditView->execute(SCI_ADDTEXT, lenFile, reinterpret_cast<LPARAM>(UnicodeConvertor.getNewBuf()));
			lenFile = int(fread(data, 1, sizeof(data), fp));
		}
		fclose(fp);
		
		UniMode unicodeMode = static_cast<UniMode>(UnicodeConvertor.getEncoding());
		(_pEditView->getCurrentBuffer()).setUnicodeMode(unicodeMode);

		if (unicodeMode != uni8Bit)
			// Override the code page if Unicode
			_pEditView->execute(SCI_SETCODEPAGE, SC_CP_UTF8);

		// Then replace the caret to the begining
		_pEditView->execute(SCI_GOTOPOS, 0);
		return true;
	}
	else
	{
		char msg[MAX_PATH + 100];
		strcpy(msg, "Can not open file \"");
		strcat(msg, fileName);
		strcat(msg, "\".");
		::MessageBox(_hSelf, msg, "ERR", MB_OK);
		return false;
	}
}


bool Notepad_plus::doOpen(const char *fileName, bool isReadOnly)
{
	int i = - 1;
	int iView;

	char longFileName[MAX_PATH];
	//::ShortToLongPathName(fileName, longFileName, 256);
	::GetFullPathName(fileName, MAX_PATH, longFileName, NULL);

	if ((i = _mainDocTab.find(longFileName)) != -1)
	{
		iView = MAIN_VIEW;
	}
	else if ((i = _subDocTab.find(longFileName)) != -1)
	{
		iView = SUB_VIEW;
	}
	if (i != -1)
	{
		switchEditViewTo(iView);
		setTitleWith(_pDocTab->activate(i));
		_pEditView->getFocus();
		if (_pTrayIco)
		{
			if (_pTrayIco->isInTray())
			{
				::ShowWindow(_hSelf, SW_SHOW);
				_pTrayIco->doTrayIcon(REMOVE);
				::SendMessage(_hSelf, WM_SIZE, 0, 0);
			}
		}
		return false;
	}

	if (!PathFileExists(longFileName))
	{
		if (::MessageBox(_hSelf, "File doesn't exist. Create it?", "Create new file", MB_YESNO) == IDYES)
		{
			FILE *f = fopen(longFileName, "w");
			fclose(f);
		}
		else
			return false;
	}


	Utf8_16_Read UnicodeConvertor;

    bool isNewDoc2Close = false;
	FILE *fp = fopen(longFileName, "rb");
    
	if (fp)
	{
        if ((_pEditView->getNbDoc() == 1) 
			&& Buffer::isUntitled(_pEditView->getCurrentTitle())
            && (!_pEditView->isCurrentDocDirty()) && (_pEditView->getCurrentDocLen() == 0))
        {
            isNewDoc2Close = true;
        }
		setTitleWith(_pDocTab->newDoc(longFileName));

		// It's VERY IMPORTANT to reset the view
		_pEditView->execute(SCI_CLEARALL);

		char data[blockSize];

		size_t lenFile = fread(data, 1, sizeof(data), fp);
		bool isNotEmpty = (lenFile != 0);

		while (lenFile > 0) 
		{
			lenFile = UnicodeConvertor.convert(data, lenFile);
			_pEditView->execute(SCI_ADDTEXT, lenFile, reinterpret_cast<LPARAM>(UnicodeConvertor.getNewBuf()));
			lenFile = int(fread(data, 1, sizeof(data), fp));
		}
		fclose(fp);
		
		// 3 formats : WIN_FORMAT, UNIX_FORMAT and MAC_FORMAT
		(_pEditView->getCurrentBuffer()).determinateFormat(isNotEmpty?UnicodeConvertor.getNewBuf():(char *)(""));
		_pEditView->execute(SCI_SETEOLMODE, _pEditView->getCurrentBuffer().getFormat());

		UniMode unicodeMode = static_cast<UniMode>(UnicodeConvertor.getEncoding());
		(_pEditView->getCurrentBuffer()).setUnicodeMode(unicodeMode);

		if (unicodeMode != uni8Bit)
			// Override the code page if Unicode
			_pEditView->execute(SCI_SETCODEPAGE, SC_CP_UTF8);

		if (isReadOnly)
			(_pEditView->getCurrentBuffer()).setReadOnly(true);

		_pEditView->getFocus();
		_pEditView->execute(SCI_SETSAVEPOINT);
		_pEditView->execute(EM_EMPTYUNDOBUFFER);

		// if file is read only, we set the view read only
		_pEditView->execute(SCI_SETREADONLY, _pEditView->isCurrentBufReadOnly());
        if (isNewDoc2Close)
            _pDocTab->closeDocAt(0);

		int numLines = int(_pEditView->execute(SCI_GETLINECOUNT));

		char numLineStr[32];
		itoa(numLines, numLineStr, 10);
		int nbDigit = strlen(numLineStr);

		if (_pEditView->increaseMaxNbDigit(nbDigit))
			_pEditView->setLineNumberWidth(_pEditView->hasMarginShowed(ScintillaEditView::_SC_MARGE_LINENUMBER));

		int maxLen = 0;
		int maxPixel = 0;
		int pixel = int(_pEditView->execute(SCI_TEXTWIDTH, STYLE_DEFAULT, (LPARAM)"P"));

		for( int i = 0 ; i < numLines ; i++ )
		{
			int len = _pEditView->getLineLength(i);
			if (maxLen < len)
			{
				maxLen = len;
				maxPixel = pixel * maxLen;
			}
		}
		int currentWidth = int(_pEditView->execute(SCI_GETSCROLLWIDTH));
		if (currentWidth < maxPixel)
        _pEditView->execute(SCI_SETSCROLLWIDTH, maxPixel);

		// Then replace the caret to the begining
		_pEditView->execute(SCI_GOTOPOS, 0);
		dynamicCheckMenuAndTB();
		_lastRecentFileList.remove(longFileName);
		if (_pTrayIco)
		{
			if (_pTrayIco->isInTray())
			{
				::ShowWindow(_hSelf, SW_SHOW);
				_pTrayIco->doTrayIcon(REMOVE);
				::SendMessage(_hSelf, WM_SIZE, 0, 0);
			}
		}

		PathRemoveFileSpec(longFileName);
		setWorkingDir(longFileName);
		return true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -