// This file is part of Notepad++ project // Copyright (C)2021 Don HO // 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 3 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, see . #pragma once #include "tinyxmlA.h" #include "tinyxml.h" #include "Scintilla.h" #include "ScintillaRef.h" #include "ToolBar.h" #include "UserDefineLangReference.h" #include "colors.h" #include "shortcut.h" #include "ContextMenu.h" #include "dpiManager.h" #include "NppDarkMode.h" #include #include #include #include #include #include "ILexer.h" #include "Lexilla.h" #include "DockingCont.h" #ifdef _WIN64 #ifdef _M_ARM64 #define ARCH_TYPE IMAGE_FILE_MACHINE_ARM64 #else #define ARCH_TYPE IMAGE_FILE_MACHINE_AMD64 #endif #else #define ARCH_TYPE IMAGE_FILE_MACHINE_I386 #endif #define CMD_INTERPRETER L"%COMSPEC%" class NativeLangSpeaker; const bool POS_VERTICAL = true; const bool POS_HORIZOTAL = false; const int UDD_SHOW = 1; // 0000 0001 const int UDD_DOCKED = 2; // 0000 0010 // 0 : 0000 0000 hide & undocked // 1 : 0000 0001 show & undocked // 2 : 0000 0010 hide & docked // 3 : 0000 0011 show & docked const int TAB_DRAWTOPBAR = 1; // 0000 0000 0000 0001 const int TAB_DRAWINACTIVETAB = 2; // 0000 0000 0000 0010 const int TAB_DRAGNDROP = 4; // 0000 0000 0000 0100 const int TAB_REDUCE = 8; // 0000 0000 0000 1000 const int TAB_CLOSEBUTTON = 16; // 0000 0000 0001 0000 const int TAB_DBCLK2CLOSE = 32; // 0000 0000 0010 0000 const int TAB_VERTICAL = 64; // 0000 0000 0100 0000 const int TAB_MULTILINE = 128; // 0000 0000 1000 0000 const int TAB_HIDE = 256; // 0000 0001 0000 0000 const int TAB_QUITONEMPTY = 512; // 0000 0010 0000 0000 const int TAB_ALTICONS = 1024; // 0000 0100 0000 0000 const int TAB_PINBUTTON = 2048; // 0000 1000 0000 0000 const int TAB_INACTIVETABSHOWBUTTON = 4096; // 0001 0000 0000 0000 const bool activeText = true; const bool activeNumeric = false; enum class EolType: std::uint8_t { windows, macos, unix, // special values unknown, // can not be the first value for legacy code osdefault = windows, }; /*! ** \brief Convert an int into a FormatType ** \param value An arbitrary int ** \param defvalue The default value to use if an invalid value is provided */ EolType convertIntToFormatType(int value, EolType defvalue = EolType::osdefault); enum UniMode { uni8Bit = 0, // ANSI uniUTF8 = 1, // UTF-8 with BOM uni16BE = 2, // UTF-16 Big Ending with BOM uni16LE = 3, // UTF-16 Little Ending with BOM uniCookie = 4, // UTF-8 without BOM uni7Bit = 5, // uni16BE_NoBOM = 6, // UTF-16 Big Ending without BOM uni16LE_NoBOM = 7, // UTF-16 Little Ending without BOM uniEnd}; enum ChangeDetect { cdDisabled = 0x0, cdEnabledOld = 0x01, cdEnabledNew = 0x02, cdAutoUpdate = 0x04, cdGo2end = 0x08 }; enum BackupFeature {bak_none = 0, bak_simple = 1, bak_verbose = 2}; enum OpenSaveDirSetting {dir_followCurrent = 0, dir_last = 1, dir_userDef = 2}; enum MultiInstSetting {monoInst = 0, multiInstOnSession = 1, multiInst = 2}; enum writeTechnologyEngine {defaultTechnology = 0, directWriteTechnology = 1, directWriteTechnologyUnavailable = 2}; enum urlMode {urlDisable = 0, urlNoUnderLineFg, urlUnderLineFg, urlNoUnderLineBg, urlUnderLineBg, urlMin = urlDisable, urlMax = urlUnderLineBg}; enum AutoIndentMode { autoIndent_none = 0, autoIndent_advanced = 1, autoIndent_basic = 2 }; enum SysTrayAction { sta_none = 0, sta_minimize = 1, sta_close = 2, sta_minimize_close = 3 }; const int LANG_INDEX_INSTR = 0; const int LANG_INDEX_INSTR2 = 1; const int LANG_INDEX_TYPE = 2; const int LANG_INDEX_TYPE2 = 3; const int LANG_INDEX_TYPE3 = 4; const int LANG_INDEX_TYPE4 = 5; const int LANG_INDEX_TYPE5 = 6; const int LANG_INDEX_TYPE6 = 7; const int LANG_INDEX_TYPE7 = 8; const int LANG_INDEX_SUBSTYLE1 = 9; const int LANG_INDEX_SUBSTYLE2 = 10; const int LANG_INDEX_SUBSTYLE3 = 11; const int LANG_INDEX_SUBSTYLE4 = 12; const int LANG_INDEX_SUBSTYLE5 = 13; const int LANG_INDEX_SUBSTYLE6 = 14; const int LANG_INDEX_SUBSTYLE7 = 15; const int LANG_INDEX_SUBSTYLE8 = 16; const int COPYDATA_PARAMS = 0; //const int COPYDATA_FILENAMESA = 1; // obsolete, no more useful const int COPYDATA_FILENAMESW = 2; const int COPYDATA_FULL_CMDLINE = 3; #define PURE_LC_NONE 0 #define PURE_LC_BOL 1 #define PURE_LC_WSP 2 #define DECSEP_DOT 0 #define DECSEP_COMMA 1 #define DECSEP_BOTH 2 #define DROPBOX_AVAILABLE 1 #define ONEDRIVE_AVAILABLE 2 #define GOOGLEDRIVE_AVAILABLE 4 #define NPP_STYLING_FILESIZE_LIMIT_DEFAULT (200 * 1024 * 1024) // 200MB+ file won't be styled const int FINDREPLACE_INSELECTION_THRESHOLD_DEFAULT = 1024; const wchar_t fontSizeStrs[][3] = {L"", L"5", L"6", L"7", L"8", L"9", L"10", L"11", L"12", L"14", L"16", L"18", L"20", L"22", L"24", L"26", L"28"}; const wchar_t localConfFile[] = L"doLocalConf.xml"; const wchar_t notepadStyleFile[] = L"asNotepad.xml"; // issue xml/log file name const wchar_t nppLogNetworkDriveIssue[] = L"nppLogNetworkDriveIssue"; const wchar_t nppLogNulContentCorruptionIssue[] = L"nppLogNulContentCorruptionIssue"; void cutString(const wchar_t *str2cut, std::vector & patternVect); void cutStringBy(const wchar_t *str2cut, std::vector & patternVect, char byChar, bool allowEmptyStr); // style names const wchar_t g_npcStyleName[] = L"Non-printing characters custom color"; struct Position { intptr_t _firstVisibleLine = 0; intptr_t _startPos = 0; intptr_t _endPos = 0; intptr_t _xOffset = 0; intptr_t _selMode = 0; intptr_t _scrollWidth = 1; intptr_t _offset = 0; intptr_t _wrapCount = 0; }; struct MapPosition { private: intptr_t _maxPeekLenInKB = 512; // 512 KB public: intptr_t _firstVisibleDisplayLine = -1; intptr_t _firstVisibleDocLine = -1; // map intptr_t _lastVisibleDocLine = -1; // map intptr_t _nbLine = -1; // map intptr_t _higherPos = -1; // map intptr_t _width = -1; intptr_t _height = -1; intptr_t _wrapIndentMode = -1; intptr_t _KByteInDoc = _maxPeekLenInKB; bool _isWrap = false; bool isValid() const { return (_firstVisibleDisplayLine != -1); }; bool canScroll() const { return (_KByteInDoc < _maxPeekLenInKB); }; // _nbCharInDoc < _maxPeekLen : Don't scroll the document for the performance issue }; struct sessionFileInfo : public Position { sessionFileInfo(const wchar_t* fn, const wchar_t *ln, int encoding, bool userReadOnly,bool isPinned, const Position& pos, const wchar_t *backupFilePath, FILETIME originalFileLastModifTimestamp, const MapPosition & mapPos) : Position(pos), _encoding(encoding), _isUserReadOnly(userReadOnly), _isPinned(isPinned), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos) { if (fn) _fileName = fn; if (ln) _langName = ln; if (backupFilePath) _backupFilePath = backupFilePath; } sessionFileInfo(const std::wstring& fn) : _fileName(fn) {} std::wstring _fileName; std::wstring _langName; std::vector _marks; std::vector _foldStates; int _encoding = -1; bool _isUserReadOnly = false; bool _isMonitoring = false; int _individualTabColour = -1; bool _isRTL = false; bool _isPinned = false; std::wstring _backupFilePath; FILETIME _originalFileLastModifTimestamp {}; MapPosition _mapPos; }; struct Session { size_t nbMainFiles() const {return _mainViewFiles.size();}; size_t nbSubFiles() const {return _subViewFiles.size();}; size_t _activeView = 0; size_t _activeMainIndex = 0; size_t _activeSubIndex = 0; bool _includeFileBrowser = false; std::wstring _fileBrowserSelectedItem; std::vector _mainViewFiles; std::vector _subViewFiles; std::vector _fileBrowserRoots; }; struct CmdLineParams { bool _isNoPlugin = false; bool _isReadOnly = false; bool _isNoSession = false; bool _isNoTab = false; bool _isPreLaunch = false; bool _showLoadingTime = false; bool _alwaysOnTop = false; intptr_t _line2go = -1; intptr_t _column2go = -1; intptr_t _pos2go = -1; POINT _point = {}; bool _isPointXValid = false; bool _isPointYValid = false; bool _isSessionFile = false; bool _isRecursive = false; bool _openFoldersAsWorkspace = false; bool _monitorFiles = false; LangType _langType = L_EXTERNAL; std::wstring _localizationPath; std::wstring _udlName; std::wstring _pluginMessage; std::wstring _easterEggName; unsigned char _quoteType = 0; int _ghostTypingSpeed = -1; // -1: initial value 1: slow 2: fast 3: speed of light CmdLineParams() { _point.x = 0; _point.y = 0; } bool isPointValid() const { return _isPointXValid && _isPointYValid; } }; // A POD class to send CmdLineParams through WM_COPYDATA and to Notepad_plus::loadCommandlineParams struct CmdLineParamsDTO { bool _isReadOnly = false; bool _isNoSession = false; bool _isSessionFile = false; bool _isRecursive = false; bool _openFoldersAsWorkspace = false; bool _monitorFiles = false; intptr_t _line2go = 0; intptr_t _column2go = 0; intptr_t _pos2go = 0; LangType _langType = L_EXTERNAL; wchar_t _udlName[MAX_PATH] = {'\0'}; wchar_t _pluginMessage[MAX_PATH] = {'\0'}; static CmdLineParamsDTO FromCmdLineParams(const CmdLineParams& params) { CmdLineParamsDTO dto; dto._isReadOnly = params._isReadOnly; dto._isNoSession = params._isNoSession; dto._isSessionFile = params._isSessionFile; dto._isRecursive = params._isRecursive; dto._openFoldersAsWorkspace = params._openFoldersAsWorkspace; dto._monitorFiles = params._monitorFiles; dto._line2go = params._line2go; dto._column2go = params._column2go; dto._pos2go = params._pos2go; dto._langType = params._langType; wcsncpy(dto._udlName, params._udlName.c_str(), MAX_PATH); wcsncpy(dto._pluginMessage, params._pluginMessage.c_str(), MAX_PATH); return dto; } }; #define FWI_PANEL_WH_DEFAULT 100 struct FloatingWindowInfo { int _cont = 0; RECT _pos = { 0, 0, FWI_PANEL_WH_DEFAULT, FWI_PANEL_WH_DEFAULT }; FloatingWindowInfo(int cont, int x, int y, int w, int h) : _cont(cont) { _pos.left = x; _pos.top = y; _pos.right = w; _pos.bottom = h; } }; struct PluginDlgDockingInfo final { std::wstring _name; int _internalID = -1; int _currContainer = -1; int _prevContainer = -1; bool _isVisible = false; PluginDlgDockingInfo(const wchar_t* pluginName, int id, int curr, int prev, bool isVis) : _name(pluginName), _internalID(id), _currContainer(curr), _prevContainer(prev), _isVisible(isVis) {} bool operator == (const PluginDlgDockingInfo& rhs) const { return _internalID == rhs._internalID and _name == rhs._name; } }; struct ContainerTabInfo final { int _cont = 0; int _activeTab = 0; ContainerTabInfo(int cont, int activeTab) : _cont(cont), _activeTab(activeTab) {}; }; #define DMD_PANEL_WH_DEFAULT 200 struct DockingManagerData final { int _leftWidth = DMD_PANEL_WH_DEFAULT; int _rightWidth = DMD_PANEL_WH_DEFAULT; int _topHeight = DMD_PANEL_WH_DEFAULT; int _bottomHeight = DMD_PANEL_WH_DEFAULT; // will be updated at runtime (Notepad_plus::init & DockingManager::runProc DMM_MOVE_SPLITTER) LONG _minDockedPanelVisibility = HIGH_CAPTION; SIZE _minFloatingPanelSize = { (HIGH_CAPTION) * 6, HIGH_CAPTION }; std::vector _floatingWindowInfo; std::vector _pluginDockInfo; std::vector _containerTabInfo; bool getFloatingRCFrom(int floatCont, RECT& rc) const { for (size_t i = 0, fwiLen = _floatingWindowInfo.size(); i < fwiLen; ++i) { if (_floatingWindowInfo[i]._cont == floatCont) { rc.left = _floatingWindowInfo[i]._pos.left; rc.top = _floatingWindowInfo[i]._pos.top; rc.right = _floatingWindowInfo[i]._pos.right; rc.bottom = _floatingWindowInfo[i]._pos.bottom; return true; } } return false; } }; const int FONTSTYLE_NONE = 0; const int FONTSTYLE_BOLD = 1; const int FONTSTYLE_ITALIC = 2; const int FONTSTYLE_UNDERLINE = 4; const int STYLE_NOT_USED = -1; const int COLORSTYLE_FOREGROUND = 0x01; const int COLORSTYLE_BACKGROUND = 0x02; const int COLORSTYLE_ALL = COLORSTYLE_FOREGROUND|COLORSTYLE_BACKGROUND; struct Style final { int _styleID = STYLE_NOT_USED; std::wstring _styleDesc; COLORREF _fgColor = COLORREF(STYLE_NOT_USED); COLORREF _bgColor = COLORREF(STYLE_NOT_USED); int _colorStyle = COLORSTYLE_ALL; bool _isFontEnabled = false; std::wstring _fontName; int _fontStyle = STYLE_NOT_USED; int _fontSize = STYLE_NOT_USED; int _nesting = FONTSTYLE_NONE; int _keywordClass = STYLE_NOT_USED; std::wstring _keywords; }; struct GlobalOverride final { bool isEnable() const {return (enableFg || enableBg || enableFont || enableFontSize || enableBold || enableItalic || enableUnderLine);} bool enableFg = false; bool enableBg = false; bool enableFont = false; bool enableFontSize = false; bool enableBold = false; bool enableItalic = false; bool enableUnderLine = false; }; struct StyleArray { auto begin() { return _styleVect.begin(); }; auto end() { return _styleVect.end(); }; void clear() { _styleVect.clear(); }; Style& getStyler(size_t index) { if (index >= _styleVect.size()) throw std::out_of_range("Styler index out of range"); return _styleVect[index]; }; void addStyler(int styleID, TiXmlNode *styleNode); void addStyler(int styleID, const std::wstring& styleName) { _styleVect.emplace_back(); Style& s = _styleVect.back(); s._styleID = styleID; s._styleDesc = styleName; s._fgColor = black; s._bgColor = white; }; Style* findByID(int id) { for (size_t i = 0; i < _styleVect.size(); ++i) { if (_styleVect[i]._styleID == id) return &(_styleVect[i]); } return nullptr; }; Style* findByName(const std::wstring& name) { for (size_t i = 0; i < _styleVect.size(); ++i) { if (_styleVect[i]._styleDesc == name) return &(_styleVect[i]); } return nullptr; }; protected: std::vector