diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts
index 5e9678c..c7cf1c3 100644
--- a/lang/zh_CN/winghex_zh_CN.ts
+++ b/lang/zh_CN/winghex_zh_CN.ts
@@ -478,12 +478,12 @@
书签
-
+
Untitled
未命名
-
+
Not allowed operation in non-UI thread
该操作在非 UI 线程非法
@@ -865,18 +865,18 @@
MainWindow
-
+
File
文件
-
-
+
+
View
视图
-
+
About
关于
@@ -897,317 +897,319 @@
选长:
-
+
Edit
编辑
-
+
Script
脚本
-
-
-
+
+
+
Plugin
插件
-
+
Setting
设置
-
-
+
+
Log
日志
-
+
ExportFindResult
导出搜索结果
-
+
ClearFindResult
清空记录
-
-
+
+
FindResult
搜索结果
-
-
-
-
+
+
+
+
Copy
复制
-
-
-
-
-
+
+
+
+
+
CopyToClipBoard
数据已拷贝到粘贴板
-
+
LittleEndian
小端
-
+
BigEndian
大端
-
+
Number
数值
-
-
+
+
CheckSum
校验和
-
-
+
+
DeleteBookMark
删除书签
-
-
+
+
ClearBookMark
清空书签
-
-
-
-
+
+
+
+
BookMark
书签
-
-
+
+
DecodeText
解码字符串
-
+
ScriptConsole
脚本控制台
-
-
+
+
Basic
基础
-
+
New
新建
-
+
OpenF
打开文件
-
+
OpenWorkSpace
打开工作区
-
+
RecentFiles
最近打开
-
+
+
+
Reload
重新加载
-
-
+
+
Save
保存
-
+
SaveAs
另存为
-
+
ConvertWS
转为工作区
-
+
Export
导出
-
+
SaveSel
保存选区字节
-
-
-
-
+
+
+
+
General
基本
-
+
Undo
撤销
-
+
Redo
恢复
-
+
Cut
剪切
-
+
Paste
粘贴
-
+
Delete
删除
-
+
Clone
克隆
-
+
Lookup
查询
-
+
Find
查找
-
+
Goto
跳转
-
-
+
+
Encoding
编码
-
+
FileInfo
文件信息
-
-
+
+
Hex
十六进制
-
+
CutHex
剪切(十六进制)
-
+
CopyHex
复制(十六进制)
-
+
PasteHex
粘贴(十六进制)
-
-
+
+
Fill
填充
-
+
FillZero
填充零
-
-
-
-
-
+
+
+
+
+
MetaData
标注
-
+
DeleteMetadata
删除标注
-
+
ClearMetadata
清空标注
-
+
MetaDataEdit
编辑标注
-
+
DeleteMetaData
删除标注
-
+
ClearMetaData
清空标注
-
+
Display
显示
-
+
ViewText
文本预览
-
+
Scale
缩放
@@ -1242,781 +1244,793 @@
加载插件中:
-
+
SetupConsole
启动脚本控制台
-
+
SetupScriptManager
启动脚本管理器
-
+
SetupScriptService
启动脚本服务
-
+
SetupScriptEditor
构建脚本编辑器
-
+
SetupSetDialog
构建设置窗体
-
+
SetupPlgWidgets
启动插件组件
-
+
SetupDockingLayout
恢复 Dock 布局
-
+
SetupWaiting
启动即将完成
-
+
SetupFinished
启动完毕
-
+
NoExtension
无扩展
-
-
+
+
ExportResult
导出结果
-
+
NothingToSave
没有保存的数据
-
+
OpenExt
打开 - 拓展
-
+
ResetScale
重置缩放
-
+
ShowMetafg
标注前景色
-
+
ShowMetabg
标注背景色
-
+
ShowMetaComment
批注
-
+
MetaShowAll
显示所有标注
-
+
MetaHideAll
隐藏所有标注
-
+
FileStatus
文件状态
-
+
InfoSave
是否保存
-
+
ReadOnly
可读写
-
+
SetLocked
启用/禁用锁定编辑
-
+
ErrUnLock
锁定编辑失败
-
+
SetOver
启用/禁用改变大小
-
+
+ InputRequest
+
+
+
+
UnsignedHex
无符号 Hex
-
+
BgScriptOutput
后台脚本输出
-
+
ErrUnOver
锁定文件大小失败
-
+
Window
窗体
-
+
Editor
编辑器
-
+
Tools
工具
-
+
HexEditorLayout
编辑器布局
-
+
SetBaseAddr
设置基址
-
+
addressBase
基址
-
+
inputAddressBase
请输入基址
-
+
WarnBigBaseAddress
基址过大,你得到的地址将会不正确!
-
+
ErrBaseAddress
非法基址输入
-
+
SetColInfo
显示/隐藏地址栏
-
+
SetHeaderInfo
显示/隐藏表头
-
+
SetAsciiString
显示/隐藏解码字符串
-
+
Layout
布局
-
+
Fullscreen
全屏
-
+
Default
默认
-
-
-
+
+
+
LayoutRestoring...
恢复布局中...
-
+
RestoreLayout
恢复布局
-
-
+
+
SaveLayout
保存布局
-
+
ExportLog
导出日志
-
+
ClearLog
清空日志
-
+
InsepctQt
监视 Qt
-
+
ScriptEditor
脚本编辑器
-
+
Scripts
脚本仓库
-
+
PluginFunctions
插件功能
-
+
ScriptSetting
脚本设置
-
+
PluginSettings
插件设置
-
+
Info
信息
-
+
Software
软件
-
+
Sponsor
赞助
-
+
CheckUpdate
检查更新
-
+
Wiki
网页 Wiki
-
+
AboutQT
关于 QT
-
+
SetPageIDEmptyTryUseName
设置页 ID 为空,尝试使用名称作为 ID
-
+
SetPageDupNameIgnored
设置页重复的 ID 名称,已忽略加载
-
+
Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3
插件 %1 包含重复 ID (%2),该 ID 已被插件 %3 注册
-
-
+
+
ChooseFile
选择文件
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error
错误
-
-
+
+
FileNotExist
文件不存在!
-
-
-
-
-
+
+
+
+
+
FilePermission
因文件权限无法继续!
-
+
ProjectFile (*.wingpro)
项目文件 (*.wingpro)
-
+
ReloadSuccessfully
文件重新加载成功!
-
+
ReloadUnSuccessfully
文件重新加载失败!
-
-
-
-
+
+
+
+
ChooseSaveFile
请选择保存文件路径:
-
+
NoMoreClone
克隆已到上限,无法继续操作!
-
+
FindFininishBusy
查找任务繁忙,请勿重复查找!
-
+
MayTooMuchFindResult
搜索数量已到达上限,结果可能不全,建议请按区段搜索。
-
+
SaveLayoutSuccess
保存布局成功
-
+
SaveLayoutError
保存布局失败
-
+
HasClonedView
该编辑页已被克隆编辑,如果关闭,相关联的页也会被关闭,你确认继续吗?
-
+
+
+ ReloadNeededYesOrNo
+
+
+
+
SaveWorkSpace
保存工作区
-
+
WingHexWorkSpace (*.wingpro)
羽云十六进制工作区 (*.wingpro)
-
+
ConfirmSave
正在关闭未保存的文件或工作区,你确定保存吗?
-
+
[Info]
【信息】
-
+
[Warn]
【警告】
-
+
[Error]
【错误】
-
+
ConfirmAPPSave
你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗?
-
-
-
+
+
+
SaveSuccessfully
保存成功!
-
-
+
+
SaveWSError
保存工作区错误!
-
-
+
+
Warn
警告
-
+
Opening...
打开文件中...
-
+
WorkSpaceOpening...
打开工作区中...
-
+
Reloading...
重载文件中...
-
+
Saving...
保存中...
-
+
SaveNewFirst
请首先保存新建的文件
-
+
AlreadyWorkSpace
已经是工作区,无需转化
-
+
ConvWorkSpaceFailed
转化为工作区失败
-
+
ConvWorkSpaceSuccess
转化为工作区成功
-
+
SavingAs...
另存为中...
-
+
SaveUnSuccessfully
保存失败!
-
+
Exporting...
导出中...
-
+
ChooseExportFile
请选择导出文件路径:
-
+
ExportSuccessfully
导出成功!
-
+
ExportUnSuccessfully
导出失败!
-
+
SavingSel...
保存选中字节中...
-
+
SaveSelSuccess
保存选区字节成功!
-
+
SaveSelError
保存选区字节失败,因文件不具有可写权限!
-
-
+
+
CutToClipBoard
数据已剪切到粘贴板!
-
-
+
+
UnCutToClipBoard
由于保持大小限制,数据剪切到粘贴板失败!
-
-
+
+
UnCopyToClipBoard
由于保持大小限制,数据剪切到复制板失败!
-
-
+
+
Finding...
查找中...
-
+
DeleteSuccess
删除成功
-
+
DeleteFailed
删除失败
-
+
FindFininish
查找结果完毕!
-
+
PleaseInputFill
请输入填充字节值
-
+
FillInputTruncWarn
填充输入数值过大,将会被截断填充
-
+
FillInputError
填充字节输入错误
-
-
+
+
InputComment
请输入批注:
-
-
+
+
BookmarkDelSuccess
删除书签成功
-
+
BookmarkDelNoItem
无书签可删除
-
+
BookmarkClearSuccess
书签清空完毕
-
-
-
+
+
+
NoSelection
没有选区,无法继续的操作!
-
+
NoMetaData
无可编辑标记
-
+
PleaseClearSel
请清空选择
-
+
MetaDelSuccess
元数据删除成功
-
+
MetaDelNoItem
无元数据可删除
-
+
MetaClearSuccess
元数据清空完毕
-
+
FindResultExporting...
查找结果导出中...
-
-
+
+
EmptyFindResult
没有可导出的搜索结果!
-
+
SaveFindResult
导出搜索结果成功!
-
+
SaveFindResultError
导出结果失败!
-
+
TooManyBytesDecode
超出解码字节限制……
-
+
NoTextFileMayInvalid
该文件不是文本文件,以文本方式预览并不是一个好的方式,你确认继续吗?
-
+
LayoutSaving...
布局保存中...
-
+
+
PleaseInput
请输入
-
+
LogExporting...
日志导出中...
-
+
ExportLogError
导出日志失败!
-
+
ExportLogSuccess
导出日志成功,路径:
-
+
ClearLogSuccess
清空日志成功!
-
+
BadNetwork
无法与远程服务器的更新检查建立连接,请检查网络。
-
+
NewestVersion
当前软件为最新版本
-
-
+
+
OlderVersion
你使用的软件为老版本,建议到 Github 和 Gitee 的仓库发行版下载更新。
-
+
CheckingUpdate
检查更新中……
-
+
Too much opened files
打开的文件过多,无法继续操作!
-
+
FilePermissionSure2Quit
因文件权限无法保存,你确认要退出吗?
-
+
UnknownErrorSure2Quit
因未知错误无法保存,你确认要退出吗?
-
+
WorkSpaceUnSavedSure2Quit
工作区文件无法保存,你确认要退出吗?
-
+
CopyLimit
拷贝字节超出限制
-
+
ErrOpenFileBelow
打开文件出现错误(由于权限不足),如下为打开错误的文件:
diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts
index e443ec8..7156f66 100644
--- a/lang/zh_TW/winghex_zh_TW.ts
+++ b/lang/zh_TW/winghex_zh_TW.ts
@@ -478,12 +478,12 @@
書簽
-
+
Untitled
未命名
-
+
Not allowed operation in non-UI thread
該操作在非 UI 線程非法
@@ -865,18 +865,18 @@
MainWindow
-
+
File
檔
-
-
+
+
View
視圖
-
+
About
關於
@@ -897,317 +897,319 @@
選長:
-
+
Edit
編輯
-
+
Script
腳本
-
-
-
+
+
+
Plugin
插件
-
+
Setting
設置
-
-
+
+
Log
日誌
-
+
ExportFindResult
導出搜索結果
-
+
ClearFindResult
清空記錄
-
-
+
+
FindResult
搜索結果
-
-
-
-
+
+
+
+
Copy
複製
-
-
-
-
-
+
+
+
+
+
CopyToClipBoard
數據已拷貝到粘貼板
-
+
LittleEndian
小端
-
+
BigEndian
大端
-
+
Number
數值
-
-
+
+
CheckSum
校驗和
-
-
+
+
DeleteBookMark
刪除書簽
-
-
+
+
ClearBookMark
清空書簽
-
-
-
-
+
+
+
+
BookMark
書簽
-
-
+
+
DecodeText
解碼字串
-
+
ScriptConsole
腳本控制臺
-
-
+
+
Basic
基礎
-
+
New
新建
-
+
OpenF
打開檔
-
+
OpenWorkSpace
打開工作區
-
+
RecentFiles
最近打開
-
+
+
+
Reload
重新加載
-
-
+
+
Save
保存
-
+
SaveAs
另存為
-
+
ConvertWS
轉為工作區
-
+
Export
導出
-
+
SaveSel
保存選區位元組
-
-
-
-
+
+
+
+
General
基本
-
+
Undo
撤銷
-
+
Redo
恢復
-
+
Cut
剪切
-
+
Paste
粘貼
-
+
Delete
刪除
-
+
Clone
克隆
-
+
Lookup
查詢
-
+
Find
查找
-
+
Goto
跳轉
-
-
+
+
Encoding
編碼
-
+
FileInfo
檔資訊
-
-
+
+
Hex
十六進制
-
+
CutHex
剪切(十六進制)
-
+
CopyHex
複製(十六進制)
-
+
PasteHex
粘貼(十六進制)
-
-
+
+
Fill
填充
-
+
FillZero
填充零
-
-
-
-
-
+
+
+
+
+
MetaData
標注
-
+
DeleteMetadata
刪除標注
-
+
ClearMetadata
清空標注
-
+
MetaDataEdit
編輯標注
-
+
DeleteMetaData
刪除標注
-
+
ClearMetaData
清空標注
-
+
Display
顯示
-
+
ViewText
文本預覽
-
+
Scale
縮放
@@ -1242,781 +1244,793 @@
加載插件中:
-
+
SetupConsole
啟動腳本控制臺
-
+
SetupScriptManager
啟動腳本管理器
-
+
SetupScriptService
啟動腳本服務
-
+
SetupScriptEditor
構建腳本編輯器
-
+
SetupSetDialog
構建設置窗體
-
+
SetupPlgWidgets
啟動插件組件
-
+
SetupDockingLayout
恢復 Dock 佈局
-
+
SetupWaiting
啟動即將完成
-
+
SetupFinished
啟動完畢
-
+
NoExtension
無擴展
-
-
+
+
ExportResult
導出結果
-
+
NothingToSave
沒有保存的數據
-
+
OpenExt
打開 - 拓展
-
+
ResetScale
重置縮放
-
+
ShowMetafg
標注前景色
-
+
ShowMetabg
標注背景色
-
+
ShowMetaComment
批註
-
+
MetaShowAll
顯示所有標注
-
+
MetaHideAll
隱藏所有標注
-
+
FileStatus
檔狀態
-
+
InfoSave
是否保存
-
+
ReadOnly
可讀寫
-
+
SetLocked
啟用/禁用鎖定編輯
-
+
ErrUnLock
鎖定編輯失敗
-
+
SetOver
啟用/禁用改變大小
-
+
+ InputRequest
+
+
+
+
UnsignedHex
無符號 Hex
-
+
BgScriptOutput
後臺腳本輸出
-
+
ErrUnOver
鎖定檔大小失敗
-
+
Window
窗體
-
+
Editor
編輯器
-
+
Tools
工具
-
+
HexEditorLayout
編輯器佈局
-
+
SetBaseAddr
設置基址
-
+
addressBase
基址
-
+
inputAddressBase
請輸入基址
-
+
WarnBigBaseAddress
基址過大,你得到的地址將會不正確!
-
+
ErrBaseAddress
非法基址輸入
-
+
SetColInfo
顯示/隱藏地址欄
-
+
SetHeaderInfo
顯示/隱藏表頭
-
+
SetAsciiString
顯示/隱藏解碼字串
-
+
Layout
佈局
-
+
Fullscreen
全屏
-
+
Default
默認
-
-
-
+
+
+
LayoutRestoring...
恢復佈局中...
-
+
RestoreLayout
恢復佈局
-
-
+
+
SaveLayout
保存佈局
-
+
ExportLog
導出日誌
-
+
ClearLog
清空日誌
-
+
InsepctQt
監視 Qt
-
+
ScriptEditor
腳本編輯器
-
+
Scripts
腳本倉庫
-
+
PluginFunctions
插件功能
-
+
ScriptSetting
腳本設置
-
+
PluginSettings
插件設置
-
+
Info
資訊
-
+
Software
軟體
-
+
Sponsor
贊助
-
+
CheckUpdate
檢查更新
-
+
Wiki
網頁 Wiki
-
+
AboutQT
關於 QT
-
+
SetPageIDEmptyTryUseName
設置頁 ID 為空,嘗試使用名稱作為 ID
-
+
SetPageDupNameIgnored
設置頁重複的 ID 名稱,已忽略加載
-
+
Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3
插件 %1 包含重複 ID (%2),該 ID 已被插件 %3 註冊
-
-
+
+
ChooseFile
選擇檔
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error
錯誤
-
-
+
+
FileNotExist
檔不存在!
-
-
-
-
-
+
+
+
+
+
FilePermission
因檔許可權無法繼續!
-
+
ProjectFile (*.wingpro)
專案檔 (*.wingpro)
-
+
ReloadSuccessfully
檔重新加載成功!
-
+
ReloadUnSuccessfully
檔重新加載失敗!
-
-
-
-
+
+
+
+
ChooseSaveFile
請選擇保存檔路徑:
-
+
NoMoreClone
克隆已到上限,無法繼續操作!
-
+
FindFininishBusy
查找任務繁忙,請勿重複查找!
-
+
MayTooMuchFindResult
搜索數量已到達上限,結果可能不全,建議請按區段搜索。
-
+
SaveLayoutSuccess
保存佈局成功
-
+
SaveLayoutError
保存佈局失敗
-
+
HasClonedView
該編輯頁已被克隆編輯,如果關閉,相關聯的頁也會被關閉,你確認繼續嗎?
-
+
+
+ ReloadNeededYesOrNo
+
+
+
+
SaveWorkSpace
保存工作區
-
+
WingHexWorkSpace (*.wingpro)
羽雲十六進制工作區 (*.wingpro)
-
+
ConfirmSave
正在關閉未保存的檔或工作區,你確定保存嗎?
-
+
[Info]
【資訊】
-
+
[Warn]
【警告】
-
+
[Error]
【錯誤】
-
+
ConfirmAPPSave
你嘗試關閉程式,但仍存在未保存的檔或工作區,你確定保存這些更改嗎?
-
-
-
+
+
+
SaveSuccessfully
保存成功!
-
-
+
+
SaveWSError
保存工作區錯誤!
-
-
+
+
Warn
警告
-
+
Opening...
打開檔中...
-
+
WorkSpaceOpening...
打開工作區中...
-
+
Reloading...
重載檔中...
-
+
Saving...
保存中...
-
+
SaveNewFirst
請首先保存新建的檔
-
+
AlreadyWorkSpace
已經是工作區,無需轉化
-
+
ConvWorkSpaceFailed
轉化為工作區失敗
-
+
ConvWorkSpaceSuccess
轉化為工作區成功
-
+
SavingAs...
另存為中...
-
+
SaveUnSuccessfully
保存失敗!
-
+
Exporting...
導出中...
-
+
ChooseExportFile
請選擇導出檔路徑:
-
+
ExportSuccessfully
導出成功!
-
+
ExportUnSuccessfully
導出失敗!
-
+
SavingSel...
保存選中位元組中...
-
+
SaveSelSuccess
保存選區位元組成功!
-
+
SaveSelError
保存選區位元組失敗,因檔不具有可寫許可權!
-
-
+
+
CutToClipBoard
數據已剪切到粘貼板!
-
-
+
+
UnCutToClipBoard
由於保持大小限制,數據剪切到粘貼板失敗!
-
-
+
+
UnCopyToClipBoard
由於保持大小限制,數據剪切到複製板失敗!
-
-
+
+
Finding...
查找中...
-
+
DeleteSuccess
刪除成功
-
+
DeleteFailed
刪除失敗
-
+
FindFininish
查找結果完畢!
-
+
PleaseInputFill
請輸入填充位元組值
-
+
FillInputTruncWarn
填充輸入數值過大,將會被截斷填充
-
+
FillInputError
填充位元組輸入錯誤
-
-
+
+
InputComment
請輸入批註:
-
-
+
+
BookmarkDelSuccess
刪除書簽成功
-
+
BookmarkDelNoItem
無書簽可刪除
-
+
BookmarkClearSuccess
書簽清空完畢
-
-
-
+
+
+
NoSelection
沒有選區,無法繼續的操作!
-
+
NoMetaData
無可編輯標記
-
+
PleaseClearSel
請清空選擇
-
+
MetaDelSuccess
元數據刪除成功
-
+
MetaDelNoItem
無元數據可刪除
-
+
MetaClearSuccess
元數據清空完畢
-
+
FindResultExporting...
查找結果導出中...
-
-
+
+
EmptyFindResult
沒有可導出的搜索結果!
-
+
SaveFindResult
導出搜索結果成功!
-
+
SaveFindResultError
導出結果失敗!
-
+
TooManyBytesDecode
超出解碼位元組限制……
-
+
NoTextFileMayInvalid
該檔不是文本檔,以文本方式預覽並不是一個好的方式,你確認繼續嗎?
-
+
LayoutSaving...
佈局保存中...
-
+
+
PleaseInput
請輸入
-
+
LogExporting...
日誌導出中...
-
+
ExportLogError
導出日誌失敗!
-
+
ExportLogSuccess
導出日誌成功,路徑:
-
+
ClearLogSuccess
清空日誌成功!
-
+
BadNetwork
無法與遠程伺服器的更新檢查建立連接,請檢查網路。
-
+
NewestVersion
當前軟體為最新版本
-
-
+
+
OlderVersion
你使用的軟體為老版本,建議到 Github 和 Gitee 的倉庫發行版下載更新。
-
+
CheckingUpdate
檢查更新中……
-
+
Too much opened files
打開的檔過多,無法繼續操作!
-
+
FilePermissionSure2Quit
因檔許可權無法保存,你確認要退出嗎?
-
+
UnknownErrorSure2Quit
因未知錯誤無法保存,你確認要退出嗎?
-
+
WorkSpaceUnSavedSure2Quit
工作區檔無法保存,你確認要退出嗎?
-
+
CopyLimit
拷貝位元組超出限制
-
+
ErrOpenFileBelow
打開檔出現錯誤(由於許可權不足),如下為打開錯誤的檔:
diff --git a/src/class/angelobjstring.cpp b/src/class/angelobjstring.cpp
index 2076f60..758c2dc 100644
--- a/src/class/angelobjstring.cpp
+++ b/src/class/angelobjstring.cpp
@@ -69,7 +69,7 @@ QString AngelObjString::dictionaryToString(void *obj, asDebugger *dbg) {
auto engine = dic->GetEngine();
- s << " [";
+ s << " {";
asUINT n = 0;
for (CScriptDictionary::CIterator it = dic->begin(); it != dic->end();
it++, n++) {
@@ -88,7 +88,7 @@ QString AngelObjString::dictionaryToString(void *obj, asDebugger *dbg) {
if (n < dic->GetSize() - 1)
s << ", ";
}
- s << "]";
+ s << "}";
return str;
}
diff --git a/src/class/ascompletion.cpp b/src/class/ascompletion.cpp
index 0eee59b..868c42b 100644
--- a/src/class/ascompletion.cpp
+++ b/src/class/ascompletion.cpp
@@ -154,11 +154,6 @@ bool AsCompletion::processTrigger(const QString &trigger,
auto code = content.toUtf8();
QList nodes;
- QList docNodes;
-
- if (m_parseDocument) {
- docNodes = parseDocument();
- }
if (!trigger.isEmpty() && trigger != *DOT_TRIGGER) {
clearFunctionTip();
@@ -226,24 +221,35 @@ bool AsCompletion::processTrigger(const QString &trigger,
return false;
}
- QString prefix;
auto etoken = tokens.back();
+ // it can not be any trigger, so take the last as prefix
+ QString prefix = etoken.content;
if (etoken.type == asTC_VALUE || etoken.type == asTC_COMMENT ||
etoken.type == asTC_UNKNOWN) {
popup()->hide();
return false;
}
+ if (trigger.isEmpty() && popup()->isVisible()) {
+ setCompletionPrefix(prefix);
+ return true;
+ }
+
+ QList docNodes;
+ if (m_parseDocument) {
+ docNodes = parseDocument();
+ }
+
// if trigger is empty, it's making editing
if (trigger.isEmpty()) {
- // it can not be any trigger, so take the last as prefix
- prefix = etoken.content;
tokens.removeLast();
if (tokens.isEmpty()) {
applyEmptyNsNode(nodes, docNodes);
} else {
etoken = tokens.back(); // checking later
}
+ } else {
+ prefix.clear();
}
if (nodes.isEmpty()) {
@@ -266,8 +272,52 @@ bool AsCompletion::processTrigger(const QString &trigger,
}
if (trigger == *DOT_TRIGGER) {
- // member guessing ?
- applyClassNodes(nodes);
+ // member type guessing ? basic match is enough. (>n<)
+ auto isBasicType = [](const QString &type) {
+ static QStringList basicType{
+ "int", "int8", "int16", "int32", "int64",
+ "uint", "uint8", "uint16", "uint32", "uint64",
+ "float", "double", "byte"};
+
+ return basicType.contains(type);
+ };
+
+ auto clsNodes = parser.headerNodes();
+
+ // filter the type we can use to auto-complete in docNodes
+ for (auto &item : docNodes) {
+ if (item.type == CodeInfoTip::Type::Class) {
+ auto name = item.nameSpace;
+ if (name.isEmpty()) {
+ name = item.name;
+ }
+ clsNodes.insert(name, item.children);
+ }
+ // a typedef can only be used to define an alias
+ // for primitive types, so NO NEED for auto-completing
+ }
+
+ tokens.removeLast();
+ auto ns = getNamespace(tokens);
+ for (auto &item : docNodes) {
+ if (etoken.content == item.name && ns == item.nameSpace) {
+ auto retType = item.addinfo.value(CodeInfoTip::RetType);
+
+ // auto type inference is not supported.
+ // PRs will be welcomed !!!
+ if (isBasicType(retType)) {
+ popup()->hide();
+ return false;
+ }
+
+ nodes.append(clsNodes.value(retType));
+ break;
+ }
+ }
+
+ if (nodes.isEmpty()) {
+ applyClassNodes(nodes);
+ }
} else if (etoken.content.length() >= triggerAmount()) {
// completion for a.b.c or a::b.c or a::b::c.d or ::a::b.c
if (trigger == *DBL_COLON_TRIGGER) {
@@ -368,6 +418,7 @@ QList AsCompletion::parseDocument() {
va.dontAddGlobal = true;
va.name = var.name;
va.nameSpace = QString::fromUtf8(var.scope.join("::"));
+ va.addinfo.insert(CodeInfoTip::RetType, var.type);
va.type = CodeInfoTip::Type::Variable;
ret.append(va);
}
@@ -389,17 +440,47 @@ QList AsCompletion::parseDocument() {
}
break;
case QAsCodeParser::SymbolType::TypeDef:
- tip.type = CodeInfoTip::Type::KeyWord;
+ tip.type = CodeInfoTip::Type::TypeDef;
break;
case QAsCodeParser::SymbolType::Variable:
+ tip.addinfo.insert(CodeInfoTip::RetType, sym.type);
tip.type = CodeInfoTip::Type::Variable;
break;
case QAsCodeParser::SymbolType::Class:
case QAsCodeParser::SymbolType::Interface:
- tip.type = CodeInfoTip::Type::Class;
for (auto &mem : sym.children) {
- // TODO
+ if (mem.vis != QAsCodeParser::Visiblity::Public) {
+ continue;
+ }
+ CodeInfoTip ctip;
+ ctip.name = mem.name;
+ ctip.nameSpace = QString::fromUtf8(mem.scope.join("::"));
+ if (mem.symtype == QAsCodeParser::SymbolType::Function) {
+ ctip.type = CodeInfoTip::Type::Function;
+ ctip.addinfo.insert(CodeInfoTip::RetType,
+ QString::fromUtf8(mem.type));
+ ctip.addinfo.insert(
+ CodeInfoTip::Args,
+ QString::fromUtf8(mem.additonalInfo));
+ for (auto &var : mem.children) {
+ CodeInfoTip va;
+ va.dontAddGlobal = true;
+ va.name = var.name;
+ va.nameSpace =
+ QString::fromUtf8(var.scope.join("::"));
+ va.addinfo.insert(CodeInfoTip::RetType, var.type);
+ va.type = CodeInfoTip::Type::Variable;
+ tip.children.append(va);
+ }
+ tip.children.append(ctip);
+ } else if (mem.symtype ==
+ QAsCodeParser::SymbolType::Variable) {
+ ctip.addinfo.insert(CodeInfoTip::RetType, mem.type);
+ ctip.type = CodeInfoTip::Type::Variable;
+ tip.children.append(ctip);
+ }
}
+ tip.type = CodeInfoTip::Type::Class;
break;
case QAsCodeParser::SymbolType::Invalid:
case QAsCodeParser::SymbolType::Import:
diff --git a/src/class/codeinfotip.cpp b/src/class/codeinfotip.cpp
index c8c494f..673471d 100644
--- a/src/class/codeinfotip.cpp
+++ b/src/class/codeinfotip.cpp
@@ -36,6 +36,7 @@ QIcon CodeInfoTip::getDisplayIcon(Type type, CodeInfoVisibility vis) {
case Type::Group:
return icon(ICON_NAMESPACE);
case Type::Class:
+ case Type::TypeDef:
return icon(ICON_CLASS);
case Type::ClsFunction:
case Type::Function:
diff --git a/src/class/codeinfotip.h b/src/class/codeinfotip.h
index 7c17167..c9f4176 100644
--- a/src/class/codeinfotip.h
+++ b/src/class/codeinfotip.h
@@ -36,6 +36,7 @@ public:
Variable,
Property = Variable,
Enumerater,
+ TypeDef
};
enum CacheIndex {
diff --git a/src/class/ctypeparser.cpp b/src/class/ctypeparser.cpp
index 742644a..22d23a1 100644
--- a/src/class/ctypeparser.cpp
+++ b/src/class/ctypeparser.cpp
@@ -151,6 +151,9 @@ void CTypeParser::initialize() {
ADD_TYPE(longlong, QMetaType::LongLong);
ADD_TYPE_U(ulonglong, QMetaType::ULongLong);
+ using uint = unsigned int;
+ ADD_TYPE_U(uint, QMetaType::UInt);
+
using BOOL = bool;
using BYTE = byte;
using WORD = uint16;
@@ -242,6 +245,8 @@ void CTypeParser::initialize() {
#undef ADD_TYPE
#undef ADD_TYPE_S
+
+ base_types_ = type_maps_.keys();
}
void CTypeParser::setIncludePaths(const QStringList &paths) {
@@ -627,7 +632,7 @@ TokenTypes CTypeParser::getTokenType(const QString &token) const {
return keywords_.value(token);
} else if (qualifiers_.contains(token)) {
return kQualifier;
- } else if (type_maps_.contains(token)) {
+ } else if (base_types_.contains(token)) {
return kBasicDataType;
} else if (struct_defs_.contains(token)) {
return kStructName;
diff --git a/src/class/ctypeparser.h b/src/class/ctypeparser.h
index bce5f61..62430da 100644
--- a/src/class/ctypeparser.h
+++ b/src/class/ctypeparser.h
@@ -211,6 +211,9 @@ private:
/// @note All enum types have fixed size, so they're not stored
QHash> type_maps_;
+ /// basic types
+ QStringList base_types_;
+
/// unsigned types
QStringList unsigned_types_;
diff --git a/src/class/qascodeparser.cpp b/src/class/qascodeparser.cpp
index 76bb720..0c34f32 100644
--- a/src/class/qascodeparser.cpp
+++ b/src/class/qascodeparser.cpp
@@ -119,12 +119,26 @@ QAsCodeParser::parseIntell(qsizetype offset,
continue;
}
break;
- case SymbolType::Class:
- sym.children = parseClassContent(offset, sym.scope, seg.codes);
- break;
- case SymbolType::Interface:
- sym.children = parseInterfaceContent(offset, sym.scope, seg.codes);
- break;
+ case SymbolType::Class: {
+ auto syms =
+ parseClassContent(offset - seg.offset, sym.scope, seg.codes);
+ // TODO: PRS, 'cause i have no need to code-complete a class
+ sym.inherit = syms.first;
+ sym.children = syms.second;
+ if (offset > seg.offset && offset < seg.end()) {
+ ret.append(syms.second);
+ }
+ } break;
+ case SymbolType::Interface: {
+ auto syms = parseInterfaceContent(offset - seg.offset, sym.scope,
+ seg.codes);
+ // TODO: PRS, 'cause i have no need to code-complete an interface
+ sym.inherit = syms.first;
+ sym.children = syms.second;
+ if (offset > seg.offset && offset < seg.end()) {
+ ret.append(syms.second);
+ }
+ } break;
case SymbolType::Invalid:
case SymbolType::Import:
continue;
@@ -510,7 +524,8 @@ QAsCodeParser::parseStatementBlock(const QByteArrayList &ns,
QList ret;
for (auto &symlist : syms) {
for (auto &sym : symlist) {
- if (sym.symtype == SymbolType::Variable) {
+ if (sym.symtype == SymbolType::Variable &&
+ !sym.type.isEmpty()) {
auto var = sym.name;
auto n = std::find_if(
ret.begin(), ret.end(),
@@ -940,13 +955,14 @@ QAsCodeParser::CodeSegment QAsCodeParser::parseFuncDef() {
auto begin = t1.pos;
skipCodeBlock();
getToken(&t1);
+ rewindTo(&t1);
auto end = t1.pos;
// seg.name is empty
seg.scope = currentNs;
seg.offset = begin;
seg.type = SymbolType::FnDef;
- seg.codes = _code.sliced(begin, end - begin + 1);
+ seg.codes = _code.sliced(begin, end - begin);
return seg;
}
@@ -1027,6 +1043,7 @@ void QAsCodeParser::superficiallyParseVarInit() {
} while (indentParan || indentBrace ||
(t.type != ttListSeparator && t.type != ttEndStatement &&
t.type != ttEndStatementBlock));
+ rewindTo(&t);
} else if (t.type == ttOpenParenthesis) {
sToken start = t;
@@ -1308,6 +1325,7 @@ QAsCodeParser::CodeSegment QAsCodeParser::parseTypedef() {
auto begin = token.pos;
skipCodeBlock();
getToken(&token);
+ rewindTo(&token);
auto end = token.pos;
// seg.name is empty
@@ -1423,22 +1441,27 @@ QAsCodeParser::parseGlobalVarDecls(const QByteArrayList &ns,
return parseDeclaration(ns, false, true);
}
-QAsCodeParser::CodeSegment QAsCodeParser::parseFunctionMethod() {
+QAsCodeParser::CodeSegment QAsCodeParser::parseFunctionMethod(Visiblity &vis) {
CodeSegment seg;
sToken t1;
getToken(&t1);
+ vis = Visiblity::Public;
+
// A class method can start with 'private' or 'protected'
if (t1.type == ttPrivate) {
rewindTo(&t1);
parseToken(ttPrivate);
getToken(&t1);
+ vis = Visiblity::Private;
} else if (t1.type == ttProtected) {
rewindTo(&t1);
parseToken(ttProtected);
getToken(&t1);
+ vis = Visiblity::Protected;
}
+
if (_isSyntaxError)
return seg;
@@ -1530,12 +1553,13 @@ QAsCodeParser::parseFuncDefContent(const QByteArrayList &ns,
return parseFuncDefContent(ns);
}
-QList
+QPair>
QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
const QByteArray &code) {
reset();
_code = code;
+ QByteArrayList inhertSyms;
QList syms;
sToken t;
@@ -1544,32 +1568,30 @@ QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
// Optional list of interfaces that are being implemented and classes that
// are being inherited
if (t.type == ttColon) {
- Symbol inhertSym;
+ QByteArray inhertSym;
// assuming it as an interface
- inhertSym.symtype = SymbolType::Interface;
-
- Symbol isym;
- isym.scope = parseOptionalScope();
- isym.name = getSymbolString(parseIdentifier());
- isym.symtype = SymbolType::Class; // assuming it as a class
-
- inhertSym.children.append(isym);
-
+ inhertSym = parseOptionalScope().join("::");
+ if (!inhertSym.isEmpty()) {
+ inhertSym += "::";
+ }
+ inhertSym += getSymbolString(parseIdentifier());
+ inhertSyms.append(inhertSym);
getToken(&t);
while (t.type == ttListSeparator) {
- isym.scope = parseOptionalScope();
- isym.name = getSymbolString(parseIdentifier());
- inhertSym.children.append(isym);
+ inhertSym = parseOptionalScope().join("::");
+ if (!inhertSym.isEmpty()) {
+ inhertSym += "::";
+ }
+ inhertSym += getSymbolString(parseIdentifier());
+ inhertSyms.append(inhertSym);
getToken(&t);
}
-
- syms.append(inhertSym);
}
if (t.type != ttStartStatementBlock) {
rewindErrorTo(&t);
- return syms;
+ return {inhertSyms, syms};
}
// Parse properties
@@ -1581,11 +1603,11 @@ QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
auto fndef = parseFuncDefContent(ns);
syms.append(fndef);
} else if (isFuncDecl(true)) {
- auto fn = parseFunctionMethod();
+ Symbol sym;
+ auto fn = parseFunctionMethod(sym.vis);
// add function symbols
- Symbol sym;
- sym.symtype = fn.type;
+ sym.symtype = SymbolType::Function;
sym.scope = fn.scope;
sym.offset = fn.offset;
sym.name = fn.name;
@@ -1595,7 +1617,8 @@ QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
// deep parsing
if (offset >= fn.offset && offset < fn.end()) {
- auto ss = parseStatementBlock(fn.scope, fn.codes, offset);
+ auto ss =
+ parseStatementBlock(fn.scope, fn.codes, offset - fn.offset);
syms.append(ss);
}
} else if (isVirtualPropertyDecl()) {
@@ -1609,11 +1632,11 @@ QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
getToken(&t);
else {
rewindErrorTo(&t);
- return syms;
+ return {inhertSyms, syms};
}
if (_isSyntaxError)
- return syms;
+ return {inhertSyms, syms};
getToken(&t);
rewindTo(&t);
@@ -1622,15 +1645,16 @@ QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
getToken(&t);
if (t.type != ttEndStatementBlock) {
rewindErrorTo(&t);
- return syms;
+ return {inhertSyms, syms};
}
- return syms;
+ return {inhertSyms, syms};
}
-QList
+QPair>
QAsCodeParser::parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
const QByteArray &code) {
+ QByteArrayList inhertSyms;
QList syms;
sToken t;
@@ -1638,12 +1662,22 @@ QAsCodeParser::parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
getToken(&t);
// Can optionally have a list of interfaces that are inherited
if (t.type == ttColon) {
- parseOptionalScope();
- parseIdentifier();
+ QByteArray inhertSym;
+
+ inhertSym = parseOptionalScope().join("::");
+ if (!inhertSym.isEmpty()) {
+ inhertSym += "::";
+ }
+ inhertSym += getSymbolString(parseIdentifier());
+ inhertSyms.append(inhertSym);
getToken(&t);
while (t.type == ttListSeparator) {
- parseOptionalScope();
- parseIdentifier();
+ inhertSym = parseOptionalScope().join("::");
+ if (!inhertSym.isEmpty()) {
+ inhertSym += "::";
+ }
+ inhertSym += getSymbolString(parseIdentifier());
+ inhertSyms.append(inhertSym);
getToken(&t);
}
}
@@ -1670,7 +1704,7 @@ QAsCodeParser::parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
}
if (_isSyntaxError)
- return syms;
+ return {inhertSyms, syms};
getToken(&t);
rewindTo(&t);
@@ -1679,10 +1713,10 @@ QAsCodeParser::parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
getToken(&t);
if (t.type != ttEndStatementBlock) {
rewindErrorTo(&t);
- return syms;
+ return {inhertSyms, syms};
}
- return syms;
+ return {inhertSyms, syms};
}
QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() {
diff --git a/src/class/qascodeparser.h b/src/class/qascodeparser.h
index bfd6742..132dd2f 100644
--- a/src/class/qascodeparser.h
+++ b/src/class/qascodeparser.h
@@ -90,6 +90,7 @@ public:
Visiblity vis = QAsCodeParser::Visiblity::Public;
QByteArray additonalInfo; // for other additonal info
+ QByteArrayList inherit;
QList children;
};
@@ -134,7 +135,7 @@ private:
CodeSegment parseInterface();
CodeSegment parseFuncDef();
CodeSegment parseFunction();
- CodeSegment parseFunctionMethod();
+ CodeSegment parseFunctionMethod(Visiblity &vis);
private:
// parse tokens
@@ -172,12 +173,13 @@ private:
Symbol parseFuncDefContent(const QByteArrayList &ns);
- QList parseClassContent(qsizetype offset, const QByteArrayList &ns,
- const QByteArray &code);
+ QPair>
+ parseClassContent(qsizetype offset, const QByteArrayList &ns,
+ const QByteArray &code);
- QList parseInterfaceContent(qsizetype offset,
- const QByteArrayList &ns,
- const QByteArray &code);
+ QPair>
+ parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
+ const QByteArray &code);
QList parseStatementBlock(const QByteArrayList &ns,
const QByteArray &code, qsizetype end);
diff --git a/src/control/editorview.cpp b/src/control/editorview.cpp
index e05b0ab..95b914d 100644
--- a/src/control/editorview.cpp
+++ b/src/control/editorview.cpp
@@ -121,6 +121,9 @@ EditorView::EditorView(QWidget *parent)
m_metadata->setDocument(doc);
});
+ connect(&_watcher, &QFileSystemWatcher::fileChanged, this,
+ &EditorView::need2Reload);
+
applySettings();
// build up call tables
@@ -284,6 +287,9 @@ ErrFile EditorView::newFile(size_t index) {
if (isCloneFile()) {
return ErrFile::ClonedFile;
}
+ if (!m_fileName.isEmpty()) {
+ _watcher.removePath(m_fileName);
+ }
auto istr = QString::number(index);
m_fileName = tr("Untitled") + istr;
this->setWindowTitle(m_fileName);
@@ -320,6 +326,10 @@ ErrFile EditorView::openFile(const QString &filename) {
return ErrFile::Permission;
}
+ if (!m_fileName.isEmpty()) {
+ _watcher.removePath(m_fileName);
+ }
+
m_hex->setDocument(QSharedPointer(p));
m_hex->setLockedFile(readonly);
m_hex->setKeepSize(true);
@@ -335,6 +345,8 @@ ErrFile EditorView::openFile(const QString &filename) {
auto tab = this->tabWidget();
tab->setIcon(Utilities::getIconFromFile(style(), m_fileName));
tab->setToolTip(m_fileName);
+
+ _watcher.addPath(m_fileName);
}
return ErrFile::Success;
@@ -372,6 +384,10 @@ ErrFile EditorView::openExtFile(const QString &ext, const QString &file) {
return ErrFile::Error;
}
+ if (!m_fileName.isEmpty()) {
+ _watcher.removePath(m_fileName);
+ }
+
m_hex->setDocument(QSharedPointer(p));
m_hex->setLockedFile(readonly);
m_hex->setKeepSize(true);
@@ -562,10 +578,14 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
file.close();
if (!isExport) {
+ if (!m_fileName.isEmpty()) {
+ _watcher.removePath(m_fileName);
+ }
m_fileName = QFileInfo(fileName).absoluteFilePath();
m_isNewFile = false;
m_docType = DocumentType::File;
doc->setDocSaved();
+ _watcher.addPath(m_fileName);
}
#ifdef Q_OS_LINUX
adjustPermission();
diff --git a/src/control/editorview.h b/src/control/editorview.h
index e382811..405884e 100644
--- a/src/control/editorview.h
+++ b/src/control/editorview.h
@@ -18,6 +18,7 @@
#ifndef EDITORVIEW_H
#define EDITORVIEW_H
+#include
#include
#include
@@ -553,6 +554,8 @@ signals:
void sigOnMetadata();
void sigOnBookMark();
+ void need2Reload();
+
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
@@ -589,6 +592,7 @@ private:
QReadWriteLock _rwlock;
CallTable _viewFns;
+ QFileSystemWatcher _watcher;
};
#endif // EDITORVIEW_H
diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp
index 08df9d5..7648947 100644
--- a/src/dialog/mainwindow.cpp
+++ b/src/dialog/mainwindow.cpp
@@ -245,7 +245,8 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
sm.registerCallBack(ScriptMachine::Interactive, callbacks);
callbacks.getInputFn = [this]() -> QString {
- return WingInputDialog::getText(this, tr(""), tr(""));
+ return WingInputDialog::getText(this, tr("InputRequest"),
+ tr("PleaseInput"));
};
callbacks.clearFn = [this]() { m_bgScriptOutput->clear(); };
callbacks.printMsgFn =
@@ -3162,6 +3163,22 @@ void MainWindow::connectEditorView(EditorView *editor) {
connect(editor, &EditorView::sigOnPasteHex, this, &MainWindow::on_pastehex);
connect(editor, &EditorView::sigOnPasteFile, this,
&MainWindow::on_pastefile);
+
+ editor->setProperty("__RELOAD__", false);
+ connect(editor, &EditorView::need2Reload, this, [editor, this]() {
+ if (editor->isBigFile()) {
+ editor->reload();
+ }
+ if (currentEditor() == editor) {
+ auto ret = WingMessageBox::question(this, tr("Reload"),
+ tr("ReloadNeededYesOrNo"));
+ if (ret == QMessageBox::Yes) {
+ editor->reload();
+ }
+ } else {
+ editor->setProperty("__RELOAD__", true);
+ }
+ });
}
void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
@@ -3188,6 +3205,15 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
Q_ASSERT(cur);
auto hexeditor = cur->hexEditor();
+ auto needReload = cur->property("__RELOAD__").toBool();
+ if (needReload) {
+ auto ret = WingMessageBox::question(this, tr("Reload"),
+ tr("ReloadNeededYesOrNo"));
+ if (ret == QMessageBox::Yes) {
+ cur->reload();
+ }
+ cur->setProperty("__RELOAD__", false);
+ }
connect(hexeditor, &QHexView::cursorLocationChanged, this,
&MainWindow::on_locChanged);
connect(hexeditor, &QHexView::cursorSelectionChanged, this,