diff --git a/.gitmodules b/.gitmodules index edc82ff..829ad49 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,6 @@ path = 3rdparty/AngelScript url = git@github.com:Wing-summer/AngelScript.git branch=stable +[submodule "3rdparty/cpptrace"] + path = 3rdparty/cpptrace + url = git@github.com:Wing-summer/cpptrace.git diff --git a/3rdparty/cpptrace b/3rdparty/cpptrace new file mode 160000 index 0000000..6689d14 --- /dev/null +++ b/3rdparty/cpptrace @@ -0,0 +1 @@ +Subproject commit 6689d14c203eed390ae7bb64f56a983cfd7dff9c diff --git a/3rdparty/qcodeedit2/lib/qeditor.cpp b/3rdparty/qcodeedit2/lib/qeditor.cpp index 8127742..df51279 100644 --- a/3rdparty/qcodeedit2/lib/qeditor.cpp +++ b/3rdparty/qcodeedit2/lib/qeditor.cpp @@ -2037,8 +2037,6 @@ void QEditor::createSimpleBasicContextMenu(bool shortcut, bool extTool) { a->setObjectName("paste"); if (shortcut) Q_SHORTCUT(a, "Ctrl+V", "Edit"); - connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, - SLOT(checkClipboard())); connect(a, SIGNAL(triggered()), this, SLOT(paste())); diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e8b297..82a7603 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,19 @@ find_package( Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network Concurrent PrintSupport Xml LinguistTools) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message("Build ${PROJECT_NAME} with ${CMAKE_BUILD_TYPE}.") +elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + message("Build ${PROJECT_NAME} with ${CMAKE_BUILD_TYPE}.") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message( + WARNING + "${PROJECT_NAME}'s stacktrace won't work built with ${CMAKE_BUILD_TYPE}." + ) +else() + message(FATAL_ERROR "Unsupported build type!") +endif() + install(CODE "set(CMAKE_INSTALL_LOCAL_ONLY TRUE)" ALL_COMPONENTS) option(BUILD_TEST_PLUGIN OFF) @@ -72,6 +85,7 @@ set(ADS_VERSION 4.3.1) option(BUILD_EXAMPLES "Build the examples" FALSE) option(BUILD_STATIC "Build the static library" TRUE) +add_subdirectory(3rdparty/cpptrace) add_subdirectory(3rdparty/QHexView) add_subdirectory(3rdparty/qcodeedit2) add_subdirectory(3rdparty/Qt-Advanced-Docking-System) @@ -158,7 +172,10 @@ set(DIALOG_SRC src/dialog/splashdialog.h src/dialog/historydeldialog.h src/dialog/historydeldialog.cpp - src/dialog/historydeldialog.ui) + src/dialog/historydeldialog.ui + src/dialog/crashreport.h + src/dialog/crashreport.cpp + src/dialog/crashreport.ui) set(CONTROL_SRC src/control/editorview.h @@ -195,7 +212,6 @@ set(CONTROL_SRC set(CLASS_SRC src/class/logger.cpp src/class/logger.h - src/class/scopeguard.h src/class/skinmanager.cpp src/class/skinmanager.h src/class/workspacemanager.cpp @@ -264,7 +280,9 @@ set(CLASS_SRC src/class/dockcomponentsfactory.cpp src/class/diffutil.h src/class/diffutil.cpp - src/class/clickcallback.h) + src/class/clickcallback.h + src/class/crashhandler.h + src/class/crashhandler.cpp) set(INTERNAL_PLG_SRC src/class/wingangelapi.h src/class/wingangelapi.cpp @@ -502,6 +520,7 @@ target_link_libraries( Qt${QT_VERSION_MAJOR}::GuiPrivate Qt${QT_VERSION_MAJOR}::CorePrivate Qt${QT_VERSION_MAJOR}::Xml + cpptrace::cpptrace QtSingleApplication::QtSingleApplication QHexView QCodeEditor2 diff --git a/TestPlugin/lang/TestPlugin_zh_CN.ts b/TestPlugin/lang/TestPlugin_zh_CN.ts index 04a86bb..dfb4c98 100644 --- a/TestPlugin/lang/TestPlugin_zh_CN.ts +++ b/TestPlugin/lang/TestPlugin_zh_CN.ts @@ -296,59 +296,60 @@ TestPlugin - + Test 测试 - - - + + + TestPlugin 测试插件 - + Button - 按钮 - - + Click 点击 - + A Test Plugin for WingHexExplorer2. 一个用来测试羽云十六进制编辑器2的插件 - - + - - - - - - - - - - + + + + + + + + + + + + InvalidParamsCount 无效参数个数 - - + + InvalidParam 非法参数 - + AllocArrayFailed 分配数组失败 diff --git a/TestPlugin/testplugin.cpp b/TestPlugin/testplugin.cpp index 52f190c..a49cbdf 100644 --- a/TestPlugin/testplugin.cpp +++ b/TestPlugin/testplugin.cpp @@ -166,6 +166,15 @@ TestPlugin::TestPlugin() : WingHex::IWingPlugin() { info.ret = MetaType::Bool; _scriptInfo.insert(QStringLiteral("pluginMetaTestEnabled"), info); } + + { + WingHex::IWingPlugin::ScriptFnInfo info; + info.fn = std::bind( + QOverload::of(&TestPlugin::testCrash), this, + std::placeholders::_1); + info.ret = MetaType::Void; + _scriptInfo.insert(QStringLiteral("testCrash"), info); + } } TestPlugin::~TestPlugin() { destoryTestShareMem(); } @@ -437,10 +446,10 @@ TestPlugin::colorTable(const QList ¶ms) { } auto invoked = - emit invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray", - WINGAPI_RETURN_ARG(void *, array), - WINGAPI_ARG(MetaType, MetaType::Color), - WINGAPI_ARG(QVector, colors)); + invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray", + WINGAPI_RETURN_ARG(void *, array), + WINGAPI_ARG(MetaType, MetaType::Color), + WINGAPI_ARG(QVector, colors)); if (invoked) { if (array) { qDeleteAll(colors); @@ -496,6 +505,14 @@ QVariant TestPlugin::pluginMetaTestEnabled(const QVariantList ¶ms) { return pluginMetaTestEnabled(); } +QVariant TestPlugin::testCrash(const QVariantList ¶ms) { + if (!params.isEmpty()) { + return getScriptCallError(-1, tr("InvalidParamsCount")); + } + testCrash(); + return {}; +} + void TestPlugin::test_a() { emit debug(__FUNCTION__); } void TestPlugin::test_b(const QString &b) { @@ -604,6 +621,15 @@ void TestPlugin::setPluginMetaTestEnabled(bool b) { bool TestPlugin::pluginMetaTestEnabled() { return ENABLE_META; } +void TestPlugin::testCrash() { + // if you want to reproduce nullptr deferenced, + // you can use this example. 'volatile' is important in release mode + // volatile int *a = nullptr; + // (*a)++; + + abort(); +} + QHash TestPlugin::registeredScriptFns() const { return _scriptInfo; diff --git a/TestPlugin/testplugin.h b/TestPlugin/testplugin.h index a2d0eab..15f4307 100644 --- a/TestPlugin/testplugin.h +++ b/TestPlugin/testplugin.h @@ -91,6 +91,8 @@ private: QVariant setPluginMetaTestEnabled(const QVariantList ¶ms); QVariant pluginMetaTestEnabled(const QVariantList ¶ms); + QVariant testCrash(const QVariantList ¶ms); + private: void test_a(); void test_b(const QString &b); @@ -110,6 +112,8 @@ private: void setPluginMetaTestEnabled(bool b); bool pluginMetaTestEnabled(); + void testCrash(); + private: QDialog *_tform = nullptr; QMenu *_tmenu = nullptr; diff --git a/images/crashicon.png b/images/crashicon.png new file mode 100644 index 0000000..f1352e8 Binary files /dev/null and b/images/crashicon.png differ diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts index 705133f..aaad219 100644 --- a/lang/zh_CN/winghex_zh_CN.ts +++ b/lang/zh_CN/winghex_zh_CN.ts @@ -74,25 +74,25 @@ AppManager - + GenericCallNotFullySupported 该软件脚本系统不完全支持通用调用,故软件将会退出。 - + SetupClang 启动 Clang 服务 - + OpeningFiles 打开文件 - - - - + + + + AlreadyOpened 文件已被打开 @@ -219,6 +219,24 @@ 颜色选择器 + + CrashReport + + + CrashReport + + + + + <html><head/><body><p><span style=" font-size:12pt; font-weight:700;">Opps! The software has crashed! Please send the information below to the dev:</span></p></body></html> + + + + + CopyToClipBoard + 数据已拷贝到粘贴板 + + DbgCallStackModel @@ -314,67 +332,67 @@ EditorView - + Cut 剪切 - + CutHex 剪切(十六进制) - + Copy 复制 - + CopyHex 复制(十六进制) - + Paste 粘贴 - + PasteHex 粘贴(十六进制) - + Delete 删除 - + Find 查找 - + Goto 跳转 - + Fill 填充 - + MetaData 标注 - + BookMark 书签 - + Untitled 未命名 @@ -786,1188 +804,1188 @@ MainWindow - + File 文件 - - + + View 视图 - + About 关于 - + WingHexExplorer 羽云十六进制编辑器 - + loc: 坐标: - + sel: 选长: - + Edit 编辑 - + Script 脚本 - - - + + + Plugin 插件 - + Setting 设置 - - + + Log 日志 - + ExportFindResult 导出搜索结果 - + ClearFindResult 清空记录 - - + + FindResult 搜索结果 - - - - - - - + + + + + + + Copy 复制 - - - - - - - - + + + + + + + + CopyToClipBoard 数据已拷贝到粘贴板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 数值 - - + + CheckSum 校验和 - - + + DeleteBookMark 删除书签 - - + + ClearBookMark 清空书签 - - - - + + + + BookMark 书签 - - + + DecodeText 解码字符串 - + ScriptConsole 脚本控制台 - - + + DVList 可视化列表 - - + + DVTree 可视化树数据 - - + + DVTable 可视化表格 - - + + DVText 可视化文本 - - + + 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 缩放 - + SetupRecent 启动最近文件服务 - + SetupUI 初始化界面 - + SetupDocking 启动 Dock 服务 - + LaunchingLog 启动日志系统 - + SetupPluginSystem 启动插件系统 - + LoadingPlg: 加载插件中: - + SetupConsole 启动脚本控制台 - + SetupScriptManager 启动脚本管理器 - + SetupScriptService 启动脚本服务 - + SetupScriptEditor 构建脚本编辑器 - + SetupSetDialog 构建设置窗体 - + SetupPlgWidgets 启动插件组件 - + SetupDockingLayout 恢复 Dock 布局 - + SetupWaiting 启动即将完成 - + SetupFinished 启动完毕 - + NoExtension 无扩展 - - - - - - + + + + + + ExportResult 导出结果 - - - + + + NothingToSave 没有保存的数据 - - - - + + + + ClearResult 清空结果 - + OpenExt 打开 - 拓展 - + ResetScale 重置缩放 - + ShowMetafg 标注前景色 - + ShowMetabg 标注背景色 - + ShowMetaComment 批注 - + MetaShowAll 显示所有标注 - + MetaHideAll 隐藏所有标注 - + FileStatus 文件状态 - - + + InfoSave 是否保存 - - + + ReadOnly 可读写 - - + + SetLocked 启用/禁用锁定编辑 - + ErrUnLock 锁定编辑失败 - - + + SetOver 启用/禁用改变大小 - + ErrUnOver 锁定文件大小失败 - + Window 窗体 - + Editor 编辑器 - + Tools 工具 - + HexEditorLayout 编辑器布局 - + SetBaseAddr 设置基址 - + addressBase 基址 - + inputAddressBase 请输入基址 - + WarnBigBaseAddress 基址过大,你得到的地址将会不正确! - + ErrBaseAddress 非法基址输入 - + SetColInfo 显示/隐藏地址栏 - + SetHeaderInfo 显示/隐藏表头 - + SetAsciiString 显示/隐藏解码字符串 - + Layout 布局 - + Fullscreen 全屏 - + Default 默认 - - - + + + LayoutRestoring... 恢复布局中... - + RestoreLayout 恢复布局 - - + + SaveLayout 保存布局 - + ExportLog 导出日志 - + ClearLog 清空日志 - + 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 + 文件不存在! + - - - - - - - - - - - - - - - - - - - - Error - 错误 - - - - - FileNotExist - 文件不存在! - - - - - - - - - - + + + + + FilePermission 因文件权限无法继续! - + ProjectFile (*.wingpro) 项目文件 (*.wingpro) - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - - - - - - - + + + + + + + ChooseSaveFile 请选择保存文件路径: - + NoMoreClone 克隆已到上限,无法继续操作! - + FindFininishBusy 查找任务繁忙,请勿重复查找! - + MayTooMuchFindResult 搜索数量已到达上限,结果可能不全,建议请按区段搜索。 - + SaveLayoutSuccess 保存布局成功 - + SaveLayoutError 保存布局失败 - + HasClonedView 该编辑页已被克隆编辑,如果关闭,相关联的页也会被关闭,你确认继续吗? - + SaveWorkSpace 保存工作区 - + WingHexWorkSpace (*.wingpro) 羽云十六进制工作区 (*.wingpro) - + ConfirmSave 正在关闭未保存的文件或工作区,你确定保存吗? - + Column %1 列 %1 - + ConfirmAPPSave 你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗? - - - - - - + + + + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作区错误! - + Warn 警告 - + ScriptObjShow 脚本对象 - + 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 超出解码字节限制…… - + LayoutSaving... 布局保存中... - + PleaseInput 请输入 - + LogExporting... 日志导出中... - + ExportLogError 导出日志失败! - + ExportLogSuccess 导出日志成功,路径: - + ClearLogSuccess 清空日志成功! - + BadNetwork 无法与远程服务器的更新检查建立连接,请检查网络。 - + NewestVersion 当前软件为最新版本 - - + + OlderVersion 你使用的软件为老版本,建议到 Github 和 Gitee 的仓库发行版下载更新。 - + CheckingUpdate 检查更新中…… - + Too much opened files 打开的文件过多,无法继续操作! - + FilePermissionSure2Quit 因文件权限无法保存,你确认要退出吗? - + UnknownErrorSure2Quit 因未知错误无法保存,你确认要退出吗? - + WorkSpaceUnSavedSure2Quit 工作区文件无法保存,你确认要退出吗? - + CopyLimit 拷贝字节超出限制 - + ErrOpenFileBelow 打开文件出现错误(由于权限不足),如下为打开错误的文件: @@ -2198,210 +2216,210 @@ PluginSystem - + LoadingPlugin 加载插件中: - + InvalidPluginBrokenInfo 加载插件失败:损坏的插件数据 - + AppClosingCanceled: 程序关闭被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 总计发现设备拓展插件数目: - + RegisterScriptFnUnSupportedTypes: 因脚本函数含有未支持的类型而注册失败: - - + + RegisterScriptFnInvalidSig: 因脚本函数签名非法而注册失败: - - + + RegisterScriptFnConflitSig: 因脚本函数签名冲突而注册失败: - + InvalidEnumName: 非法枚举名: - + InvalidEnumValue: 非法枚举值: - + InvalidMarcosRegister: 非法宏注册: - + ErrLoadPluginSign 插件加载失败:非法插件签名! - + ErrLoadPluginSDKVersion 插件加载失败:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加载失败:非法插件名称! - + ErrLoadInitPlugin 插件加载失败:初始化插件失败! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 注册插件对象中…… - + ErrLoadExtPluginSign 设备拓展插件加载失败:非法插件签名! - + ErrLoadExtPluginSDKVersion 设备拓展插件加载失败:非法插件 SDK 版本! - + ExtPluginAuthor : 设备拓展插件作者: - + ExtPluginWidgetRegister 设备拓展注册插件对象中…… - + ErrLoadInitExtPlugin 设备拓展插件加载失败:初始化插件失败! - + ChooseFile 选择文件 - - + + Error 错误 - + FileNotExist 文件不存在! - + FilePermission 因文件权限无法继续! - + EmptyNameDockWidget: 空的贴边组件名: - + InvalidNameDockWidget: 无效贴边组件名: - + InvalidNullDockWidget: 无效空贴边组件: - + [EvilCall] 【恶意调用】 - + Not allowed operation in non-UI thread 该操作在非 UI 线程非法 - + UnsafePluginDir 不安全的插件目录,请将插件目录设置为仅管理员账户可写 - + InvalidPluginID 加载插件失败:非法插件标识符 - + InvalidDupPlugin 加载插件失败:重复的插件标识符 - + FoundPluginCount 总计发现插件数目: - + PluginLoadingFailedSummary 有依赖插件加载失败总结 - + - Dependencies: - 依赖: - + PUID: 插件唯一标志符: - + Version: 版本: - + PluginLoadingFinished 加载插件完毕! @@ -2645,27 +2663,27 @@ Restart from the begining ? - + &Find 查找(&F) - + Fin&d next 查找下一个(&D) - + &Replace 替换(&R) - + &Goto line... 跳转到行(&G) @@ -2707,7 +2725,7 @@ Do you wish to keep up to date by reloading the file? 您是否希望通过重新加载文件来保持最新状态? - + untitled 未命名 @@ -5020,10 +5038,10 @@ Do you wish to keep up to date by reloading the file? - - - - + + + + Error 错误 @@ -5053,58 +5071,58 @@ Do you wish to keep up to date by reloading the file? 运行中... - - + + ChooseFile 选择文件 - - + + FilePermission 因文件权限无法继续! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - + ChooseSaveFile 请选择保存文件路径: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失败! - + FormatCodeFailed 代码格式化失败 - - + + CannotSave2RunScript 无法保存,故无法继续运行脚本。 - + ScriptStillRunning 脚本仍在运行,你确定要退出吗? diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts index 8e34f08..f7e64f6 100644 --- a/lang/zh_TW/winghex_zh_TW.ts +++ b/lang/zh_TW/winghex_zh_TW.ts @@ -74,25 +74,25 @@ AppManager - + GenericCallNotFullySupported 該軟體腳本系統不完全支持通用調用,故軟體將會退出。 - + SetupClang 啟動 Clang 服務 - + OpeningFiles 打開檔 - - - - + + + + AlreadyOpened 檔已被打開 @@ -219,6 +219,24 @@ 顏色選擇器 + + CrashReport + + + CrashReport + + + + + <html><head/><body><p><span style=" font-size:12pt; font-weight:700;">Opps! The software has crashed! Please send the information below to the dev:</span></p></body></html> + + + + + CopyToClipBoard + 數據已拷貝到粘貼板 + + DbgCallStackModel @@ -314,67 +332,67 @@ EditorView - + Cut 剪切 - + CutHex 剪切(十六進制) - + Copy 複製 - + CopyHex 複製(十六進制) - + Paste 粘貼 - + PasteHex 粘貼(十六進制) - + Delete 刪除 - + Find 查找 - + Goto 跳轉 - + Fill 填充 - + MetaData 標注 - + BookMark 書簽 - + Untitled 未命名 @@ -786,1188 +804,1188 @@ MainWindow - + File - - + + View 視圖 - + About 關於 - + WingHexExplorer 羽雲十六進制編輯器 - + loc: 座標: - + sel: 選長: - + Edit 編輯 - + Script 腳本 - - - + + + Plugin 插件 - + Setting 設置 - - + + Log 日誌 - + ExportFindResult 導出搜索結果 - + ClearFindResult 清空記錄 - - + + FindResult 搜索結果 - - - - - - - + + + + + + + Copy 複製 - - - - - - - - + + + + + + + + CopyToClipBoard 數據已拷貝到粘貼板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 數值 - - + + CheckSum 校驗和 - - + + DeleteBookMark 刪除書簽 - - + + ClearBookMark 清空書簽 - - - - + + + + BookMark 書簽 - - + + DecodeText 解碼字串 - + ScriptConsole 腳本控制臺 - - + + DVList 可視化列表 - - + + DVTree 可視化樹數據 - - + + DVTable 可視化表格 - - + + DVText 可視化文本 - - + + 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 縮放 - + SetupRecent 啟動最近檔服務 - + SetupUI 初始化介面 - + SetupDocking 啟動 Dock 服務 - + LaunchingLog 啟動日誌系統 - + SetupPluginSystem 啟動插件系統 - + LoadingPlg: 加載插件中: - + SetupConsole 啟動腳本控制臺 - + SetupScriptManager 啟動腳本管理器 - + SetupScriptService 啟動腳本服務 - + SetupScriptEditor 構建腳本編輯器 - + SetupSetDialog 構建設置窗體 - + SetupPlgWidgets 啟動插件組件 - + SetupDockingLayout 恢復 Dock 佈局 - + SetupWaiting 啟動即將完成 - + SetupFinished 啟動完畢 - + NoExtension 無擴展 - - - - - - + + + + + + ExportResult 導出結果 - - - + + + NothingToSave 沒有保存的數據 - - - - + + + + ClearResult 清空結果 - + OpenExt 打開 - 拓展 - + ResetScale 重置縮放 - + ShowMetafg 標注前景色 - + ShowMetabg 標注背景色 - + ShowMetaComment 批註 - + MetaShowAll 顯示所有標注 - + MetaHideAll 隱藏所有標注 - + FileStatus 檔狀態 - - + + InfoSave 是否保存 - - + + ReadOnly 可讀寫 - - + + SetLocked 啟用/禁用鎖定編輯 - + ErrUnLock 鎖定編輯失敗 - - + + SetOver 啟用/禁用改變大小 - + ErrUnOver 鎖定檔大小失敗 - + Window 窗體 - + Editor 編輯器 - + Tools 工具 - + HexEditorLayout 編輯器佈局 - + SetBaseAddr 設置基址 - + addressBase 基址 - + inputAddressBase 請輸入基址 - + WarnBigBaseAddress 基址過大,你得到的地址將會不正確! - + ErrBaseAddress 非法基址輸入 - + SetColInfo 顯示/隱藏地址欄 - + SetHeaderInfo 顯示/隱藏表頭 - + SetAsciiString 顯示/隱藏解碼字串 - + Layout 佈局 - + Fullscreen 全屏 - + Default 默認 - - - + + + LayoutRestoring... 恢復佈局中... - + RestoreLayout 恢復佈局 - - + + SaveLayout 保存佈局 - + ExportLog 導出日誌 - + ClearLog 清空日誌 - + 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 + 檔不存在! + - - - - - - - - - - - - - - - - - - - - Error - 錯誤 - - - - - FileNotExist - 檔不存在! - - - - - - - - - - + + + + + FilePermission 因檔許可權無法繼續! - + ProjectFile (*.wingpro) 專案檔 (*.wingpro) - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - - - - - - - + + + + + + + ChooseSaveFile 請選擇保存檔路徑: - + NoMoreClone 克隆已到上限,無法繼續操作! - + FindFininishBusy 查找任務繁忙,請勿重複查找! - + MayTooMuchFindResult 搜索數量已到達上限,結果可能不全,建議請按區段搜索。 - + SaveLayoutSuccess 保存佈局成功 - + SaveLayoutError 保存佈局失敗 - + HasClonedView 該編輯頁已被克隆編輯,如果關閉,相關聯的頁也會被關閉,你確認繼續嗎? - + SaveWorkSpace 保存工作區 - + WingHexWorkSpace (*.wingpro) 羽雲十六進制工作區 (*.wingpro) - + ConfirmSave 正在關閉未保存的檔或工作區,你確定保存嗎? - + Column %1 列 %1 - + ConfirmAPPSave 你嘗試關閉程式,但仍存在未保存的檔或工作區,你確定保存這些更改嗎? - - - - - - + + + + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作區錯誤! - + Warn 警告 - + ScriptObjShow 腳本對象 - + 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 超出解碼位元組限制…… - + LayoutSaving... 佈局保存中... - + PleaseInput 請輸入 - + LogExporting... 日誌導出中... - + ExportLogError 導出日誌失敗! - + ExportLogSuccess 導出日誌成功,路徑: - + ClearLogSuccess 清空日誌成功! - + BadNetwork 無法與遠程伺服器的更新檢查建立連接,請檢查網路。 - + NewestVersion 當前軟體為最新版本 - - + + OlderVersion 你使用的軟體為老版本,建議到 Github 和 Gitee 的倉庫發行版下載更新。 - + CheckingUpdate 檢查更新中…… - + Too much opened files 打開的檔過多,無法繼續操作! - + FilePermissionSure2Quit 因檔許可權無法保存,你確認要退出嗎? - + UnknownErrorSure2Quit 因未知錯誤無法保存,你確認要退出嗎? - + WorkSpaceUnSavedSure2Quit 工作區檔無法保存,你確認要退出嗎? - + CopyLimit 拷貝位元組超出限制 - + ErrOpenFileBelow 打開檔出現錯誤(由於許可權不足),如下為打開錯誤的檔: @@ -2198,210 +2216,210 @@ PluginSystem - + LoadingPlugin 加載插件中: - + InvalidPluginBrokenInfo 加載插件失敗:損壞的插件數據 - + AppClosingCanceled: 程式關閉被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 總計發現設備拓展插件數目: - + RegisterScriptFnUnSupportedTypes: 因腳本函數含有未支持的類型而註冊失敗: - - + + RegisterScriptFnInvalidSig: 因腳本函數簽名非法而註冊失敗: - - + + RegisterScriptFnConflitSig: 因腳本函數簽名衝突而註冊失敗: - + InvalidEnumName: 非法枚舉名: - + InvalidEnumValue: 非法枚舉值: - + InvalidMarcosRegister: 非法宏註冊: - + ErrLoadPluginSign 插件加載失敗:非法插件簽名! - + ErrLoadPluginSDKVersion 插件加載失敗:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加載失敗:非法插件名稱! - + ErrLoadInitPlugin 插件加載失敗:初始化插件失敗! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 註冊插件對象中…… - + ErrLoadExtPluginSign 設備拓展插件加載失敗:非法插件簽名! - + ErrLoadExtPluginSDKVersion 設備拓展插件加載失敗:非法插件 SDK 版本! - + ExtPluginAuthor : 設備拓展插件作者: - + ExtPluginWidgetRegister 設備拓展註冊插件對象中…… - + ErrLoadInitExtPlugin 設備拓展插件加載失敗:初始化插件失敗! - + ChooseFile 選擇檔 - - + + Error 錯誤 - + FileNotExist 檔不存在! - + FilePermission 因檔許可權無法繼續! - + EmptyNameDockWidget: 空的貼邊組件名: - + InvalidNameDockWidget: 無效貼邊組件名: - + InvalidNullDockWidget: 無效空貼邊組件: - + [EvilCall] 【惡意調用】 - + Not allowed operation in non-UI thread 該操作在非 UI 線程非法 - + UnsafePluginDir 不安全的插件目錄,請將插件目錄設置為僅管理員帳戶可寫 - + InvalidPluginID 加載插件失敗:非法插件識別字 - + InvalidDupPlugin 加載插件失敗:重複的插件識別字 - + FoundPluginCount 總計發現插件數目: - + PluginLoadingFailedSummary 有依賴插件加載失敗總結 - + - Dependencies: - 依賴: - + PUID: 插件唯一標誌符: - + Version: 版本: - + PluginLoadingFinished 加載插件完畢! @@ -2645,27 +2663,27 @@ Restart from the begining ? - + &Find 查找(&F) - + Fin&d next 查找下一個(&D) - + &Replace 替換(&R) - + &Goto line... 跳轉到行(&G) @@ -2707,7 +2725,7 @@ Do you wish to keep up to date by reloading the file? 您是否希望通過重新加載檔來保持最新狀態? - + untitled 未命名 @@ -5020,10 +5038,10 @@ Do you wish to keep up to date by reloading the file? - - - - + + + + Error 錯誤 @@ -5053,58 +5071,58 @@ Do you wish to keep up to date by reloading the file? 運行中... - - + + ChooseFile 選擇檔 - - + + FilePermission 因檔許可權無法繼續! - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - + ChooseSaveFile 請選擇保存檔路徑: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失敗! - + FormatCodeFailed 代碼格式化失敗 - - + + CannotSave2RunScript 無法保存,故無法繼續運行腳本。 - + ScriptStillRunning 腳本仍在運行,你確定要退出嗎? diff --git a/resources.qrc b/resources.qrc index ab73264..57e7c48 100644 --- a/resources.qrc +++ b/resources.qrc @@ -14,6 +14,7 @@ images/convpro.png images/copy.png images/copyhex.png + images/crashicon.png images/cut.png images/cuthex.png images/dbgcontinue.png diff --git a/src/class/appmanager.cpp b/src/class/appmanager.cpp index bfe462d..bd755ca 100644 --- a/src/class/appmanager.cpp +++ b/src/class/appmanager.cpp @@ -24,6 +24,7 @@ #include "angelscript.h" #include "clangformatmanager.h" #include "control/toast.h" +#include "crashhandler.h" #include "dbghelper.h" #include "define.h" #include "dialog/mainwindow.h" @@ -41,6 +42,8 @@ AppManager::AppManager(int &argc, char *argv[]) : QtSingleApplication(argc, argv) { ASSERT_SINGLETON; + CrashHandler::instance().init(); + auto args = arguments(); if (this->isRunning()) { QByteArray buffer; diff --git a/src/class/crashhandler.cpp b/src/class/crashhandler.cpp new file mode 100644 index 0000000..af5d269 --- /dev/null +++ b/src/class/crashhandler.cpp @@ -0,0 +1,135 @@ +#include "crashhandler.h" +#include "angelscript.h" +#include "dialog/crashreport.h" +#include "plugin/pluginsystem.h" + +#include +#include +#include + +#include + +#ifdef Q_OS_WIN +#include + +#include + +LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS *) { + CrashHandler::reportCrashAndExit(); + // Terminate the program + return EXCEPTION_EXECUTE_HANDLER; +} + +#else +#include +#include +#include + +void signalHandler(int) { CrashHandler::reportCrashAndExit(); } + +#endif + +CrashHandler &CrashHandler::instance() { + static CrashHandler ins; + return ins; +} + +void CrashHandler::init() { +#ifdef Q_OS_WIN + ::SetUnhandledExceptionFilter(ExceptionFilter); +#else + ::signal(SIGSEGV, signalHandler); + ::signal(SIGILL, signalHandler); + ::signal(SIGABRT, signalHandler); + ::signal(SIGFPE, signalHandler); + ::signal(SIGBUS, signalHandler); +#endif +} + +CrashHandler::CrashHandler() {} + +void CrashHandler::reportCrashAndExit() { + QString buffer; + QTextStream ss(&buffer); + + ss << QStringLiteral("Basic Infomation:") << Qt::endl; + ss << QStringLiteral("* Qt: ") << QLibraryInfo::build() << Qt::endl; + ss << QStringLiteral("* OS: ") << QSysInfo::prettyProductName() << Qt::endl; + ss << QStringLiteral("* Version: ") << WINGHEX_VERSION << Qt::endl; + ss << QStringLiteral("* ScriptEngine: ") << ANGELSCRIPT_VERSION_STRING + << Qt::endl; + + ss << Qt::endl; + + // we should keep this exception free + auto &plgsys = PluginSystem::instance(); + ss << QStringLiteral("Plugin System:") << Qt::endl; + ss << QStringLiteral("* Loading: ") << plgsys.currentLoadingPlugin() + << Qt::endl; + + size_t i = 1; + ss << QStringLiteral("* Plugins:") << Qt::endl; + for (auto &plg : plgsys.plugins()) { + auto info = plgsys.getPluginInfo(plg); + + auto header = QStringLiteral(" "); + ss << header << QStringLiteral("#") << i << Qt::endl; + + ss << header << QStringLiteral("- ID: ") << info.id << Qt::endl; + ss << header << QStringLiteral("- Name: ") << plg->pluginName() + << Qt::endl; + ss << header << QStringLiteral("- License: ") << info.license + << Qt::endl; + ss << header << QStringLiteral("- Author: ") << info.author << Qt::endl; + ss << header << QStringLiteral("- Vendor: ") << info.vendor << Qt::endl; + ss << header << QStringLiteral("- Version: ") + << info.version.toString(); + ss << header << QStringLiteral("- Comment: ") << plg->pluginComment() + << Qt::endl; + ss << header << QStringLiteral("- URL: ") << info.url << Qt::endl; + + i++; + + ss << Qt::endl; + } + + i = 1; + ss << QStringLiteral("* Devices:") << Qt::endl; + for (auto &plg : plgsys.devices()) { + auto info = plgsys.getPluginInfo(plg); + + auto header = QStringLiteral(" "); + ss << header << QStringLiteral("#") << i << Qt::endl; + + ss << header << QStringLiteral("- ID: ") << info.id << Qt::endl; + ss << header << QStringLiteral("- Name: ") << plg->pluginName() + << Qt::endl; + ss << header << QStringLiteral("- License: ") << info.license + << Qt::endl; + ss << header << QStringLiteral("- Author: ") << info.author << Qt::endl; + ss << header << QStringLiteral("- Vendor: ") << info.vendor << Qt::endl; + ss << header << QStringLiteral("- Version: ") + << info.version.toString(); + ss << header << QStringLiteral("- Comment: ") << plg->pluginComment() + << Qt::endl; + ss << header << QStringLiteral("- URL: ") << info.url << Qt::endl; + + i++; + + ss << Qt::endl; + } + + auto str = cpptrace::generate_trace().to_string(); + ss << QString::fromStdString(str) << Qt::endl; + + CrashReport r; + r.setInfomation(buffer); + r.exec(); + +#ifdef Q_OS_LINUX + // because abort() will also trigger it + ::signal(SIGABRT, nullptr); +#endif + + abort(); +} diff --git a/src/class/crashhandler.h b/src/class/crashhandler.h new file mode 100644 index 0000000..199239a --- /dev/null +++ b/src/class/crashhandler.h @@ -0,0 +1,18 @@ +#ifndef CRASHHANDLER_H +#define CRASHHANDLER_H + +#include + +class CrashHandler { +public: + static CrashHandler &instance(); + + void init(); + + static void reportCrashAndExit(); + +private: + CrashHandler(); +}; + +#endif // CRASHHANDLER_H diff --git a/src/class/scopeguard.h b/src/class/scopeguard.h deleted file mode 100644 index 08245c5..0000000 --- a/src/class/scopeguard.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SCOPEGUARD_H -#define SCOPEGUARD_H - -#include - -template -class ScopeGuard { - const DctorFn &dctorfn; - - Q_DISABLE_COPY_MOVE(ScopeGuard) - -public: - ScopeGuard(CtorFn &&ctorfn, DctorFn &&dctorfn) : dctorfn(dctorfn) { - ctorfn(); - } - ~ScopeGuard() { dctorfn(); } -}; - -#endif // SCOPEGUARD_H diff --git a/src/class/settingmanager.cpp b/src/class/settingmanager.cpp index 10979af..3668b31 100644 --- a/src/class/settingmanager.cpp +++ b/src/class/settingmanager.cpp @@ -213,7 +213,8 @@ void SettingManager::setLogCount(qsizetype newLogCount) { void SettingManager::checkWriteableAndWarn() { HANDLE_CONFIG; if (!CONFIG.isWritable()) { - Logger::warning(tr("ConfigUnableSave")); + Logger::warning(QStringLiteral("") + tr("ConfigUnableSave") + + QStringLiteral("")); } } diff --git a/src/control/editorview.cpp b/src/control/editorview.cpp index 60f4980..1b4cf72 100644 --- a/src/control/editorview.cpp +++ b/src/control/editorview.cpp @@ -32,7 +32,6 @@ #include #ifdef Q_OS_LINUX -#include "class/scopeguard.h" #include #endif diff --git a/src/dialog/crashreport.cpp b/src/dialog/crashreport.cpp new file mode 100644 index 0000000..07471f8 --- /dev/null +++ b/src/dialog/crashreport.cpp @@ -0,0 +1,40 @@ +#include "crashreport.h" +#include "ui_crashreport.h" + +#include +#include + +#include "utilities.h" + +#include "control/toast.h" + +CrashReport::CrashReport(QWidget *parent) + : QWidget(parent), ui(new Ui::CrashReport) { + ui->setupUi(this); + + _dialog = new FramelessDialogBase(parent); + _dialog->buildUpContent(this); + _dialog->setWindowTitle(this->windowTitle()); + _dialog->setMinimumSize(600, 500); + + Utilities::moveToCenter(_dialog); +} + +CrashReport::~CrashReport() { delete ui; } + +void CrashReport::setInfomation(const QString &info) { + ui->textBrowser->setText(info); +} + +int CrashReport::exec() { return _dialog->exec(); } + +void CrashReport::on_buttonBox_clicked(QAbstractButton *button) { + if (button == ui->buttonBox->button(QDialogButtonBox::Save)) { + auto clipboard = qApp->clipboard(); + clipboard->setText(ui->textBrowser->toPlainText()); + Toast::toast(_dialog, NAMEICONRES(QStringLiteral("copy")), + tr("CopyToClipBoard")); + } else { + _dialog->done(1); + } +} diff --git a/src/dialog/crashreport.h b/src/dialog/crashreport.h new file mode 100644 index 0000000..76da1fb --- /dev/null +++ b/src/dialog/crashreport.h @@ -0,0 +1,33 @@ +#ifndef CRASHREPORT_H +#define CRASHREPORT_H + +#include "dialog/framelessdialogbase.h" + +#include +#include + +namespace Ui { +class CrashReport; +} + +class CrashReport : public QWidget { + Q_OBJECT + +public: + explicit CrashReport(QWidget *parent = nullptr); + ~CrashReport(); + +public slots: + void setInfomation(const QString &info); + int exec(); + +private slots: + void on_buttonBox_clicked(QAbstractButton *button); + +private: + Ui::CrashReport *ui; + + FramelessDialogBase *_dialog = nullptr; +}; + +#endif // CRASHREPORT_H diff --git a/src/dialog/crashreport.ui b/src/dialog/crashreport.ui new file mode 100644 index 0000000..08bee6c --- /dev/null +++ b/src/dialog/crashreport.ui @@ -0,0 +1,90 @@ + + + CrashReport + + + + 0 + 0 + 446 + 390 + + + + CrashReport + + + + 8 + + + 12 + + + 12 + + + 12 + + + 12 + + + + + 10 + + + 15 + + + 15 + + + + + + 100 + 100 + + + + + + + :/com.wingsummer.winghex/images/crashicon.png + + + true + + + + + + + <html><head/><body><p><span style=" font-size:12pt; font-weight:700;">Opps! The software has crashed! Please send the information below to the dev:</span></p></body></html> + + + true + + + + + + + + + + + + QDialogButtonBox::Ok|QDialogButtonBox::Save + + + + + + + + + + diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index 7c85d90..23c61b7 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -32,7 +32,6 @@ #include "class/logger.h" #include "class/qkeysequences.h" #include "class/richtextitemdelegate.h" -#include "class/scopeguard.h" #include "class/scriptconsolemachine.h" #include "class/settingmanager.h" #include "class/wingfiledialog.h" @@ -1941,8 +1940,8 @@ EditorView *MainWindow::newfileGUI() { void MainWindow::on_newfile() { newfileGUI(); } void MainWindow::on_openfile() { - ScopeGuard g([this]() { showStatus(tr("Opening...")); }, - [this]() { showStatus({}); }); + showStatus(tr("Opening...")); + QScopeGuard g([this]() { showStatus({}); }); auto filename = WingFileDialog::getOpenFileName(this, tr("ChooseFile"), m_lastusedpath); @@ -1972,8 +1971,8 @@ void MainWindow::on_openfile() { } void MainWindow::on_openworkspace() { - ScopeGuard g([this]() { showStatus(tr("WorkSpaceOpening...")); }, - [this]() { showStatus({}); }); + showStatus(tr("WorkSpaceOpening...")); + QScopeGuard g([this]() { showStatus({}); }); auto filename = WingFileDialog::getOpenFileName( this, tr("ChooseFile"), m_lastusedpath, tr("ProjectFile (*.wingpro)")); @@ -2008,8 +2007,8 @@ void MainWindow::on_openworkspace() { } void MainWindow::on_reload() { - ScopeGuard g([this]() { showStatus(tr("Reloading...")); }, - [this]() { showStatus({}); }); + showStatus(tr("Reloading...")); + QScopeGuard g([this]() { showStatus({}); }); auto editor = currentEditor(); if (editor == nullptr) { @@ -2030,8 +2029,8 @@ void MainWindow::on_reload() { } void MainWindow::on_save() { - ScopeGuard g([this]() { showStatus(tr("Saving...")); }, - [this]() { showStatus({}); }); + showStatus(tr("Saving...")); + QScopeGuard g([this]() { showStatus({}); }); auto editor = currentEditor(); if (editor == nullptr) { @@ -2101,8 +2100,8 @@ void MainWindow::on_convpro() { } void MainWindow::on_saveas() { - ScopeGuard g([this]() { showStatus(tr("SavingAs...")); }, - [this]() { showStatus({}); }); + showStatus(tr("SavingAs...")); + QScopeGuard g([this]() { showStatus({}); }); auto editor = currentEditor(); if (editor == nullptr) { @@ -2147,8 +2146,8 @@ void MainWindow::on_saveas() { } void MainWindow::on_exportfile() { - ScopeGuard g([this]() { showStatus(tr("Exporting...")); }, - [this]() { showStatus({}); }); + showStatus(tr("Exporting...")); + QScopeGuard g([this]() { showStatus({}); }); auto editor = currentEditor(); if (editor == nullptr) { @@ -2177,8 +2176,8 @@ void MainWindow::on_exportfile() { } void MainWindow::on_savesel() { - ScopeGuard g([this]() { showStatus(tr("SavingSel...")); }, - [this]() { showStatus({}); }); + showStatus(tr("SavingSel...")); + QScopeGuard g([this]() { showStatus({}); }); auto hexeditor = currentHexView(); if (hexeditor == nullptr) { @@ -2745,8 +2744,8 @@ void MainWindow::on_clearfindresult() { } void MainWindow::on_exportfindresult() { - ScopeGuard g([this]() { showStatus(tr("FindResultExporting...")); }, - [this]() { showStatus({}); }); + showStatus(tr("FindResultExporting...")); + QScopeGuard g([this]() { showStatus({}); }); auto editor = currentEditor(); if (editor == nullptr) { @@ -3001,8 +3000,8 @@ void MainWindow::on_fullScreen() { } void MainWindow::on_saveLayout() { - ScopeGuard g([this]() { showStatus(tr("LayoutSaving...")); }, - [this]() { showStatus({}); }); + showStatus(tr("LayoutSaving...")); + QScopeGuard g([this]() { showStatus({}); }); static auto suffix = QStringLiteral(".wing-layout"); bool ok; @@ -3039,8 +3038,8 @@ void MainWindow::on_saveLayout() { } void MainWindow::on_exportlog() { - ScopeGuard g([this]() { showStatus(tr("LogExporting...")); }, - [this]() { showStatus({}); }); + showStatus(tr("LogExporting...")); + QScopeGuard g([this]() { showStatus({}); }); auto nfile = saveLog(); if (nfile.isEmpty()) { Toast::toast(this, NAMEICONRES(QStringLiteral("log")), diff --git a/src/dialog/scriptingdialog.cpp b/src/dialog/scriptingdialog.cpp index cd914d5..4e13947 100644 --- a/src/dialog/scriptingdialog.cpp +++ b/src/dialog/scriptingdialog.cpp @@ -1040,8 +1040,7 @@ void ScriptingDialog::startDebugScript(const QString &fileName) { } _DebugingScript = fileName; - PluginSystem::instance().dispatchEvent( - IWingPlugin::RegisteredEvent::ScriptPragmaInit, {}); + PluginSystem::instance().scriptPragmaBegin(); m_consoleout->machine()->executeScript(fileName, true); updateRunDebugMode(); @@ -1393,8 +1392,7 @@ void ScriptingDialog::on_runscript() { return; } m_consoleout->clear(); - PluginSystem::instance().dispatchEvent( - IWingPlugin::RegisteredEvent::ScriptPragmaInit, {}); + PluginSystem::instance().scriptPragmaBegin(); m_consoleout->machine()->executeScript(e->fileName()); updateRunDebugMode(); } diff --git a/src/dialog/splashdialog.cpp b/src/dialog/splashdialog.cpp index 7764653..574cab7 100644 --- a/src/dialog/splashdialog.cpp +++ b/src/dialog/splashdialog.cpp @@ -27,8 +27,8 @@ SplashDialog::SplashDialog(QWidget *parent) QStringLiteral("

%1

") .arg(qAppName())); - setWindowFlags(Qt::CustomizeWindowHint | Qt::SplashScreen | - Qt::WindowStaysOnTopHint); + setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint | + Qt::Window); setAttribute(Qt::WA_DeleteOnClose); setModal(true); show(); diff --git a/src/plugin/pluginsystem.cpp b/src/plugin/pluginsystem.cpp index a701570..3846679 100644 --- a/src/plugin/pluginsystem.cpp +++ b/src/plugin/pluginsystem.cpp @@ -38,14 +38,10 @@ #include #include #include -#include PluginSystem::PluginSystem(QObject *parent) : QObject(parent) {} -PluginSystem::~PluginSystem() { - Q_ASSERT(_loadedplgs.isEmpty()); - Q_ASSERT(_loadeddevs.isEmpty()); -} +PluginSystem::~PluginSystem() {} void PluginSystem::initCheckingEngine() { _engine = dynamic_cast(asCreateScriptEngine()); @@ -58,8 +54,12 @@ void PluginSystem::initCheckingEngine() { void PluginSystem::finalizeCheckingEngine() { _engine->ShutDownAndRelease(); } +QString PluginSystem::currentLoadingPlugin() const { return _curLoadingPlg; } + QStringList PluginSystem::scriptMarcos() const { return _scriptMarcos; } +void PluginSystem::scriptPragmaBegin() { _pragmaedPlg.clear(); } + const QList &PluginSystem::plugins() const { return _loadedplgs; } @@ -83,6 +83,10 @@ PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) { if (fileinfo.exists()) { auto fileName = fileinfo.absoluteFilePath(); + _curLoadingPlg = + QDir(qApp->applicationDirPath()).relativeFilePath(fileName); + + QScopeGuard g([this]() { _curLoadingPlg.clear(); }); QPluginLoader loader(fileName, this); Logger::info(tr("LoadingPlugin") + fileinfo.fileName()); @@ -493,13 +497,15 @@ bool PluginSystem::dispatchEvent(IWingPlugin::RegisteredEvent event, if (r == es.constEnd()) { return false; } - return (*r)->eventOnScriptPragma(section, params.at(3).toStringList()); - } break; - case WingHex::IWingPlugin::RegisteredEvent::ScriptPragmaInit: { - Q_ASSERT(params.isEmpty()); - for (auto &plg : _evplgs[event]) { + auto plg = *r; + if (!_pragmaedPlg.contains(plg)) { plg->eventOnScriptPragmaInit(); } + return plg->eventOnScriptPragma(section, params.at(3).toStringList()); + } break; + case WingHex::IWingPlugin::RegisteredEvent::ScriptPragmaInit: { + Q_ASSERT(false); + // should not go there, lazy calling instead } break; case WingHex::IWingPlugin::RegisteredEvent::PluginFileOpened: { Q_ASSERT(params.size() == 4); @@ -1281,6 +1287,7 @@ void PluginSystem::loadPlugin(IWingDevice *p, PluginInfo &meta, registerPluginPages(p); connectInterface(p); + registerMarcoDevice(p); // ok register into menu open auto menu = @@ -1417,6 +1424,12 @@ void PluginSystem::registerPluginPages(IWingPluginBase *p) { } } +void PluginSystem::registerMarcoDevice(IWingDevice *plg) { + auto id = getPUID(plg).toUpper(); + auto sep = QStringLiteral("_"); + _scriptMarcos.append(sep + id + sep); +} + bool PluginSystem::updateTextList_API(const QStringList &data, const QString &title, const ClickCallBack &click, diff --git a/src/plugin/pluginsystem.h b/src/plugin/pluginsystem.h index 95c00b0..ad236a8 100644 --- a/src/plugin/pluginsystem.h +++ b/src/plugin/pluginsystem.h @@ -162,6 +162,9 @@ public: QStringList scriptMarcos() const; +public: + void scriptPragmaBegin(); + public: PluginInfo getPluginInfo(IWingPluginBase *plg) const; @@ -256,6 +259,7 @@ private: private: void connectInterface(IWingDevice *plg); void connectLoadingInterface(IWingDevice *plg); + void registerMarcoDevice(IWingDevice *plg); private: void connectBaseInterface(IWingPluginBase *plg); @@ -275,6 +279,10 @@ public: const QString &title, const ClickCallBack &click, const ClickCallBack &dblclick); +public: + // fpr crash checking + QString currentLoadingPlugin() const; + private: template T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) { @@ -396,8 +404,12 @@ private: asCScriptEngine *_engine = nullptr; QStringList _scriptMarcos; + QList _pragmaedPlg; QReadWriteLock _rwlock; + +private: + QString _curLoadingPlg; }; #endif // PLUGINSYSTEM_H