// 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 "ILexer.h" #include "Lexilla.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 TEXT("%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 0001 const int TAB_DRAWINACTIVETAB = 2; //0000 0000 0010 const int TAB_DRAGNDROP = 4; //0000 0000 0100 const int TAB_REDUCE = 8; //0000 0000 1000 const int TAB_CLOSEBUTTON = 16; //0000 0001 0000 const int TAB_DBCLK2CLOSE = 32; //0000 0010 0000 const int TAB_VERTICAL = 64; //0000 0100 0000 const int TAB_MULTILINE = 128; //0000 1000 0000 const int TAB_HIDE = 256; //0001 0000 0000 const int TAB_QUITONEMPTY = 512; //0010 0000 0000 const int TAB_ALTICONS = 1024; //0100 0000 0000 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, uniUTF8=1, uni16BE=2, uni16LE=3, uniCookie=4, uni7Bit=5, uni16BE_NoBOM=6, uni16LE_NoBOM=7, 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}; enum urlMode {urlDisable = 0, urlNoUnderLineFg, urlUnderLineFg, urlNoUnderLineBg, urlUnderLineBg, urlMin = urlDisable, urlMax = urlUnderLineBg}; 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 COPYDATA_PARAMS = 0; const int COPYDATA_FILENAMESA = 1; 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 const TCHAR fontSizeStrs[][3] = {TEXT(""), TEXT("5"), TEXT("6"), TEXT("7"), TEXT("8"), TEXT("9"), TEXT("10"), TEXT("11"), TEXT("12"), TEXT("14"), TEXT("16"), TEXT("18"), TEXT("20"), TEXT("22"), TEXT("24"), TEXT("26"), TEXT("28")}; const TCHAR localConfFile[] = TEXT("doLocalConf.xml"); const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml"); // issue xml/log file name const TCHAR nppLogNetworkDriveIssue[] = TEXT("nppLogNetworkDriveIssue"); const TCHAR nppLogNulContentCorruptionIssue[] = TEXT("nppLogNulContentCorruptionIssue"); void cutString(const TCHAR *str2cut, std::vector & patternVect); void cutStringBy(const TCHAR *str2cut, std::vector & patternVect, char byChar, bool allowEmptyStr); 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 TCHAR *fn, const TCHAR *ln, int encoding, bool userReadOnly, const Position& pos, const TCHAR *backupFilePath, FILETIME originalFileLastModifTimestamp, const MapPosition & mapPos) : _isUserReadOnly(userReadOnly), _encoding(encoding), Position(pos), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos) { if (fn) _fileName = fn; if (ln) _langName = ln; if (backupFilePath) _backupFilePath = backupFilePath; } sessionFileInfo(generic_string fn) : _fileName(fn) {} generic_string _fileName; generic_string _langName; std::vector _marks; std::vector _foldStates; int _encoding = -1; bool _isUserReadOnly = false; bool _isMonitoring = false; generic_string _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; generic_string _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; generic_string _localizationPath; generic_string _udlName; generic_string _pluginMessage; generic_string _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]; wchar_t _pluginMessage[MAX_PATH]; 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; } }; struct FloatingWindowInfo { int _cont = 0; RECT _pos = {}; 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 { generic_string _name; int _internalID = -1; int _currContainer = -1; int _prevContainer = -1; bool _isVisible = false; PluginDlgDockingInfo(const TCHAR* pluginName, int id, int curr, int prev, bool isVis) : _internalID(id), _currContainer(curr), _prevContainer(prev), _isVisible(isVis), _name(pluginName) {} 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) {}; }; struct DockingManagerData final { int _leftWidth = 200; int _rightWidth = 200; int _topHeight = 200; int _bottomHight = 200; std::vector _flaotingWindowInfo; std::vector _pluginDockInfo; std::vector _containerTabInfo; bool getFloatingRCFrom(int floatCont, RECT& rc) const { for (size_t i = 0, fwiLen = _flaotingWindowInfo.size(); i < fwiLen; ++i) { if (_flaotingWindowInfo[i]._cont == floatCont) { rc.left = _flaotingWindowInfo[i]._pos.left; rc.top = _flaotingWindowInfo[i]._pos.top; rc.right = _flaotingWindowInfo[i]._pos.right; rc.bottom = _flaotingWindowInfo[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; generic_string _styleDesc; COLORREF _fgColor = COLORREF(STYLE_NOT_USED); COLORREF _bgColor = COLORREF(STYLE_NOT_USED); int _colorStyle = COLORSTYLE_ALL; bool _isFontEnabled = false; generic_string _fontName; int _fontStyle = FONTSTYLE_NONE; int _fontSize = STYLE_NOT_USED; int _nesting = FONTSTYLE_NONE; int _keywordClass = STYLE_NOT_USED; generic_string _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) { assert(index < _styleVect.size()); return _styleVect[index]; }; void addStyler(int styleID, TiXmlNode *styleNode); void addStyler(int styleID, const generic_string& 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 generic_string& name) { for (size_t i = 0; i < _styleVect.size(); ++i) { if (_styleVect[i]._styleDesc == name) return &(_styleVect[i]); } return nullptr; }; protected: std::vector