Merge branch 'master' into cmake-dev

* master: (22 commits)
  support high dpi
  核心编辑器组件升级到2.11
  更新2.8以后新插件接口开发说明
  update README.md. 上传银河麒麟效果图。
  更新代码到2.0,更新接口到2.0新接口,让插件可以和最新ndd兼容
  update README.md. 更新macos 2.9 效果图。
  update README.md. 更新mac效果图
  Fix build error under Ubuntu and the shortcut problem
  update README.md.
  提交使用手册。
  update README.md.
  update README.md.
  update README.md.
  update README.md. 提交2.8效果图
  update README.md. 更新UOS效果图。
  update README.md. 更新图片。
  update README.md. 更新空闲群
  update README.md. 新增群#728578708
  update README.md.
  update README.md. 调整108插件说明。
  ...
This commit is contained in:
zinface 2023-11-20 22:38:53 +08:00
commit f5d0a54ab5
80 changed files with 8395 additions and 3238 deletions

BIN
08281.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
Ndd使用说明.CHM Normal file

Binary file not shown.

View File

@ -4,11 +4,9 @@
## 项目简介
这是一个使用C++编写的文本编辑器Notepad--,可以支持Win/Linux/Mac平台。
Notepad-- 是使用C++编写的轻量级文本编辑器, 简称ndd, 可以支持Window/Mac/Linux操作系统平台。
我们的目标是要进行文本编辑类软件的国产可替代重点在国产Uos/Linux系统、Mac 系统上发展。
一个支持windows/linux/mac的文本编辑器目标是要国产替换同类软件来自中国。
我们的目标完成文本编辑类软件的国产可替代重点在国产Uos/Linux系统、Mac 系统上发展。
对比其它竞品Notepad类软件而言我们的优势是可以跨平台支持linux mac操作系统。
@ -20,8 +18,7 @@
最新版本下载地址https://gitee.com/cxasm/notepad--/releases/latest
NDD 具备插件编写功能希望广大的CPP/QT开发者加入我们插件功能均可以留上您的大名和捐赠渠道希望
开发者参与插件功能开发。
NDD 具备插件编写功能,如果您愿意开发插件,还请提交给我们。
做国人自己的免费编辑器,离不开您的支持,请通过微信捐赠我们。
@ -151,24 +148,46 @@ yay -S notepad---git
```
## 联络方式
QQ群372613546 959439826(已满) 用户群做NDD的问题反馈、功能建议等。
QQ群372613546(已满) 959439826(已满728578708空闲 用户群做NDD的问题反馈、功能建议等。
QQ群 616606091 开发群建议懂CPP/QT、愿意参与NDD项目代码贡献的开发人士加入。
## 编译或使用手册
见build目录下文档 linux开源编译及下载说明.txt
见本仓库文档 Ndd使用说明.CHM
## 效果预览
**windows效果图**
![输入图片说明](png/0828.png)
![输入图片说明](png/11.png.png)
![深色模式主题](png/2.8win.png)
![输入图片说明](png/6.png)
![编辑修改二进制](png/08282.png)
![文件对比](png/6.png)
**MacOS 效果图:**
![Mac系统运行图](png/%E6%88%AA%E5%B1%8F2023-02-26%2011.41.20.png)
![输入图片说明](png/100602.png)
![输入图片说明](png/100601.png)
![Mac系统文件对比图](png/%E6%88%AA%E5%B1%8F2023-02-26%2011.45.48.png)
![输入图片说明](png/092601.png)
**Redhat7.x 效果图:**
![输入图片说明](png/10.png.png)
**UOS 深度 效果图:**
![输入图片说明](png/0809.png)
**银河麒麟 开源openkylin amd x64 效果图:**
![输入图片说明](png/kinly01.png)
![输入图片说明](png/kinly02.png)
![输入图片说明](png/kinly03.png)

BIN
png/0412.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
png/0803.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
png/0809.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

BIN
png/0828.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
png/08282.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

BIN
png/092601.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

BIN
png/100601.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 KiB

BIN
png/100602.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

BIN
png/2.8win.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
png/kinly01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

BIN
png/kinly02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

BIN
png/kinly03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

BIN
png/openkylin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

View File

@ -75,6 +75,7 @@
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <Windows.h>
#include <thread>
#endif
#include <memory>
@ -102,6 +103,7 @@ inline std::wstring StringToWString(const std::string& str)
int CCNotePad::s_padTimes = 0;
int CCNotePad::s_zoomValue = 0;
QFileSystemWatcher* CCNotePad::m_fileWatch = nullptr;
QString CCNotePad::s_lastOpenDirPath = "";
QList<CCNotePad*> *CCNotePad::s_padInstances = nullptr;
@ -506,6 +508,9 @@ FileExtLexer s_fileExtMapLexerId[FileExtMapLexerIdLen] = {
{QString("v"), L_VERILOG},
{QString("rs"), L_RUST},
{QString("frm"), L_VB},
{QString("log"), L_LOG},
{QString("asm"), L_ASM},
{QString("ps1"), L_POWERSHELL},
{QString("NULL"), L_EXTERNAL},
};
@ -1013,7 +1018,7 @@ int CCNotePad::runAsAdmin(const QString& filePath)
//{
// m_shareMem->detach();
//}
QString argStr = QString("-muti %1").arg(filePath);
QString argStr = QString("-muti \"%1\"").arg(filePath);
std::basic_string<TCHAR> args = StringToWString(argStr.toStdString());
size_t shellExecRes = (size_t)::ShellExecute(NULL, TEXT("runas"), nddFullPath, args.c_str(), TEXT("."), SW_SHOW);
@ -1320,7 +1325,11 @@ void CCNotePad::quickshow()
ui.editTabWidget->installEventFilter(this);
m_fileWatch = new QFileSystemWatcher(this);
if (m_fileWatch == nullptr)
{
//20230701 发现bugm_fileWatch对象为this,导致主窗口切换时崩溃。
m_fileWatch = new QFileSystemWatcher(nullptr);
}
connect(m_fileWatch, &QFileSystemWatcher::fileChanged, this, &CCNotePad::slot_fileChange);
@ -1745,7 +1754,10 @@ void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData)
pMenu->addAction(pAction);
pAction->setText(procData.m_strPlugName);
pAction->setData(procData.m_strFilePath);
connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork);
procData.m_pAction = pAction;
sendParaToPlugin(procData);
//connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork);
}
else if (procData.m_menuType == 1)
{
@ -1764,7 +1776,43 @@ void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData)
m_pluginList.append(procData);
}
//真正执行插件的工作
QsciScintilla* getCurEditView(QWidget* parent)
{
if (CCNotePad::s_padInstances != nullptr)
{
CCNotePad* p = static_cast<CCNotePad*>(parent);
int index = CCNotePad::s_padInstances->indexOf(p);
if (-1 == index)
{
return nullptr;
}
else
{
return CCNotePad::s_padInstances->at(index)->getCurEditView();
}
}
return nullptr;
}
bool pluginInvoke(QWidget* parent, int cmdId, void* data)
{
if (CCNotePad::s_padInstances != nullptr)
{
int index = CCNotePad::s_padInstances->indexOf(dynamic_cast<CCNotePad*>(parent));
if (-1 == index)
{
return false;
}
else
{
return CCNotePad::s_padInstances->at(index)->pluginInvoke(cmdId, data);
}
}
return false;
}
//真正执行插件的工作。这是在不需要执行二级菜单的情况下,调用的插件执行函数
void CCNotePad::onPlugWork(bool check)
{
QAction* pAct = dynamic_cast<QAction*>(sender());
@ -1779,11 +1827,17 @@ void CCNotePad::onPlugWork(bool check)
if (pMainCallBack != NULL)
{
std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
std::function<bool(int, void*)> pluginCallBack = std::bind(&CCNotePad::pluginInvoke, this, std::placeholders::_1, std::placeholders::_2);
std::function<QsciScintilla* (QWidget*)> foundCallBack = std::bind(&::getCurEditView, std::placeholders::_1);
std::function<bool(QWidget* ,int, void*)> pluginCallBack = std::bind(&::pluginInvoke, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
try {
pMainCallBack(this, plugPath, foundCallBack, pluginCallBack, nullptr);
}
catch (...)
{
ui.statusBar->showMessage(tr("plugin %1 load failed !").arg(plugPath));
QApplication::beep();
}
}
else
{
@ -1805,10 +1859,17 @@ void CCNotePad::sendParaToPlugin(NDD_PROC_DATA& procData)
if (pMainCallBack != NULL)
{
std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
std::function<bool(int, void*)> pluginCallBack = std::bind(&CCNotePad::pluginInvoke, this, std::placeholders::_1, std::placeholders::_2);
std::function<QsciScintilla* (QWidget*)> foundCallBack = std::bind(&::getCurEditView, std::placeholders::_1);
std::function<bool(QWidget*, int, void*)> pluginCallBack = std::bind(&::pluginInvoke, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
try {
pMainCallBack(this, plugPath, foundCallBack, pluginCallBack, &procData);
}
catch (...)
{
ui.statusBar->showMessage(tr("plugin %1 load failed !").arg(plugPath));
QApplication::beep();
}
}
else
{
@ -2050,6 +2111,16 @@ void CCNotePad::syncCurSkinToMenu(int id)
s_curStyleId = id;
}
//释放所有插件里面的实例对象。所以插件对象名称都是nddplg
void CCNotePad::destroyAllPluginModule()
{
QList<QObject*> objList = this->findChildren<QObject*>("nddplg");
for (int i = 0; i < objList.size(); ++i)
{
objList[i]->deleteLater();
}
}
void CCNotePad::slot_changeChinese()
{
if (m_translator->load(":/realcompare_zh.qm"))
@ -2067,6 +2138,7 @@ void CCNotePad::slot_changeChinese()
if (m_isToolMenuLoaded)
{
#ifdef NO_PLUGIN
destroyAllPluginModule();
ui.menuPlugin->clear();
ui.menuPlugin->addAction(ui.actionPlugin_Manager);
#endif
@ -5355,7 +5427,7 @@ void hide_file(const QString& szFile)
//isBakWrite 是否写保护swp文件默认true。只有新文件时不需要因为新文件不存在覆盖写的问题
//isStatic 是否静默不弹出对话框在外部批量查找替换文件夹时使用避免弹窗中断。默认false
//isClearSwpFile:是否回收swp交换文件在外部批量查找替换文件夹时使用替换后直接删除swp文件。默认false
bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBakWrite, bool isStatic,bool isClearSwpFile)
bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBakWrite, bool isStatic, bool isClearSwpFile)
{
QFile srcfile(fileName);
@ -9090,6 +9162,82 @@ ScintillaEditView* CCNotePad::getCurEditView()
return nullptr;
}
void CCNotePad::setEditLangs(ScintillaEditView* pEdit, LangType langs)
{
QsciLexer* curLexer = pEdit->lexer();
if (curLexer == nullptr)
{
//设定为目标语法
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
pEdit->setLexer(lexer);
}
else if (curLexer->lexerId() != langs)
{
pEdit->setLexer(nullptr);
delete curLexer;
curLexer = nullptr;
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
pEdit->setLexer(lexer);
}
syncCurDocLexerToMenu(pEdit);
}
#ifdef NO_PLUGIN
//插件中调用主程序的功能。
//cmdId 执行什么动作,一定固定后,主程序不能随便修改,否则会引发兼容性问题。
bool CCNotePad::pluginInvoke(int cmdId, void* data)
{
bool ret = false;
switch (cmdId)
{
case 1:
{
//新建一个文件。
slot_actionNewFile_toggle(true);
//默认不需要。
if (data != nullptr)
{
QVariant* pVar = (QVariant*)data;
//回传回去新建文件的名称
ScintillaEditView* pw = this->getCurEditView();
if (pw != nullptr)
{
pVar->setValue(getFilePathProperty(pw));
}
}
ret = true;
}
break;
case 2:
{
//设定当前编辑器的语言。0 js 1 json 2 html
int lang = *((int*)data);
LangType langs = ((lang == 0) ? L_JAVASCRIPT : L_JSON);
if (lang == 2)
{
langs = L_HTML;
}
ScintillaEditView* pEdit = this->getCurEditView();
if (pEdit != nullptr)
{
setEditLangs(pEdit, langs);
}
ret = true;
}
break;
default:
break;
}
return ret;
}
#endif
//tab space 互转
void CCNotePad::spaceTabConvert(SpaceTab type)
{
@ -9872,70 +10020,3 @@ void CCNotePad::on_md5hash()
pWin->setAttribute(Qt::WA_DeleteOnClose);
pWin->show();
}
#ifdef NO_PLUGIN
//插件中调用主程序的功能。
//cmdId 执行什么动作,一定固定后,主程序不能随便修改,否则会引发兼容性问题。
bool CCNotePad::pluginInvoke(int cmdId, void* data)
{
bool ret = false;
switch (cmdId)
{
case 1:
{
//新建一个文件。
slot_actionNewFile_toggle(true);
//默认不需要。
if (data != nullptr)
{
QVariant* pVar = (QVariant*)data;
//回传回去新建文件的名称
ScintillaEditView* pw = getCurEditView();
if (pw != nullptr)
{
pVar->setValue(getFilePathProperty(pw));
}
}
ret = true;
}
break;
case 2:
{
//设定当前编辑器的语言。0 js 1 json
int lang = *((int*)data);
LangType langs = ((lang == 0) ? L_JAVASCRIPT : L_JSON);
ScintillaEditView* pEdit = getCurEditView();
if (pEdit != nullptr)
{
QsciLexer* curLexer = pEdit->lexer();
if (curLexer == nullptr)
{
//设定为目标语法
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
pEdit->setLexer(lexer);
}
else if (curLexer->lexerId() != langs)
{
pEdit->setLexer(nullptr);
delete curLexer;
curLexer = nullptr;
QsciLexer* lexer = ScintillaEditView::createLexer(langs);
pEdit->setLexer(lexer);
}
syncCurDocLexerToMenu(pEdit);
}
ret = true;
}
default:
break;
}
return ret;
}
#endif

View File

@ -150,6 +150,11 @@ public:
void setUserDefShortcutKey(int shortcutId);
QtLangSet* getLangSet();
void setEditLangs(ScintillaEditView* pEdit,LangType langs);
#ifdef NO_PLUGIN
//插件中调用主程序的功能。
bool pluginInvoke(int cmdId, void* data);
#endif
signals:
void signSendRegisterKey(QString key);
void signRegisterReplay(int code);
@ -355,8 +360,6 @@ private slots:
#ifdef NO_PLUGIN
void onPlugWork(bool check);
void sendParaToPlugin(NDD_PROC_DATA& procData);
//cmdId 执行什么动作,一定固定后,主程序不能随便修改,否则会引发兼容性问题。
bool pluginInvoke(int cmdId, void* data);
#endif
void slot_showWebAddr(bool check);
void slot_langFileSuffix();
@ -475,6 +478,7 @@ private:
void loadPluginLib();
void loadPluginProcs(QString strLibDir, QMenu* pMenu);
void onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData);
void destroyAllPluginModule();
#endif
void setUserDefShortcutKey();
@ -523,7 +527,7 @@ private:
QMap<QString, LexerNode> m_lexerNameToIndex;
//监控文件被修改的对象
QFileSystemWatcher* m_fileWatch;
static QFileSystemWatcher* m_fileWatch;
QString m_cmpLeftFilePath;
QString m_cmpRightFilePath;
@ -561,9 +565,6 @@ private:
QAction* m_selectRightCmp;
//所有打开的notebook均保存起来。关闭时切换share里面保存的地址
static QList<CCNotePad*> *s_padInstances;
//当前打开的二进制文件,保存在这里
QMap<QString, HexFileMgr*> m_hexFileMgr;
@ -635,6 +636,8 @@ private:
QList<NDD_PROC_DATA> m_pluginList;
public:
//所有打开的notebook均保存起来。关闭时切换share里面保存的地址
static QList<CCNotePad*>* s_padInstances;
static QString s_lastOpenDirPath;
static int s_restoreLastFile; //自动恢复上次打开的文件

View File

@ -23,7 +23,7 @@ enum TAB_TYPES {
MARK_TYPE,
};
const int MAX_RECORD_KEY_LENGTH = 20;
const int MAX_RECORD_KEY_LENGTH = 120;
FindWin::FindWin(QWidget *parent):QMainWindow(parent), m_editTabWidget(nullptr), m_isFindFirst(true), m_findHistory(nullptr), \
pEditTemp(nullptr), m_curEditWin(nullptr), m_isStatic(false), m_isReverseFind(false), m_pMainPad(parent)

View File

@ -22,9 +22,10 @@ struct ndd_proc_data
QString m_version; // [可选]版本号码
QString m_auther; // [可选]作者名称
int m_menuType; // [可选]菜单类型(0不使用二级菜单 1创建二级菜单)
QMenu* m_rootMenu; // [依赖]当 m_menuType = 1给出二级根菜单的地址(默认为 nullptr)
QMenu* m_rootMenu; // [依赖]当 m_menuType = 1则给出二级根菜单的地址(默认为 nullptr)
QAction* m_pAction; // []如果m_menuType = 0给出一级菜单动作的地址。其他值nullptr 插件内部不用填写,主程序传递下来
ndd_proc_data(): m_rootMenu(nullptr), m_menuType(0)
ndd_proc_data(): m_rootMenu(nullptr), m_pAction(nullptr),m_menuType(0)
{
}

View File

@ -1,13 +1,12 @@
[Desktop Entry]
Version=1.0
Name=Notepad--
Name[zh_CN]=Notepad--
Comment=Notepad-- 是一个国产跨平台、简单的文本编辑器。
Name=NotePad--
Name[zh_CN]=NotePad--
Comment=NotePad-- 是一个国产跨平台、简单的文本编辑器。
Type=Application
Exec=notepad-- %F
Icon=notepad--
Exec=NotePad-- %F
Icon=/usr/share/icons/hicolor/128x128/apps/notepad--.png
Categories=Development;Office;
Terminal=false
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-patch;text/x-adasrc;text/x-chdr;text/x-csrc;text/css;application/x-desktop;text/x-patch;text/x-fortran;text/html;text/x-java;text/x-tex;text/x-makefile;text/x-objcsrc;text/x-pascal;application/x-perl;application/x-perl;application/x-php;text/vnd.wap.wml;text/x-python;application/x-ruby;text/sgml;application/xml;model/vrml;image/svg+xml;application/json;
# Generated from the DesktopGenerater component of the z-Tools toolkit

View File

@ -121,11 +121,18 @@ class MyApplication : public QApplication
int main(int argc, char *argv[])
{
//可以防止某些屏幕下的字体拥挤重叠问题。暂时屏蔽不使用qt方法使用windows自带方案
// 发现windows自带方案模糊。//发现下面打开后在win10上反而效果不好界面会变得很大默认还是不开启的好。
//QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
//QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
#ifdef Q_OS_WIN
HDC hdc = CreateDC(L"display", NULL, NULL, NULL);
int ndpi = GetDeviceCaps(hdc, LOGPIXELSY);
qputenv("QT_SCALE_FACTOR", QString::number(ndpi / 96.0).toUtf8());
#endif // Q_OS_WIN
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#ifdef Q_OS_MAC
MyApplication a(argc, argv);
@ -133,6 +140,10 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
//不能开启,开启后相对路径打开文件失败
//QDir::setCurrent(QCoreApplication::applicationDirPath());

View File

@ -5,6 +5,6 @@ class QMenu;
class QsciScintilla;
class QWidget;
typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit, std::function<bool(int, void*)>, NDD_PROC_DATA* procData);
typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*(QWidget*)>getCurEdit, std::function<bool(QWidget* ,int, void*)> pluginCallBack, NDD_PROC_DATA* procData);
int loadProc(const QString& strDirOut, std::function<void(NDD_PROC_DATA&, QMenu*)> funcallback, QMenu* pUserData);

View File

@ -4,6 +4,7 @@
#include <functional>
#include <qsciscintilla.h>
#include "qttestclass.h"
#include "instanceobj.h"
#ifdef WIN32
#include <Windows.h>
#endif
@ -25,8 +26,7 @@
#endif
NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* procData);
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* (QWidget*)>getCurEdit, std::function<bool(QWidget*, int, void*)> pluginCallBack, NDD_PROC_DATA* procData);
#ifdef __cplusplus
}
@ -34,8 +34,9 @@
static NDD_PROC_DATA s_procData;
static QWidget* s_pMainNotepad = nullptr;
std::function<QsciScintilla* ()> s_getCurEdit;
std::function<bool(int, void*)> s_invokeMainFun;
std::function<QsciScintilla* (QWidget*)> s_getCurEdit;
std::function<bool(QWidget*, int, void*)> s_invokeMainFun;
bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
{
@ -61,14 +62,23 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
//s_invokeMainFun: 可以回调NDD主程序中的功能函数比如创建新文件功能等根据需要可实时扩展。
//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空如果pProcData->m_menuType = 1则该指针有值。目前需要关心s_procData.m_rootMenu
//开发者可以在该菜单下面,自行创建二级菜单
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, std::function<bool(int, void*)> pluginCallBack, NDD_PROC_DATA* pProcData)
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*(QWidget*)>getCurEdit, std::function<bool(QWidget*, int, void*)> pluginCallBack, NDD_PROC_DATA* pProcData)
{
QsciScintilla* pEdit = getCurEdit();
if (pEdit == nullptr)
InstanceObj* pInstanse = nullptr;
if (pProcData != nullptr)
{
pInstanse = new InstanceObj(pNotepad);
pInstanse->setObjectName("nddplg");
}
else
{
return -1;
}
s_getCurEdit = getCurEdit;
s_invokeMainFun = pluginCallBack;
//务必拷贝一份pProcData在外面会释放。
if (pProcData != nullptr)
{
@ -76,18 +86,8 @@ int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<Q
}
s_pMainNotepad = pNotepad;
s_getCurEdit = getCurEdit;
s_invokeMainFun = pluginCallBack;
//如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
//插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
//做一个简单的转大写的操作
QtTestClass* p = new QtTestClass(pNotepad,pEdit);
//主窗口关闭时,子窗口也关闭。避免空指针操作
p->setWindowFlag(Qt::Window);
p->show();
QObject::connect(pProcData->m_pAction, &QAction::triggered, pInstanse, &InstanceObj::doMainWork, Qt::UniqueConnection);
return 0;
}

View File

@ -0,0 +1,31 @@
#include "instanceobj.h"
#include "qttestclass.h"
#include <qsciscintilla.h>
#include <QWidget>
#include <QMenu>
#include <QMessageBox>
InstanceObj::InstanceObj(QWidget* pNotepad) :QObject(pNotepad)
{
m_pNotepad = pNotepad;
}
InstanceObj::~InstanceObj()
{
}
void InstanceObj::doMainWork()
{
//做一个简单的转大写的操作
if (m_pMainToolWin.isNull())
{
m_pMainToolWin = new QtTestClass(m_pNotepad);
m_pMainToolWin->setWindowFlag(Qt::Window);
m_pMainToolWin->setAttribute(Qt::WA_DeleteOnClose);
}
m_pMainToolWin->show();
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <QObject>
#include <QWidget>
#include <QPointer>
#include "qttestclass.h"
class QMenu;
class InstanceObj :public QObject
{
public:
//外面Ndd释放时会自动释放该对象。
InstanceObj(QWidget* pNotepad);
~InstanceObj();
public slots:
void doMainWork();
public:
QWidget* m_pNotepad;
QPointer<QtTestClass> m_pMainToolWin;
private:
InstanceObj(const InstanceObj& other) = delete;
InstanceObj& operator=(const InstanceObj& other) = delete;
};

View File

@ -1,11 +1,14 @@
#include "qttestclass.h"
#include <qsciscintilla.h>
QtTestClass::QtTestClass(QWidget *parent, QsciScintilla* pEdit)
: QWidget(parent)
extern std::function<QsciScintilla* (QWidget*)> s_getCurEdit;
QtTestClass::QtTestClass(QWidget *parent): QWidget(parent)
{
ui.setupUi(this);
m_pEdit = pEdit;
m_pNotepad = parent;
}
QtTestClass::~QtTestClass()
@ -13,18 +16,26 @@ QtTestClass::~QtTestClass()
void QtTestClass::on_upper()
{
QString text = m_pEdit->text();
QsciScintilla* pEdit = s_getCurEdit(m_pNotepad);
if (pEdit != nullptr)
{
QString text = pEdit->text();
text = text.toUpper();
text = text.toUpper();
m_pEdit->setText(text);
pEdit->setText(text);
}
}
void QtTestClass::on_lower()
{
QString text = m_pEdit->text();
QsciScintilla* pEdit = s_getCurEdit(m_pNotepad);
if (pEdit != nullptr)
{
QString text = pEdit->text();
text = text.toLower();
text = text.toLower();
m_pEdit->setText(text);
pEdit->setText(text);
}
}

View File

@ -9,7 +9,7 @@ class QtTestClass : public QWidget
Q_OBJECT
public:
QtTestClass(QWidget *parent, QsciScintilla* pEdit);
QtTestClass(QWidget *parent);
~QtTestClass();
private slots:
@ -17,5 +17,6 @@ private slots:
void on_lower();
private:
Ui::QtTestClassClass ui;
QsciScintilla* m_pEdit;
QWidget* m_pNotepad;
};

View File

@ -10,9 +10,12 @@ struct ndd_proc_data
QString m_version; //版本号码。可选;插件里面需填写
QString m_auther;//作者名称。可选;插件里面需填写
int m_menuType;//菜单类型。0不使用二级菜单 1创建二级菜单插件里面需填写
QMenu* m_rootMenu;//如果m_menuType = 1给出二级根菜单的地址。其他值nullptr 插件内部不用填写,主程序传递下来
ndd_proc_data(): m_rootMenu(nullptr), m_menuType(0)
QMenu* m_rootMenu;//如果m_menuType = 1给出二级根菜单的地址。其他值nullptr 插件内部不用填写,主程序传递下来
QAction* m_pAction;//如果m_menuType = 0给出一级菜单动作的地址。其他值nullptr 插件内部不用填写,主程序传递下来
ndd_proc_data(): m_rootMenu(nullptr), m_pAction(nullptr),m_menuType(0)
{
}

View File

@ -72,6 +72,10 @@
# include BOOST_REGEX_USER_CONFIG
#ifdef Q_OS_UNIX
#define BOOST_REGEX_STANDALONE
#endif
#ifndef BOOST_REGEX_STANDALONE
# include <boost/config.hpp>
# include <boost/predef.h>

View File

@ -152,7 +152,8 @@
#define SCLEX_IDL 154
#define SCLEX_GO 155
#define SCLEX_TXT 156
#define SCLEX_LOG 157
#define SCLEX_GCode 158
#define SCLEX_AUTOMATIC 1000

View File

@ -989,6 +989,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CLEARREPRESENTATION 2667
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_GETRECORSTATUS 3003
#define SCI_SETLEXER 4001
#define SCI_GETLEXER 4002
#define SCI_COLOURISE 4003
@ -1093,7 +1094,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_DOUBLECLICK 2006
#define SCN_UPDATEUI 2007
#define SCN_MODIFIED 2008
#define SCN_MACRORECORD 2009
#define SCN_MACRORECORD_ID 2009
#define SCN_MARGINCLICK 2010
#define SCN_NEEDSHOWN 2011
#define SCN_PAINTED 2013

View File

@ -1,4 +1,4 @@
// Scintilla source code edit control
// Scintilla source code edit control
/** @file LexCPP.cxx
** Lexer for C++, C, Java, and JavaScript.
** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
@ -6,18 +6,16 @@
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <utility>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
#include "ILexer.h"
#include "Scintilla.h"
@ -39,7 +37,7 @@ using namespace Scintilla;
namespace {
// Use an unnamed namespace to protect the functions and classes from name conflicts
bool IsSpaceEquiv(int state) noexcept {
constexpr bool IsSpaceEquiv(int state) noexcept {
return (state <= SCE_C_COMMENTDOC) ||
// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
@ -86,7 +84,7 @@ bool followsReturnKeyword(const StyleContext &sc, LexAccessor &styler) {
return !*s;
}
bool IsSpaceOrTab(int ch) noexcept {
constexpr bool IsSpaceOrTab(int ch) noexcept {
return ch == ' ' || ch == '\t';
}
@ -143,10 +141,10 @@ BracketPair FindBracketPair(std::vector<std::string> &tokens) {
void highlightTaskMarker(StyleContext &sc, LexAccessor &styler,
int activity, const WordList &markerList, bool caseSensitive){
if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) {
const int lengthMarker = 50;
constexpr Sci_PositionU lengthMarker = 50;
char marker[lengthMarker+1] = "";
const Sci_Position currPos = static_cast<Sci_Position>(sc.currentPos);
int i = 0;
const Sci_PositionU currPos = sc.currentPos;
Sci_PositionU i = 0;
while (i < lengthMarker) {
const char ch = styler.SafeGetCharAt(currPos + i);
if (IsASpace(ch) || isoperator(ch)) {
@ -165,18 +163,14 @@ void highlightTaskMarker(StyleContext &sc, LexAccessor &styler,
}
}
struct EscapeSequence {
int digitsLeft;
CharacterSet setHexDigits;
CharacterSet setOctDigits;
CharacterSet setNoneNumeric;
CharacterSet *escapeSetValid;
EscapeSequence() {
digitsLeft = 0;
escapeSetValid = 0;
setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef");
setOctDigits = CharacterSet(CharacterSet::setNone, "01234567");
}
class EscapeSequence {
const CharacterSet setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef");
const CharacterSet setOctDigits = CharacterSet(CharacterSet::setNone, "01234567");
const CharacterSet setNoneNumeric;
const CharacterSet *escapeSetValid = nullptr;
int digitsLeft = 0;
public:
EscapeSequence() = default;
void resetEscapeState(int nextChar) {
digitsLeft = 0;
escapeSetValid = &setNoneNumeric;
@ -197,26 +191,39 @@ struct EscapeSequence {
bool atEscapeEnd(int currChar) const {
return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar);
}
void consumeDigit() noexcept {
digitsLeft--;
}
};
std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) {
std::string restOfLine;
Sci_Position i =0;
Sci_Position line = styler.GetLine(start);
Sci_Position pos = start;
Sci_Position endLine = styler.LineEnd(line);
char ch = styler.SafeGetCharAt(start, '\n');
const Sci_Position endLine = styler.LineEnd(styler.GetLine(start));
while (((start+i) < endLine) && (ch != '\r')) {
const char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
while (pos < endLine) {
if (ch == '\\' && ((pos + 1) == endLine)) {
// Continuation line
line++;
pos = styler.LineStart(line);
endLine = styler.LineEnd(line);
ch = styler.SafeGetCharAt(pos, '\n');
} else {
const char chNext = styler.SafeGetCharAt(pos + 1, '\n');
if (ch == '/' && (chNext == '/' || chNext == '*'))
break;
if (allowSpace || (ch != ' '))
if (allowSpace || (ch != ' ')) {
restOfLine += ch;
i++;
}
pos++;
ch = chNext;
}
}
return restOfLine;
}
bool IsStreamCommentStyle(int style) noexcept {
constexpr bool IsStreamCommentStyle(int style) noexcept {
return style == SCE_C_COMMENT ||
style == SCE_C_COMMENTDOC ||
style == SCE_C_COMMENTDOCKEYWORD ||
@ -234,12 +241,24 @@ struct PPDefinition {
}
};
constexpr int inactiveFlag = 0x40;
class LinePPState {
int state;
int ifTaken;
int level;
// Track the state of preprocessor conditionals to allow showing active and inactive
// code in different styles.
// Only works up to 31 levels of conditional nesting.
// state is a bit mask with 1 bit per level
// bit is 1 for level if section inactive, so any bits set = inactive style
int state = 0;
// ifTaken is a bit mask with 1 bit per level
// bit is 1 for level if some branch at this level has been taken
int ifTaken = 0;
// level is the nesting level of #if constructs
int level = -1;
static const int maximumNestingLevel = 31;
bool ValidLevel() const noexcept {
return level >= 0 && level < 32;
return level >= 0 && level < maximumNestingLevel;
}
int maskLevel() const noexcept {
if (level >= 0) {
@ -249,11 +268,17 @@ class LinePPState {
}
}
public:
LinePPState() : state(0), ifTaken(0), level(-1) {
LinePPState() noexcept {
}
bool IsActive() const noexcept {
return state == 0;
}
bool IsInactive() const noexcept {
return state != 0;
}
int ActiveState() const noexcept {
return state ? inactiveFlag : 0;
}
bool CurrentIfTaken() const noexcept {
return (ifTaken & maskLevel()) != 0;
}
@ -289,7 +314,7 @@ public:
class PPStates {
std::vector<LinePPState> vlls;
public:
LinePPState ForLine(Sci_Position line) const {
LinePPState ForLine(Sci_Position line) const noexcept {
if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
return vlls[line];
} else {
@ -359,7 +384,7 @@ const char *const cppWordLists[] = {
"Global classes and typedefs",
"Preprocessor definitions",
"Task marker and error marker keywords",
0,
nullptr,
};
struct OptionSetCPP : public OptionSet<OptionsCPP> {
@ -468,13 +493,17 @@ LexicalClass lexicalClasses[] = {
27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence",
};
const int sizeLexicalClasses = static_cast<int>(ELEMENTS(lexicalClasses));
}
enum { lvRelease4 = 2, lvRelease5 = 3 };
class LexerCPP : public ILexerWithMetaData {
bool caseSensitive;
CharacterSet setWord;
CharacterSet setNegationOp;
CharacterSet setArithmethicOp;
CharacterSet setAddOp;
CharacterSet setMultOp;
CharacterSet setRelOp;
CharacterSet setLogicalOp;
CharacterSet setWordStart;
@ -489,7 +518,8 @@ class LexerCPP : public ILexerWithMetaData {
struct SymbolValue {
std::string value;
std::string arguments;
SymbolValue(const std::string &value_="", const std::string &arguments_="") : value(value_), arguments(arguments_) {
SymbolValue() noexcept = default;
SymbolValue(const std::string &value_, const std::string &arguments_) : value(value_), arguments(arguments_) {
}
SymbolValue &operator = (const std::string &value_) {
value = value_;
@ -506,7 +536,6 @@ class LexerCPP : public ILexerWithMetaData {
OptionSetCPP osCPP;
EscapeSequence escapeSeq;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
enum { ssIdentifier, ssDocKeyword };
SubStyles subStyles;
std::string returnBuffer;
@ -515,18 +544,24 @@ public:
caseSensitive(caseSensitive_),
setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
setNegationOp(CharacterSet::setNone, "!"),
setArithmethicOp(CharacterSet::setNone, "+-/*%"),
setAddOp(CharacterSet::setNone, "+-"),
setMultOp(CharacterSet::setNone, "*/%"),
setRelOp(CharacterSet::setNone, "=!<>"),
setLogicalOp(CharacterSet::setNone, "|&"),
subStyles(styleSubable, 0x80, 0x40, activeFlag) {
subStyles(styleSubable, 0x80, 0x40, inactiveFlag) {
}
// Deleted so LexerCPP objects can not be copied.
LexerCPP(const LexerCPP &) = delete;
LexerCPP(LexerCPP &&) = delete;
void operator=(const LexerCPP &) = delete;
void operator=(LexerCPP &&) = delete;
virtual ~LexerCPP() {
}
void SCI_METHOD Release() override {
void SCI_METHOD Release() noexcept override {
delete this;
}
int SCI_METHOD Version() const override {
return lvMetaData;
int SCI_METHOD Version() const noexcept override {
return lvRelease4;
}
const char * SCI_METHOD PropertyNames() override {
return osCPP.PropertyNames();
@ -545,11 +580,11 @@ public:
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void * SCI_METHOD PrivateCall(int, void *) override {
return 0;
void * SCI_METHOD PrivateCall(int, void *) noexcept override {
return nullptr;
}
int SCI_METHOD LineEndTypesSupported() override {
int SCI_METHOD LineEndTypesSupported() noexcept override {
return SC_LINE_END_TYPE_UNICODE;
}
@ -564,10 +599,10 @@ public:
}
int SCI_METHOD StyleFromSubStyle(int subStyle) override {
const int styleBase = subStyles.BaseStyle(MaskActive(subStyle));
const int active = subStyle & activeFlag;
return styleBase | active;
const int inactive = subStyle & inactiveFlag;
return styleBase | inactive;
}
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
int SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override {
return MaskActive(style);
}
void SCI_METHOD FreeSubStyles() override {
@ -576,21 +611,21 @@ public:
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
subStyles.SetIdentifiers(style, identifiers);
}
int SCI_METHOD DistanceToSecondaryStyles() override {
return activeFlag;
int SCI_METHOD DistanceToSecondaryStyles() noexcept override {
return inactiveFlag;
}
const char * SCI_METHOD GetSubStyleBases() override {
const char * SCI_METHOD GetSubStyleBases() noexcept override {
return styleSubable;
}
int SCI_METHOD NamedStyles() override {
return std::max(subStyles.LastAllocated() + 1,
static_cast<int>(ELEMENTS(lexicalClasses))) +
activeFlag;
sizeLexicalClasses) +
inactiveFlag;
}
const char * SCI_METHOD NameOfStyle(int style) override {
if (style >= NamedStyles())
return "";
if (style < static_cast<int>(ELEMENTS(lexicalClasses)))
if (style < sizeLexicalClasses)
return lexicalClasses[style].name;
// TODO: inactive and substyles
return "";
@ -603,23 +638,23 @@ public:
if (firstSubStyle >= 0) {
const int lastSubStyle = subStyles.LastAllocated();
if (((style >= firstSubStyle) && (style <= (lastSubStyle))) ||
((style >= firstSubStyle + activeFlag) && (style <= (lastSubStyle + activeFlag)))) {
((style >= firstSubStyle + inactiveFlag) && (style <= (lastSubStyle + inactiveFlag)))) {
int styleActive = style;
if (style > lastSubStyle) {
returnBuffer = "inactive ";
styleActive -= activeFlag;
styleActive -= inactiveFlag;
}
const int styleMain = StyleFromSubStyle(styleActive);
returnBuffer += lexicalClasses[styleMain].tags;
return returnBuffer.c_str();
}
}
if (style < static_cast<int>(ELEMENTS(lexicalClasses)))
if (style < sizeLexicalClasses)
return lexicalClasses[style].tags;
if (style >= activeFlag) {
if (style >= inactiveFlag) {
returnBuffer = "inactive ";
const int styleActive = style - activeFlag;
if (styleActive < static_cast<int>(ELEMENTS(lexicalClasses)))
const int styleActive = style - inactiveFlag;
if (styleActive < sizeLexicalClasses)
returnBuffer += lexicalClasses[styleActive].tags;
else
returnBuffer = "";
@ -630,20 +665,29 @@ public:
const char * SCI_METHOD DescriptionOfStyle(int style) override {
if (style >= NamedStyles())
return "";
if (style < static_cast<int>(ELEMENTS(lexicalClasses)))
if (style < sizeLexicalClasses)
return lexicalClasses[style].description;
// TODO: inactive and substyles
return "";
}
// ILexer5 methods
//const char * SCI_METHOD GetName() {
// return caseSensitive ? "cpp" : "cppnocase";
//}
/*int SCI_METHOD GetIdentifier() {
return caseSensitive ? SCLEX_CPP : SCLEX_CPPNOCASE;
}*/
//const char * SCI_METHOD PropertyGet(const char *key);
static ILexer *LexerFactoryCPP() {
return new LexerCPP(true);
}
static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false);
}
static int MaskActive(int style) noexcept {
return style & ~activeFlag;
constexpr static int MaskActive(int style) noexcept {
return style & ~inactiveFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens, const SymbolTable &preprocessorDefinitions);
std::vector<std::string> Tokenize(const std::string &expr) const;
@ -663,8 +707,12 @@ Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val)
return -1;
}
//const char * SCI_METHOD LexerCPP::PropertyGet(const char *key) {
// return osCPP.PropertyGet(key);
//}
Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
WordList *wordListN = nullptr;
switch (n) {
case 0:
wordListN = &keywords;
@ -784,7 +832,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
ppDefineHistory.clear();
std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(),
[lineCurrent](const PPDefinition &p) { return p.line >= lineCurrent; });
[lineCurrent](const PPDefinition &p) noexcept { return p.line >= lineCurrent; });
if (itInvalid != ppDefineHistory.end()) {
ppDefineHistory.erase(itInvalid, ppDefineHistory.end());
definitionsChanged = true;
@ -801,12 +849,12 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? activeFlag : 0;
int activitySet = preproc.ActiveState();
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);
const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD);
Sci_Position lineEndNext = styler.LineEnd(lineCurrent);
Sci_PositionU lineEndNext = styler.LineEnd(lineCurrent);
for (; sc.More();) {
@ -828,7 +876,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
isIncludePreprocessor = false;
inRERange = false;
if (preproc.IsInactive()) {
activitySet = activeFlag;
activitySet = inactiveFlag;
sc.SetState(sc.state | activitySet);
}
}
@ -844,7 +892,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
// Handle line continuation generically.
if (sc.ch == '\\') {
if (static_cast<Sci_Position>((sc.currentPos+1)) >= lineEndNext) {
if ((sc.currentPos+1) >= lineEndNext) {
lineCurrent++;
lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
@ -938,7 +986,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
break;
case SCE_C_PREPROCESSOR:
if (options.stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
if (IsASpace(sc.ch) || (sc.ch == '(')) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
} else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) {
@ -1059,7 +1107,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
}
break;
case SCE_C_ESCAPESEQUENCE:
escapeSeq.digitsLeft--;
escapeSeq.consumeDigit();
if (!escapeSeq.atEscapeEnd(sc.ch)) {
break;
}
@ -1111,12 +1159,12 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
case SCE_C_REGEX:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (! inRERange && sc.ch == '/') {
} else if (!inRERange && sc.ch == '/') {
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
while (IsLowerCase(sc.ch))
sc.Forward(); // gobble regex flags
sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (sc.ch == '\\' && (static_cast<Sci_Position>(sc.currentPos+1) < lineEndNext)) {
} else if (sc.ch == '\\' && ((sc.currentPos+1) < lineEndNext)) {
// Gobble up the escaped character
sc.Forward();
} else if (sc.ch == '[') {
@ -1253,6 +1301,8 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
isIncludePreprocessor = true;
} else {
if (options.trackPreprocessor) {
// If #if is nested too deeply (>31 levels) the active/inactive appearance
// will stop reflecting the code.
if (sc.Match("ifdef") || sc.Match("ifndef")) {
const bool isIfDef = sc.Match("ifdef");
const int startRest = isIfDef ? 5 : 6;
@ -1264,47 +1314,58 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
preproc.StartSection(ifGood);
} else if (sc.Match("else")) {
// #else is shown as active if either preceding or following section is active
// as that means that it contributed to the result.
if (!preproc.CurrentIfTaken()) {
// Inactive, may become active if parent scope active
assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag));
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? activeFlag : 0;
activitySet = preproc.ActiveState();
// If following is active then show "else" as active
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) {
sc.ChangeState(SCE_C_PREPROCESSOR);
} else if (preproc.IsActive()) {
// Active -> inactive
assert(sc.state == SCE_C_PREPROCESSOR);
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
activitySet = preproc.ActiveState();
// Continue to show "else" as active as it ends active section.
}
} else if (sc.Match("elif")) {
// Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif
// #elif is shown as active if either preceding or following section is active
// as that means that it contributed to the result.
if (!preproc.CurrentIfTaken()) {
// Inactive, if expression true then may become active if parent scope active
assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag));
// Similar to #if
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true);
const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? activeFlag : 0;
activitySet = preproc.ActiveState();
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
sc.ChangeState(SCE_C_PREPROCESSOR);
}
} else if (!preproc.IsInactive()) {
} else if (preproc.IsActive()) {
// Active -> inactive
assert(sc.state == SCE_C_PREPROCESSOR);
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
activitySet = preproc.ActiveState();
// Continue to show "elif" as active as it ends active section.
}
} else if (sc.Match("endif")) {
preproc.EndSection();
activitySet = preproc.IsInactive() ? activeFlag : 0;
activitySet = preproc.ActiveState();
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) {
if (options.updatePreprocessor && preproc.IsActive()) {
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);
size_t startName = 0;
while ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName]))
startName++;
size_t endName = startName;
while ((endName < restOfLine.length()) && setWord.Contains(static_cast<unsigned char>(restOfLine[endName])))
while ((endName < restOfLine.length()) && setWord.Contains(restOfLine[endName]))
endName++;
std::string key = restOfLine.substr(startName, endName-startName);
if ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) {
@ -1336,7 +1397,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
}
}
} else if (sc.Match("undef")) {
if (options.updatePreprocessor && !preproc.IsInactive()) {
if (options.updatePreprocessor && preproc.IsActive()) {
const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false);
std::vector<std::string> tokens = Tokenize(restOfLine);
if (tokens.size() >= 1) {
@ -1526,11 +1587,11 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
}
// Evaluate identifiers
const size_t maxIterations = 100;
constexpr size_t maxIterations = 100;
size_t iterations = 0; // Limit number of iterations in case there is a recursive macro.
for (size_t i = 0; (i<tokens.size()) && (iterations < maxIterations);) {
iterations++;
if (setWordStart.Contains(static_cast<unsigned char>(tokens[i][0]))) {
if (setWordStart.Contains(tokens[i][0])) {
SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i]);
if (it != preprocessorDefinitions.end()) {
// Tokenize value
@ -1557,7 +1618,7 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
macroTokens.erase(std::remove_if(macroTokens.begin(), macroTokens.end(), OnlySpaceOrTab), macroTokens.end());
for (size_t iMacro = 0; iMacro < macroTokens.size();) {
if (setWordStart.Contains(static_cast<unsigned char>(macroTokens[iMacro][0]))) {
if (setWordStart.Contains(macroTokens[iMacro][0])) {
std::map<std::string, std::string>::const_iterator itFind = arguments.find(macroTokens[iMacro]);
if (itFind != arguments.end()) {
// TODO: Possible that value will be expression so should insert tokenized form
@ -1618,13 +1679,15 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
}
// Evaluate expressions in precedence order
enum precedence { precArithmetic, precRelative, precLogical };
for (int prec=precArithmetic; prec <= precLogical; prec++) {
enum precedence { precMult, precAdd, precRelative
, precLogical, /* end marker */ precLast };
for (int prec = precMult; prec < precLast; prec++) {
// Looking at 3 tokens at a time so end at 2 before end
for (size_t k=0; (k+2)<tokens.size();) {
const char chOp = tokens[k+1][0];
if (
((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) ||
((prec==precMult) && setMultOp.Contains(chOp)) ||
((prec==precAdd) && setAddOp.Contains(chOp)) ||
((prec==precRelative) && setRelOp.Contains(chOp)) ||
((prec==precLogical) && setLogicalOp.Contains(chOp))
) {
@ -1657,11 +1720,9 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
result = valA || valB;
else if (tokens[k+1] == "&&")
result = valA && valB;
char sResult[30];
sprintf(sResult, "%d", result);
std::vector<std::string>::iterator itInsert =
tokens.erase(tokens.begin() + k, tokens.begin() + k + 3);
tokens.insert(itInsert, sResult);
tokens.insert(itInsert, std::to_string(result));
} else {
k++;
}
@ -1675,9 +1736,9 @@ std::vector<std::string> LexerCPP::Tokenize(const std::string &expr) const {
const char *cp = expr.c_str();
while (*cp) {
std::string word;
if (setWord.Contains(static_cast<unsigned char>(*cp))) {
if (setWord.Contains(*cp)) {
// Identifiers and numbers
while (setWord.Contains(static_cast<unsigned char>(*cp))) {
while (setWord.Contains(*cp)) {
word += *cp;
cp++;
}
@ -1686,17 +1747,17 @@ std::vector<std::string> LexerCPP::Tokenize(const std::string &expr) const {
word += *cp;
cp++;
}
} else if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
} else if (setRelOp.Contains(*cp)) {
word += *cp;
cp++;
if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
if (setRelOp.Contains(*cp)) {
word += *cp;
cp++;
}
} else if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
} else if (setLogicalOp.Contains(*cp)) {
word += *cp;
cp++;
if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
if (setLogicalOp.Contains(*cp)) {
word += *cp;
cp++;
}

View File

@ -0,0 +1,429 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <regex>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StringCopy.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "CharacterCategory.h"
#include "LexerModule.h"
#include "OptionSet.h"
#include "SubStyles.h"
#include "DefaultLexer.h"
#include "LexAccessor.h"
#include "UniConversion.h"
using namespace Scintilla;
//const char styleSubable[] = { SCE_P_IDENTIFIER, 0 };
//Default = 0,//中文
//Ascii = 1,//英文
//Keyword = 2, //关键字只有以TXT为母版的
static LexicalClass lexicalClasses[] = {
// Lexer Python SCLEX_PYTHON SCE_P_:
0, "SCE_GCODE_DEFAULT", "default", "default",
1, "SCE_GCODE_KEYWORD", "keyword", "keyword",
2, "SCE_GCODE_KEYWORD1", "keyword", "keyword",
3, "SCE_GCODE_COMMNET", "Comment", "Comment",
4, "SCE_GCODE_POSITION", "Position", "Position",
5, "SCE_GCODE_VELOCITY","velocity","velocity",
};
enum LOG_STATUS {
SCE_GCODE_DEFAULT=0,
SCE_GCODE_KEYWORD, //关键字
SCE_GCODE_KEYWORD1, //关键字
SCE_GCODE_COMMNET, //数字
SCE_GCODE_POSITION_X, //位置 X Y Z
SCE_GCODE_POSITION_Y, //位置 X Y Z
SCE_GCODE_POSITION_Z, //位置 X Y Z
SCE_GCODE_OFFSET,//I J K 偏移
SCE_GCODE_VELOCITY,//速度 F
SCE_GCODE_TIMES,// P 次数
SCE_GCODE_IDENTIFIER,
SCE_GCODE_IDENTIFIER_KEYWORD,
SCE_GCODE_IDENTIFIER_KEYWORD1,
SCE_GCODE_IDENTIFIER_POSITION_X,
SCE_GCODE_IDENTIFIER_POSITION_Y,
SCE_GCODE_IDENTIFIER_POSITION_Z,
SCE_GCODE_IDENTIFIER_OFFSET,
SCE_GCODE_IDENTIFIER_VELOCITY,
SCE_GCODE_IDENTIFIER_TIMES,
SCE_GCODE_IDENTIFIER_COMMENT,
};
// Options used for LexerPython
struct OptionsTxt {
bool num;
bool data;
bool keyword;
OptionsTxt() {
num = true;
data = true;
keyword = true;
}
};
//获取行最多获取1024个字符串
static std::string GetLineContents(LexAccessor& styler, Sci_Position start, const int len = 1024) {
std::string lineContent;
Sci_Position i = 0;
char ch = styler.SafeGetCharAt(start, '\n');
const Sci_Position endLine = styler.LineEnd(styler.GetLine(start));
while (((start + i) < endLine) && (i < len)) {
const char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
lineContent += ch;
i++;
ch = chNext;
}
return lineContent;
}
struct OptionSetTxt : public OptionSet<OptionsTxt> {
OptionSetTxt() {
DefineProperty("lexer.log.num", &OptionsTxt::num,
"text Unicode string");
DefineProperty("lexer.txt.keyword", &OptionsTxt::keyword,
"text keyword");
}
};
class LexGCode :public DefaultLexer
{
WordList keywords;
WordList keywords1;
OptionsTxt options;
OptionSetTxt osTxt;
CharacterSet setWord;
CharacterSet setWordStart;
public:
explicit LexGCode() :
DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)),
setWord(CharacterSet::setDigits, "GMXYZPIJKF-", 0x80, true),//字母、数字、下划线、. 单词的字符集。
setWordStart(CharacterSet::setNone, "GMXYZPIJKF", 0x80, true)
{
}
virtual ~LexGCode() {}
void SCI_METHOD Release() override {
delete this;
}
int SCI_METHOD Version() const override {
return lvSubStyles;
}
const char *SCI_METHOD PropertyNames() override {
return osTxt.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) override {
return osTxt.PropertyType(name);
}
const char *SCI_METHOD DescribeProperty(const char *name) override {
return osTxt.DescribeProperty(name);
}
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
const char *SCI_METHOD DescribeWordListSets() override {
return "";
}
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void *SCI_METHOD PrivateCall(int, void *) override {
return 0;
}
int SCI_METHOD LineEndTypesSupported() override {
return SC_LINE_END_TYPE_UNICODE;
}
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
return style;
}
int SCI_METHOD DistanceToSecondaryStyles() override {
return 0;
}
static ILexer * LexerFactoryGCode() {
return new LexGCode();
}
};
Sci_Position SCI_METHOD LexGCode::PropertySet(const char *key, const char *val) {
if (osTxt.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
Sci_Position SCI_METHOD LexGCode::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywords;
break;
case 1:
wordListN = &keywords1;
break;
}
Sci_Position firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
const int indicatorWhitespace = 1;
inline bool IsAAsciiChar(int ch) {
return (ch < 0x80);
}
inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
if (ch < 0x80)
return (isalpha(ch) || ch == '_');
if (!unicodeIdentifiers)
return false;
return IsXidStart(ch);
}
//是否是单词分割符号对于ascii中的数字和字母以外的字符比如 . @ \t 等,都作为一个单词的分割符号。
inline bool IsWordSplitChar(int ch) noexcept {
return (ch < 0x80) && !isalnum(ch);
}
inline bool IsLineEol(int ch) noexcept {
return ch == '\n' || ch == '\r';
}
//只识别中文和英文两种单词的状态
void SCI_METHOD LexGCode::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, NULL);
const Sci_Position endPos = startPos + length;
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
Sci_Position startIndicator = sc.currentPos;
bool isDataMatch = false;
for (; sc.More();) {
switch (sc.state)
{
case SCE_GCODE_DEFAULT:
{
if (!sc.atLineEnd && (sc.ch == ';'))
{
sc.SetState(SCE_GCODE_IDENTIFIER_COMMENT);
}
else if (!sc.atLineEnd && setWordStart.Contains(sc.ch)) {
//如果不在行尾,而且当前字符是一个单词的开头标识字符,则进入标识符识别状态。
if (sc.Match('G') && IsADigit(sc.chNext))
{
sc.SetState(SCE_GCODE_IDENTIFIER_KEYWORD);
sc.Forward();
}
else if (sc.Match('M') && IsADigit(sc.chNext))
{
sc.SetState(SCE_GCODE_IDENTIFIER_KEYWORD1);
sc.Forward();
}
else if (sc.Match('X')&& (IsADigit(sc.chNext) || (sc.chNext == '-')))
{
sc.SetState(SCE_GCODE_IDENTIFIER_POSITION_X);
sc.Forward();
}
else if (sc.Match('Y') && (IsADigit(sc.chNext) || (sc.chNext == '-')))
{
sc.SetState(SCE_GCODE_IDENTIFIER_POSITION_Y);
sc.Forward();
}
else if (sc.Match('Z') && (IsADigit(sc.chNext) || (sc.chNext == '-')))
{
sc.SetState(SCE_GCODE_IDENTIFIER_POSITION_Z);
sc.Forward();
}
else if ((sc.Match('I') || sc.Match('J') || sc.Match('K')) && (IsADigit(sc.chNext) || (sc.chNext == '-')))
{
sc.SetState(SCE_GCODE_IDENTIFIER_OFFSET);
sc.Forward();
}
else if (sc.Match('F') && IsADigit(sc.chNext))
{
sc.SetState(SCE_GCODE_IDENTIFIER_VELOCITY);
sc.Forward();
}
else if (sc.Match('P') && IsADigit(sc.chNext))
{
sc.SetState(SCE_GCODE_IDENTIFIER_TIMES);
sc.Forward();
}
}
}
break;
case SCE_GCODE_IDENTIFIER_COMMENT:
{
if (sc.atLineEnd)
{
sc.ChangeState(SCE_GCODE_COMMNET);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_KEYWORD:
case SCE_GCODE_IDENTIFIER_KEYWORD1:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
char s[1000];
//取出当前标识符注意标识符不会超过512这是预计不会有人傻到取名一个超过1000的字符串变量。
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_GCODE_KEYWORD);
}
else if (keywords1.InList(s)) {
sc.ChangeState(SCE_GCODE_KEYWORD1);
}
else
{
sc.ChangeState(SCE_GCODE_DEFAULT);
}
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_POSITION_X:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_POSITION_X);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_POSITION_Y:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_POSITION_Y);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_POSITION_Z:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_POSITION_Z);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_OFFSET:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_OFFSET);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_VELOCITY:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_VELOCITY);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
case SCE_GCODE_IDENTIFIER_TIMES:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
sc.ChangeState(SCE_GCODE_TIMES);
sc.SetState(SCE_GCODE_DEFAULT);
}
}
break;
}
sc.Forward();
}
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
sc.Complete();
}
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
Sci_Position pos = styler.LineStart(line);
const Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = pos; i < eol_pos; i++) {
const char ch = styler[i];
if (ch == '#')
return true;
else if (ch != ' ' && ch != '\t')
return false;
}
return false;
}
static bool IsQuoteLine(Sci_Position line, const Accessor &styler) {
const int style = styler.StyleAt(styler.LineStart(line)) & 31;
return false;
}
//不处理任何折叠
void SCI_METHOD LexGCode::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {
return;
}
static const char *const txtWordListDesc[] = {
0
};
LexerModule lmGCode(SCLEX_GCode, LexGCode::LexerFactoryGCode, "gcode", txtWordListDesc);

View File

@ -0,0 +1,362 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <regex>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StringCopy.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "CharacterCategory.h"
#include "LexerModule.h"
#include "OptionSet.h"
#include "SubStyles.h"
#include "DefaultLexer.h"
#include "LexAccessor.h"
#include "UniConversion.h"
using namespace Scintilla;
//const char styleSubable[] = { SCE_P_IDENTIFIER, 0 };
//Default = 0,//中文
//Ascii = 1,//英文
//Keyword = 2, //关键字只有以TXT为母版的
static LexicalClass lexicalClasses[] = {
// Lexer Python SCLEX_PYTHON SCE_P_:
0, "SCE_LOG_DEFAULT", "default", "default",
1, "SCE_LOG_NUM", "Num", "Num",
2, "SCE_LOG_DATE", "Date", "Date",
3, "SCE_LOG_KEYWORD", "keyword", "keyword",
};
enum LOG_STATUS {
SCE_LOG_DEFAULT=0,
SCE_LOG_NUM ,
SCE_LOG_DATE,
SCE_LOG_KEYWORD,
SCE_LOG_IDENTIFIER,
SCE_LOG_HEX
};
// Options used for LexerPython
struct OptionsTxt {
bool num;
bool data;
bool keyword;
OptionsTxt() {
num = true;
data = true;
keyword = true;
}
};
struct OptionSetTxt : public OptionSet<OptionsTxt> {
OptionSetTxt() {
DefineProperty("lexer.log.num", &OptionsTxt::num,
"text Unicode string");
DefineProperty("lexer.txt.data", &OptionsTxt::data,
"text literals ascii string");
DefineProperty("lexer.txt.keyword", &OptionsTxt::keyword,
"text keyword");
}
};
class LexLOG :public DefaultLexer
{
WordList keywords;
OptionsTxt options;
OptionSetTxt osTxt;
CharacterSet setWord;
CharacterSet setWordStart;
CharacterSet hexWord;
public:
explicit LexLOG() :
DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)),
setWord(CharacterSet::setAlphaNum, "._", 0x80, true),//字母、数字、下划线、. 单词的字符集。
setWordStart(CharacterSet::setAlpha, "_", 0x80, true),
hexWord(CharacterSet::setDigits, "abcdefABCDEF", 0x80, true)
{
}
virtual ~LexLOG() {}
void SCI_METHOD Release() override {
delete this;
}
int SCI_METHOD Version() const override {
return lvSubStyles;
}
const char *SCI_METHOD PropertyNames() override {
return osTxt.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) override {
return osTxt.PropertyType(name);
}
const char *SCI_METHOD DescribeProperty(const char *name) override {
return osTxt.DescribeProperty(name);
}
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
const char *SCI_METHOD DescribeWordListSets() override {
return "";
}
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
void *SCI_METHOD PrivateCall(int, void *) override {
return 0;
}
int SCI_METHOD LineEndTypesSupported() override {
return SC_LINE_END_TYPE_UNICODE;
}
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
return style;
}
int SCI_METHOD DistanceToSecondaryStyles() override {
return 0;
}
static ILexer *LexerFactoryLog() {
return new LexLOG();
}
};
Sci_Position SCI_METHOD LexLOG::PropertySet(const char *key, const char *val) {
if (osTxt.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
Sci_Position SCI_METHOD LexLOG::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywords;
break;
}
Sci_Position firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
const int indicatorWhitespace = 1;
inline bool IsAAsciiChar(int ch) {
return (ch < 0x80);
}
inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
if (ch < 0x80)
return (isalpha(ch) || ch == '_');
if (!unicodeIdentifiers)
return false;
return IsXidStart(ch);
}
//是否是单词分割符号对于ascii中的数字和字母以外的字符比如 . @ \t 等,都作为一个单词的分割符号。
inline bool IsWordSplitChar(int ch) noexcept {
return (ch < 0x80) && !isalnum(ch);
}
inline bool IsLineEol(int ch) noexcept {
return ch == '\n' || ch == '\r';
}
//获取行最多获取128个字符串
static std::string GetLineContents(LexAccessor& styler, Sci_Position start, const int len=128) {
std::string lineContent;
Sci_Position i = 0;
char ch = styler.SafeGetCharAt(start, '\n');
const Sci_Position endLine = styler.LineEnd(styler.GetLine(start));
while (((start + i) < endLine) && ( i < len)) {
const char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
lineContent += ch;
i++;
ch = chNext;
}
return lineContent;
}
//只识别中文和英文两种单词的状态
void SCI_METHOD LexLOG::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, NULL);
const Sci_Position endPos = startPos + length;
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
std::regex patternData ("\\d{4}[-/]\\d{2}[-/]\\d{2} \\d{2}:\\d{2}:\\d{2}[.:]\\d{1,3}");
Sci_Position startIndicator = sc.currentPos;
bool isDataMatch = false;
for (; sc.More();) {
//如果是在行开头则获取64字节识别出其中的日期。
if (sc.atLineStart) {
std::string lineContens = GetLineContents(styler, sc.currentPos,64);
//匹配里面的日期时间值
std::smatch result;
std::string::const_iterator iterStart = lineContens.begin();
std::string::const_iterator iterEnd = lineContens.end();
//匹配到日期
if (std::regex_search(iterStart, iterEnd, result, patternData))
{
int start = result[0].first - iterStart;
int end = result[0].second - iterStart;
int i = 0;
while (i < start)
{
sc.Forward();
++i;
}
sc.SetState(SCE_LOG_DATE);
while (i < end)
{
sc.Forward();
++i;
}
sc.SetState(SCE_LOG_DEFAULT);
}
}
/*if (!sc.atLineEnd && !setWordStart.Contains(sc.chPrev) && setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_LOG_DEFAULT);
sc.ChangeState(SCE_LOG_IDENTIFIER);
}*/
switch (sc.state)
{
case SCE_LOG_HEX:
{
if (!hexWord.Contains(sc.ch))
{
sc.ChangeState(SCE_LOG_NUM);//16进制和10进制一样的格式
sc.SetState(SCE_LOG_DEFAULT);
}
}
break;
case SCE_LOG_NUM:
{
if (!IsADigit(sc.ch))
{
sc.SetState(SCE_LOG_DEFAULT);
}
}
break;
case SCE_LOG_DEFAULT:
{
//注意顺序,要先判断数字。
if (sc.Match('0','x'))
{
sc.SetState(SCE_LOG_HEX);
sc.Forward();
}
else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
//如果当前字符是数字,或者是.数字,则直接设置当前状态为数字。
sc.SetState(SCE_LOG_NUM);
}
else if (!sc.atLineEnd && setWordStart.Contains(sc.ch)) {
//如果不在行尾,而且当前字符是一个单词的开头标识字符,则进入标识符识别状态。
sc.SetState(SCE_LOG_IDENTIFIER);
}
}
break;
case SCE_LOG_IDENTIFIER:
{
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch))
{
char s[1000];
//取出当前标识符注意标识符不会超过1000这是预计不会有人傻到取名一个超过1000的字符串变量。
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_LOG_KEYWORD);
}
else
{
sc.ChangeState(SCE_LOG_DEFAULT);
}
sc.SetState(SCE_LOG_DEFAULT);
}
}
}
sc.Forward();
}
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
sc.Complete();
}
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
Sci_Position pos = styler.LineStart(line);
const Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = pos; i < eol_pos; i++) {
const char ch = styler[i];
if (ch == '#')
return true;
else if (ch != ' ' && ch != '\t')
return false;
}
return false;
}
static bool IsQuoteLine(Sci_Position line, const Accessor &styler) {
const int style = styler.StyleAt(styler.LineStart(line)) & 31;
return false;
}
//不处理任何折叠
void SCI_METHOD LexLOG::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {
return;
}
static const char *const txtWordListDesc[] = {
0
};
LexerModule lmLog(SCLEX_LOG, LexLOG::LexerFactoryLog, "log", txtWordListDesc);

View File

@ -619,12 +619,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
// 2: here doc text (lines after the delimiter)
int Quote; // the char after '<<'
bool Quoted; // true if Quote in ('\'','"','`')
bool StripIndent; // true if '<<~' requested to strip leading whitespace
int DelimiterLength; // strlen(Delimiter)
char Delimiter[HERE_DELIM_MAX]; // the Delimiter
HereDocCls() {
State = 0;
Quote = 0;
Quoted = false;
StripIndent = false;
DelimiterLength = 0;
Delimiter[0] = '\0';
}
@ -885,7 +887,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
sc.SetState(SCE_PL_DEFAULT);
break;
case SCE_PL_COMMENTLINE:
if (sc.atLineEnd) {
if (sc.atLineStart) {
sc.SetState(SCE_PL_DEFAULT);
}
break;
@ -896,8 +898,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
HereDoc.State = 1; // pre-init HERE doc class
HereDoc.Quote = sc.chNext;
HereDoc.Quoted = false;
HereDoc.StripIndent = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
if (delim_ch == '~') { // was actually '<<~'
sc.Forward();
HereDoc.StripIndent = true;
HereDoc.Quote = delim_ch = sc.chNext;
}
if (IsASpaceOrTab(delim_ch)) {
// skip whitespace; legal only for quoted delimiters
Sci_PositionU i = sc.currentPos + 1;
@ -964,6 +972,11 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
case SCE_PL_HERE_QX:
// also implies HereDoc.State == 2
sc.Complete();
if (HereDoc.StripIndent) {
// skip whitespace
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
sc.Forward();
}
if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) {
int c = sc.GetRelative(HereDoc.DelimiterLength);
if (c == '\r' || c == '\n') { // peek first, do not consume match
@ -1701,6 +1714,12 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int
} else if (ch == ']') {
levelCurrent--;
}
} else if (style == SCE_PL_STRING_QW) {
// qw
if (stylePrevCh != style)
levelCurrent++;
else if (styleNext != style)
levelCurrent--;
}
// POD folding
if (options.foldPOD && atLineStart) {

View File

@ -1,4 +1,4 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
@ -33,9 +33,9 @@ using namespace Scintilla;
//const char styleSubable[] = { SCE_P_IDENTIFIER, 0 };
//Default = 0,//中文
//Ascii = 1,//英文
//Keyword = 2, //关键字只有以TXT为母版的
//Default = 0,//中文
//Ascii = 1,//英文
//Keyword = 2, //关键字只有以TXT为母版的
LexicalClass lexicalClasses[] = {
// Lexer Python SCLEX_PYTHON SCE_P_:
@ -50,10 +50,12 @@ enum literalsAllowed { litNone = 0, litU = 1, litB = 2, litF = 4 };
struct OptionsTxt {
bool ascii;
bool utf8;
bool keyword;
OptionsTxt() {
ascii = true;
utf8 = true;
keyword = true;
}
};
@ -66,6 +68,9 @@ struct OptionSetTxt : public OptionSet<OptionsTxt> {
DefineProperty("lexer.txt.asciistring", &OptionsTxt::ascii,
"text literals ascii string");
DefineProperty("lexer.txt.keyword", &OptionsTxt::keyword,
"text keyword");
}
};
@ -75,9 +80,10 @@ class LexTXT :public DefaultLexer
//SubStyles subStyles;
OptionsTxt options;
OptionSetTxt osTxt;
bool isUserDefMode;
public:
explicit LexTXT() :
DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses))/*,
DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)), isUserDefMode(false)/*,
subStyles(styleSubable, 0x80, 0x40, 0)*/ {
}
virtual ~LexTXT() {}
@ -161,7 +167,7 @@ Sci_Position SCI_METHOD LexTXT::WordListSet(int n, const char *wl) {
case 0:
wordListN = &keywords;
break;
}
}
Sci_Position firstModification = -1;
if (wordListN) {
WordList wlNew;
@ -170,6 +176,7 @@ Sci_Position SCI_METHOD LexTXT::WordListSet(int n, const char *wl) {
wordListN->Set(wl);
firstModification = 0;
}
isUserDefMode = (wordListN->Length() > 0);
}
return firstModification;
}
@ -202,108 +209,104 @@ inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
return IsXidStart(ch);
}
//只识别中文和英文两种单词的状态
//是否是单词分割符号对于ascii中的数字和字母以外的字符比如 . @ \t 等,都作为一个单词的分割符号。
inline bool IsWordSplitChar(int ch) noexcept {
//return ch == ' ' || ch == '\t';
return (ch < 0x80) && !isalnum(ch);
}
inline bool IsLineEol(int ch) noexcept {
return ch == '\n' || ch == '\r';
}
//只识别中文和英文两种单词的状态
void SCI_METHOD LexTXT::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, NULL);
const Sci_Position endPos = startPos + length;
//// Backtrack to previous line in case need to fix its tab whinging
//Sci_Position lineCurrent = styler.GetLine(startPos);
//if (startPos > 0) {
// if (lineCurrent > 0) {
// lineCurrent--;
// // Look for backslash-continued lines
// while (lineCurrent > 0) {
// Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;
// const int eolStyle = styler.StyleAt(eolPos);
// if (eolStyle == SCE_P_STRING
// || eolStyle == SCE_P_CHARACTER
// || eolStyle == SCE_P_STRINGEOL) {
// lineCurrent -= 1;
// }
// else {
// break;
// }
// }
// startPos = styler.LineStart(lineCurrent);
// }
// initStyle = (startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1));
//}
//initStyle = initStyle & 31;
//if (initStyle == SCE_P_STRINGEOL) {
// initStyle = SCE_P_DEFAULT;
//}
//const WordClassifier& classifierIdentifiers = subStyles.Classifier(SCE_TXT_IDENTIFIER);
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
Sci_Position startIndicator = sc.currentPos;
for (; sc.More();) {
// Check for a new state starting character
if (sc.state == SCE_TXT_DEFAULT)
{
//遇到下一个ASCII字符的时候进入识别状态
if (IsAAsciiChar(sc.ch))
{
sc.SetState(SCE_TXT_IDENTIFIER);
}
}
else if (sc.state == SCE_TXT_ASCII)
{
//遇到下一个非ASCII字符的时候进入识别状态
if (!IsAAsciiChar(sc.ch))
{
sc.SetState(SCE_TXT_IDENTIFIER);
}
}
if (sc.state == SCE_TXT_IDENTIFIER) {
//txt就三种状态、英文、中文、自定义关键字。默认是中文。
//遇到非字符和非数字,开始检测单词,是关键字则识别为关键字;若不是关键字,则肯定是英文字符
//如果遇到非ASCII字符则开始检查
if (!IsAAsciiChar(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
int style = SCE_TXT_IDENTIFIER;
if (keywords.InList(s))
{
style = SCE_TXT_KEYWORD;
}
else
{
//不是关键字,就是普通的英文单词
style = SCE_TXT_ASCII;
}
sc.ChangeState(style);
//下面函数运行就已经把关键字或英文给单独设置风格了。此时默认进入中文风格状态
sc.SetState(SCE_TXT_DEFAULT);
}
}
sc.Forward();
}
//最后一段不能遗漏,也需要识别
if (sc.state == SCE_TXT_IDENTIFIER)
if (!isUserDefMode)
{
if (IsAAsciiChar(sc.chPrev))
{
sc.ChangeState(SCE_TXT_ASCII);
for (; sc.More();) {
// Check for a new state starting character
if (sc.state == SCE_TXT_DEFAULT)
{
if (IsAAsciiChar(sc.ch))
{
sc.SetState(SCE_TXT_ASCII);
}
}
else if (sc.state == SCE_TXT_ASCII)
{
if (!IsAAsciiChar(sc.ch))
{
sc.SetState(SCE_TXT_DEFAULT);
}
}
sc.Forward();
}
}
else
{
sc.ChangeState(SCE_TXT_DEFAULT);
}
for (; sc.More();) {
// Check for a new state starting character
if (sc.state == SCE_TXT_DEFAULT)
{
if (IsAAsciiChar(sc.ch))
{
//如果要识别关键字,必须要跳过当前空白字符。否则 中文空格后面第一个关键字无法高亮
if (IsWordSplitChar(sc.ch) && IsAWordStart(sc.chNext, false))
{
//这里切换的时候ForwardSetState跳过当前空白字符
sc.ForwardSetState(SCE_TXT_ASCII);
continue;
}
sc.SetState(SCE_TXT_ASCII);
}
}
else if (sc.state == SCE_TXT_ASCII)
{
if (!IsAAsciiChar(sc.ch))
{
sc.SetState(SCE_TXT_DEFAULT);
}
else //存在自定义关键字,说明是用户自定义语法。
{
//下面是识别关键字的逻辑。在英文逻辑下,对单词进行识别。
//所谓单词,一定是包围在前后空格或\t中的英文单词
if ((IsWordSplitChar(sc.ch) /*|| IsLineEol(sc.ch)*/) && isalpha(sc.chPrev))
{
char s[512];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s))
{
sc.ChangeState(SCE_TXT_KEYWORD);
}
sc.SetState(SCE_TXT_ASCII);
}
if (IsWordSplitChar(sc.ch) && IsAWordStart(sc.chNext, false))
{
//这里切换的时候ForwardSetState跳过当前空白字符
sc.ForwardSetState(SCE_TXT_ASCII);
continue;
//sc.SetState(SCE_TXT_ASCII);
}
}
}
sc.Forward();
}
}
//最后一段不能遗漏,也需要识别
sc.SetState(SCE_TXT_DEFAULT);
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
@ -330,7 +333,7 @@ static bool IsQuoteLine(Sci_Position line, const Accessor &styler) {
}
//不处理任何折叠
//不处理任何折叠
void SCI_METHOD LexTXT::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {
return;
}

View File

@ -190,6 +190,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmTEHex);
LINK_LEXER(lmTeX);
LINK_LEXER(lmTxt);
LINK_LEXER(lmLog);
LINK_LEXER(lmTxt2tags);
LINK_LEXER(lmVB);
LINK_LEXER(lmVBScript);
@ -198,6 +199,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmVisualProlog);
LINK_LEXER(lmXML);
LINK_LEXER(lmYAML);
LINK_LEXER(lmGCode);
//--Autogenerated -- end of automatically generated section

View File

@ -509,6 +509,8 @@ Sci::Line Document::LineFromPositionIndex(Sci::Position pos, int lineCharacterIn
}
int SCI_METHOD Document::SetLevel(Sci_Position line, int level) {
//20230306 这个标记如果不去掉那么fold的尾部会包含下面新增的空行定位一天才定位到此。
level &= ~SC_FOLDLEVELWHITEFLAG;
const int prev = Levels()->SetLevel(static_cast<Sci::Line>(line), level, LinesTotal());
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,

View File

@ -1977,8 +1977,18 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) {
// Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
// characters representing themselves.
} else {
//发现这里在macOs下面输入要崩溃。于是把windows macos还是区分一下
unsigned int utf32[1] = { 0 };
#if defined(Q_OS_WIN)
UTF32FromUTF8(s, len, utf32, ELEMENTS(utf32));
#elif defined(Q_OS_MAC)
//在MAC上面最多输入3个字符。因为一个UTF8编码也就三个字符。而且这里原设计也就只接受一个字符。
UTF32FromUTF8(s, (len > 3 ? 3 : len), utf32, ELEMENTS(utf32));
#elif defined(Q_OS_UNIX)
UTF32FromUTF8(s, len, utf32, ELEMENTS(utf32));
#endif
byte = utf32[0];
}
NotifyChar(byte);
@ -2836,7 +2846,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
// Send notification
SCNotification scn = {};
scn.nmhdr.code = SCN_MACRORECORD;
scn.nmhdr.code = SCN_MACRORECORD_ID;
scn.message = iMessage;
scn.wParam = wParam;
scn.lParam = lParam;
@ -5809,12 +5819,26 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return pdoc->Length();
case SCI_CUT:
Cut();
SetLastXChosen();
if (!sel.Empty())
{
Cut();
SetLastXChosen();
}
else
{
KeyCommand(SCI_LINECUT);
}
break;
case SCI_COPY:
Copy();
if (!sel.Empty())
{
Copy();
}
else
{
KeyCommand(SCI_LINECOPY);
}
break;
case SCI_COPYALLOWLINE:
@ -7832,6 +7856,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
recordingMacro = false;
return 0;
case SCI_GETRECORSTATUS:
return (recordingMacro ? 1 : 0);
case SCI_MOVECARETINSIDEVIEW:
MoveCaretInsideView();
break;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Scintilla source code edit control
// Scintilla source code edit control
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin.
**/
@ -167,270 +167,356 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
// On textual margins move marker to the left to try to avoid overlapping the text
centreX = ircWhole.left + dimOn2 + 1;
}
if (markType == SC_MARK_ROUNDRECT) {
PRectangle rcRounded = rc;
rcRounded.left = rc.left + 1;
rcRounded.right = rc.right - 1;
surface->RoundedRectangle(rcRounded, fore, back);
} else if (markType == SC_MARK_CIRCLE) {
const PRectangle rcCircle = PRectangle::FromInts(
centreX - dimOn2,
centreY - dimOn2,
centreX + dimOn2,
centreY + dimOn2);
surface->Ellipse(rcCircle, fore, back);
} else if (markType == SC_MARK_ARROW) {
Point pts[] = {
Point::FromInts(centreX - dimOn4, centreY - dimOn2),
Point::FromInts(centreX - dimOn4, centreY + dimOn2),
Point::FromInts(centreX + dimOn2 - dimOn4, centreY),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_ARROWDOWN) {
Point pts[] = {
Point::FromInts(centreX - dimOn2, centreY - dimOn4),
Point::FromInts(centreX + dimOn2, centreY - dimOn4),
Point::FromInts(centreX, centreY + dimOn2 - dimOn4),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
switch (markType)
{
case SC_MARK_ROUNDRECT:
{
PRectangle rcRounded = rc;
rcRounded.left = rc.left + 1;
rcRounded.right = rc.right - 1;
surface->RoundedRectangle(rcRounded, fore, back);
}
break;
case SC_MARK_CIRCLE:
{
const PRectangle rcCircle = PRectangle::FromInts(
centreX - dimOn2,
centreY - dimOn2,
centreX + dimOn2,
centreY + dimOn2);
surface->Ellipse(rcCircle, fore, back);
}
break;
case SC_MARK_ARROW:
{
Point pts[] = {
Point::FromInts(centreX - dimOn4, centreY - dimOn2),
Point::FromInts(centreX - dimOn4, centreY + dimOn2),
Point::FromInts(centreX + dimOn2 - dimOn4, centreY),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_PLUS) {
Point pts[] = {
Point::FromInts(centreX - armSize, centreY - 1),
Point::FromInts(centreX - 1, centreY - 1),
Point::FromInts(centreX - 1, centreY - armSize),
Point::FromInts(centreX + 1, centreY - armSize),
Point::FromInts(centreX + 1, centreY - 1),
Point::FromInts(centreX + armSize, centreY -1),
Point::FromInts(centreX + armSize, centreY +1),
Point::FromInts(centreX + 1, centreY + 1),
Point::FromInts(centreX + 1, centreY + armSize),
Point::FromInts(centreX - 1, centreY + armSize),
Point::FromInts(centreX - 1, centreY + 1),
Point::FromInts(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
}
break;
case SC_MARK_ARROWDOWN:
{
Point pts[] = {
Point::FromInts(centreX - dimOn2, centreY - dimOn4),
Point::FromInts(centreX + dimOn2, centreY - dimOn4),
Point::FromInts(centreX, centreY + dimOn2 - dimOn4),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_MINUS) {
Point pts[] = {
Point::FromInts(centreX - armSize, centreY - 1),
Point::FromInts(centreX + armSize, centreY -1),
Point::FromInts(centreX + armSize, centreY +1),
Point::FromInts(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
}
break;
case SC_MARK_PLUS:
{
Point pts[] = {
Point::FromInts(centreX - armSize, centreY - 1),
Point::FromInts(centreX - 1, centreY - 1),
Point::FromInts(centreX - 1, centreY - armSize),
Point::FromInts(centreX + 1, centreY - armSize),
Point::FromInts(centreX + 1, centreY - 1),
Point::FromInts(centreX + armSize, centreY - 1),
Point::FromInts(centreX + armSize, centreY + 1),
Point::FromInts(centreX + 1, centreY + 1),
Point::FromInts(centreX + 1, centreY + armSize),
Point::FromInts(centreX - 1, centreY + armSize),
Point::FromInts(centreX - 1, centreY + 1),
Point::FromInts(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_SMALLRECT) {
PRectangle rcSmall;
rcSmall.left = rc.left + 1;
rcSmall.top = rc.top + 2;
rcSmall.right = rc.right - 1;
rcSmall.bottom = rc.bottom - 2;
surface->RectangleDraw(rcSmall, fore, back);
}
break;
case SC_MARK_MINUS:
{
Point pts[] = {
Point::FromInts(centreX - armSize, centreY - 1),
Point::FromInts(centreX + armSize, centreY - 1),
Point::FromInts(centreX + armSize, centreY + 1),
Point::FromInts(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
// An invisible marker so don't draw anything
}
break;
case SC_MARK_SMALLRECT:
{
PRectangle rcSmall;
rcSmall.left = rc.left + 1;
rcSmall.top = rc.top + 2;
rcSmall.right = rc.right - 1;
rcSmall.bottom = rc.bottom - 2;
surface->RectangleDraw(rcSmall, fore, back);
} else if (markType == SC_MARK_VLINE) {
}
break;
case SC_MARK_EMPTY:
case SC_MARK_BACKGROUND:
case SC_MARK_UNDERLINE:
case SC_MARK_AVAILABLE:
break;
case SC_MARK_VLINE:
{
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, ircWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
surface->PenColour(colourTail);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
} else if (markType == SC_MARK_TCORNER) {
surface->PenColour(colourTail);
surface->MoveTo(centreX, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY + 1);
surface->PenColour(colourHead);
surface->LineTo(centreX, ircWhole.bottom);
} else if (markType == SC_MARK_LCORNERCURVE) {
surface->PenColour(colourTail);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY-3);
surface->LineTo(centreX+3, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
} else if (markType == SC_MARK_TCORNERCURVE) {
surface->PenColour(colourTail);
surface->MoveTo(centreX, centreY-3);
surface->LineTo(centreX+3, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY-2);
surface->PenColour(colourHead);
surface->LineTo(centreX, ircWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) {
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
if (tFold == LineMarker::headWithTail)
}
break;
case SC_MARK_LCORNER:
{
surface->PenColour(colourTail);
else
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
}
break;
case SC_MARK_TCORNER:
{
surface->PenColour(colourTail);
surface->MoveTo(centreX, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
surface->PenColour(colourBody);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY + 1);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
surface->PenColour(colourHead);
surface->LineTo(centreX, ircWhole.bottom);
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
if (tFold == LineMarker::body) {
surface->PenColour(colourTail);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_BOXMINUS) {
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
break;
case SC_MARK_LCORNERCURVE:
{
surface->PenColour(colourTail);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - 3);
surface->LineTo(centreX + 3, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
if (tFold == LineMarker::headWithTail)
break;
case SC_MARK_TCORNERCURVE:
{
surface->PenColour(colourTail);
else
surface->MoveTo(centreX, centreY - 3);
surface->LineTo(centreX + 3, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
surface->PenColour(colourBody);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - 2);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
surface->PenColour(colourHead);
surface->LineTo(centreX, ircWhole.bottom);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_CIRCLEMINUS) {
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType >= SC_MARK_CHARACTER) {
char character[1];
character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1);
PRectangle rcText = rc;
rcText.left += (rc.Width() - width) / 2;
rcText.right = rc.left + width;
surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2,
character, 1, fore, back);
} else if (markType == SC_MARK_DOTDOTDOT) {
XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);
for (int b=0; b<3; b++) {
const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
surface->FillRectangle(rcBlob, fore);
right += 5.0f;
}
} else if (markType == SC_MARK_ARROWS) {
surface->PenColour(fore);
int right = centreX - 2;
const int armLength = dimOn2 - 1;
for (int b = 0; b<3; b++) {
surface->MoveTo(right, centreY);
surface->LineTo(right - armLength, centreY - armLength);
surface->MoveTo(right, centreY);
surface->LineTo(right - armLength, centreY + armLength);
right += 4;
break;
case SC_MARK_BOXPLUS:
{
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
}
} else if (markType == SC_MARK_SHORTARROW) {
Point pts[] = {
Point::FromInts(centreX, centreY + dimOn2),
Point::FromInts(centreX + dimOn2, centreY),
Point::FromInts(centreX, centreY - dimOn2),
Point::FromInts(centreX, centreY - dimOn4),
Point::FromInts(centreX - dimOn4, centreY - dimOn4),
Point::FromInts(centreX - dimOn4, centreY + dimOn4),
break;
case SC_MARK_BOXPLUSCONNECTED:
{
if (tFold == LineMarker::headWithTail)
surface->PenColour(colourTail);
else
surface->PenColour(colourBody);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
if (tFold == LineMarker::body) {
surface->PenColour(colourTail);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
}
break;
case SC_MARK_BOXMINUS:
{
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize + 1);
surface->LineTo(centreX, ircWhole.bottom);
}
break;
case SC_MARK_BOXMINUSCONNECTED:
{
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize + 1);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
surface->PenColour(colourTail);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
}
break;
case SC_MARK_CIRCLEPLUS:
{
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
}
break;
case SC_MARK_CIRCLEPLUSCONNECTED:
{
if (tFold == LineMarker::headWithTail)
surface->PenColour(colourTail);
else
surface->PenColour(colourBody);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
}
break;
case SC_MARK_CIRCLEMINUS:
{
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
}
break;
case SC_MARK_CIRCLEMINUSCONNECTED:
{
surface->PenColour(colourHead);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, ircWhole.bottom);
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY - blobSize);
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawMinus(surface, centreX, centreY, blobSize, colourTail);
}
break;
case SC_MARK_DOTDOTDOT:
{
XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);
for (int b = 0; b < 3; b++) {
const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom - 2);
surface->FillRectangle(rcBlob, fore);
right += 5.0f;
}
}
break;
case SC_MARK_ARROWS:
{
surface->PenColour(fore);
int right = centreX - 2;
const int armLength = dimOn2 - 1;
for (int b = 0; b < 3; b++) {
surface->MoveTo(right, centreY);
surface->LineTo(right - armLength, centreY - armLength);
surface->MoveTo(right, centreY);
surface->LineTo(right - armLength, centreY + armLength);
right += 4;
}
}
break;
case SC_MARK_SHORTARROW:
{
Point pts[] = {
Point::FromInts(centreX, centreY + dimOn2),
Point::FromInts(centreX + dimOn2, centreY),
Point::FromInts(centreX, centreY - dimOn2),
Point::FromInts(centreX, centreY - dimOn4),
Point::FromInts(centreX - dimOn4, centreY - dimOn4),
Point::FromInts(centreX - dimOn4, centreY + dimOn4),
Point::FromInts(centreX, centreY + dimOn4),
Point::FromInts(centreX, centreY + dimOn2),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else if (markType == SC_MARK_LEFTRECT) {
PRectangle rcLeft = rcWhole;
rcLeft.right = rcLeft.left + 4;
surface->FillRectangle(rcLeft, back);
} else if (markType == SC_MARK_BOOKMARK) {
const int halfHeight = minDim / 3;
Point pts[] = {
Point::FromInts(ircWhole.left, centreY-halfHeight),
Point::FromInts(ircWhole.right - 3, centreY - halfHeight),
Point::FromInts(ircWhole.right - 3 - halfHeight, centreY),
Point::FromInts(ircWhole.right - 3, centreY + halfHeight),
Point::FromInts(ircWhole.left, centreY + halfHeight),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else { // SC_MARK_FULLRECT
surface->FillRectangle(rcWhole, back);
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
}
break;
case SC_MARK_LEFTRECT:
{
PRectangle rcLeft = rcWhole;
rcLeft.right = rcLeft.left + 4;
surface->FillRectangle(rcLeft, back);
}
break;
case SC_MARK_BOOKMARK:
{
const int halfHeight = minDim / 3;
Point pts[] = {
Point::FromInts(ircWhole.left, centreY - halfHeight),
Point::FromInts(ircWhole.right - 3, centreY - halfHeight),
Point::FromInts(ircWhole.right - 3 - halfHeight, centreY),
Point::FromInts(ircWhole.right - 3, centreY + halfHeight),
Point::FromInts(ircWhole.left, centreY + halfHeight),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
}
break;
default:
{
if (markType >= SC_MARK_CHARACTER) {
char character[1];
character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1);
PRectangle rcText = rc;
rcText.left += (rc.Width() - width) / 2;
rcText.right = rc.left + width;
surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2,
character, 1, fore, back);
}
else { // SC_MARK_FULLRECT
surface->FillRectangle(rcWhole, back);
}
}
}
}

View File

@ -364,9 +364,11 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc,
marks &= vs.ms[margin].mask;
PRectangle rcMarker = rcSelMargin;
rcMarker.top = static_cast<XYPOSITION>(yposScreen);
rcMarker.bottom = static_cast<XYPOSITION>(yposScreen + vs.lineHeight);
PRectangle rcMarker(
rcSelMargin.left,
static_cast<XYPOSITION>(yposScreen),
rcSelMargin.right,
static_cast<XYPOSITION>(yposScreen + vs.lineHeight));
if (vs.ms[margin].style == SC_MARGIN_NUMBER) {
if (firstSubLine) {
std::string sNumber;
@ -412,11 +414,12 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc,
if (firstSubLine) {
surface->FillRectangle(rcMarker,
vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back);
PRectangle rcText = rcMarker;
if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
const int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
rcMarker.left = rcMarker.right - width - 3;
rcText.left = rcText.right - width - 3;
}
DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker,
DrawStyledText(surface, vs, vs.marginStyleOffset, rcText,
stMargin, 0, stMargin.length, drawAll);
} else {
// if we're displaying annotation lines, color the margin to match the associated document line

View File

@ -1,4 +1,4 @@
// Scintilla source code edit control
// Scintilla source code edit control
/** @file UniConversion.cxx
** Functions to handle UTF-8 and UTF-16 strings.
**/
@ -166,7 +166,7 @@ size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen)
size_t ui = 0;
for (size_t i = 0; i < len;) {
unsigned char ch = s[i];
const unsigned int byteCount = UTF8BytesOfLead[ch];
unsigned int byteCount = UTF8BytesOfLead[ch];
unsigned int value;
if (i + byteCount > len) {
@ -179,7 +179,12 @@ size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen)
}
if (ui == tlen) {
throw std::runtime_error("UTF32FromUTF8: attempted write beyond end");
//在macos下面中文输入shift+_会导致触发这里的崩溃。发现macos下面输入shift+_引入的两个字符——会同时输入。
//即这里——长度是6个字符。但是外面来的tlen=1,导致二者没有匹配。但是崩溃总不是一个好的选择。
//我们直接强行赋值byteCount=3然后输出拉倒。20230506
//throw std::runtime_error("UTF32FromUTF8: attempted write beyond end");
ui = tlen - 1;
byteCount = 3;
}
i++;

View File

@ -1,4 +1,4 @@
// Scintilla source code edit control
// Scintilla source code edit control
/** @file UniConversion.h
** Functions to handle UTF-8 and UTF-16 strings.
**/
@ -8,6 +8,8 @@
#ifndef UNICONVERSION_H
#define UNICONVERSION_H
#include "Qsci/qsciglobal.h"
namespace Scintilla {
const int UTF8MaxBytes = 4;
@ -48,7 +50,8 @@ inline constexpr bool UTF8IsAscii(int ch) noexcept {
}
enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 };
int UTF8Classify(const unsigned char *us, size_t len) noexcept;
QSCINTILLA_EXPORT int UTF8Classify(const unsigned char *us, size_t len) noexcept;
// Similar to UTF8Classify but returns a length of 1 for invalid bytes
// instead of setting the invalid flag

View File

@ -252,27 +252,30 @@ QVariant QsciScintillaBase::inputMethodQuery(Qt::InputMethodQuery query) const
{
int paraStart = sci->pdoc->ParaUp(pos);
int paraEnd = sci->pdoc->ParaDown(pos);
QVarLengthArray<char,1024> buffer(paraEnd - paraStart + 1);
Sci_CharacterRange charRange;
charRange.cpMin = paraStart;
charRange.cpMax = paraEnd;
if (paraEnd - paraStart <= 0)
{
return "";
}
QByteArray buffer(paraEnd - paraStart + 1,0);
//QVarLengthArray<char,1024> buffer(paraEnd - paraStart + 1);
Sci_TextRange textRange;
textRange.chrg = charRange;
textRange.chrg.cpMin = paraStart;
textRange.chrg.cpMax = paraEnd;
textRange.lpstrText = buffer.data();
SendScintilla(SCI_GETTEXTRANGE, 0, (sptr_t)&textRange);
SendScintilla(SCI_GETTEXTRANGE, 0, &textRange);
return bytesAsText(buffer.constData());
return bytesAsText(buffer.constData(), buffer.size());
}
case Qt::ImCurrentSelection:
{
QVarLengthArray<char,1024> buffer(SendScintilla(SCI_GETSELTEXT));
QVarLengthArray<char,1024> buffer(SendScintilla(SCI_GETSELTEXT) + 1);
SendScintilla(SCI_GETSELTEXT, 0, (sptr_t)buffer.data());
return bytesAsText(buffer.constData());
return bytesAsText(buffer.constData(), buffer.size() - 1);
}
default:

View File

@ -35,6 +35,11 @@ QT_END_NAMESPACE
class QsciScintilla;
#ifdef Q_OS_WIN
//windows系统下面不允许随意修改默认快捷键。因为加载快捷键会降低启动速度。
#else
#define USER_SHUT_CUT_DEF
#endif
//! \brief The QsciCommandSet class represents the set of all internal editor
//! commands that may have keys bound.
@ -84,6 +89,13 @@ private:
QsciCommandSet(const QsciCommandSet &);
QsciCommandSet &operator=(const QsciCommandSet &);
public:
#ifdef USER_SHUT_CUT_DEF
void readUserShutKey();
void saveUserDefQsciShutkey();
#endif
};
#endif

View File

@ -53,7 +53,7 @@ enum LangType {
L_CSOUND, L_ERLANG, L_ESCRIPT, L_FORTH, L_LATEX, \
L_MMIXAL, L_NIM, L_NNCRONTAB, L_OSCRIPT, L_REBOL, \
L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG, L_TYPESCRIPT, \
L_EDIFACT, L_MARKDOWN, L_OCTAVE, L_PO, L_POV, L_IDL, L_GO, L_GLOBAL, L_TXT, \
L_EDIFACT, L_MARKDOWN, L_OCTAVE, L_PO, L_POV, L_IDL, L_GO, L_GLOBAL, L_LOG, L_GCode, L_APDL, L_TXT,\
// Don't use L_JS, use L_JAVASCRIPT instead
// The end of enumated language type, so it should be always at the end
L_EXTERNAL = 100, L_USER_DEFINE=200,L_USER_TXT,L_USER_CPP //用户自定义顺序与UserLangMother保存一致

View File

@ -0,0 +1,64 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerApdl : public QsciLexer
{
Q_OBJECT
public:
enum {
DEFAULT=0,
COMMENT,
COMMENTBLOCK,
NUMBER,
STRING,
OPERATOR,
WORD,
PROCESSOR,
COMMAND,
SLASHCOMMAND,
STARCOMMAND,
ARGUMENT,
FUNCTION,
};
QsciLexerApdl(QObject *parent=0);
virtual ~QsciLexerApdl();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerApdl(const QsciLexerApdl&);
QsciLexerApdl& operator=(const QsciLexerApdl&);
};

View File

@ -0,0 +1,61 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerGCode : public QsciLexer
{
Q_OBJECT
public:
enum {
DEFAULT = 0,
KEYWORD, //关键字
KEYWORD1, //关键字
COMMNET,
POSITIONX, //位置 X Y Z
POSITIONY, //位置 X Y Z
POSITIONZ, //位置 X Y Z
OFFSET,//I J K 偏移
VELOCITY,//速度 F
TIMES,// P 次数
};
QsciLexerGCode(QObject *parent=0);
virtual ~QsciLexerGCode();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerGCode(const QsciLexerGCode&);
QsciLexerGCode& operator=(const QsciLexerGCode&);
};

View File

@ -0,0 +1,71 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerIntelHex : public QsciLexer
{
Q_OBJECT
public:
enum {
DEFAULT=0,
RECSTART,
RECTYPE,
RECTYPE_UNKNOWN,
BYTECOUNT,
BYTECOUNT_WRONG,
NOADDRESS,
DATAADDRESS,
RECCOUNT,
STARTADDRESS,
ADDRESSFIELD_UNKNOWN,
EXTENDEDADDRESS,
DATA_ODD,
DATA_EVEN,
DATA_UNKNOWN,
DATA_EMPTY,
CHECKSUM,
CHECKSUM_WRONG,
GARBAGE,
};
QsciLexerIntelHex(QObject *parent=0);
virtual ~QsciLexerIntelHex();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerIntelHex(const QsciLexerIntelHex&);
QsciLexerIntelHex& operator=(const QsciLexerIntelHex&);
};

View File

@ -0,0 +1,64 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerLisp : public QsciLexer
{
Q_OBJECT
public:
enum {
DEFAULT=0,
COMMENT,
NUMBER,
KEYWORD,
KEYWORD_KW,
SYMBOL,
STRING,
STRINGEOL =8,
IDENTIFIER,
OPERATOR,
SPECIAL,
MULTI_COMMENT,
};
QsciLexerLisp(QObject *parent=0);
virtual ~QsciLexerLisp();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerLisp(const QsciLexerLisp&);
QsciLexerLisp& operator=(const QsciLexerLisp&);
};

View File

@ -0,0 +1,55 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerLog : public QsciLexer
{
Q_OBJECT
public:
enum {
Default = 0,
Num= 1,//中文
Date = 2,//英文
Keyword = 3, //关键字只有以TXT为母版的自定义语言才有默认txt是没有关键字说法的
};
QsciLexerLog(QObject *parent=0);
virtual ~QsciLexerLog();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerLog(const QsciLexerLog&);
QsciLexerLog& operator=(const QsciLexerLog&);
};

View File

@ -0,0 +1,69 @@
#pragma once
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
class QSCINTILLA_EXPORT QsciLexerPowerShell : public QsciLexer
{
Q_OBJECT
public:
enum {
DEFAULT = 0,
COMMENT,
STRING,
CHARACTER,
NUMBER,
VARIABLE,
OPERATOR,
IDENTIFIER,
KEYWORD,
CMDLET,
ALIAS,
FUNCTION,
USER1,
COMMENTSTREAM,
HERE_STRING,
HERE_CHARACTER,
COMMENTDOCKEYWORD,
};
QsciLexerPowerShell(QObject *parent=0);
virtual ~QsciLexerPowerShell();
//! Returns the name of the language.
const char* language() const;
const char * lexer() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//int lexerId() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string.
const char* keywords(int set);
//! Returns the descriptive name for style number \a style. If the
//! style is invalid for this language then an empty QString is returned.
//! This is intended to be used in user preference dialogs.
QString description(int style) const;
private:
QsciLexerPowerShell(const QsciLexerPowerShell&);
QsciLexerPowerShell& operator=(const QsciLexerPowerShell&);
};

View File

@ -30,6 +30,12 @@
class QsciScintilla;
enum USER_DEFINE_MACRO {
MACRO_FIND_NEXT = 5000,//查找下一个
MACRO_REPLACE_ALL,//全部替换
MACRO_REPLACE_ONE,//替换一条
MACRO_EXE_MENU_FUN,//执行菜单栏上面的命令
};
//! \brief The QsciMacro class represents a sequence of recordable editor
//! commands.
@ -68,6 +74,10 @@ public:
//! \sa load()
QString save() const;
//signals:
// //从外部调用记录宏非qscintilla内部宏
// void s_record(unsigned int msg, unsigned long wParam, void* lParam);
public slots:
//! Play the macro.
virtual void play();

View File

@ -85,9 +85,13 @@ enum FindNextType {
//! in other Qt editor classes. It also provides a higher level interface to
//! features specific to Scintilla such as syntax styling, call tips,
//! auto-indenting and auto-completion than that provided by QsciScintillaBase.
class QsciMacro;
class QSCINTILLA_EXPORT QsciScintilla : public QsciScintillaBase
{
Q_OBJECT
friend QsciMacro;
public:
//! This enum defines the different auto-indentation styles.
@ -1500,6 +1504,8 @@ public:
//! \sa hasSelectedText()
QString selectedText() const;
bool selectedRawBytes(QByteArray& bytes) const;
//! Returns whether or not the selection is drawn up to the right hand
//! border.
//!
@ -1670,7 +1676,8 @@ public:
void setHtmlHighLightTag(bool v);
bool getHtmlHighLightTag();
/* virtual void adjuctSkinStyle() {}*/
intptr_t searchInTarget(QByteArray& text2Find, size_t fromPos, size_t toPos) const;
public slots:
//! Appends the text \a text to the end of the text edit. Note that the
@ -2124,6 +2131,7 @@ signals:
//! within the line.
void cursorPositionChanged(int line, int index);
//和cursorPositionChanged类似但是只有当前行号真正发送变化后才触发该信号。
void cursorPosChange(int line, int pos);
//! This signal is emitted whenever text is selected or de-selected.
@ -2220,6 +2228,16 @@ protected:
void setStylesFont(const QFont& f, int style);
//运行用户自定义的宏。故意放在最后,防止破坏兼容性
virtual void playUserMacroRecord(unsigned int msg, unsigned long wParam, void* lParam)
{
}
//识别中文UTF8字符的情况。
virtual bool startAutoWordCompletion(AutoCompletionSource acs, bool checkThresh,
bool choose_single);
private slots:
void handleCallTipClick(int dir);
void handleCharAdded(int charadded);

View File

@ -2251,6 +2251,8 @@ public:
//!
SCI_STOPRECORD = 3002,
SCI_GETRECORSTATUS = 3003,//是否在记录中 0 否1是
//! This message sets the number of the lexer to use for syntax
//! styling.
//! \a wParam is the number of the lexer and is one of the SCLEX_*
@ -3004,7 +3006,10 @@ public:
SCK_INSERT = 309,
SCK_ESCAPE = 7,
SCK_BACK = 8,
SCK_TAB = 9,
//20230506 最开始这里是9我修改为了109。因为百度输入法下面对shitf+(中文输入时
//会先来一个8再来一个9的映射键。恰好这两个键有冲突。其他8对应之前的删除我已经在快捷键中把删除那个干掉了。
//9的话对应这个缩进所以修改为109不使用9这样一来百度输入法的9会映射到其他键而不与这里的SCK_TAB冲突。
SCK_TAB = 109,//9,
SCK_RETURN = 13,
SCK_ADD = 310,
SCK_SUBTRACT = 311,

View File

@ -386,7 +386,7 @@ void QsciScintillaQt::NotifyParent(SCNotification scn)
emit qsb->SCN_INDICATORRELEASE(scn.position, scn.modifiers);
break;
case SCN_MACRORECORD:
case SCN_MACRORECORD_ID:
emit qsb->SCN_MACRORECORD(scn.message, scn.wParam,
reinterpret_cast<void *>(scn.lParam));
break;

View File

@ -36,6 +36,23 @@
#undef USING_OSX_KEYS
#endif
#ifdef USER_SHUT_CUT_DEF
void QsciCommandSet::readUserShutKey()
{
QString userDefFile = QString("notepad/scishortcut");
QSettings qs(QSettings::IniFormat, QSettings::UserScope, userDefFile);
qs.setIniCodec("UTF-8");
readSettings(qs, "qsci");
}
void QsciCommandSet::saveUserDefQsciShutkey()
{
QString userDefFile = QString("notepad/scishortcut");
QSettings qs(QSettings::IniFormat, QSettings::UserScope, userDefFile);
qs.setIniCodec("UTF-8");
writeSettings(qs, "qsci");
}
#endif
// The ctor.
QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
@ -168,14 +185,14 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
#endif
#if 0
//测试无效
{
QsciCommand::ParaDownExtend,
Qt::Key_BracketRight | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection down one paragraph")
},
//测试无效
{
QsciCommand::ParaDownExtend,
Qt::Key_BracketRight | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection down one paragraph")
},
#endif
{
QsciCommand::ParaUp,
@ -261,7 +278,6 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
"Extend rectangular selection right one character")
},
#if 0
{
QsciCommand::WordLeft,
#if defined(USING_OSX_KEYS)
@ -272,7 +288,6 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move left one word")
},
#endif
{
QsciCommand::WordLeftExtend,
#if defined(USING_OSX_KEYS)
@ -283,7 +298,6 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection left one word")
},
#if 0
{
QsciCommand::WordRight,
#if defined(USING_OSX_KEYS)
@ -294,15 +308,12 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move right one word")
},
#endif
#if 0
{
QsciCommand::WordRightExtend,
Qt::Key_Right | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection right one word")
},
#endif
#if 0
{
QsciCommand::WordLeftEnd,
@ -442,7 +453,7 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
{
QsciCommand::VCHome,
#if defined(USING_OSX_KEYS)
0,
Qt::Key_H | Qt::META,
#else
Qt::Key_Home,
#endif
@ -611,7 +622,7 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move up one page")
},
/* {
{
QsciCommand::PageUpExtend,
Qt::Key_PageUp | Qt::SHIFT,
0,
@ -623,7 +634,7 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection up one page")
},*/
},
{
QsciCommand::PageDown,
Qt::Key_PageDown,
@ -634,7 +645,7 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move down one page")
},
/*{
{
QsciCommand::PageDownExtend,
Qt::Key_PageDown | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
@ -654,7 +665,7 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection down one page")
},*/
},
#if 0
{
QsciCommand::StutteredPageUp,
@ -697,9 +708,12 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
QsciCommand::DeleteBack,
Qt::Key_Backspace,
#if defined(USING_OSX_KEYS)
Qt::Key_H | Qt::META,
0,
#else
Qt::Key_Backspace | Qt::SHIFT,
//发现百度输入法输入shift+( 会映射到第8个命令也就是当前这条会导致删除字符。
// 发现这个快捷键完全是多余将这个快捷键删除。删除后百度输入法shift+(会与下一条冲突。20230506
//Qt::Key_Backspace | Qt::SHIFT,
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Delete previous character")
},
@ -711,6 +725,9 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
QT_TRANSLATE_NOOP("QsciCommand",
"Delete previous character if not at start of line")
},
#endif
{
QsciCommand::DeleteWordLeft,
Qt::Key_Backspace | Qt::CTRL,
@ -723,7 +740,6 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete word to right")
},
#endif
#if 0
{
QsciCommand::DeleteWordRightEnd,
@ -771,165 +787,164 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
0,
QT_TRANSLATE_NOOP("QsciCommand", "Copy current line")
},
/* {
QsciCommand::LineTranspose,
Qt::Key_T | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Transpose current and previous lines")
},*/
#if 0
{
QsciCommand::LineDuplicate,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate the current line")
},
#endif
{
QsciCommand::SelectAll,
Qt::Key_A | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Select all")
},
#if 0
{
QsciCommand::MoveSelectedLinesUp,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move selected lines up one line")
},
{
QsciCommand::MoveSelectedLinesDown,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move selected lines down one line")
},
#endif
#if 0
{
QsciCommand::SelectionDuplicate,
Qt::Key_D | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate selection")
},
#endif
{
QsciCommand::SelectionLowerCase,
Qt::Key_U | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to lower case")
},
{
QsciCommand::SelectionUpperCase,
Qt::Key_U | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to upper case")
},
{
QsciCommand::SelectionCut,
Qt::Key_X | Qt::CTRL,
Qt::Key_Delete | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Cut selection")
},
{
QsciCommand::SelectionCopy,
Qt::Key_C | Qt::CTRL,
Qt::Key_Insert | Qt::CTRL,
QT_TRANSLATE_NOOP("QsciCommand", "Copy selection")
},
{
QsciCommand::Paste,
Qt::Key_V | Qt::CTRL,
Qt::Key_Insert | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Paste")
},
{
QsciCommand::EditToggleOvertype,
Qt::Key_Insert,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Toggle insert/overtype")
},
{
QsciCommand::Newline,
Qt::Key_Return,
Qt::Key_Return | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Insert newline")
},
#if 0
{
QsciCommand::Formfeed,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Formfeed")
},
#endif
{
QsciCommand::Tab,
Qt::Key_Tab,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Indent one level")
},
#if 0
{
QsciCommand::Backtab,
Qt::Key_Tab | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "De-indent one level")
},
{
QsciCommand::Cancel,
Qt::Key_Escape,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Cancel")
},
#endif
{
QsciCommand::Undo,
Qt::Key_Z | Qt::CTRL,
Qt::Key_Backspace | Qt::ALT,
QT_TRANSLATE_NOOP("QsciCommand", "Undo last command")
},
{
QsciCommand::Redo,
#if defined(USING_OSX_KEYS)
Qt::Key_Z | Qt::CTRL | Qt::SHIFT,
#else
Qt::Key_Y | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Redo last command")
},
#if 1
{
QsciCommand::ZoomIn,
Qt::Key_Equal | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom in")
},
{
QsciCommand::ZoomOut,
Qt::Key_Minus | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom out")
},
#endif
#if 0
{
QsciCommand::MoveLineUp,
Qt::Key_Up | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move Line up")
},
/* {
QsciCommand::LineTranspose,
Qt::Key_T | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Transpose current and previous lines")
},*/
#if 0
{
QsciCommand::LineDuplicate,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate the current line")
},
#endif
{
QsciCommand::SelectAll,
Qt::Key_A | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Select all")
},
#if 0
{
QsciCommand::MoveSelectedLinesUp,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move selected lines up one line")
},
{
QsciCommand::MoveSelectedLinesDown,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move selected lines down one line")
},
#endif
{
QsciCommand::SelectionDuplicate,
Qt::Key_D | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate selection")
},
{
QsciCommand::SelectionLowerCase,
Qt::Key_U | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to lower case")
},
{
QsciCommand::SelectionUpperCase,
Qt::Key_U | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to upper case")
},
{
QsciCommand::SelectionCut,
Qt::Key_X | Qt::CTRL,
Qt::Key_Delete | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Cut selection")
},
{
QsciCommand::SelectionCopy,
Qt::Key_C | Qt::CTRL,
Qt::Key_Insert | Qt::CTRL,
QT_TRANSLATE_NOOP("QsciCommand", "Copy selection")
},
{
QsciCommand::Paste,
Qt::Key_V | Qt::CTRL,
Qt::Key_Insert | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Paste")
},
{
QsciCommand::EditToggleOvertype,
Qt::Key_Insert,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Toggle insert/overtype")
},
{
QsciCommand::Newline,
Qt::Key_Return,
Qt::Key_Return | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Insert newline")
},
#if 0
{
QsciCommand::Formfeed,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Formfeed")
},
#endif
{
QsciCommand::Tab,
Qt::Key_Tab,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Indent one level")
},
{
QsciCommand::MovdLineDown,
Qt::Key_Down | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move Line down")
},
#endif
{
QsciCommand::Backtab,
Qt::Key_Tab | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "De-indent one level")
},
#if 0
{
QsciCommand::Cancel,
Qt::Key_Escape,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Cancel")
},
#endif
{
QsciCommand::Undo,
Qt::Key_Z | Qt::CTRL,
Qt::Key_Backspace | Qt::ALT,
QT_TRANSLATE_NOOP("QsciCommand", "Undo last command")
},
{
QsciCommand::Redo,
#if defined(USING_OSX_KEYS)
Qt::Key_Z | Qt::CTRL | Qt::SHIFT,
#else
Qt::Key_Y | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Redo last command")
},
#if 1
{
QsciCommand::ZoomIn,
Qt::Key_Equal | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom in")
},
{
QsciCommand::ZoomOut,
Qt::Key_Minus | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom out")
},
#endif
#if 0
{
QsciCommand::MoveLineUp,
Qt::Key_Up | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move Line up")
},
{
QsciCommand::MovdLineDown,
Qt::Key_Down | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move Line down")
},
#endif
};
// Clear the default map.
@ -939,13 +954,20 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
// control character into the text).
for (int k = 'A'; k <= 'Z'; ++k)
qsci->SendScintilla(QsciScintillaBase::SCI_ASSIGNCMDKEY,
k + (QsciScintillaBase::SCMOD_CTRL << 16),
QsciScintillaBase::SCI_NULL);
k + (QsciScintillaBase::SCMOD_CTRL << 16),
QsciScintillaBase::SCI_NULL);
for (int i = 0; i < sizeof (cmd_table) / sizeof (cmd_table[0]); ++i)
{
cmds.append(
new QsciCommand(qsci, cmd_table[i].cmd, cmd_table[i].key,
cmd_table[i].altkey, cmd_table[i].desc));
new QsciCommand(qsci, cmd_table[i].cmd, cmd_table[i].key,
cmd_table[i].altkey, cmd_table[i].desc));
}
#ifdef USER_SHUT_CUT_DEF
readUserShutKey();
#endif
}
@ -1061,3 +1083,5 @@ QsciCommand *QsciCommandSet::find(QsciCommand::Command command) const
// This should never happen.
return 0;
}

163
src/qscint/src/qscilexerapdl.cpp Executable file
View File

@ -0,0 +1,163 @@
#include "Qsci/qscilexerapdl.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
//#if defined(Q_OS_WIN)
// QFont QsciLexerApdl::s_defaultTxtFont("Courier New", QsciLexer::s_defaultFontSize);
//#elif defined(Q_OS_MAC)
// QFont QsciLexerApdl::s_defaultTxtFont("STSong",14);
//#else
// QFont QsciLexerApdl::s_defaultTxtFont("Courier 10 Pitch", 12);
//#endif
QsciLexerApdl::QsciLexerApdl(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_APDL);
m_commentSymbol = "#";
}
QsciLexerApdl::~QsciLexerApdl()
{
}
// Returns the language name.
const char* QsciLexerApdl::language() const
{
return "APDL";
}
// Returns the lexer name.
const char *QsciLexerApdl::lexer() const
{
return "apdl";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerApdl::defaultColor(int style) const
{
switch (style)
{
case DEFAULT:
return QColor(0x80, 0x80, 0x80);
case COMMENT:
case COMMENTBLOCK:
return QColor(0x00, 0x7f, 0x00);
case NUMBER:
return QColor(0xff, 0x80, 0x00);
case PROCESSOR:
case COMMAND:
case SLASHCOMMAND:
case STARCOMMAND:
return QColor(0x00, 0x00, 0xff);
case WORD:
case STRING:
return QColor(0x7f, 0x00, 0x7f);
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerApdl::defaultEolFill(int style) const
{
//if (style == VerbatimString)
// return true;
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerApdl::defaultFont(int style) const
{
switch (style)
{
case PROCESSOR:
case COMMAND:
case SLASHCOMMAND:
case STARCOMMAND:
{
QFont f(QsciLexer::s_defaultLangFont);
f.setBold(true);
return f;
}
break;
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerApdl::keywords(int set)
{
if (set == 1)
return "cfopen cfclose dim do dowhile else endif enddo finish get if then vwread vwrite";
return 0;
}
// Returns the user name of a style.
QString QsciLexerApdl::description(int style) const
{
switch (style)
{
case DEFAULT:
return tr("Default");
case COMMENT:
return tr("Comment");
case COMMENTBLOCK:
return tr("Comment Block");
case NUMBER:
return tr("Number");
case STRING:
return tr("String");
case OPERATOR:
return tr("Operator");
case WORD:
return tr("Word");
case PROCESSOR:
return tr("Processor");
case COMMAND:
return tr("Command");
case SLASHCOMMAND:
return tr("Slash Command");
case STARCOMMAND:
return tr("Star Command");
case ARGUMENT:
return tr("Argument");
case FUNCTION:
return tr("Function");
default:
break;
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerApdl::defaultPaper(int style) const
{
//if (style == VerbatimString)
// return QColor(0xe0, 0xff, 0xe0);
return QsciLexer::defaultPaper(style);
}
// Return the lexer identifier.
//int QsciLexerApdl::lexerId() const
//{
// return L_TXT;
//}

View File

@ -76,9 +76,11 @@ QColor QsciLexerBash::defaultColor(int style) const
return QColor(0x80,0x80,0x80);
case Error:
case Backticks:
return QColor(0xff,0xff,0x00);
case Backticks:
return QColor(0x00, 0x00, 0xff);
case Comment:
return QColor(0x00,0x7f,0x00);
@ -261,9 +263,6 @@ QColor QsciLexerBash::defaultPaper(int style) const
case ParameterExpansion:
return QColor(0xff,0xff,0xe0);
case Backticks:
return QColor(0xa0,0x80,0x80);
case HereDocumentDelimiter:
case SingleQuotedHereDocument:
return QColor(0xdd,0xd0,0xdd);

View File

@ -135,10 +135,10 @@ QColor QsciLexerCPP::defaultColor(int style) const
return QColor(0x3f, 0x70, 0x3f);
case Number:
return QColor(0x00, 0x7f, 0x7f);
return QColor(0xff, 0x80, 0x00);
case Keyword:
return QColor(0x80, 0x00, 0xff);
return QColor(0x00,0x00,0xff);
case DoubleQuotedString:
case SingleQuotedString:
@ -150,7 +150,7 @@ QColor QsciLexerCPP::defaultColor(int style) const
case Operator:
case UnclosedString:
return QColor(0x00, 0x00, 0x00);
return QColor(0x00, 0x00, 0x80);
case VerbatimString:
case TripleQuotedVerbatimString:
@ -274,21 +274,24 @@ QFont QsciLexerCPP::defaultFont(int style) const
case InactiveCommentDocKeywordError:
case TaskMarker:
case InactiveTaskMarker:
{
#if defined(Q_OS_WIN)
f = QFont("Courier New",QsciLexer::s_defaultFontSize);
f = QFont("Courier New", QsciLexer::s_defaultFontSize);
#elif defined(Q_OS_MAC)
f = QFont("Comic Sans MS", 12);
#else
f = QFont("Bitstream Vera Serif",9);
f = QsciLexer::s_defaultLangFont;
#endif
}
break;
case Keyword:
case InactiveKeyword:
case Operator:
case InactiveOperator:
f = QsciLexer::defaultFont(style);
f.setBold(false);
f.setBold(true);
break;
case DoubleQuotedString:
@ -306,11 +309,11 @@ QFont QsciLexerCPP::defaultFont(int style) const
case HashQuotedString:
case InactiveHashQuotedString:
#if defined(Q_OS_WIN)
f = QFont("Courier New",QsciLexer::s_defaultFontSize);
f = QFont("Courier New", QsciLexer::s_defaultFontSize);
#elif defined(Q_OS_MAC)
f = QFont("Courier", 12);
#else
f = QFont("Bitstream Vera Sans Mono",9);
f = QsciLexer::s_defaultLangFont;
#endif
break;
@ -344,9 +347,9 @@ const char *QsciLexerCPP::keywords(int set)
"catch char class compl const const_cast continue "
"default delete do double dynamic_cast else enum "
"explicit export extern false float for friend goto if "
"inline int long mutable namespace new not not_eq "
"operator or or_eq private protected public register "
"reinterpret_cast return short signed sizeof static "
"inline int long mutable namespace new not not_eq nullptr null "
"out operator or or_eq private protected public println register "
"reinterpret_cast return short signed sizeof static system "
"static_cast struct switch template this throw true "
"try typedef typeid typename union unsigned using "
"virtual void volatile wchar_t while xor xor_eq";

View File

@ -100,7 +100,7 @@ QColor QsciLexerFortran77::defaultColor(int style) const
return QColor(0x7f,0x7f,0x00);
case Label:
return QColor(0xe0,0xc0,0xe0);
return QColor(0x00,0x00,0x00);
}
return QsciLexer::defaultColor(style);
@ -136,6 +136,7 @@ QFont QsciLexerFortran77::defaultFont(int style) const
case Operator:
case DottedOperator:
case Keyword:
f = QsciLexer::defaultFont(style);
f.setBold(true);
break;
@ -241,6 +242,9 @@ QColor QsciLexerFortran77::defaultPaper(int style) const
if (style == Continuation)
return QColor(0xf0,0xe0,0x80);
if (style == Label)
return QColor(0xe0,0xc0,0xe0);
return QsciLexer::defaultPaper(style);
}

157
src/qscint/src/qscilexergcode.cpp Executable file
View File

@ -0,0 +1,157 @@
#include "Qsci/qscilexergcode.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
QsciLexerGCode::QsciLexerGCode(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_GCode);
m_commentSymbol = ";";
}
QsciLexerGCode::~QsciLexerGCode()
{
}
// Returns the language name.
const char* QsciLexerGCode::language() const
{
return "GCode";
}
// Returns the lexer name.
const char *QsciLexerGCode::lexer() const
{
return "gcode";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerGCode::defaultColor(int style) const
{
switch (style)
{
case KEYWORD:
return QColor(0, 0, 255);
case KEYWORD1:
return QColor(0, 0, 128);
case POSITIONX:
return QColor(128, 0, 0);
case POSITIONY:
return QColor(0, 128, 0);
case POSITIONZ:
return QColor(0, 0, 128);
case OFFSET:
return QColor(255, 128, 0);
case VELOCITY:
return QColor(255, 0, 0);
case COMMNET:
return QColor(0, 128, 0);
case TIMES:
return QColor(127, 127, 0);
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerGCode::defaultEolFill(int style) const
{
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerGCode::defaultFont(int style) const
{
switch (style)
{
case KEYWORD:
case KEYWORD1:
case VELOCITY:
#if defined(Q_OS_MAC)
{
QFont f("Courier New", 18);
f.setBold(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
f.setBold(true);
return f;
}
#endif
break;
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerGCode::keywords(int set)
{
if (set == 1)
return "G00 G01 G1 G02 G2 G03 G04 G05 G06 G07 G08 G09 G10 G16 G17 G18 G19 G20 "
"G21 G22 G22 G23 G23 G24 G25 G26 G28 G30 G31 G32 G33 G34 G35 G40 G41 G42 G43 G44 "
"G45 G46 G47 G48 G49 G50 G51 G52 G53 G54 G55 G56 G57 G58 G59 G60 G61 G62 G63 "
"G68 G69 G70 G71 G74 G75 G76 G80 G81 G33 G90 G91 G92 G93 G94 G95 G96 G97";
if (set == 2)
return "M00 M104 M02 M109 M03 M140 M04 M190 M05 M106 M06 M08 M09 M30";
return 0;
}
// Returns the user name of a style.
QString QsciLexerGCode::description(int style) const
{
switch (style)
{
case DEFAULT:
return tr("Default");
case KEYWORD:
return tr("keyword");
case KEYWORD1:
return tr("Keyword1");
case COMMNET:
return tr("Comment");
case POSITIONX:
return tr("Position-X");
case POSITIONY:
return tr("Position-Y");
case POSITIONZ:
return tr("Position-Z");
case OFFSET:
return tr("Offset");
case VELOCITY:
return tr("Velocity");
case TIMES:
return tr("Times");
default:
break;
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerGCode::defaultPaper(int style) const
{
//if (style == VerbatimString)
// return QColor(0xe0, 0xff, 0xe0);
return QsciLexer::defaultPaper(style);
}
// Return the lexer identifier.
//int QsciLexerGCode::lexerId() const
//{
// return L_TXT;
//}

View File

@ -363,7 +363,7 @@ QColor QsciLexerGlobal::defaultPaper(int style) const
return QColor(0xE0E0E0);
case FOLD:
return QColor(0xF3F3F3);
return QColor(0xFFFF7F);
case FOLD_ACTIVE:
return QColor(0x2E3436);
@ -456,7 +456,7 @@ int QsciLexerGlobal::changeOperBit(int style) const
return BG_BIT;
case SELECT_TEXT_COLOR:
return FG_BIT | BG_BIT;
return /*FG_BIT |*/ BG_BIT;
case CARET_COLOUR:
return FG_BIT;

View File

@ -583,13 +583,13 @@ QString QsciLexerHTML::description(int style) const
return tr("Unknown attribute");
case HTMLNumber:
return tr("HTML number");
return tr("Number");
case HTMLDoubleQuotedString:
return tr("HTML double-quoted string");
return tr("double-quoted string");
case HTMLSingleQuotedString:
return tr("HTML single-quoted string");
return tr("single-quoted string");
case OtherInTag:
return tr("Other text in a tag");

View File

@ -0,0 +1,213 @@
#include "Qsci/qscilexerintelhex.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
QsciLexerIntelHex::QsciLexerIntelHex(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_IHEX);
m_commentSymbol = ";";
}
QsciLexerIntelHex::~QsciLexerIntelHex()
{
}
// Returns the language name.
const char* QsciLexerIntelHex::language() const
{
return "IHEX";
}
// Returns the lexer name.
const char *QsciLexerIntelHex::lexer() const
{
return "ihex";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerIntelHex::defaultColor(int style) const
{
switch (style)
{
case DEFAULT:
return QColor();
case RECSTART:
case RECTYPE:
case RECTYPE_UNKNOWN:
return QColor(127, 0, 0);
case BYTECOUNT:
return QColor(127,127,0);
case BYTECOUNT_WRONG:
return QColor(255,255,0);
case NOADDRESS:
return QColor(127,0,255);
case DATAADDRESS:
case STARTADDRESS:
case EXTENDEDADDRESS:
return QColor(0, 127, 255);
case CHECKSUM:
return QColor(0,191,0);
case CHECKSUM_WRONG:
return QColor(255,255,0);
case GARBAGE:
return QColor();
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerIntelHex::defaultEolFill(int style) const
{
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerIntelHex::defaultFont(int style) const
{
switch (style)
{
case DATA_ODD:
#if defined(Q_OS_MAC)
{
QFont f("Courier New", 18);
f.setBold(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
f.setBold(true);
return f;
}
#endif
break;
case GARBAGE:
case DATA_UNKNOWN:
case ADDRESSFIELD_UNKNOWN:
case RECTYPE_UNKNOWN:
#if defined(Q_OS_MAC)
{
QFont f("Courier New", 18);
f.setItalic(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
f.setItalic(true);
return f;
}
#endif
break;
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerIntelHex::keywords(int set)
{
return 0;
}
// Returns the user name of a style.
QString QsciLexerIntelHex::description(int style) const
{
switch (style)
{
case DEFAULT:
return("Default");
case RECSTART:
return ("Recstart");
case RECTYPE:
return ("Rectype");
case RECTYPE_UNKNOWN:
return ("Rectype Unknown");
case BYTECOUNT:
return ("Byte Count");
case BYTECOUNT_WRONG:
return ("Bytecount Wrong");
case NOADDRESS:
return ("Noaddress");
case DATAADDRESS:
return ("Data Address");
case RECCOUNT:
return ("Reccount");
case STARTADDRESS:
return ("Start address");
case ADDRESSFIELD_UNKNOWN:
return ("Addressfield Unknown");
case EXTENDEDADDRESS:
return ("Extended Address");
case DATA_ODD:
return ("Data Odd");
case DATA_EVEN:
return ("Data Even");
case DATA_UNKNOWN:
return ("Data Unknown");
case DATA_EMPTY:
return ("Data Empty");
case CHECKSUM:
return ("Checksum");
case CHECKSUM_WRONG:
return ("Checksum Wrong");
case GARBAGE:
return ("Garbage");
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerIntelHex::defaultPaper(int style) const
{
switch(style)
{
case BYTECOUNT_WRONG:
case CHECKSUM_WRONG:
return QColor(255, 0, 0);
default:
break;
}
return QsciLexer::defaultPaper(style);
}

View File

@ -60,7 +60,7 @@ QColor QsciLexerJSON::defaultColor(int style) const
{
case UnclosedString:
case Error:
return QColor(0xff, 0xff, 0xff);
return QColor(0x0, 0x0, 0x0);
case Number:
return QColor(0x00, 0x7f, 0x7f);

164
src/qscint/src/qscilexerlisp.cpp Executable file
View File

@ -0,0 +1,164 @@
#include "Qsci/qscilexerlisp.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
QsciLexerLisp::QsciLexerLisp(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_LISP);
m_commentSymbol = ";";
}
QsciLexerLisp::~QsciLexerLisp()
{
}
// Returns the language name.
const char* QsciLexerLisp::language() const
{
return "LISP";
}
// Returns the lexer name.
const char *QsciLexerLisp::lexer() const
{
return "lisp";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerLisp::defaultColor(int style) const
{
switch (style)
{
case COMMENT:
return QColor(0, 128, 0);
case NUMBER:
return QColor(255, 128, 0);
case KEYWORD:
case KEYWORD_KW:
return QColor(0, 0, 255);
case SYMBOL:
return QColor(0, 0, 128);
case STRING:
case MULTI_COMMENT:
return QColor(128, 128, 128);
case OPERATOR:
return QColor(0, 128, 192);
case SPECIAL:
return QColor(128, 0, 0);
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerLisp::defaultEolFill(int style) const
{
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerLisp::defaultFont(int style) const
{
switch (style)
{
case KEYWORD:
case SYMBOL:
#if defined(Q_OS_MAC)
{
QFont f("Courier New", 18);
f.setBold(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
f.setBold(true);
return f;
}
#endif
break;
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerLisp::keywords(int set)
{
if (set == 1)
return "not defun + - * / = < > <= >= princ eval apply funcall quote identity function complement backquote lambda set "
"setq setf defmacro gensym make symbol intern name value plist get getf putprop remprop hash array aref "
"car cdr caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar "
"cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr cons list append reverse last nth nthcdr "
"member assoc subst sublis nsubst nsublis remove length mapc mapcar mapl maplist mapcan mapcon rplaca rplacd nconc delete "
"atom symbolp numberp boundp null listp consp minusp zerop plusp evenp oddp eq eql equal cond case and or let l if "
"prog prog1 prog2 progn go return do dolist dotimes catch throw error cerror break continue errset baktrace evalhook "
"truncate float rem min max abs sin cos tan expt exp sqrt random logand logior logxor lognot bignums logeqv lognand lognor "
"logorc2 logtest logbitp logcount integer nil";
return 0;
}
// Returns the user name of a style.
QString QsciLexerLisp::description(int style) const
{
switch (style)
{
case DEFAULT:
return("Default");
case COMMENT:
return ("Comment");
case NUMBER:
return ("Number");
case KEYWORD:
return ("Keyword");
case KEYWORD_KW:
return ("Keyword_kw");
case SYMBOL:
return ("Symbol");
case STRING:
return ("String");
case STRINGEOL:
return ("String Eol");
case IDENTIFIER:
return ("Identifier");
case OPERATOR:
return ("Operator");
case SPECIAL:
return ("Special");
case MULTI_COMMENT:
return ("Multi Comment");
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerLisp::defaultPaper(int style) const
{
return QsciLexer::defaultPaper(style);
}

145
src/qscint/src/qscilexerlog.cpp Executable file
View File

@ -0,0 +1,145 @@
#include "Qsci/qscilexerlog.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
//#if defined(Q_OS_WIN)
// QFont QsciLexerLog::s_defaultTxtFont("Courier New", QsciLexer::s_defaultFontSize);
//#elif defined(Q_OS_MAC)
// QFont QsciLexerLog::s_defaultTxtFont("STSong",14);
//#else
// QFont QsciLexerLog::s_defaultTxtFont("Courier 10 Pitch", 12);
//#endif
QsciLexerLog::QsciLexerLog(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_LOG);
m_commentSymbol = "#";
}
QsciLexerLog::~QsciLexerLog()
{
}
// Returns the language name.
const char* QsciLexerLog::language() const
{
return "LOG";
}
// Returns the lexer name.
const char *QsciLexerLog::lexer() const
{
return "log";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerLog::defaultColor(int style) const
{
switch (style)
{
case Num:
return QColor(0, 0, 255);
case Keyword:
return QColor(163, 21, 21);
case Date:
return QColor(0, 128, 0);
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerLog::defaultEolFill(int style) const
{
//if (style == VerbatimString)
// return true;
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerLog::defaultFont(int style) const
{
switch (style)
{
case Default:
return QsciLexer::s_defaultLangFont;
case Num:
case Date:
return QsciLexer::s_defaultLangFont;
case Keyword:
#if defined(Q_OS_WIN)
return QsciLexer::s_defaultLangFont;
#elif defined(Q_OS_MAC)
{
QFont f(QsciLexer::s_defaultLangFont);
f.setBold(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
f.setBold(true);
return f;
}
#endif
break;
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerLog::keywords(int set)
{
if (set == 1)
return "info error debug warn ";
return 0;
}
// Returns the user name of a style.
QString QsciLexerLog::description(int style) const
{
switch (style)
{
case Default:
return tr("Default");
case Num:
return tr("Num");
case Date:
return tr("Date");
case Keyword:
return tr("Keyword");
default:
break;
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerLog::defaultPaper(int style) const
{
//if (style == VerbatimString)
// return QColor(0xe0, 0xff, 0xe0);
return QsciLexer::defaultPaper(style);
}
// Return the lexer identifier.
//int QsciLexerLog::lexerId() const
//{
// return L_TXT;
//}

View File

@ -0,0 +1,209 @@
#include "Qsci/qscilexerpowershell.h"
#include "Qsci/qsciscintillabase.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
QsciLexerPowerShell::QsciLexerPowerShell(QObject *parent)
: QsciLexer(parent)
{
setLexerId(L_POWERSHELL);
m_commentSymbol = ";";
}
QsciLexerPowerShell::~QsciLexerPowerShell()
{
}
// Returns the language name.
const char* QsciLexerPowerShell::language() const
{
return "POWERSHELL";
}
// Returns the lexer name.
const char *QsciLexerPowerShell::lexer() const
{
return "powershell";
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerPowerShell::defaultColor(int style) const
{
switch (style)
{
case COMMENT:
return QColor(0, 128, 0);
case CHARACTER:
case STRING:
return QColor(128, 128, 128);
case NUMBER:
return QColor(255, 128, 0);
case OPERATOR:
return QColor(0, 0, 128);
case KEYWORD:
return QColor(0, 0, 255);
case CMDLET:
return QColor(128, 0, 255);
case ALIAS:
return QColor(0, 128, 255);
case COMMENTSTREAM:
return QColor(0, 128, 128);
case HERE_STRING:
case HERE_CHARACTER:
case COMMENTDOCKEYWORD:
return QColor(0, 128, 128);
default:
break;
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerPowerShell::defaultEolFill(int style) const
{
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerPowerShell::defaultFont(int style) const
{
switch (style)
{
case VARIABLE:
case OPERATOR:
case KEYWORD:
case COMMENTDOCKEYWORD:
#if defined(Q_OS_MAC)
{
QFont f("Courier New", 18);
f.setBold(true);
return f;
}
#else
{
QFont f(s_defaultLangFont);
//f.setBold(true);
return f;
}
#endif
default:
break;
}
return QsciLexer::s_defaultLangFont;
}
// Returns the set of keywords.
const char* QsciLexerPowerShell::keywords(int set)
{
if (set == 1)
return "break continue do else elseif filter for foreach function if in return switch until where while";
if (set == 2)
return "add-content add-history add-member add-pssnapin clear-content clear-item clear-itemproperty clear-variable "
"compare-object convertfrom-securestring convert-path convertto-html convertto-securestring copy-item copy-itemproperty "
"export-alias export-clixml export-console export-csv foreach-object format-custom format-list format-table format-wide "
"get-acl get-alias get-authenticodesignature get-childitem get-command get-content get-credential get-culture get-date "
"get-eventlog get-executionpolicy get-help get-history get-host get-item get-itemproperty get-location get-member "
"get-pfxcertificate get-process get-psdrive get-psprovider get-pssnapin get-service get-tracesource get-uiculture "
"get-unique get-variable get-wmiobject group-object import-alias import-clixml import-csv invoke-expression invoke-history "
"invoke-item join-path measure-command measure-object move-item move-itemproperty new-alias new-item new-itemproperty "
"new-object new-psdrive new-service new-timespan new-variable out-default out-file out-host out-null out-printer out-string "
"pop-location push-location read-host remove-item remove-itemproperty remove-psdrive remove-pssnapin remove-variable "
"rename-item rename-itemproperty resolve-path restart-service resume-service select-object select-string set-acl set-alias "
"set-authenticodesignature set-content set-date set-executionpolicy set-item set-itemproperty set-location set-psdebug "
"set-service set-tracesource set-variable sort-object split-path start-service start-sleep start-transcript stop-process "
"stop-service stop-transcript suspend-service tee-object test-path trace-command update-formatdata update-typedata "
"where-object write-debug write-error write-host write-output write-progress write-verbose write-warning";
if (set == 3)
return "ac asnp clc cli clp clv cpi cpp cvpa diff epal epcsv fc fl foreach ft fw gal gc gci gcm gdr ghy gi gl gm gp gps group gsv "
"gsnp gu gv gwmi iex ihy ii ipal ipcsv mi mp nal ndr ni nv oh rdr ri rni rnp rp rsnp rv rvpa sal sasv sc select si sl sleep "
"sort sp spps spsv sv tee where write cat cd clear cp h history kill lp ls mount mv popd ps pushd pwd r rm rmdir echo cls chdir "
"copy del dir erase move rd ren set type";
if (set == 6)
return "component description example externalhelp forwardhelpcategory forwardhelptargetname functionality inputs link notes outputs parameter remotehelprunspace role synopsis";
return 0;
}
// Returns the user name of a style.
QString QsciLexerPowerShell::description(int style) const
{
switch (style)
{
case DEFAULT:
return "Default";
case COMMENT:
return "Comment";
case STRING:
return "String";
case CHARACTER:
return "Character";
case NUMBER:
return "Number";
case VARIABLE:
return "Variable";
case OPERATOR:
return "Operator";
case KEYWORD:
return "Keyword";
case CMDLET:
return "Cmdlet";
case ALIAS:
return "Alias";
case FUNCTION:
return "Function";
case USER1:
return "User1";
case COMMENTSTREAM:
return "Comment stream";
case HERE_STRING:
return "Here String";
case HERE_CHARACTER:
return "Here Character";
case COMMENTDOCKEYWORD:
return "Comment Doc Keyword";
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerPowerShell::defaultPaper(int style) const
{
return QsciLexer::defaultPaper(style);
}

View File

@ -6,7 +6,7 @@
#include <qsettings.h>
#if defined(Q_OS_WIN)
QFont QsciLexerText::s_defaultTxtFont(u8"宋体", QsciLexer::s_defaultFontSize);
QFont QsciLexerText::s_defaultTxtFont("Courier New", QsciLexer::s_defaultFontSize);
#elif defined(Q_OS_MAC)
QFont QsciLexerText::s_defaultTxtFont("STSong",14);
#else

View File

@ -101,46 +101,20 @@ bool QsciLexerYAML::defaultEolFill(int style) const
// Returns the font of the text for a style.
QFont QsciLexerYAML::defaultFont(int style) const
{
QFont f;
QFont f(QsciLexer::s_defaultLangFont);
switch (style)
{
case Default:
case TextBlockMarker:
#if defined(Q_OS_WIN)
f = QFont("Courier New", 14);
#elif defined(Q_OS_MAC)
f = QFont("Times New Roman", 12);
#else
f = QFont("Bitstream Charter", 10);
#endif
break;
case Identifier:
f = QsciLexer::defaultFont(style);
f.setBold(true);
break;
case DocumentDelimiter:
#if defined(Q_OS_WIN)
f = QFont("Comic Sans MS",9);
#elif defined(Q_OS_MAC)
f = QFont("Comic Sans MS", 12);
#else
f = QFont("Bitstream Vera Serif",9);
#endif
case Identifier:
f.setBold(true);
break;
case SyntaxErrorMarker:
#if defined(Q_OS_WIN)
f = QFont("Times New Roman", 11);
#elif defined(Q_OS_MAC)
f = QFont("Times New Roman", 12);
#else
f = QFont("Bitstream Charter", 10);
#endif
f.setBold(true);
f.setItalic(true);
break;

View File

@ -229,8 +229,18 @@ void QsciMacro::play()
QList<Macro>::const_iterator it;
for (it = macro.begin(); it != macro.end(); ++it)
qsci->SendScintilla((*it).msg, static_cast<uintptr_t>((*it).wParam),
{
if (it->msg >= 5000)
{
qsci->playUserMacroRecord((*it).msg, static_cast<uintptr_t>((*it).wParam),
(void*) (*it).text.constData());
}
else
{
qsci->SendScintilla((*it).msg, static_cast<uintptr_t>((*it).wParam),
(*it).text.constData());
}
}
}
@ -292,8 +302,16 @@ void QsciMacro::record(unsigned int msg, unsigned long wParam, void *lParam)
case QsciScintillaBase::SCI_APPENDTEXT:
case QsciScintillaBase::SCI_SEARCHNEXT:
case QsciScintillaBase::SCI_SEARCHPREV:
case MACRO_FIND_NEXT://查找下一个。需要flag 和 查找内容
case MACRO_REPLACE_ALL:
case MACRO_REPLACE_ONE:
m.text.append(reinterpret_cast<const char *>(lParam));
break;
case MACRO_EXE_MENU_FUN:
m.text.append(QByteArray::number((int)wParam));
break;
}
macro.append(m);

View File

@ -22,6 +22,7 @@
TEMPLATE = lib
CONFIG += qt warn_off thread exceptions hide_symbols release staticlib
DEFINES+= QT_NO_DEBUG_OUTPUT
CONFIG(debug, debug|release) {
mac: {
@ -103,6 +104,7 @@ HEADERS = \
./Qsci/qscicommandset.h \
./Qsci/qscidocument.h \
./Qsci/qscilexer.h \
./Qsci/qscilexerapdl.h \
./Qsci/qscilexerasm.h \
./Qsci/qscilexerbash.h \
./Qsci/qscilexerbatch.h \
@ -118,15 +120,19 @@ HEADERS = \
./Qsci/qscilexerfortran.h \
./Qsci/qscilexerfortran77.h \
./Qsci/qscilexergo.h \
./Qsci/qscilexergcode.h \
./Qsci/qscilexerglobal.h \
./Qsci/qscilexertext.h \
./Qsci/qscilexerrust.h \
./Qsci/qscilexerhtml.h \
./Qsci/qscilexeridl.h \
./Qsci/qscilexerintelhex.h \
./Qsci/qscilexerjava.h \
./Qsci/qscilexerjavascript.h \
./Qsci/qscilexerjson.h \
./Qsci/qscilexerlua.h \
./Qsci/qscilexerlog.h \
./Qsci/qscilexerlisp.h \
./Qsci/qscilexermakefile.h \
./Qsci/qscilexermarkdown.h \
./Qsci/qscilexermatlab.h \
@ -134,6 +140,7 @@ HEADERS = \
./Qsci/qscilexerpascal.h \
./Qsci/qscilexerperl.h \
./Qsci/qscilexerpostscript.h \
./Qsci/qscilexerpowershell.h \
./Qsci/qscilexerpo.h \
./Qsci/qscilexerpov.h \
./Qsci/qscilexerproperties.h \
@ -224,7 +231,6 @@ HEADERS = \
!ios:HEADERS += ./Qsci/qsciprinter.h
SOURCES = \
qscilexertext.cpp \
qscilexerrust.cpp \
qscilexernsis.cpp \
qsciscintilla.cpp \
@ -235,6 +241,7 @@ SOURCES = \
qscicommandset.cpp \
qscidocument.cpp \
qscilexer.cpp \
qscilexerapdl.cpp \
qscilexerasm.cpp \
qscilexerbash.cpp \
qscilexerbatch.cpp \
@ -251,13 +258,17 @@ SOURCES = \
qscilexerfortran77.cpp \
qscilexergo.cpp \
qscilexerglobal.cpp \
qscilexergcode.cpp \
qscilexertext.cpp \
qscilexerhtml.cpp \
qscilexeridl.cpp \
qscilexerintelhex.cpp \
qscilexerjava.cpp \
qscilexerjavascript.cpp \
qscilexerjson.cpp \
qscilexerlua.cpp \
qscilexerlog.cpp \
qscilexerlisp.cpp \
qscilexermakefile.cpp \
qscilexermarkdown.cpp \
qscilexermatlab.cpp \
@ -265,6 +276,7 @@ SOURCES = \
qscilexerpascal.cpp \
qscilexerperl.cpp \
qscilexerpostscript.cpp \
qscilexerpowershell.cpp \
qscilexerpo.cpp \
qscilexerpov.cpp \
qscilexerproperties.cpp \
@ -331,6 +343,7 @@ SOURCES = \
../scintilla/lexers/LexForth.cpp \
../scintilla/lexers/LexFortran.cpp \
../scintilla/lexers/LexGAP.cpp \
../scintilla/lexers/LexGCode.cpp \
../scintilla/lexers/LexGui4Cli.cpp \
../scintilla/lexers/LexHTML.cpp \
../scintilla/lexers/LexHaskell.cpp \
@ -344,6 +357,7 @@ SOURCES = \
../scintilla/lexers/LexLisp.cpp \
../scintilla/lexers/LexLout.cpp \
../scintilla/lexers/LexLua.cpp \
../scintilla/lexers/LexLog.cpp \
../scintilla/lexers/LexMMIXAL.cpp \
../scintilla/lexers/LexMPT.cpp \
../scintilla/lexers/LexMSSQL.cpp \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -261,6 +261,14 @@ void QsciScintilla::handleCharAdded(int ch)
return;
}
else if (isListActive() && ch > 0x80)
{
cancelList();
//不是ascii字符是中文UTF8的情况。
//识别中文Utf8字符。
startAutoWordCompletion(acSource, false, use_single == AcusAlways);
return;
}
// Handle call tips.
if (call_tips_style != CallTipsNone && !lex.isNull() && strchr("(),", ch) != NULL)
@ -282,8 +290,14 @@ void QsciScintilla::handleCharAdded(int ch)
startAutoCompletion(acSource, false, use_single == AcusAlways);
else if (acThresh >= 1 && isWordCharacter(ch))
startAutoCompletion(acSource, true, use_single == AcusAlways);
else if(ch > 0x80)
{
//不是ascii字符是中文UTF8的情况。
//识别中文Utf8字符。
startAutoWordCompletion(acSource, false, use_single == AcusAlways);
}
}
}
// See if a call tip is active.
@ -786,6 +800,15 @@ void QsciScintilla::startAutoCompletion(AutoCompletionSource acs,
}
//放在子类中去完成。
bool QsciScintilla::startAutoWordCompletion(AutoCompletionSource acs,
bool checkThresh, bool choose_single)
{
return false;
}
// Maintain the indentation of the previous line.
void QsciScintilla::maintainIndentation(char ch, long pos)
{
@ -2382,6 +2405,21 @@ QString QsciScintilla::selectedText() const
return qs;
}
//20230929 在base64编码时如果文本中有二进制字符比如一些控制字符。
//如果使用selectedText则获取的文件字节转换为QString会乱码。此时不对直接获取原始字节码。
bool QsciScintilla::selectedRawBytes(QByteArray& bytes) const
{
if (!selText)
return false;
//char *buf = new char[SendScintilla(SCI_GETSELECTIONEND) - SendScintilla(SCI_GETSELECTIONSTART) + 1];
int size = SendScintilla(SCI_GETSELTEXT, 0);
bytes.resize(size);
SendScintilla(SCI_GETSELTEXT, bytes.data());
return true;
}
// Return the current text.
QString QsciScintilla::text() const
@ -3671,8 +3709,11 @@ void QsciScintilla::setStylesFont(const QFont &f, int style)
long(f.pointSizeF() * SC_FONT_SIZE_MULTIPLIER));
// Pass the Qt weight via the back door.
SendScintilla(SCI_STYLESETWEIGHT, style, -f.weight());
//SendScintilla(SCI_STYLESETWEIGHT, style, -f.weight());
//20230712 发现粗体总是存在混淆修改一个风格会导致其余风格也被设置。于是注释掉上面的SCI_STYLESETWEIGHT
//使用下面的SCI_STYLESETBOLD取代后发现问题解除。
SendScintilla(SCI_STYLESETBOLD, style, f.bold());
SendScintilla(SCI_STYLESETITALIC, style, f.italic());
SendScintilla(SCI_STYLESETUNDERLINE, style, f.underline());
@ -4360,6 +4401,11 @@ bool QsciScintilla::getHtmlHighLightTag()
return isHtmlHighLightTag;
}
intptr_t QsciScintilla::searchInTarget(QByteArray& text2Find, size_t fromPos, size_t toPos) const
{
SendScintilla(SCI_SETTARGETRANGE, fromPos, toPos);
return SendScintilla(SCI_SEARCHINTARGET, text2Find.size(), text2Find.data());
}
// Return the word at the given coordinates.
QString QsciScintilla::wordAtLineIndex(int line, int index) const
@ -4701,7 +4747,7 @@ QMenu *QsciScintilla::createStandardContextMenu()
action = menu->addAction(tr("&Copy"), this, SLOT(copy()));
action->setObjectName("copy");
set_shortcut(action, QsciCommand::SelectionCopy);
//set_shortcut(action, QsciCommand::SelectionCopy);
action->setEnabled(has_selection);
if (!read_only)

View File

@ -11,7 +11,7 @@
static const char* VersionStr = u8"(内部测试非稳定) v2.0.0";
#else
static const char* VersionStr = "v1.23.2";
static const char* VersionStr = "v2.0.0";
#endif // TEST_PRE
// Bug: 在 Visual Studio 中引发无法构建的问题,此处被重复定义(在 cmake 中已对其定义)

Binary file not shown.