diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro
index f1fecf1b..0a6ee8ee 100644
--- a/RedPandaIDE/RedPandaIDE.pro
+++ b/RedPandaIDE/RedPandaIDE.pro
@@ -17,6 +17,8 @@ APP_NAME = RedPandaCPP
APP_VERSION = 2.27
+APP_VERSION_SUFFIX = alpha
+
# TEST_VERSION = beta2
system(git rev-list HEAD --count): TEST_VERSION = $$system(git rev-list HEAD --count)
@@ -57,9 +59,9 @@ DEFINES += PREFIX=\\\"$${PREFIX}\\\"
DEFINES += LIBEXECDIR=\\\"$${LIBEXECDIR}\\\"
DEFINES += APP_NAME=\\\"$${APP_NAME}\\\"
isEmpty(TEST_VERSION) {
- DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}\\\"
+ DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}$${APP_VERSION_SUFFIX}\\\"
} else {
- DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}.$${TEST_VERSION}\\\"
+ DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}$${APP_VERSION_SUFFIX}.$${TEST_VERSION}\\\"
}
win32 {
_WINDOWS_PREFER_OPENCONSOLE = $$(WINDOWS_PREFER_OPENCONSOLE)
diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
index c1f9e754..d33fb003 100644
--- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
@@ -5159,10 +5159,6 @@
-
-
-
-
@@ -5420,7 +5416,11 @@
-
+
+
+
+
+
diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
index 28d86d1d..40673f19 100644
--- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
@@ -1607,24 +1607,24 @@ p, li { white-space: pre-wrap; }
要剪切的内容超过了字符数限制!
-
+
16进制: %1
-
+
十进制: %1
-
+
打印文档
-
-
-
+
+
+
Ctrl+单击以获取更多信息
@@ -1633,27 +1633,27 @@ p, li { white-space: pre-wrap; }
未找到符号'%1'!
-
+
找不到astyle程序
-
+
找不到astyle程序"%1".
-
+
断点条件
-
+
输入当前断点的生效条件:
-
+
只读
@@ -2506,12 +2506,12 @@ p, li { white-space: pre-wrap; }
表单
-
+
主题:
-
+
使用自定义主题
@@ -2521,12 +2521,12 @@ p, li { white-space: pre-wrap; }
图标集:
-
+
使用自定义图标
-
+
图标缩放:
@@ -2536,17 +2536,17 @@ p, li { white-space: pre-wrap; }
字体:
-
+
语言:
-
+
*需要重启之后生效
-
+
大小:
@@ -4472,18 +4472,18 @@ p, li { white-space: pre-wrap; }
MainWindow
-
+
小熊猫C++
-
-
-
+
+
+
编译器
@@ -4557,7 +4557,7 @@ p, li { white-space: pre-wrap; }
-
+
调试主控台
@@ -4633,7 +4633,7 @@ p, li { white-space: pre-wrap; }
工具栏2
-
+
新建
@@ -4766,9 +4766,9 @@ p, li { white-space: pre-wrap; }
-
-
-
+
+
+
复制
@@ -4779,7 +4779,7 @@ p, li { white-space: pre-wrap; }
-
+
粘贴
@@ -4790,8 +4790,8 @@ p, li { white-space: pre-wrap; }
-
-
+
+
选择全部
@@ -4915,38 +4915,38 @@ p, li { white-space: pre-wrap; }
-
-
+
+
新建试题集
-
+
添加试题
-
+
删除试题
-
-
+
+
保存试题集
-
-
+
+
载入试题集
@@ -4994,7 +4994,7 @@ p, li { white-space: pre-wrap; }
-
+
Remove Problem Set
删除试题案例
@@ -5002,21 +5002,21 @@ p, li { white-space: pre-wrap; }
-
+
打开答案源代码文件
-
+
Run Current Case
运行所有案例
-
+
测试案例验证选项
@@ -5076,15 +5076,15 @@ p, li { white-space: pre-wrap; }
-
-
+
+
导入FPS试题集
-
-
+
+
导出FPS试题集
@@ -5335,7 +5335,7 @@ p, li { white-space: pre-wrap; }
-
+
删除所有断点
@@ -5699,7 +5699,7 @@ p, li { white-space: pre-wrap; }
保存为模板...
-
+
新建文件
@@ -5740,7 +5740,7 @@ p, li { white-space: pre-wrap; }
-
+
重命名符号
@@ -5761,13 +5761,13 @@ p, li { white-space: pre-wrap; }
-
+
导出为RTF
-
+
导出为HTML
@@ -6036,42 +6036,42 @@ p, li { white-space: pre-wrap; }
运行参数...
-
+
文件编码
-
+
文件历史
-
-
-
-
-
-
+
+
+
+
+
+
正在调试
-
-
-
-
-
-
+
+
+
+
+
+
正在运行
-
-
-
-
-
-
+
+
+
+
+
+
正在编译
@@ -6085,17 +6085,17 @@ p, li { white-space: pre-wrap; }
行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5
-
+
只读
-
+
插入
-
+
覆写
@@ -6112,7 +6112,7 @@ p, li { white-space: pre-wrap; }
确认
-
+
源文件尚未编译。
@@ -6129,39 +6129,39 @@ p, li { white-space: pre-wrap; }
重新编译?
-
-
-
+
+
+
错误的编译器设置
-
-
-
+
+
+
编译器被设置为不生成可执行文件。
-
-
+
+
我们需要可执行文件来运行试题案例。
-
+
无编译器设置
-
+
没有配置编译器设置。
-
+
无法启动调试器
@@ -6182,33 +6182,33 @@ p, li { white-space: pre-wrap; }
项目尚未构建。是否构建?
-
+
宿主程序不存在
-
+
动态链接库(DLL)需要一个宿主程序来运行。
-
+
但它不存在。
-
+
宿主程序不存在
-
+
宿主程序'%1'不存在。
-
-
+
+
请在调试前改正设置。
@@ -6217,8 +6217,8 @@ p, li { white-space: pre-wrap; }
重新编译?
-
-
+
+
保存上次打开信息失败
@@ -6227,37 +6227,37 @@ p, li { white-space: pre-wrap; }
无法删除旧上次打开信息文件'%1'
-
+
无法保存上次打开信息文件'%1'
-
-
+
+
载入上次打开信息失败
-
-
+
+
无法载入上次打开信息文件'%1'
-
+
打开源代码文件
-
-
-
+
+
+
纠正调试用编译设置
-
-
+
+
生成的可执行文件中会缺少调试符号信息,因此无法编译。
@@ -6266,81 +6266,81 @@ p, li { white-space: pre-wrap; }
如果你正在使用Release版的编译器设置集,请在工具栏中将其改为Debug版本。
-
-
-
+
+
+
您也可以手动在选项对话框的编译器设置页中修正下列选项:
-
-
-
+
+
+
- 打开“生成调试信息(-g3)"选项.
-
-
-
+
+
+
- 关闭"剥除附加信息(-s)"选项.
-
-
-
+
+
+
- 关闭"优化级别(-O)选项,或将其设置为"调试(-Og)"级别.
-
-
-
-
+
+
+
+
在更换编译器设置集或修改其设置后,需要重新编译.
-
-
-
+
+
+
您现在就要手动修改编译器设置集的设置吗?
-
-
+
+
批量设置案例
-
+
显示详细调试器日志
-
+
全部复制
-
+
跳转到行
-
+
行
-
+
模板已存在
-
+
模板%1已存在。是否覆盖?
@@ -6348,25 +6348,25 @@ p, li { white-space: pre-wrap; }
-
-
-
+
+
+
清除
-
+
导出
-
+
插入代码段
-
-
+
+
试题集%1
@@ -6395,56 +6395,66 @@ p, li { white-space: pre-wrap; }
项目已经被修改过,是否需要重新构建?
-
+
自动保存出错
-
+
自动保存"%1"到"%2"失败:%3
-
+
试题属性...
-
+
设置试题集名称
-
+
试题集名称:
-
+
删除
-
+
+
+
+
+
+
+
+
+
+
+
删除全部书签
-
+
修改描述
-
-
-
+
+
+
书签描述
-
-
-
+
+
+
描述:
@@ -6453,70 +6463,69 @@ p, li { white-space: pre-wrap; }
在调试主控台中显示调试器输出
-
+
清除这次搜索
-
+
删除所有搜索
-
+
断点条件...
-
+
断点条件
-
+
输入当前断点的生效条件:
-
+
Remove all breakpoints
删除所有断点
-
- 行: %1 列: %2 选中:%3 总行数: %4
+ 行: %1 列: %2 选中:%3 总行数: %4
-
+
删除当前断点
-
+
重命名文件
-
-
+
+
添加文件夹
-
-
+
+
新文件夹
-
+
文件夹:
-
+
重命名
@@ -6529,24 +6538,23 @@ p, li { white-space: pre-wrap; }
要现在去修改设置吗?
-
+
修改试题集名称
-
+
无法写入配置文件'%1'。
-
+
修改试题名称
-
- 行: %1 列: %2 总行数: %3
+ 行: %1 列: %2 总行数: %3
@@ -6569,12 +6577,12 @@ p, li { white-space: pre-wrap; }
是否现在去改正?
-
+
项目文件缺失
-
+
下列项目文件缺失,无法构建项目:
@@ -6591,202 +6599,202 @@ p, li { white-space: pre-wrap; }
请取消该设置,重新编译然后重新启动调试。
-
+
跳转到试题网址
-
+
添加试题案例
-
+
运行当前案例
-
+
删除文件夹
-
+
切换为普通视图
-
+
切换为自定义视图
-
+
按类型排序
-
+
按名称排序
-
+
显示继承的成员
-
+
跳转到声明处
-
+
跳转到定义处
-
+
仅当前文件
-
+
整个项目
-
-
+
+
新建文件夹
-
+
重命名
-
-
+
-
-
+
+
+
删除
-
+
在编辑器中打开
-
+
使用外部程序打开
-
+
在终端中打开
-
+
在文件资源管理器中打开
-
+
字符集
-
+
转换为%1编码
-
+
换行符
-
+
已自动保存%1个文件
-
+
设置答案源代码...
-
+
选择其他文件...
-
+
选择答案源代码文件
-
+
变量断点被触发
-
+
"%1"的值发生了变化:
-
+
新值: %1
-
+
项目文件夹被删除
-
+
项目"%1"的文件夹已被外部程序删除.
-
+
项目将被关闭.
-
+
保存设置失败
-
+
文件夹非空
-
+
项目文件夹不是空的,已有的文件可能会被覆盖。
-
+
您确定要继续吗?
-
+
被监控的变量
-
+
当下面的变量被修改时暂停执行(该变量必须可以从当前程序处访问):
@@ -6795,17 +6803,17 @@ p, li { white-space: pre-wrap; }
中止
-
+
FPS试题集文件(*.fps;*.xml)
-
+
FPS试题集文件(*.fps)
-
+
导出时出错
@@ -6815,7 +6823,7 @@ p, li { white-space: pre-wrap; }
C/C++源代码文件 (*.c *.cpp *.cc *.cxx)
-
+
新建文件夹%1
@@ -6828,13 +6836,13 @@ p, li { white-space: pre-wrap; }
无标题%1
-
+
你真的要删除%1吗?
-
+
你真的要删除%1个文件吗?
@@ -6847,7 +6855,7 @@ p, li { white-space: pre-wrap; }
变量"%1"有改动:
-
+
旧值: %1
@@ -6856,63 +6864,63 @@ p, li { white-space: pre-wrap; }
新值: %1
-
+
保存项目
-
+
项目'%1'有改动。
-
-
+
+
需要保存吗?
-
-
+
+
文件已发生变化
-
-
-
+
+
+
新建项目文件?
-
-
-
+
+
+
您是否要将新建的文件加入项目?
-
-
-
-
-
+
+
+
+
+
保存失败
-
+
改变项目编译器配置集
-
+
改变项目的编译器配置集会导致所有的自定义编译器选项被重置。
-
-
+
+
你真的想要那么做吗?
@@ -6921,12 +6929,12 @@ p, li { white-space: pre-wrap; }
批量设置案例
-
+
选择输入数据文件
-
+
输入数据文件 (*.in)
@@ -6935,78 +6943,78 @@ p, li { white-space: pre-wrap; }
无标题%1
-
+
修改监视表达式
-
+
监视表达式
-
+
您真的要清除该文件的所有断点吗?
-
+
新建项目
-
+
关闭'%1'以打开新项目?
-
+
文件夹不存在
-
+
文件夹'%1'不存在。是否创建?
-
+
无法创建文件夹
-
+
创建文件夹'%1'失败。
-
+
-
+
文件夹%1不是空的。
-
+
你真的要删除它吗?
-
+
改变工作文件夹
-
+
File '%1' is not in the current working folder
文件'%1'不在当前工作文件夹中。
-
+
是否将工作文件夹改设为'%1'?
@@ -7015,28 +7023,28 @@ p, li { white-space: pre-wrap; }
正在删除试题...
-
+
无法提交
-
+
Git需要用信息进行提交。
-
+
选择输入数据文件
-
-
+
+
所有文件 (*.*)
-
+
Choose Expected Input Data File
选择期望输出文件
@@ -7048,59 +7056,59 @@ p, li { white-space: pre-wrap; }
-
+
选择工作文件夹
-
-
+
+
头文件已存在
-
-
+
+
头文件"%1"已存在!
-
+
源文件已存在!
-
+
源文件"%1"已存在!
-
+
无法提交!
-
+
下列文件处于冲突状态,请解决后重新添加和提交:
-
+
提交信息
-
+
提交信息:
-
+
提交失败
-
+
提交信息不能为空!
@@ -7109,22 +7117,22 @@ p, li { white-space: pre-wrap; }
小熊猫Dev-C++项目文件 (*.dev)
-
+
新建项目失败
-
+
无法使用模板创建项目
-
+
删除文件
-
+
同时从硬盘上删除文件?
@@ -7133,27 +7141,27 @@ p, li { white-space: pre-wrap; }
无标题
-
+
新的项目文件名
-
+
文件名:
-
+
文件已存在!
-
+
文件'%1'已经存在!
-
+
添加到项目
@@ -7170,12 +7178,12 @@ p, li { white-space: pre-wrap; }
请在工具栏中选择Debug编译器配置集,或者在“编译器配置集”设置的“编译/链接选项”页中<b>启用</b>“生成调试信息(-g3)”、<b>禁用</b>“剥除附件信息(-3)”。
-
+
C/C++源代码文件 (*.c *.cpp *.cc *.cxx)
-
+
本操作会删除此试题的所有案例。
@@ -7184,7 +7192,7 @@ p, li { white-space: pre-wrap; }
调试失败
-
+
可执行文件中没有符号表信息,无法调试。
@@ -7209,123 +7217,123 @@ p, li { white-space: pre-wrap; }
您也可以删除所有断点,打开“CPU信息窗口”,然后调试汇编代码。
-
+
未能生成可执行文件。
-
+
请查看“工具输出”面板中的详细信息。
-
+
小熊猫C++项目文件(*.dev)
-
+
重命名出错
-
+
符号'%1'在系统头文件中定义,无法修改。
-
+
新名称
-
-
-
-
+
+
+
+
替换出错
-
+
无法打开文件'%1'进行替换!
-
+
内容和上次查找时不一致。
-
+
RTF格式文件 (*.rtf)
-
+
HTML文件 (*.html)
-
+
当前的试题集不是空的。
-
+
试题%1
-
-
+
+
试题集文件 (*.pbs)
-
-
+
+
载入失败
-
-
+
+
试题案例%1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
错误
-
+
项目历史
-
-
+
+
载入主题失败
-
-
+
+
清除历史
@@ -7334,8 +7342,8 @@ p, li { white-space: pre-wrap; }
编译生成的可执行文件中没有符号表,无法被调试。
-
-
+
+
版本控制
@@ -7344,61 +7352,61 @@ p, li { white-space: pre-wrap; }
请在工具栏中选用Debug编译器配置集,或者在选项对话框的编辑器配置集页中勾选“生成调试信息(-g3)"选项。
-
+
磁盘文件'%1'已被修改。
-
+
是否重新读取它的内容?
-
+
磁盘文件'%1'已被删除。
-
+
是否保持它在小熊猫C++中打开的编辑窗口?
-
+
打开
-
-
+
+
编译失败
-
+
运行失败
-
-
-
-
+
+
+
+
确认转换
-
+
完全一致
-
+
忽略行首/行尾空格
-
+
忽略多余空格
@@ -7407,43 +7415,43 @@ p, li { white-space: pre-wrap; }
行: %1 列: %2 (%3个字符) 总行数: %4
-
-
-
+
+
+
如果你正在使用Release版的编译器设置集,请在工具栏中将其改为Debug版本。
-
-
-
-
+
+
+
+
当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗?
-
+
新监视表达式
-
+
输入监视表达式
-
+
(%1/%2)正在解析文件"%3"
-
-
+
+
完成%1个文件的解析,用时%2秒
-
+
(每秒%1个文件)
@@ -8847,7 +8855,7 @@ p, li { white-space: pre-wrap; }
QFileSystemModel
-
+
<b>文件名 "%1" 无法被使用!</b><p>可能是重名、过长、为空或者是使用了不能出现在文件名里的符号。
@@ -8856,13 +8864,13 @@ p, li { white-space: pre-wrap; }
QObject
-
+
保存
-
+
将修改保存到"%1"?
@@ -10870,18 +10878,18 @@ p, li { white-space: pre-wrap; }
性能
-
-
-
-
+
+
+
+
编译器配置集
-
-
+
+
@@ -10893,7 +10901,7 @@ p, li { white-space: pre-wrap; }
自动链接
-
+
@@ -10969,15 +10977,15 @@ p, li { white-space: pre-wrap; }
杂项
-
-
+
+
程序运行
-
+
试题集
@@ -11036,8 +11044,8 @@ p, li { white-space: pre-wrap; }
项目选项
-
-
+
+
diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
index 571ddac6..b8a8b616 100644
--- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
@@ -4868,10 +4868,6 @@
-
-
-
-
@@ -5133,7 +5129,11 @@
-
+
+
+
+
+
diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro
index 6ae1fd32..43919b7d 100644
--- a/Red_Panda_CPP.pro
+++ b/Red_Panda_CPP.pro
@@ -21,8 +21,6 @@ qsynedit.depends = redpanda_qt_utils
APP_NAME = RedPandaCPP
-APP_VERSION = 2.27
-
win32: {
SUBDIRS += \
redpanda-win-git-askpass
diff --git a/libs/qsynedit/qsynedit/document.cpp b/libs/qsynedit/qsynedit/document.cpp
index 4b027ae4..8d01a4e6 100644
--- a/libs/qsynedit/qsynedit/document.cpp
+++ b/libs/qsynedit/qsynedit/document.cpp
@@ -895,6 +895,14 @@ int Document::stringWidth(const QString &str, int left) const
return right - left;
}
+int Document::stringWidth(const QString &str, int left, const QFontMetrics &asciFontMetrics, const QFontMetrics &nonAsciiFontMetrics)
+{
+ QList glyphStartCharList = calcGlyphStartCharList(str);
+ int right;
+ calcGlyphPositionList(str, glyphStartCharList, asciFontMetrics, nonAsciiFontMetrics, left, right);
+ return right - left;
+}
+
int Document::glyphCount(int line)
{
QMutexLocker locker(&mMutex);
@@ -929,20 +937,7 @@ int Document::glyphWidth(int line, int glyphIdx)
int Document::glyphWidth(const QString &glyph, int left) const
{
- int glyphWidth;
- if (glyph.length()==1 && glyph[0].unicode()<0xFF) {
- QChar ch = glyph[0];
- if (ch == '\t') {
- glyphWidth = tabWidth() - left % tabWidth();
- } else {
- glyphWidth = mFontMetrics.horizontalAdvance(ch);
- //qDebug()< Document::calcLineWidth(const QString &lineText, const QList &gl
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
}
+QList Document::calcGlyphPositionList(const QString &lineText, const QList &glyphStartCharList, const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics, int left, int &right) const
+{
+ right = std::max(0,left);
+ int start,end;
+ QList glyphPostionList;
+ for (int i=0;i=count())
return 0;
- QList glyphPositionList = mLines[line]->glyphPositionList();
+ QList glyphPositionList = mLines[line]->glyphStartPositionList();
return xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
}
@@ -1010,7 +1026,7 @@ int Document::xposToGlyphStartChar(int line, int xpos)
QMutexLocker locker(&mMutex);
if (line<0 || line>=count())
return 0;
- QList glyphPositionList = mLines[line]->glyphPositionList();
+ QList glyphPositionList = mLines[line]->glyphStartPositionList();
int glyphIdx = xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
return mLines[line]->glyphStartChar(glyphIdx);
}
@@ -1040,7 +1056,7 @@ int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos)
QList glyphPositionList;
int width;
if (mLines[line]->lineText() == newStr) {
- glyphPositionList = mLines[line]->glyphPositionList();
+ glyphPositionList = mLines[line]->glyphStartPositionList();
width = mLines[line]->width();
} else {
glyphPositionList = calcGlyphPositionList(mLines[line]->lineText(), width);
@@ -1124,24 +1140,24 @@ void Document::internalClear()
}
}
+void Document::setLineWidth(int line, const QString &lineText, int newWidth, const QList glyphStartPositionList)
+{
+ QMutexLocker locker(&mMutex);
+ if (line<0 || line>=count())
+ return ;
+ if (lineText != mLines[line]->lineText())
+ return;
+ mLines[line]->mWidth = newWidth;
+ mLines[line]->mGlyphStartPositionList = glyphStartPositionList;
+ Q_ASSERT(mLines[line]->mGlyphStartPositionList.length() == mLines[line]->mGlyphStartCharList.length());
+}
+
QList Document::calcGlyphPositionList(const QString &lineText, const QList &glyphStartCharList, int left, int &right) const
{
- right = std::max(0,left);
- int start,end;
- QList glyphPostionList;
- for (int i=0;i Document::calcGlyphPositionList(const QString &lineText, int &width)
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
}
+QList Document::getGlyphStartCharList(int line, const QString &lineText)
+{
+ if (line<0 || line>=count() || mLines[line]->lineText()!=lineText)
+ return calcGlyphStartCharList(lineText);
+ return mLines[line]->glyphStartCharList();
+}
+
+QList Document::getGlyphStartPositionList(int line, const QString &lineText, int &lineWidth)
+{
+ if (line<0 || line>=count() || mLines[line]->lineText()!=lineText)
+ return calcGlyphPositionList(lineText,lineWidth);
+ lineWidth = mLines[line]->width();
+ return mLines[line]->glyphStartPositionList();
+}
+
NewlineType Document::getNewlineType()
{
QMutexLocker locker(&mMutex);
@@ -1212,21 +1243,21 @@ int DocumentLine::glyphStartPosition(int i)
return 0;
if (mWidth<0)
updateWidth();
- if (i>=mGlyphPositionList.length())
+ if (i>=mGlyphStartPositionList.length())
return mWidth;
- return mGlyphPositionList[i];
+ return mGlyphStartPositionList[i];
}
int DocumentLine::glyphWidth(int i)
{
- if (i<0 || i>=mGlyphPositionList.length())
+ if (i<0 || i>=mGlyphStartPositionList.length())
return 0;
if( mWidth <0)
updateWidth();
int start = glyphStartPosition(i);
int end;
- if (i+1 &DocumentLine::glyphPositionList()
+const QList &DocumentLine::glyphStartPositionList()
{
if(mWidth<0)
updateWidth();
- return mGlyphPositionList;
+ return mGlyphStartPositionList;
}
int DocumentLine::glyphStartChar(int i) const
@@ -1703,4 +1734,64 @@ int searchForSegmentIdx(const QList segList, int minVal, int maxVal, int va
return -1;
}
+int Document::updateGlyphStartPositionList(
+ const QString &lineText,
+ const QList &glyphStartCharList, int startChar, int endChar,
+ const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics,
+ QList &glyphStartPositionList, int left, int &right, int &startGlyph, int &endGlyph) const
+{
+ right = std::max(0,left);
+ startGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),startChar);
+ endGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),endChar);
+ for (int i=startGlyph;i glyphStartCharList)
+{
+ QList addedList = calcGlyphStartCharList(strAdded);
+ for (int i=0;i segList, int maxVal, int idx)
+{
+ if (idx<0 || idx>=segList.length())
+ return 0;
+ if (idx == segList.length()-1)
+ return maxVal - segList[idx];
+ return segList[idx+1]-segList[idx];
+}
+
}
diff --git a/libs/qsynedit/qsynedit/document.h b/libs/qsynedit/qsynedit/document.h
index b771d38f..1f64b652 100644
--- a/libs/qsynedit/qsynedit/document.h
+++ b/libs/qsynedit/qsynedit/document.h
@@ -31,8 +31,9 @@
namespace QSynedit {
int searchForSegmentIdx(const QList segList, int minVal, int maxVal, int value);
-
+int calcSegmentInterval(const QList segList, int maxVal, int idx);
QList calcGlyphStartCharList(const QString &text);
+void expandGlyphStartCharList(const QString& strAdded, int oldStrLen, QList glyphStartCharList);
class Document;
@@ -83,7 +84,7 @@ private:
* @brief get list of start position of the glyphs in the line text
* @return start positions of the glyph (in pixel)
*/
- const QList& glyphPositionList();
+ const QList& glyphStartPositionList();
/**
* @brief get start index of the chars representing the specified glyph.
@@ -145,7 +146,7 @@ private:
void setLineText(const QString &newLineText);
void updateWidth();
- void invalidateWidth() { mWidth = -1; mGlyphPositionList.clear(); }
+ void invalidateWidth() { mWidth = -1; mGlyphStartPositionList.clear(); }
private:
QString mLineText; /* the unicode code points of the text */
/**
@@ -160,11 +161,11 @@ private:
* @brief start columns of the glyphs
*
* A glyph may occupy more than one columns in the screen.
- * Each elements of mGlyphPositionList is the columns occupied by the glyph.
+ * Each elements of mGlyphStartPositionList is the columns occupied by the glyph.
* The width of a glyph is affected by the font used to display,
* so it must be recalculated each time the font is changed.
*/
- QList mGlyphPositionList;
+ QList mGlyphStartPositionList;
/**
* @brief state of the syntax highlighter after this line is parsed
*
@@ -441,6 +442,8 @@ public:
*/
int stringWidth(const QString &str, int left) const;
+ int stringWidth(const QString &str, int left, const QFontMetrics &asciFontMetrics, const QFontMetrics &nonAsciiFontMetrics);
+
int glyphCount(int line);
/**
* @brief get start index of the chars representing the specified glyph in the specified line.
@@ -515,6 +518,14 @@ public:
int charToGlyphStartPosition(int line, const QString newStr, int charPos);
int xposToGlyphStartChar(int line, const QString newStr, int xpos);
+ int updateGlyphStartPositionList(
+ const QString& lineText,
+ const QList &glyphStartCharList,
+ int startChar, int endChar,
+ const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics,
+ QList &glyphStartPositionList,
+ int left, int &right, int &startGlyph, int &endGlyph) const;
+
bool getAppendNewLineAtEOF();
void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
@@ -554,11 +565,22 @@ protected:
void putTextStr(const QString& text);
void internalClear();
private:
+ void setLineWidth(int line, const QString& lineText, int newWidth, const QList glyphStartPositionList);
+
+ int glyphWidth(const QString& glyph, int left,
+ const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics) const;
+
int xposToGlyphIndex(int strWidth, QList glyphPositionList, int xpos) const;
int charToGlyphIndex(const QString& str, QList glyphStartCharList, int charPos) const;
QList calcLineWidth(const QString& lineText, const QList &glyphStartCharList, int &width);
+ QList calcGlyphPositionList(const QString& lineText, const QList &glyphStartCharList,
+ const QFontMetrics &fontMetrics,
+ const QFontMetrics &nonAsciiFontMetrics,
+ int left, int &right) const;
QList calcGlyphPositionList(const QString& lineText, const QList &glyphStartCharList, int left, int &right) const;
QList calcGlyphPositionList(const QString& lineText, int &width) const;
+ QList getGlyphStartCharList(int line, const QString &lineText);
+ QList getGlyphStartPositionList(int line, const QString &lineText, int &lineWidth);
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
void loadUTF16BOMFile(QFile& file);
void loadUTF32BOMFile(QFile& file);
@@ -588,6 +610,8 @@ private:
#else
QMutex mMutex;
#endif
+
+ friend class QSynEditPainter;
};
enum class ChangeReason {
diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp
index c79a993b..c085453f 100644
--- a/libs/qsynedit/qsynedit/painter.cpp
+++ b/libs/qsynedit/qsynedit/painter.cpp
@@ -354,7 +354,12 @@ int QSynEditPainter::fixXValue(int xpos)
}
void QSynEditPainter::paintToken(
- const QString &token, int tokenWidth, int tokenLeft,
+ const QString& lineText,
+ const QList &glyphStartCharList,
+ const QList &glyphStartPositionList,
+ int startGlyph,
+ int endGlyph,
+ int tokenWidth, int tokenLeft,
int first, int last, bool /*isSelection*/, const QFont& font,
const QFont& fontForNonAscii, bool showGlyphs)
{
@@ -362,8 +367,12 @@ void QSynEditPainter::paintToken(
int nX;
bool lastGlyphAscii = false;
bool fontInited = false;
+ int tokenRight = tokenWidth+tokenLeft;
-// qDebug()<<"Paint token"<= first && rcToken.right() > rcToken.left()) {
nX = fixXValue(first);
@@ -375,14 +384,12 @@ void QSynEditPainter::paintToken(
} else {
int tokenWidth=0;
startPaint = false;
- QList glyphStartCharList = calcGlyphStartCharList(token);
-// qDebug()<<"painting:"<document()->glyphWidth(glyph, tokenLeft+tokenWidth);
-// qDebug()<first) {
if (!startPaint ) {
nX-= (first - tokenWidth - 1) ;
@@ -410,8 +417,8 @@ void QSynEditPainter::paintToken(
QString textToPaint = glyph;
while(i+1document()->glyphWidth(glyph2,0);
+ glyphWidth += calcSegmentInterval(glyphStartPositionList, tokenLeft+tokenWidth, i);
textToPaint+=glyph2;
if (tokenWidth + glyphWidth > last )
break;
@@ -544,7 +551,10 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
}
}
-void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
+void QSynEditPainter::paintHighlightToken(const QString& lineText,
+ const QList &glyphStartCharList,
+ const QList &glyphStartPositionsList,
+ bool bFillToEOL)
{
bool isComplexToken;
int nC1, nC2, nC1Sel, nC2Sel;
@@ -578,16 +588,7 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
// if (bSpecialLine && mEdit->mOptions.testFlag(eoSpecialLineDefaultFg))
// colFG = TokenAccu.FG;
- QFont font = mEdit->font();
- font.setBold(mTokenAccu.style & FontStyle::fsBold);
- font.setItalic(mTokenAccu.style & FontStyle::fsItalic);
- font.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut);
- font.setUnderline(mTokenAccu.style & FontStyle::fsUnderline);
- QFont nonAsciiFont = mEdit->fontForNonAscii();
- nonAsciiFont.setBold(mTokenAccu.style & FontStyle::fsBold);
- nonAsciiFont.setItalic(mTokenAccu.style & FontStyle::fsItalic);
- nonAsciiFont.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut);
- nonAsciiFont.setUnderline(mTokenAccu.style & FontStyle::fsUnderline);
+
// Paint the chars
if (isComplexToken) {
@@ -596,24 +597,47 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
setDrawingColors(false);
rcToken.setRight(fixXValue(mLineSelStart));
paintToken(
- mTokenAccu.s,mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
+ lineText,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ mTokenAccu.startGlyph,
+ mTokenAccu.endGlyph,
+ mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,false,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
}
// selected part of the token
setDrawingColors(true);
nC1Sel = std::max(mLineSelStart, nC1);
nC2Sel = std::min(mLineSelEnd, nC2);
rcToken.setRight(fixXValue(nC2Sel));
- paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,true,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
+ paintToken(
+ lineText,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ mTokenAccu.startGlyph,
+ mTokenAccu.endGlyph,
+ mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,true,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
// second unselected part of the token
if (bU2) {
setDrawingColors(false);
rcToken.setRight(fixXValue(nC2));
- paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
+ paintToken(
+ lineText,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ mTokenAccu.startGlyph,
+ mTokenAccu.endGlyph,
+ mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2,false,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
}
} else {
setDrawingColors(bSel);
rcToken.setRight(fixXValue(nC2));
- paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1, nC2,bSel,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
+ paintToken(
+ lineText,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ mTokenAccu.startGlyph,
+ mTokenAccu.endGlyph,
+ mTokenAccu.width, mTokenAccu.left, nC1, nC2,bSel,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
}
}
@@ -658,9 +682,15 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
// Store the token chars with the attributes in the TokenAccu
// record. This will paint any chars already stored if there is
// a (visible) change in the attributes.
-void QSynEditPainter::addHighlightToken(const QString &token, int tokenLeft,
- int tokenWidth, int line, PTokenAttribute attri,
- bool showGlyphs)
+void QSynEditPainter::addHighlightToken(
+ const QString& lineText,
+ const QString& token, int tokenLeft,
+ int line, PTokenAttribute attri, bool showGlyphs,
+ const QList glyphStartCharList,
+ int tokenStartChar,
+ int tokenEndChar,
+ QList &glyphStartPositionList,
+ int &tokenWidth)
{
bool bCanAppend;
QColor foreground, background;
@@ -706,20 +736,52 @@ void QSynEditPainter::addHighlightToken(const QString &token, int tokenLeft,
}
// If we can't append it, then we have to paint the old token chars first.
if (!bCanAppend)
- paintHighlightToken(false);
+ paintHighlightToken(lineText, glyphStartCharList, glyphStartPositionList, false);
}
- // Don't use AppendStr because it's more expensive.
- if (bCanAppend) {
- mTokenAccu.s.append(token);
- mTokenAccu.width+=tokenWidth;
- } else {
- mTokenAccu.width = tokenWidth;
- mTokenAccu.s = token;
- mTokenAccu.left = tokenLeft;
- mTokenAccu.foreground = foreground;
- mTokenAccu.background = background;
- mTokenAccu.style = style;
- mTokenAccu.showSpecialGlyphs = showGlyphs;
+ if (!bCanAppend) {
+ mTokenAccu.font = mEdit->font();
+ mTokenAccu.font.setBold(style & FontStyle::fsBold);
+ mTokenAccu.font.setItalic(style & FontStyle::fsItalic);
+ mTokenAccu.font.setStrikeOut(style & FontStyle::fsStrikeOut);
+ mTokenAccu.font.setUnderline(style & FontStyle::fsUnderline);
+ mTokenAccu.nonAsciiFont = mEdit->fontForNonAscii();
+ mTokenAccu.nonAsciiFont.setBold(style & FontStyle::fsBold);
+ mTokenAccu.nonAsciiFont.setItalic(style & FontStyle::fsItalic);
+ mTokenAccu.nonAsciiFont.setStrikeOut(style & FontStyle::fsStrikeOut);
+ mTokenAccu.nonAsciiFont.setUnderline(style & FontStyle::fsUnderline);
+ }
+ //calculate width of the token ( and update it's glyph start positions )
+ int tokenRight;
+ int startGlyph, endGlyph;
+ tokenWidth = mEdit->mDocument->updateGlyphStartPositionList(
+ lineText,
+ glyphStartCharList,
+ tokenStartChar,
+ tokenEndChar,
+ QFontMetrics(mTokenAccu.font),
+ QFontMetrics(mTokenAccu.nonAsciiFont),
+ glyphStartPositionList,
+ tokenLeft,
+ tokenRight,
+ startGlyph,
+ endGlyph);
+
+ // Only accumulate tokens if it's visible.
+ if (tokenLeft < mRight) {
+ if (bCanAppend) {
+ mTokenAccu.width += tokenWidth;
+ Q_ASSERT(startGlyph == mTokenAccu.endGlyph);
+ mTokenAccu.endGlyph = endGlyph;
+ } else {
+ mTokenAccu.width = tokenWidth;
+ mTokenAccu.left = tokenLeft;
+ mTokenAccu.startGlyph = startGlyph;
+ mTokenAccu.endGlyph = endGlyph;
+ mTokenAccu.foreground = foreground;
+ mTokenAccu.background = background;
+ mTokenAccu.style = style;
+ mTokenAccu.showSpecialGlyphs = showGlyphs;
+ }
}
}
@@ -864,8 +926,6 @@ void QSynEditPainter::paintLines()
EditingAreaList areaList;
PCodeFoldingRange foldRange;
PTokenAttribute preeditAttr;
- int nFold;
- QString sFold;
// Initialize rcLine for drawing. Note that Top and Bottom are updated
// inside the loop. Get only the starting point for this.
@@ -950,32 +1010,60 @@ void QSynEditPainter::paintLines()
mIsLineSelected = (!mIsComplexLine) && (mLineSelStart > 0);
rcToken = rcLine;
+
+ int lineWidth;
+ QList glyphStartCharList = mEdit->mDocument->getGlyphStartCharList(vLine-1,sLine);
+ QList glyphStartPositionsList = mEdit->mDocument->getGlyphStartPositionList(vLine-1,sLine, lineWidth);
+
if (!mEdit->mSyntaxer || !mEdit->mSyntaxer->enabled()) {
sToken = sLine;
- if (mIsCurrentLine) {
- tokenWidth = mEdit->document()->lineWidth(vLine-1, sLine);
- } else {
- tokenWidth = mEdit->document()->lineWidth(vLine-1);
- }
+ tokenWidth = lineWidth;
if (mEdit->mOptions.testFlag(eoShowLineBreaks) && (!mIsLineSelected) && (!mIsSpecialLine) && (tokenWidth <= mLeft)) {
- sToken = sToken + LineBreakGlyph;
- tokenWidth += mEdit->document()->glyphWidth(LineBreakGlyph,0);
+ expandGlyphStartCharList(LineBreakGlyph, sLine.length(), glyphStartCharList);
+ int width = mEdit->document()->glyphWidth(LineBreakGlyph,0);
+ glyphStartPositionsList.append(tokenWidth);
+ sLine+=LineBreakGlyph;
+ tokenWidth += width;
}
if (mIsComplexLine) {
setDrawingColors(true);
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelStart)));
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelEnd)));
- paintToken(sToken, tokenWidth, 0, mLineSelStart, mLineSelEnd,false,mEdit->font(),mEdit->fontForNonAscii(),false);
+ paintToken(
+ sLine,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ 0,
+ glyphStartCharList.length(),
+ tokenWidth, 0, mLineSelStart, mLineSelEnd,false,mEdit->font(),mEdit->fontForNonAscii(),false);
setDrawingColors(false);
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLeft)));
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelStart)));
- paintToken(sToken, tokenWidth, 0, mLeft, mLineSelStart,false,mEdit->font(),mEdit->fontForNonAscii(),false);
+ paintToken(
+ sLine,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ 0,
+ glyphStartCharList.length(),
+ tokenWidth, 0, mLeft, mLineSelStart,false,mEdit->font(),mEdit->fontForNonAscii(),false);
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelEnd)));
rcToken.setRight(std::min(rcLine.right(), fixXValue(mRight)));
- paintToken(sToken, tokenWidth, 0, mLineSelEnd, mRight,true, mEdit->font(), mEdit->fontForNonAscii(),false);
+ paintToken(
+ sLine,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ 0,
+ glyphStartCharList.length(),
+ tokenWidth, 0, mLineSelEnd, mRight,true, mEdit->font(), mEdit->fontForNonAscii(),false);
} else {
setDrawingColors(mIsLineSelected);
- paintToken(sToken, tokenWidth, 0, mLeft, mRight, mIsLineSelected,mEdit->font(),mEdit->fontForNonAscii(),false);
+ paintToken(
+ sLine,
+ glyphStartCharList,
+ glyphStartPositionsList,
+ 0,
+ glyphStartCharList.length(),
+ tokenWidth, 0, mLeft, mRight, mIsLineSelected,mEdit->font(),mEdit->fontForNonAscii(),false);
}
//Paint editingAreaBorders
if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
@@ -1007,105 +1095,124 @@ void QSynEditPainter::paintLines()
// Test first whether anything of this token is visible.
while (!mEdit->mSyntaxer->eol()) {
sToken = mEdit->mSyntaxer->getToken();
- // Work-around buggy highlighters which return empty tokens.
if (sToken.isEmpty()) {
- mEdit->mSyntaxer->next();
- if (mEdit->mSyntaxer->eol())
- break;
- sToken = mEdit->mSyntaxer->getToken();
- // Maybe should also test whether GetTokenPos changed...
- if (sToken.isEmpty()) {
- //qDebug()<mSyntaxer->next();
+ // if (mEdit->mSyntaxer->eol())
+ // break;
+ // sToken = mEdit->mSyntaxer->getToken();
+ // // Maybe should also test whether GetTokenPos changed...
+ // if (sToken.isEmpty()) {
+ // //qDebug()<charToColumn(sLine,edit->mHighlighter->getTokenPos()+1)-1;
- tokenWidth = mEdit->stringWidth(sToken, tokenLeft);
- if ( tokenLeft + tokenWidth >= mLeft) {
- if (tokenLeft + tokenWidth >= mRight) {
- if (tokenLeft >= mRight)
- break; //*** BREAK ***
- tokenWidth = mRight - tokenLeft;
- }
- // It's at least partially visible. Get the token attributes now.
- attr = mEdit->mSyntaxer->getTokenAttribute();
+ int tokenStartChar = mEdit->mSyntaxer->getTokenPos();
+ int tokenEndChar = tokenStartChar + sToken.length();
- //rainbow parenthesis
- if (sToken == "["
- || sToken == "("
- || sToken == "{"
- ) {
- SyntaxState rangeState = mEdit->mSyntaxer->getState();
- getBraceColorAttr(rangeState.bracketLevel
- +rangeState.braceLevel
- +rangeState.parenthesisLevel
- ,attr);
- } else if (sToken == "]"
- || sToken == ")"
- || sToken == "}"
- ){
- SyntaxState rangeState = mEdit->mSyntaxer->getState();
- getBraceColorAttr(rangeState.bracketLevel
- +rangeState.braceLevel
- +rangeState.parenthesisLevel+1,
- attr);
- }
- //input method
- if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
- int startPos = mEdit->mSyntaxer->getTokenPos()+1;
- int endPos = mEdit->mSyntaxer->getTokenPos() + sToken.length();
- //qDebug()<mCaretX<<":"<mCaretX+edit->mInputPreeditString.length();
- if (!(endPos < mEdit->mCaretX
- || startPos >= mEdit->mCaretX+mEdit->mInputPreeditString.length())) {
- if (!preeditAttr) {
- preeditAttr = attr;
- } else {
- attr = preeditAttr;
- }
- }
- }
- bool showGlyph=false;
- if (attr && attr->tokenType() == TokenType::Space) {
- int pos = mEdit->mSyntaxer->getTokenPos();
- if (pos==0) {
- showGlyph = mEdit->mOptions.testFlag(eoShowLeadingSpaces);
- } else if (pos+sToken.length()==sLine.length()) {
- showGlyph = mEdit->mOptions.testFlag(eoShowTrailingSpaces);
- } else {
- showGlyph = mEdit->mOptions.testFlag(eoShowInnerSpaces);
- }
- }
- addHighlightToken(sToken, tokenLeft,
- tokenWidth, vLine,attr, showGlyph);
+ // It's at least partially visible. Get the token attributes now.
+ attr = mEdit->mSyntaxer->getTokenAttribute();
+
+ //rainbow parenthesis
+ if (sToken == "["
+ || sToken == "("
+ || sToken == "{"
+ ) {
+ SyntaxState rangeState = mEdit->mSyntaxer->getState();
+ getBraceColorAttr(rangeState.bracketLevel
+ +rangeState.braceLevel
+ +rangeState.parenthesisLevel
+ ,attr);
+ } else if (sToken == "]"
+ || sToken == ")"
+ || sToken == "}"
+ ){
+ SyntaxState rangeState = mEdit->mSyntaxer->getState();
+ getBraceColorAttr(rangeState.bracketLevel
+ +rangeState.braceLevel
+ +rangeState.parenthesisLevel+1,
+ attr);
}
+ //input method
+ if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
+ int startPos = mEdit->mSyntaxer->getTokenPos()+1;
+ int endPos = mEdit->mSyntaxer->getTokenPos() + sToken.length();
+ //qDebug()<mCaretX<<":"<mCaretX+edit->mInputPreeditString.length();
+ if (!(endPos < mEdit->mCaretX
+ || startPos >= mEdit->mCaretX+mEdit->mInputPreeditString.length())) {
+ if (!preeditAttr) {
+ preeditAttr = attr;
+ } else {
+ attr = preeditAttr;
+ }
+ }
+ }
+ bool showGlyph=false;
+ if (attr && attr->tokenType() == TokenType::Space) {
+ int pos = mEdit->mSyntaxer->getTokenPos();
+ if (pos==0) {
+ showGlyph = mEdit->mOptions.testFlag(eoShowLeadingSpaces);
+ } else if (pos+sToken.length()==sLine.length()) {
+ showGlyph = mEdit->mOptions.testFlag(eoShowTrailingSpaces);
+ } else {
+ showGlyph = mEdit->mOptions.testFlag(eoShowInnerSpaces);
+ }
+ }
+ addHighlightToken(
+ sLine,
+ sToken,
+ tokenLeft,
+ vLine, attr,showGlyph,
+ glyphStartCharList,
+ tokenStartChar,
+ tokenEndChar,
+ glyphStartPositionsList,
+ tokenWidth);
tokenLeft+=tokenWidth;
// Let the highlighter scan the next token.
mEdit->mSyntaxer->next();
}
- // Paint folding
- foldRange = mEdit->foldStartAtLine(vLine);
- if ((foldRange) && foldRange->collapsed) {
- sFold = mEdit->syntaxer()->foldString(sLine);
- nFold = mEdit->stringWidth(sFold,mEdit->mDocument->lineWidth(vLine-1));
- attr = mEdit->mSyntaxer->symbolAttribute();
- getBraceColorAttr(mEdit->mSyntaxer->getState().braceLevel,attr);
- addHighlightToken(
- sFold, mEdit->mDocument->lineWidth(vLine-1)
- , nFold, vLine, attr,false);
- } else {
- // Draw LineBreak glyph.
- if (mEdit->mOptions.testFlag(eoShowLineBreaks)
- && (!mIsLineSelected)
- && (!mIsSpecialLine)
- && (mEdit->mDocument->lineWidth(vLine-1) < mRight)) {
- addHighlightToken(LineBreakGlyph,
- mEdit->mDocument->lineWidth(vLine-1),
- mEdit->mDocument->glyphWidth(LineBreakGlyph,0),vLine, mEdit->mSyntaxer->whitespaceAttribute(),false);
+ mEdit->mDocument->setLineWidth(vLine-1, sLine, tokenLeft, glyphStartPositionsList);
+ if (tokenLeftfoldStartAtLine(vLine);
+ if ((foldRange) && foldRange->collapsed) {
+ addOnStr = mEdit->syntaxer()->foldString(sLine);
+ } else {
+ // Draw LineBreak glyph.
+ if (mEdit->mOptions.testFlag(eoShowLineBreaks)
+ && (!mIsLineSelected)
+ && (!mIsSpecialLine)
+ && (mEdit->mDocument->lineWidth(vLine-1) < mRight)) {
+ addOnStr = LineBreakGlyph;
+ }
+ }
+ if (!addOnStr.isEmpty()) {
+ expandGlyphStartCharList(addOnStr, sLine.length(), glyphStartCharList);
+ for (int i=0;imSyntaxer->symbolAttribute();
+ getBraceColorAttr(mEdit->mSyntaxer->getState().braceLevel,attr);
+ int oldLen = sLine.length();
+ sLine += addOnStr;
+ addHighlightToken(
+ sLine,
+ addOnStr,
+ tokenLeft,
+ vLine, attr, false,
+ glyphStartCharList,
+ oldLen,
+ sLine.length(),
+ glyphStartPositionsList,
+ tokenWidth);
}
}
// Draw anything that's left in the TokenAccu record. Fill to the end
// of the invalid area with the correct colors.
- paintHighlightToken(true);
+ paintHighlightToken(sLine, glyphStartCharList, glyphStartPositionsList, true);
//Paint editingAreaBorders
foreach (const PEditingArea& area, areaList) {
diff --git a/libs/qsynedit/qsynedit/painter.h b/libs/qsynedit/qsynedit/painter.h
index 0688ce0e..e7ceeb7c 100644
--- a/libs/qsynedit/qsynedit/painter.h
+++ b/libs/qsynedit/qsynedit/painter.h
@@ -31,10 +31,14 @@ class QSynEditPainter
struct SynTokenAccu {
int width;
int left;
- QString s;
+ int startGlyph;
+ int endGlyph;
+// QString s;
QColor foreground;
QColor background;
FontStyles style;
+ QFont font;
+ QFont nonAsciiFont;
bool showSpecialGlyphs;
};
@@ -54,13 +58,29 @@ private:
void computeSelectionInfo();
void setDrawingColors(bool selected);
int fixXValue(int xpos);
- void paintToken(const QString& token, int tokenWidth, int tokenLeft,
- int first, int last, bool isSelection, const QFont& font,
- const QFont& fontForNonAscii, bool showGlyphs);
+ void paintToken(
+ const QString& lineText,
+ const QList &glyphStartCharList,
+ const QList &glyphStartPositionList,
+ int startGlyph,
+ int endGlyph,
+ int tokenWidth, int tokenLeft,
+ int first, int last, bool isSelection, const QFont& font,
+ const QFont& fontForNonAscii, bool showGlyphs);
void paintEditAreas(const EditingAreaList& areaList);
- void paintHighlightToken(bool bFillToEOL);
- void addHighlightToken(const QString& token, int tokenLeft, int tokenWidth,
- int line, PTokenAttribute p_Attri, bool showGlyphs);
+ void paintHighlightToken(const QString& lineText,
+ const QList &glyphStartCharList,
+ const QList &glyphStartPositionsList, bool bFillToEOL);
+ void addHighlightToken(
+ const QString& lineText,
+ const QString& token, int tokenLeft,
+ int line, PTokenAttribute p_Attri, bool showGlyphs,
+ const QList glyphStartCharList,
+ int tokenStartChar,
+ int tokenEndChar,
+ QList &glyphStartPositionList,
+ int &tokenWidth
+ );
void paintFoldAttributes();
void getBraceColorAttr(int level, PTokenAttribute &attr);
diff --git a/libs/qsynedit/qsynedit_zh_CN.ts b/libs/qsynedit/qsynedit_zh_CN.ts
index a985e592..8496a87c 100644
--- a/libs/qsynedit/qsynedit_zh_CN.ts
+++ b/libs/qsynedit/qsynedit_zh_CN.ts
@@ -4288,29 +4288,29 @@
QSynedit::Document
-
+
无法读取文件"%1".
-
-
+
+
无法加载字符编码"%1"!
-
+
This is a binaray File!
'%1'是二进制文件!
-
+
无法保存文件"%1"!
-
+
数据未能正确写入文件"%1"。
@@ -4318,7 +4318,7 @@
QSynedit::QSynEdit
-
+
The highlighter seems to be in an infinite loop
代码分析器似乎死循环了。