📄 notepad_plus.cpp.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.
#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;
const char *urlHttpRegExpr = "http://[a-z0-9_\\-\\+.:?&@=/%#]*";
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), _isPluginCmdScModified(false), _isRTL(false), \
_linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(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);
_winVersion = getWindowsVersion();
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);
::ShowWindow(_hSelf, nppGUI._isMaximized?SW_MAXIMIZE:SW_SHOW);
}
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, "Open File error", MB_OK);
return false;
}
}
bool Notepad_plus::doOpen(const char *fileName, bool isReadOnly)
{
char longFileName[MAX_PATH];
::GetFullPathName(fileName, MAX_PATH, longFileName, NULL);
if (switchToFile(longFileName))
{
if (_pTrayIco)
{
if (_pTrayIco->isInTray())
{
::ShowWindow(_hSelf, SW_SHOW);
_pTrayIco->doTrayIcon(REMOVE);
::SendMessage(_hSelf, WM_SIZE, 0, 0);
}
}
return false;
}
if (!PathFileExists(longFileName))
{
char str2display[128];
sprintf(str2display, "%s doesn't exist. Create it?", longFileName);
if (::MessageBox(_hSelf, str2display, "Create new file", MB_YESNO) == IDYES)
{
FILE *f = fopen(longFileName, "w");
fclose(f);
}
else
{
_lastRecentFileList.remove(longFileName);
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);
_linkTriggered = true;
_isDocModifing = false;
setWorkingDir(longFileName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -