From 912dfaf227c2dfd1b64a7758d4d2aa40d0094fe5 Mon Sep 17 00:00:00 2001 From: wingsummer <1326224942@qq.com> Date: Sat, 9 Nov 2024 21:34:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=BE=E7=BD=AE=E6=96=B9=E9=9D=A2?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=9B=B4=E6=96=B0=EF=BC=9B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E7=9A=84=E9=A2=9C=E8=89=B2=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E5=A4=8D=E8=BD=AF=E4=BB=B6=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=BC=80=E6=BA=90=E5=8D=8F=E8=AE=AE=E6=97=B6?= =?UTF-8?q?=E6=96=87=E5=AD=97=E6=97=A0=E6=8D=A2=E8=A1=8C=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/QHexView/document/qhexdocument.cpp | 17 +- 3rdparty/QHexView/document/qhexdocument.h | 2 + .../qcodeedit2/lib/snippets/qsnippetmanager.h | 2 +- CMakeLists.txt | 2 +- lang/zh_CN/winghex.ts | 488 +++++++++--------- mkinstaller/pyscript/installer.py | 2 +- src/class/skinmanager.cpp | 4 + src/dialog/aboutsoftwaredialog.cpp | 7 + src/dialog/aboutsoftwaredialog.ui | 5 - src/dialog/mainwindow.cpp | 73 ++- src/dialog/mainwindow.h | 5 +- src/dialog/scriptingdialog.cpp | 10 +- src/dialog/scriptingdialog.h | 3 + src/dialog/settingdialog.cpp | 13 + src/dialog/settingdialog.h | 1 + src/model/metadatamodel.cpp | 41 +- src/plugin/iwingplugin.h | 14 +- src/plugin/pluginsystem.cpp | 53 +- src/plugin/pluginsystem.h | 2 + src/plugin/settingpage.h | 22 +- src/qcodeeditwidget/qeditconfig.cpp | 2 +- src/qcodeeditwidget/qeditconfig.h | 3 +- src/qcodeeditwidget/qformatconfig.cpp | 2 - src/qcodeeditwidget/qformatconfig.h | 1 - src/qcodeeditwidget/qsnippetedit.cpp | 6 +- src/settings/editorsettingdialog.cpp | 2 +- src/settings/editorsettingdialog.h | 2 +- src/settings/generalsettingdialog.cpp | 2 +- src/settings/generalsettingdialog.h | 2 +- src/settings/othersettingsdialog.cpp | 2 +- src/settings/othersettingsdialog.h | 2 +- src/settings/pluginsettingdialog.cpp | 16 +- src/settings/pluginsettingdialog.h | 5 +- src/settings/scriptsettingdialog.cpp | 2 +- src/settings/scriptsettingdialog.h | 2 +- .../qcodeedit2 => src}/snippets/doxclass.qcs | 0 36 files changed, 476 insertions(+), 341 deletions(-) rename {3rdparty/qcodeedit2 => src}/snippets/doxclass.qcs (100%) diff --git a/3rdparty/QHexView/document/qhexdocument.cpp b/3rdparty/QHexView/document/qhexdocument.cpp index 36b587b..95e0a3b 100644 --- a/3rdparty/QHexView/document/qhexdocument.cpp +++ b/3rdparty/QHexView/document/qhexdocument.cpp @@ -93,11 +93,13 @@ bool QHexDocument::metafgVisible() { return m_metafg; } bool QHexDocument::metaCommentVisible() { return m_metacomment; } -bool QHexDocument::isDocSaved() { return m_undostack->isClean(); } +bool QHexDocument::isDocSaved() { return m_isSaved; } + void QHexDocument::setDocSaved(bool b) { if (b) { m_undostack->setClean(); } + m_isSaved = b; emit documentSaved(b); } @@ -188,7 +190,11 @@ bool QHexDocument::RemoveBookMarks(const QList &pos) { bool QHexDocument::removeBookMark(qsizetype pos) { if (m_keepsize) { - return _bookmarks.remove(pos) != 0; + auto ret = _bookmarks.remove(pos) != 0; + if (ret) { + setDocSaved(false); + } + return ret; } return false; } @@ -197,6 +203,7 @@ bool QHexDocument::modBookMark(qsizetype pos, const QString &comment) { if (m_keepsize) { if (_bookmarks.contains(pos)) { _bookmarks[pos] = comment; + setDocSaved(false); return true; } } @@ -332,8 +339,10 @@ QHexDocument::QHexDocument(QHexBuffer *buffer, bool readonly) m_metadata = new QHexMetadata(m_undostack, this); m_metadata->setLineWidth(m_hexlinewidth); - connect(m_metadata, &QHexMetadata::metadataChanged, this, - &QHexDocument::metaDataChanged); + connect(m_metadata, &QHexMetadata::metadataChanged, this, [this] { + setDocSaved(false); + emit metaDataChanged(); + }); /*=======================*/ // added by wingsummer diff --git a/3rdparty/QHexView/document/qhexdocument.h b/3rdparty/QHexView/document/qhexdocument.h index 9e9fde2..b75a1a0 100644 --- a/3rdparty/QHexView/document/qhexdocument.h +++ b/3rdparty/QHexView/document/qhexdocument.h @@ -190,6 +190,8 @@ private: /*======================*/ // added by wingsummer + bool m_isSaved = true; + bool m_readonly; bool m_keepsize; bool m_islocked; diff --git a/3rdparty/qcodeedit2/lib/snippets/qsnippetmanager.h b/3rdparty/qcodeedit2/lib/snippets/qsnippetmanager.h index 14a30df..9cb8c86 100644 --- a/3rdparty/qcodeedit2/lib/snippets/qsnippetmanager.h +++ b/3rdparty/qcodeedit2/lib/snippets/qsnippetmanager.h @@ -33,7 +33,7 @@ class QCE_EXPORT QSnippetManager : public QObject { Q_OBJECT public: - QSnippetManager(QObject *p = 0); + explicit QSnippetManager(QObject *p = nullptr); virtual ~QSnippetManager(); int snippetCount() const; diff --git a/CMakeLists.txt b/CMakeLists.txt index ac67e6d..7766173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(PROJECT_VERSION 1.0.0) +set(PROJECT_VERSION "2.0.0-WIP") find_package( QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network Concurrent diff --git a/lang/zh_CN/winghex.ts b/lang/zh_CN/winghex.ts index 1951827..8b73af8 100644 --- a/lang/zh_CN/winghex.ts +++ b/lang/zh_CN/winghex.ts @@ -30,22 +30,17 @@ 协议 - - qrc:/com.wingsummer.winghex/LICENSE - qrc:/com.wingsummer.winghex/LICENSE - - - + Developer 开发者 - + Credit 鸣谢 - + Translator 译者 @@ -766,8 +761,8 @@ - - + + CopyToClipBoard 数据已拷贝到粘贴板 @@ -807,8 +802,8 @@ - - + + BookMark 书签 @@ -907,8 +902,8 @@ - - + + General 基本 @@ -990,7 +985,7 @@ - + Fill 填充 @@ -1219,150 +1214,160 @@ 插件功能 - + PluginSettings 插件设置 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + Wiki 网页 Wiki - + AboutQT 关于 QT - + + SetPageIDEmptyTryUseName + + + + + SetPageDupNameIgnored + + + + 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) - + Root Required! 需要管理员权限继续操作! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - - - + + + ChooseSaveFile 请选择保存文件路径: - + NoMoreClone 克隆已到上限,无法继续操作! - + FindFininishBusy 查找任务繁忙,请勿重复查找! - + MayTooMuchFindResult 搜索数量已到达上限,结果可能不全,建议请按区段搜索。 - + ConfirmSave 正在关闭未保存的文件或工作区,你确定保存吗? - + ConfirmAPPSave 你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗? - - + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作区错误! - - - + + + Warn 警告 @@ -1372,163 +1377,163 @@ 脚本对象 - - - + + + SourceChanged 局部打开原始文件更改! - - + + SaveSourceFileError 由于原文件更改,保存文件失败! - + SaveUnSuccessfully 保存失败! - + ChooseExportFile 请选择导出文件路径: - + ExportSuccessfully 导出成功! - + ExportSourceFileError 由于原文件更改,导出文件失败! - + ExportUnSuccessfully 导出失败! - + SaveSelSuccess 保存选区字节成功! - + SaveSelError 保存选区字节失败,因文件不具有可写权限! - - + + CutToClipBoard 数据已剪切到粘贴板! - - + + UnCutToClipBoard 由于保持大小限制,数据剪切到粘贴板失败! - - + + UnCopyToClipBoard 由于保持大小限制,数据剪切到复制板失败! - + FindFininish 查找结果完毕! - + PleaseInputFill 请输入填充字节值 - + FillInputError 填充字节输入错误 - - - - - - - - + + + + + + + + CheckKeepSize 请检查锁定文件大小是否开启! - - + + InputComment 请输入批注: - - - + + + NoSelection 没有选区,无法继续的操作! - + NoMetaData 无可编辑标记 - + EmptyFindResult 没有可导出的搜索结果! - + SaveFindResult 导出搜索结果成功! - + SaveFindResultError 导出结果失败! - + TooManyBytesDecode 超出解码字节限制…… - + ExportLogError 导出日志失败! - + ExportLogSuccess 导出日志成功,路径: - + ClearLogSuccess 清空日志成功! - + Too much opened files 打开的文件过多,无法继续操作! - + CopyLimit 拷贝字节超出限制 - + ErrOpenFileBelow 打开文件出现错误(由于权限不足),如下为打开错误的文件: @@ -1536,27 +1541,27 @@ MetaDataModel - + Begin 开始 - + End 结束 - + Foreground 前景色 - + Background 背景色 - + Comment 批注 @@ -1691,27 +1696,27 @@ 插件: - + Plugin 插件 - + pluginName 插件名 - + pluginAuthor 插件作者 - + pluginVersion 插件版本 - + pluginComment 插件说明 @@ -1724,57 +1729,57 @@ 正在加载插件: - + ErrLoadPluginSign 插件加载失败:非法插件签名! - + ErrLoadPluginSDKVersion 插件加载失败:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加载失败:非法插件名称! - + ErrLoadLoadedPlugin 插件加载失败:重复加载插件! - + ErrLoadInitPlugin 插件加载失败:初始化插件失败! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 注册插件对象中…… - + Creating UI widget is not allowed in non-UI thread 不能够在非用户界面线程创建用户界面组件 - + FoundPluginCount 总计发现插件数目: - + PluginLoadingFinished 加载插件完毕! @@ -2193,59 +2198,59 @@ Do you wish to keep up to date by reloading the file? - + Bold - + Italic - + Underline - + Overline - + Strikeout - + Wave underline - + Text color (aka foreground) - + Background color - + Lines color (used by all lines formatting : underline, overline, ...) - - + + Unsaved changes - - + + There are unsaved changes in this format scheme. Do you want them to be saved? @@ -2444,44 +2449,44 @@ Do you want them to be saved? QSnippetEdit - - + + Unsaved changes - + Do you want to save pattern changes to snippet %1 ? - + The current snippet data will be discarded. Do you want to continue? - + Missing data - + Please provide a name and a content to create a new snippet - - + + Error 错误 - + Invalid snippet pattern. - + Please select a valid snippet to erase @@ -4349,375 +4354,380 @@ Do you want them to be saved? ScriptingDialog - + ScriptEditor 脚本编辑器 - + ScriptPermissionDenied 因权限无法打开脚本 - + File 文件 - + Edit 编辑 - + Debugger 调试器 - + + Setting + 设置 + + + About 关于 - + Basic 基础 - + New 新建 - + OpenF 打开文件 - + RecentFiles 最近打开 - + Reload 重新加载 - - + + Save 保存 - + SaveAs 另存为 - + General 基本 - + Undo 撤销 - + Redo 恢复 - + Cut 剪切 - + Copy 复制 - + Paste 粘贴 - + Delete 删除 - + Lookup 查询 - + Find 查找 - + Replace 替换 - + Goto 跳转 - + Display 显示 - + Scale 缩放 - + ResetScale 重置缩放 - + Window 窗体 - - + + Editor 编辑器 - + Tools 工具 - + Layout 布局 - + Fullscreen 全屏 - + RestoreLayout 恢复默认布局 - + BreakPoint 断点 - + ToggleBreakPoint 切换断点 - + AddBreakPoint 添加断点 - + Settings 设置 - + Local 本地 - + Global 全局 - + Variables 变量 - + BreakPoints 断点 - + ConsoleOutput 输出 - + StackTrace 栈跟踪 - + Watch 监视 - - - - - - + + + + + + Error 错误 - + Too much opened files 打开的文件过多,无法继续操作! - - + + ChooseFile 选择文件 - - - + + + FilePermission 因文件权限无法继续! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - + ChooseSaveFile 请选择保存文件路径: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失败! - - + + CannotSave2RunScript 无法保存,故无法继续运行脚本。 - - + + ScriptStillRunning 脚本仍在运行,你确定要退出吗? - + View 视图 - + Debug 调试 - + Run 运行 - + RunWithDbg 调试运行 - + Pause 暂停 - + Continue 继续 - + Stop 停止 - + Restart 重启 - + StepInto 单步步入 - + StepOver 单步步过 - + StepOut 单步跳出 - + RemoveBreakPoint 删除断点 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + Wiki 网页 Wiki - + AboutQT 关于 QT @@ -4730,12 +4740,12 @@ Do you want them to be saved? 设置 - + TakeEffectRestart 该选项重启软件生效 - + This will reset all settings. Are you sure to continue? 这将会重置所有设置。你确认继续吗? @@ -4743,12 +4753,12 @@ Do you want them to be saved? SkinManager - + Dark 暗黑 - + Light 浅色 diff --git a/mkinstaller/pyscript/installer.py b/mkinstaller/pyscript/installer.py index c474acf..ae08cda 100755 --- a/mkinstaller/pyscript/installer.py +++ b/mkinstaller/pyscript/installer.py @@ -161,7 +161,7 @@ def update(build_path): run_command_interactive( ["xdg-icon-resource", "forceupdate"]) run_command_interactive( - ["gtk-update-icon-caches", "/usr/share/icons/hicolor"]) + ["gtk-update-icon-cache", "/usr/share/icons/hicolor"]) run_command_interactive( ["update-desktop-database", "/usr/share/applications"]) print(Fore.GREEN + ">> Installation finished..." + Style.RESET_ALL) diff --git a/src/class/skinmanager.cpp b/src/class/skinmanager.cpp index 411629d..d80e3b1 100644 --- a/src/class/skinmanager.cpp +++ b/src/class/skinmanager.cpp @@ -43,7 +43,11 @@ SkinManager::SkinManager(QObject *parent) : QObject(parent) { break; } qss.open(QFile::ReadOnly | QFile::Text); +#ifdef Q_OS_WIN + qApp->setStyle(QStyleFactory::create("windowsvista")); +#else qApp->setStyle(QStyleFactory::create("fusion")); +#endif qApp->setStyleSheet(qss.readAll()); qss.close(); } diff --git a/src/dialog/aboutsoftwaredialog.cpp b/src/dialog/aboutsoftwaredialog.cpp index 3a8b6ad..92b78f2 100644 --- a/src/dialog/aboutsoftwaredialog.cpp +++ b/src/dialog/aboutsoftwaredialog.cpp @@ -33,6 +33,13 @@ AboutSoftwareDialog::AboutSoftwareDialog(QWidget *parent) ui->tbTr->setMarkdown(data.trans); ui->lblVersion->setText(qApp->applicationVersion()); + QFile license(QStringLiteral(":/com.wingsummer.winghex/LICENSE")); + auto ret = license.open(QFile::ReadOnly); + Q_ASSERT(ret); + Q_UNUSED(ret); + auto ltxt = license.readAll(); + ui->tbLicense->setText(ltxt); + _dialog = new FramelessDialogBase(parent); _dialog->buildUpContent(this); _dialog->setWindowTitle(this->windowTitle()); diff --git a/src/dialog/aboutsoftwaredialog.ui b/src/dialog/aboutsoftwaredialog.ui index 64465c8..35989d5 100644 --- a/src/dialog/aboutsoftwaredialog.ui +++ b/src/dialog/aboutsoftwaredialog.ui @@ -131,11 +131,6 @@ - - - qrc:/com.wingsummer.winghex/LICENSE - - true diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index 38f874c..ec56f79 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -1106,6 +1106,7 @@ RibbonTabContent *MainWindow::buildPluginPage(RibbonTabContent *tab) { pannel->setVisible(false); connect(pannel, &RibbonButtonGroup::emptyStatusChanged, this, [pannel](bool isEmpty) { pannel->setVisible(!isEmpty); }); + m_pluginSettingsGroup = pannel; } return tab; } @@ -1149,35 +1150,89 @@ RibbonTabContent *MainWindow::buildAboutPage(RibbonTabContent *tab) { } void MainWindow::buildUpSettingDialog() { + QStringList usedIDs; + QString id; + m_setdialog = new SettingDialog(this); auto generalPage = new GeneralSettingDialog(m_setdialog); connect(generalPage, &SettingPage::optionNeedRestartChanged, m_setdialog, &SettingDialog::toastTakeEffectReboot); m_setdialog->addPage(generalPage); + id = generalPage->id(); + Q_ASSERT(!id.isEmpty()); + Q_ASSERT(usedIDs.indexOf(id) < 0); + usedIDs.append(id); + auto editorPage = new EditorSettingDialog(m_setdialog); connect(editorPage, &SettingPage::optionNeedRestartChanged, m_setdialog, &SettingDialog::toastTakeEffectReboot); m_setdialog->addPage(editorPage); + id = editorPage->id(); + Q_ASSERT(!id.isEmpty()); + Q_ASSERT(usedIDs.indexOf(id) < 0); + usedIDs.append(id); + auto plgPage = new PluginSettingDialog(m_setdialog); connect(plgPage, &SettingPage::optionNeedRestartChanged, m_setdialog, &SettingDialog::toastTakeEffectReboot); - plgPage->buildUp(m_settingPages); + plgPage->buildUp(m_plgPages); m_setdialog->addPage(plgPage); + id = plgPage->id(); + Q_ASSERT(!id.isEmpty()); + Q_ASSERT(usedIDs.indexOf(id) < 0); + usedIDs.append(id); auto scriptPage = new ScriptSettingDialog(m_setdialog); connect(scriptPage, &SettingPage::optionNeedRestartChanged, m_setdialog, &SettingDialog::toastTakeEffectReboot); m_setdialog->addPage(scriptPage); - - for (auto &page : m_settingPages) { - if (!page->isInPluginPage()) { - connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog, - &SettingDialog::toastTakeEffectReboot); - m_setdialog->addPage(page); - } - } + id = scriptPage->id(); + Q_ASSERT(!id.isEmpty()); + Q_ASSERT(usedIDs.indexOf(id) < 0); + usedIDs.append(id); auto otherPage = new OtherSettingsDialog(m_setdialog); + id = otherPage->id(); + Q_ASSERT(!id.isEmpty()); + Q_ASSERT(usedIDs.indexOf(id) < 0); + usedIDs.append(id); + + for (auto page_p = m_settingPages.constKeyValueBegin(); + page_p != m_settingPages.constKeyValueEnd(); ++page_p) { + auto page = page_p->first; + auto name = page->name(); + auto id = page->id(); + + // check + if (id.isEmpty()) { + id = name; + auto plg = page->property("__plg__").value(); + Logger::warning( + QStringLiteral("[") + plg->metaObject()->className() + + QStringLiteral("::") + name + QStringLiteral("] ") + + QStringLiteral(":") + tr("SetPageIDEmptyTryUseName")); + } + + if (usedIDs.contains(id)) { + auto plg = page->property("__plg__").value(); + Logger::critical( + QStringLiteral("[") + plg->metaObject()->className() + + QStringLiteral("::") + name + QStringLiteral("] ") + + QStringLiteral(":") + tr("SetPageDupNameIgnored")); + continue; + } + + connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog, + &SettingDialog::toastTakeEffectReboot); + m_setdialog->addPage(page); + if (page_p->second) { + auto icon = page->categoryIcon(); + addPannelAction(m_pluginSettingsGroup, icon, name, + [=] { m_setdialog->showConfig(id); }); + } + usedIDs.append(id); + } + connect(otherPage, &SettingPage::optionNeedRestartChanged, m_setdialog, &SettingDialog::toastTakeEffectReboot); m_setdialog->addPage(otherPage); diff --git a/src/dialog/mainwindow.h b/src/dialog/mainwindow.h index c8afdfd..56f7207 100644 --- a/src/dialog/mainwindow.h +++ b/src/dialog/mainwindow.h @@ -486,10 +486,12 @@ private: EditorView *m_curEditor = nullptr; SettingDialog *m_setdialog = nullptr; + SettingDialog *m_plgsetdlg = nullptr; RecentFileManager *m_recentmanager = nullptr; QMenu *m_recentMenu = nullptr; RibbonButtonGroup *m_scriptDBGroup = nullptr; + RibbonButtonGroup *m_pluginSettingsGroup = nullptr; ScriptManager::ScriptActionMaps _scriptMaps; //=================================================== @@ -525,7 +527,8 @@ private: QHash m_ribbonMaps; QList m_hexContextMenu; QMap> m_editorViewWidgets; - QList m_settingPages; + QHash m_settingPages; + QList m_plgPages; QList m_editorViewWidgetsBuffer; ads::CDockAreaWidget *m_leftViewArea = nullptr; diff --git a/src/dialog/scriptingdialog.cpp b/src/dialog/scriptingdialog.cpp index 839e189..47fc773 100644 --- a/src/dialog/scriptingdialog.cpp +++ b/src/dialog/scriptingdialog.cpp @@ -33,6 +33,7 @@ #include "qeditor.h" #include "qformatscheme.h" #include "qlinemarksinfocenter.h" +#include "qsnippetmanager.h" #include #include @@ -95,6 +96,9 @@ ScriptingDialog::ScriptingDialog(QWidget *parent) m_language = new QLanguageFactory(format, this); m_language->addDefinitionPath(QStringLiteral(":/qcodeedit")); + auto snippet = new QSnippetManager(this); + m_snipbind = new QSnippetBinding(snippet); + auto lmic = QLineMarksInfoCenter::instance(); lmic->loadMarkTypes(QCE::fetchDataFile(":/qcodeedit/marks.qxm")); // get symbol ID @@ -120,6 +124,8 @@ ScriptingDialog::ScriptingDialog(QWidget *parent) this->setUpdatesEnabled(true); } +ScriptingDialog::~ScriptingDialog() { delete m_snipbind; } + void ScriptingDialog::initConsole() { Q_ASSERT(m_consoleout); m_consoleout->init(); @@ -243,8 +249,7 @@ void ScriptingDialog::buildUpRibbonBar() { buildViewPage(m_ribbon->addTab(tr("View"))); m_editStateWidgets << buildDebugPage(m_ribbon->addTab(tr("Debugger"))); - // TODO: not available for v1.0.0 - // buildSettingPage(m_ribbon->addTab(tr("Setting"))); + buildSettingPage(m_ribbon->addTab(tr("Setting"))); buildAboutPage(m_ribbon->addTab(tr("About"))); connect(m_ribbon, &Ribbon::onDragDropFiles, this, @@ -719,6 +724,7 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) { }); m_language->setLanguage(editor->editor(), QStringLiteral("AngelScript")); + editor->editor()->addInputBinding(m_snipbind); m_views.append(editor); diff --git a/src/dialog/scriptingdialog.h b/src/dialog/scriptingdialog.h index 9f54af4..a4ce9bd 100644 --- a/src/dialog/scriptingdialog.h +++ b/src/dialog/scriptingdialog.h @@ -32,6 +32,7 @@ #include "model/dbgcallstackmodel.h" #include "model/dbgvarshowmodel.h" #include "qlanguagefactory.h" +#include "qsnippetbinding.h" #include "utilities.h" #include @@ -70,6 +71,7 @@ private: public: explicit ScriptingDialog(QWidget *parent = nullptr); + virtual ~ScriptingDialog(); void initConsole(); @@ -250,6 +252,7 @@ private: ads::CDockManager *m_dock = nullptr; ads::CDockAreaWidget *m_editorViewArea = nullptr; QLanguageFactory *m_language = nullptr; + QSnippetBinding *m_snipbind = nullptr; QByteArray _defaultLayout; QByteArray _savedLayout; diff --git a/src/dialog/settingdialog.cpp b/src/dialog/settingdialog.cpp index 850b725..bcdee24 100644 --- a/src/dialog/settingdialog.cpp +++ b/src/dialog/settingdialog.cpp @@ -75,6 +75,19 @@ void SettingDialog::showConfig(int index) { _dialog->exec(); } +void SettingDialog::showConfig(const QString &id) { + if (id.isEmpty()) { + ui->listWidget->setCurrentRow(0); + } + auto r = std::find_if( + m_pages.begin(), m_pages.end(), + [id](const WingHex::SettingPage *page) { return page->id() == id; }); + if (r == m_pages.end()) { + ui->listWidget->setCurrentRow(0); + } + ui->listWidget->setCurrentRow(m_pages.indexOf(*r)); +} + void SettingDialog::toastTakeEffectReboot() { auto page = qobject_cast(sender()); if (page) { diff --git a/src/dialog/settingdialog.h b/src/dialog/settingdialog.h index f4bdd75..be9ab27 100644 --- a/src/dialog/settingdialog.h +++ b/src/dialog/settingdialog.h @@ -36,6 +36,7 @@ public: void addPage(WingHex::SettingPage *page); void build(); // you can only call once void showConfig(int index = -1); + void showConfig(const QString &id); public slots: void toastTakeEffectReboot(); diff --git a/src/model/metadatamodel.cpp b/src/model/metadatamodel.cpp index 576b3e9..70895b8 100644 --- a/src/model/metadatamodel.cpp +++ b/src/model/metadatamodel.cpp @@ -32,7 +32,8 @@ int MetaDataModel::columnCount(const QModelIndex &parent) const { QVariant MetaDataModel::data(const QModelIndex &index, int role) const { switch (role) { - case Qt::DisplayRole: { + case Qt::DisplayRole: + case Qt::ToolTipRole: { auto r = index.row(); const auto &b = _doc->metadata()->getAllMetadata(); auto d = b.at(r); @@ -47,52 +48,28 @@ QVariant MetaDataModel::data(const QModelIndex &index, int role) const { if (d.foreground.alpha() == 0) { return QStringLiteral("-"); } - return QVariant(); - break; + return d.foreground.name(); } case 3: if (d.background.alpha() == 0) { return QStringLiteral("-"); } - return QVariant(); - break; + return d.background.name(); case 4: return d.comment; } } - case Qt::ToolTipRole: { - auto r = index.row(); - const auto &b = _doc->metadata()->getAllMetadata(); - auto d = b.at(r); - switch (index.column()) { - case 2: { - if (d.foreground.alpha() == 0) { - return QStringLiteral("-"); - } else { - return d.foreground.name(); - } - break; - } - case 3: - if (d.background.alpha() == 0) { - return QStringLiteral("-"); - } else { - return d.background.name(); - } - break; - case 4: - return d.comment; - } - } break; - case Qt::BackgroundRole: { + case Qt::DecorationRole: { auto r = index.row(); const auto &b = _doc->metadata()->getAllMetadata(); auto d = b.at(r); switch (index.column()) { case 2: - return d.foreground; + if (d.foreground.alpha() > 0) + return d.foreground; case 3: - return d.background; + if (d.background.alpha() > 0) + return d.background; default: break; } diff --git a/src/plugin/iwingplugin.h b/src/plugin/iwingplugin.h index 87fd258..55c5f63 100644 --- a/src/plugin/iwingplugin.h +++ b/src/plugin/iwingplugin.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -496,6 +497,10 @@ signals: class IWingPlugin : public QObject { Q_OBJECT +public: + // TODO: implement the basic type only + typedef std::function ScriptFn; + public: virtual int sdkVersion() const = 0; virtual const QString signature() const = 0; @@ -515,11 +520,18 @@ public: virtual QList registeredRibbonTools() const { return {}; } - virtual QList registeredSettingPages() const { return {}; } + // QMap + virtual QHash registeredSettingPages() const { + return {}; + } + virtual QList registeredPages() const { return {}; } virtual QList registeredEditorViewWidgets() const { return {}; } + // QHash + virtual QHash registeredScriptFn() { return {}; } + signals: // extension and exposed to WingHexAngelScript void toast(const QPixmap &icon, const QString &message); diff --git a/src/plugin/pluginsystem.cpp b/src/plugin/pluginsystem.cpp index 75ff91d..5e45df0 100644 --- a/src/plugin/pluginsystem.cpp +++ b/src/plugin/pluginsystem.cpp @@ -130,17 +130,28 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) { // clean up for (auto &plg : v) { auto handles = m_plgHandles.value(plg); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) handles.erase( std::remove_if(handles.begin(), handles.end(), [view](const QPair &v) { return v.second == view; })); - } +#else + handles.removeIf([view](const QPair &v) { + return v.second == view; + }); +#endif + } m_viewBindings.remove(view); } } +void PluginSystem::registerFn(IWingPlugin *plg, + const IWingPlugin::ScriptFn &fn) { + // TODO +} + bool PluginSystem::loadPlugin(IWingPlugin *p) { QList loadedplginfos; try { @@ -267,17 +278,43 @@ bool PluginSystem::loadPlugin(IWingPlugin *p) { } } - if (p->registeredHexContextMenu()) { - _win->m_hexContextMenu.append(p->registeredHexContextMenu()); + { + auto menu = p->registeredHexContextMenu(); + if (menu) { + _win->m_hexContextMenu.append(menu); + } } - if (!p->registeredEditorViewWidgets().isEmpty()) { - _win->m_editorViewWidgets.insert(p, - p->registeredEditorViewWidgets()); + { + auto vieww = p->registeredEditorViewWidgets(); + if (!vieww.isEmpty()) { + _win->m_editorViewWidgets.insert(p, vieww); + } } - if (!p->registeredSettingPages().isEmpty()) { - _win->m_settingPages.append(p->registeredSettingPages()); + { + auto sp = p->registeredSettingPages(); + if (!sp.isEmpty()) { + for (auto page = sp.keyBegin(); page != sp.keyEnd(); ++page) { + auto pp = *page; + pp->setProperty("__plg__", QVariant::fromValue(p)); + } + _win->m_settingPages.insert(sp); + } + } + + { + auto rp = p->registeredPages(); + if (!rp.isEmpty()) { + for (auto &page : rp) { + page->setProperty("__plg__", QVariant::fromValue(p)); + } + _win->m_plgPages.append(rp); + } + } + + for (auto &fn : p->registeredScriptFn()) { + registerFn(p, fn); } connectInterface(p); diff --git a/src/plugin/pluginsystem.h b/src/plugin/pluginsystem.h index 97999cd..4bcc246 100644 --- a/src/plugin/pluginsystem.h +++ b/src/plugin/pluginsystem.h @@ -115,6 +115,8 @@ public: void cleanUpEditorViewHandle(EditorView *view); + void registerFn(IWingPlugin *plg, const IWingPlugin::ScriptFn &fn); + private: bool loadPlugin(IWingPlugin *p); diff --git a/src/plugin/settingpage.h b/src/plugin/settingpage.h index f5a6b20..c04c483 100644 --- a/src/plugin/settingpage.h +++ b/src/plugin/settingpage.h @@ -22,23 +22,35 @@ namespace WingHex { -class SettingPage : public QWidget { +class PageBase : public QWidget { +public: + explicit PageBase(QWidget *parent = nullptr) : QWidget(parent) {} + +public: + virtual QIcon categoryIcon() const = 0; + virtual QString name() const = 0; + virtual QString id() const = 0; +}; + +class SettingPage : public PageBase { Q_OBJECT public: - explicit SettingPage(QWidget *parent = nullptr) : QWidget(parent) {} + explicit SettingPage(QWidget *parent = nullptr) : PageBase(parent) {} signals: void optionNeedRestartChanged(); public: - virtual QIcon categoryIcon() const = 0; - virtual QString name() const = 0; - virtual bool isInPluginPage() const = 0; virtual void apply() = 0; virtual void reset() = 0; virtual void cancel() = 0; }; +class PluginPage : public PageBase { +public: + explicit PluginPage(QWidget *parent = nullptr) : PageBase(parent) {} +}; + } // namespace WingHex #endif // SETTINGPAGE_H diff --git a/src/qcodeeditwidget/qeditconfig.cpp b/src/qcodeeditwidget/qeditconfig.cpp index afaf309..08a5b25 100644 --- a/src/qcodeeditwidget/qeditconfig.cpp +++ b/src/qcodeeditwidget/qeditconfig.cpp @@ -192,7 +192,7 @@ QIcon QEditConfig::categoryIcon() const { return ICONRES("file"); } QString QEditConfig::name() const { return tr("Edit"); } -bool QEditConfig::isInPluginPage() const { return false; } +QString QEditConfig::id() const { return QStringLiteral("Edit"); } /*! \brief Fills the widget subcontrols from a settings map diff --git a/src/qcodeeditwidget/qeditconfig.h b/src/qcodeeditwidget/qeditconfig.h index 2064090..083a339 100644 --- a/src/qcodeeditwidget/qeditconfig.h +++ b/src/qcodeeditwidget/qeditconfig.h @@ -20,8 +20,7 @@ public: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; - + virtual QString id() const override; virtual void apply() override; virtual void cancel() override; virtual void reset() override; diff --git a/src/qcodeeditwidget/qformatconfig.cpp b/src/qcodeeditwidget/qformatconfig.cpp index a7592ac..b61594a 100644 --- a/src/qcodeeditwidget/qformatconfig.cpp +++ b/src/qcodeeditwidget/qformatconfig.cpp @@ -103,8 +103,6 @@ QIcon QFormatConfig::categoryIcon() const { return ICONRES(""); } QString QFormatConfig::name() const { return tr("Format"); } -bool QFormatConfig::isInPluginPage() const { return false; } - /*! \brief Add a format scheme to the config widget diff --git a/src/qcodeeditwidget/qformatconfig.h b/src/qcodeeditwidget/qformatconfig.h index 178eb2b..d909b24 100644 --- a/src/qcodeeditwidget/qformatconfig.h +++ b/src/qcodeeditwidget/qformatconfig.h @@ -26,7 +26,6 @@ public: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; virtual void apply() override; virtual void cancel() override; virtual void reset() override; diff --git a/src/qcodeeditwidget/qsnippetedit.cpp b/src/qcodeeditwidget/qsnippetedit.cpp index 4628cbf..4921414 100644 --- a/src/qcodeeditwidget/qsnippetedit.cpp +++ b/src/qcodeeditwidget/qsnippetedit.cpp @@ -34,13 +34,15 @@ */ QSnippetEdit::QSnippetEdit(QWidget *p) - : QWidget(p), m_editedSnippet(-1), m_manager(nullptr) { + : QWidget(p), ui(new Ui::QSnippetEdit), m_editedSnippet(-1), + m_manager(nullptr) { ui->setupUi(this); setEnabled(false); } QSnippetEdit::QSnippetEdit(QSnippetManager *mgr, QWidget *p) - : QWidget(p), m_editedSnippet(-1), m_manager(nullptr) { + : QWidget(p), ui(new Ui::QSnippetEdit), m_editedSnippet(-1), + m_manager(nullptr) { ui->setupUi(this); setSnippetManager(mgr); } diff --git a/src/settings/editorsettingdialog.cpp b/src/settings/editorsettingdialog.cpp index 1124f95..2eff641 100644 --- a/src/settings/editorsettingdialog.cpp +++ b/src/settings/editorsettingdialog.cpp @@ -45,7 +45,7 @@ QIcon EditorSettingDialog::categoryIcon() const { return ICONRES("edit"); } QString EditorSettingDialog::name() const { return tr("Editor"); } -bool EditorSettingDialog::isInPluginPage() const { return false; } +QString EditorSettingDialog::id() const { return QStringLiteral("Editor"); } void EditorSettingDialog::apply() { auto &set = SettingManager::instance(); diff --git a/src/settings/editorsettingdialog.h b/src/settings/editorsettingdialog.h index b815398..a47b550 100644 --- a/src/settings/editorsettingdialog.h +++ b/src/settings/editorsettingdialog.h @@ -41,7 +41,7 @@ private: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; + virtual QString id() const override; virtual void apply() override; virtual void reset() override; virtual void cancel() override; diff --git a/src/settings/generalsettingdialog.cpp b/src/settings/generalsettingdialog.cpp index 58710f1..f0e401d 100644 --- a/src/settings/generalsettingdialog.cpp +++ b/src/settings/generalsettingdialog.cpp @@ -111,7 +111,7 @@ QIcon GeneralSettingDialog::categoryIcon() const { return ICONRES("general"); } QString GeneralSettingDialog::name() const { return tr("General"); } -bool GeneralSettingDialog::isInPluginPage() const { return false; } +QString GeneralSettingDialog::id() const { return QStringLiteral("General"); } void GeneralSettingDialog::apply() { auto &set = SettingManager::instance(); diff --git a/src/settings/generalsettingdialog.h b/src/settings/generalsettingdialog.h index e841a22..348229c 100644 --- a/src/settings/generalsettingdialog.h +++ b/src/settings/generalsettingdialog.h @@ -41,7 +41,7 @@ private: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; + virtual QString id() const override; virtual void apply() override; virtual void reset() override; virtual void cancel() override; diff --git a/src/settings/othersettingsdialog.cpp b/src/settings/othersettingsdialog.cpp index 2da4939..7d5c601 100644 --- a/src/settings/othersettingsdialog.cpp +++ b/src/settings/othersettingsdialog.cpp @@ -64,7 +64,7 @@ QIcon OtherSettingsDialog::categoryIcon() const { return ICONRES("other"); } QString OtherSettingsDialog::name() const { return tr("Others"); } -bool OtherSettingsDialog::isInPluginPage() const { return false; } +QString OtherSettingsDialog::id() const { return QStringLiteral("Others"); } void OtherSettingsDialog::apply() { auto &set = SettingManager::instance(); diff --git a/src/settings/othersettingsdialog.h b/src/settings/othersettingsdialog.h index b124ca4..59f032b 100644 --- a/src/settings/othersettingsdialog.h +++ b/src/settings/othersettingsdialog.h @@ -41,7 +41,7 @@ private: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; + virtual QString id() const override; virtual void apply() override; virtual void reset() override; virtual void cancel() override; diff --git a/src/settings/pluginsettingdialog.cpp b/src/settings/pluginsettingdialog.cpp index f84655b..04ae29f 100644 --- a/src/settings/pluginsettingdialog.cpp +++ b/src/settings/pluginsettingdialog.cpp @@ -47,13 +47,10 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent) PluginSettingDialog::~PluginSettingDialog() { delete ui; } -void PluginSettingDialog::buildUp(const QList &pages) { +void PluginSettingDialog::buildUp(const QList &pages) { ASSERT_SINGLETON; for (auto &page : pages) { - if (page->isInPluginPage()) { - ui->tabWidget->addTab(page, page->categoryIcon(), page->name()); - _pages << page; - } + ui->tabWidget->addTab(page, page->categoryIcon(), page->name()); } } @@ -69,24 +66,17 @@ QIcon PluginSettingDialog::categoryIcon() const { return ICONRES("plugin"); } QString PluginSettingDialog::name() const { return tr("Plugin"); } -bool PluginSettingDialog::isInPluginPage() const { return false; } +QString PluginSettingDialog::id() const { return QStringLiteral("Plugin"); } void PluginSettingDialog::apply() { auto &set = SettingManager::instance(); set.setEnablePlugin(ui->cbEnablePlugin->isChecked()); set.setEnablePlgInRoot(ui->cbEnablePluginRoot->isChecked()); set.save(SettingManager::SETTING::PLUGIN); - - for (auto &page : _pages) { - page->apply(); - } } void PluginSettingDialog::reset() { SettingManager::instance().reset(SettingManager::SETTING::PLUGIN); - for (auto &page : _pages) { - page->reset(); - } reload(); } diff --git a/src/settings/pluginsettingdialog.h b/src/settings/pluginsettingdialog.h index b49fd69..4236792 100644 --- a/src/settings/pluginsettingdialog.h +++ b/src/settings/pluginsettingdialog.h @@ -32,11 +32,10 @@ public: explicit PluginSettingDialog(QWidget *parent = nullptr); ~PluginSettingDialog(); - void buildUp(const QList &pages); + void buildUp(const QList &pages); private: Ui::PluginSettingDialog *ui; - QList _pages; void reload(); @@ -44,7 +43,7 @@ private: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; + virtual QString id() const override; virtual void apply() override; virtual void reset() override; virtual void cancel() override; diff --git a/src/settings/scriptsettingdialog.cpp b/src/settings/scriptsettingdialog.cpp index 7ab214d..c8c3586 100644 --- a/src/settings/scriptsettingdialog.cpp +++ b/src/settings/scriptsettingdialog.cpp @@ -76,7 +76,7 @@ QIcon ScriptSettingDialog::categoryIcon() const { return ICONRES("script"); } QString ScriptSettingDialog::name() const { return tr("Script"); } -bool ScriptSettingDialog::isInPluginPage() const { return false; } +QString ScriptSettingDialog::id() const { return QStringLiteral("Script"); } void ScriptSettingDialog::apply() { QStringList usrHideCats; diff --git a/src/settings/scriptsettingdialog.h b/src/settings/scriptsettingdialog.h index 8ac1fc0..2b78cd2 100644 --- a/src/settings/scriptsettingdialog.h +++ b/src/settings/scriptsettingdialog.h @@ -48,7 +48,7 @@ private: public: virtual QIcon categoryIcon() const override; virtual QString name() const override; - virtual bool isInPluginPage() const override; + virtual QString id() const override; virtual void apply() override; virtual void reset() override; virtual void cancel() override; diff --git a/3rdparty/qcodeedit2/snippets/doxclass.qcs b/src/snippets/doxclass.qcs similarity index 100% rename from 3rdparty/qcodeedit2/snippets/doxclass.qcs rename to src/snippets/doxclass.qcs