feat: 完善插件系统;增加测试插件;完善 README;
This commit is contained in:
parent
893f3112c7
commit
e47b96b563
|
@ -60,6 +60,12 @@ RibbonTabContent *Ribbon::addTab(const QString &tabName) {
|
|||
return ribbonTabContent;
|
||||
}
|
||||
|
||||
void Ribbon::addTab(RibbonTabContent *tabContent, const QString &tabName) {
|
||||
if (tabContent) {
|
||||
QTabWidget::addTab(tabContent, tabName);
|
||||
}
|
||||
}
|
||||
|
||||
RibbonTabContent *Ribbon::addTab(const QIcon &tabIcon, const QString &tabName) {
|
||||
// Note: superclass QTabWidget also has a function addTab()
|
||||
RibbonTabContent *ribbonTabContent = new RibbonTabContent;
|
||||
|
|
|
@ -29,6 +29,11 @@ public:
|
|||
/// \param[in] tabName Name of the tab
|
||||
RibbonTabContent *addTab(const QString &tabName);
|
||||
|
||||
/// Add a tab to the ribbon.
|
||||
///
|
||||
/// \param[in] tabContent pointer of the tab
|
||||
void addTab(RibbonTabContent *tabContent, const QString &tabName);
|
||||
|
||||
/// Add a tab to the ribbon.
|
||||
///
|
||||
/// \param[in] tabIcon Icon of the tab
|
||||
|
|
|
@ -17,6 +17,11 @@ find_package(
|
|||
Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network Concurrent
|
||||
PrintSupport Xml LinguistTools)
|
||||
|
||||
option(BUILD_TEST_PLUGIN OFF)
|
||||
if(BUILD_TEST_PLUGIN)
|
||||
add_subdirectory(TestPlugin)
|
||||
endif()
|
||||
|
||||
add_definitions(-DWINGHEX_VERSION="${PROJECT_VERSION}"
|
||||
-DAPP_ORG="WingCloudStudio" -DAPP_NAME="${PROJECT_NAME}")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WINGHEX_VERSION" ${PROJECT_VERSION})
|
||||
|
@ -418,6 +423,7 @@ set(PROJECT_SOURCES
|
|||
main.cpp
|
||||
src/utilities.h
|
||||
src/dbghelper.h
|
||||
src/define.h
|
||||
${QCONSOLEWIDGET_SRC}
|
||||
${QPATHEDIT_SRC}
|
||||
${WIDGET_FRAME_SRC}
|
||||
|
|
|
@ -107,6 +107,8 @@
|
|||
|
||||
  如果你想将本软件的代码用于闭源的商业代码,想要解除`GPL`系列的必须开源的限制,请必须亲自咨询我,商讨商业授权相关事宜。
|
||||
|
||||
  对于插件开发相关的,对应的开源协议就不一样了。只针对本仓库下的`src/plugin/iwingplugin.h`和`src/plugin/settingpage.h`遵守`BSD 3-Clause`协议,以允许想要做闭源和商业开发。对于本仓库下的`TestPlugin`的代码(除`TranslationUtils.cmake`这一个文件遵守`BSD 3-Clause`)遵守`MIT`协议。
|
||||
|
||||
### 使用声明
|
||||
|
||||
1. 本软件源代码不得私自应用于闭源商业用途,除非你完整开源(GPL协议的要求)。如果要将软件仓库的代码商用闭源,必须找我购买商业授权签订合同,价格私聊,非诚勿扰。
|
||||
|
|
|
@ -107,6 +107,8 @@ This software complies with the `AGPL-3.0` agreement. Please do not use it for p
|
|||
|
||||
If you want to use the code of this software for closed-source commercial code and want to lift the restriction of the `GPL` series that it must be open source, please consult me in person to discuss commercial licensing matters.
|
||||
|
||||
For plugin development, the corresponding open source agreements are different. Only `src/plugin/iwingplugin.h` and `src/plugin/settingpage.h` in this repository comply with the `BSD 3-Clause` agreement to allow closed-source and commercial development. The code of `TestPlugin` in this repository (except the file `TranslationUtils.cmake` which complies with `BSD 3-Clause`) complies with the `MIT` agreement.
|
||||
|
||||
### Usage Statement
|
||||
|
||||
1. The source code of this software shall not be used for closed-source commercial purposes unless you open source it completely (as required by the GPL agreement). If you want to commercially close the code of the software warehouse, you must contact me to purchase a commercial license and sign a contract. Please contact me for the price. Please do not disturb me if you are not serious.
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(TestPlugin)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Test mode, please configure the main program directory to facilitate debugging
|
||||
|
||||
# 测试模式,启用请配置主程序目录,方便调试
|
||||
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
option(TEST_MODE TRUE)
|
||||
|
||||
# Set the location where the SDK is stored. Only iwingplugin.h and settingpage.h
|
||||
# are required.
|
||||
|
||||
# 设置存放 SDK 的位置,只须 iwingplugin.h 和 settingpage.h 存在
|
||||
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
set(WINGHEX_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../src/plugin")
|
||||
|
||||
set(PLUGIN_INTERFACE_FOUND FALSE)
|
||||
set(PLUGIN_SETPAGE_FOUND FALSE)
|
||||
if(EXISTS "${WINGHEX_SDK}/iwingplugin.h")
|
||||
set(PLUGIN_INTERFACE_FOUND TRUE)
|
||||
endif()
|
||||
if(EXISTS "${WINGHEX_SDK}/settingpage.h")
|
||||
set(PLUGIN_SETPAGE_FOUND TRUE)
|
||||
endif()
|
||||
if(PLUGIN_INTERFACE_FOUND AND PLUGIN_SETPAGE_FOUND)
|
||||
message(STATUS "${WINGHEX_SDK} is valid SDK path")
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid SDK path!")
|
||||
endif()
|
||||
|
||||
set(WINGHEX_SDK_HEADER "${WINGHEX_SDK}/iwingplugin.h"
|
||||
"${WINGHEX_SDK}/settingpage.h")
|
||||
include_directories(${WINGHEX_SDK})
|
||||
|
||||
# For Qt
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
|
||||
find_package(
|
||||
Qt${QT_VERSION_MAJOR}
|
||||
COMPONENTS Widgets LinguistTools
|
||||
REQUIRED)
|
||||
|
||||
set(TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/lang/TestPlugin_zh_CN.ts")
|
||||
|
||||
set(TRANSLATION_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(${QT_VERSION_MAJOR} EQUAL 5)
|
||||
qt5_create_translation(QM_FILES ${TRANSLATION_PATH} ${TS_FILES} OPTIONS
|
||||
-no-obsolete)
|
||||
elseif(${QT_VERSION_MAJOR} EQUAL 6)
|
||||
qt6_create_translation(QM_FILES ${TRANSLATION_PATH} ${TS_FILES} OPTIONS
|
||||
-no-obsolete)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported QT version")
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/TranslationUtils.cmake)
|
||||
add_plugin_translations_resource(QM_RES TestPlugin ${QM_FILES})
|
||||
|
||||
add_library(
|
||||
TestPlugin SHARED
|
||||
${WINGHEX_SDK_HEADER}
|
||||
testplugin.h
|
||||
testplugin.cpp
|
||||
TestPlugin.json
|
||||
testform.h
|
||||
testform.cpp
|
||||
testform.ui
|
||||
${QM_FILES}
|
||||
${QM_RES}
|
||||
resources.qrc)
|
||||
|
||||
set_target_properties(TestPlugin PROPERTIES SUFFIX ".wingplg")
|
||||
|
||||
if(TEST_MODE)
|
||||
# If you want to be able to debug easily every time you compile, please set
|
||||
# this variable. Because this test plugin is a subproject of the main
|
||||
# project, use CMAKE_BINARY_DIR
|
||||
|
||||
# 如果你想每次编译都能够方便调试的话,请设置这个变量。因为这个测试插件是和主项目子项目,所以用 CMAKE_BINARY_DIR
|
||||
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
set(WINGHEX_PATH "${CMAKE_BINARY_DIR}")
|
||||
|
||||
set(WINGHEX_PLUGIN_PATH "${WINGHEX_PATH}/plugin")
|
||||
add_custom_command(
|
||||
TARGET TestPlugin
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${WINGHEX_PLUGIN_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:TestPlugin>
|
||||
${WINGHEX_PLUGIN_PATH})
|
||||
endif()
|
||||
|
||||
target_link_libraries(TestPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
|
@ -0,0 +1,36 @@
|
|||
# TestPlugin
|
||||
|
||||
## How to Build
|
||||
|
||||
Create a build directory and run
|
||||
|
||||
cmake -DCMAKE_PREFIX_PATH=<path_to_qtcreator> -DCMAKE_BUILD_TYPE=RelWithDebInfo <path_to_plugin_source>
|
||||
cmake --build .
|
||||
|
||||
where `<path_to_qtcreator>` is the relative or absolute path to a Qt Creator build directory, or to a
|
||||
combined binary and development package (Windows / Linux), or to the `Qt Creator.app/Contents/Resources/`
|
||||
directory of a combined binary and development package (macOS), and `<path_to_plugin_source>` is the
|
||||
relative or absolute path to this plugin directory.
|
||||
|
||||
## How to Run
|
||||
|
||||
Run a compatible Qt Creator with the additional command line argument
|
||||
|
||||
-pluginpath <path_to_plugin>
|
||||
|
||||
where `<path_to_plugin>` is the path to the resulting plugin library in the build directory
|
||||
(`<plugin_build>/lib/qtcreator/plugins` on Windows and Linux,
|
||||
`<plugin_build>/Qt Creator.app/Contents/PlugIns` on macOS).
|
||||
|
||||
You might want to add `-temporarycleansettings` (or `-tcs`) to ensure that the opened Qt Creator
|
||||
instance cannot mess with your user-global Qt Creator settings.
|
||||
|
||||
When building and running the plugin from Qt Creator, you can use
|
||||
|
||||
-pluginpath "%{buildDir}/lib/qtcreator/plugins" -tcs
|
||||
|
||||
on Windows and Linux, or
|
||||
|
||||
-pluginpath "%{buildDir}/Qt Creator.app/Contents/PlugIns" -tcs
|
||||
|
||||
for the `Command line arguments` field in the run settings.
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"Id" : "testplugin",
|
||||
"Name" : "TestPlugin",
|
||||
"Version" : "0.0.1",
|
||||
"CompatVersion" : "0.0.1",
|
||||
"Vendor" : "WingCloudStudio",
|
||||
"VendorId" : "wingcloudstudio",
|
||||
"Copyright" : "wingsummer",
|
||||
"License" : "AGPL-3.0",
|
||||
"Description" : "A Test Plugin for WingHexExplorer2",
|
||||
"Url" : "https://github.com/Wing-summer/WingHexExplorer2",
|
||||
"DocumentationUrl" : ""
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2019-2022, Pedro López-Cabanillas
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,51 @@
|
|||
# ==============================================================================
|
||||
# Copyright (C) 2024-2027 WingSummer
|
||||
#
|
||||
# You can redistribute this file and/or modify it under the terms of the BSD
|
||||
# 3-Clause.
|
||||
#
|
||||
# THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# =============================================================================
|
||||
|
||||
if(NOT TARGET Qt${QT_VERSION_MAJOR}::lconvert)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"The package \"Qt${QT_VERSION_MAJOR}LinguistTools\" is required.")
|
||||
endif()
|
||||
|
||||
set(Qt_LCONVERT_EXECUTABLE Qt${QT_VERSION_MAJOR}::lconvert)
|
||||
|
||||
function(ADD_PLUGIN_TRANSLATIONS_RESOURCE res_file target)
|
||||
set(_qm_files ${ARGN})
|
||||
set(_res_file ${CMAKE_CURRENT_BINARY_DIR}/app_translations.qrc)
|
||||
|
||||
file(
|
||||
WRITE ${_res_file}
|
||||
"<!DOCTYPE RCC><RCC version=\"1.0\">\n <qresource prefix=\"/PLGLANG/${target}\">\n"
|
||||
)
|
||||
foreach(_lang ${_qm_files})
|
||||
get_filename_component(_filename ${_lang} NAME)
|
||||
file(APPEND ${_res_file} " <file>${_filename}</file>\n")
|
||||
endforeach()
|
||||
file(APPEND ${_res_file} " </qresource>\n</RCC>\n")
|
||||
|
||||
set(${res_file}
|
||||
${_res_file}
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
add_custom_target(
|
||||
lupdate
|
||||
COMMAND ${Qt${QT_VERSION_MAJOR}_LUPDATE_EXECUTABLE} -recursive
|
||||
${PROJECT_SOURCE_DIR} -ts *.ts
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMENT "Updating translations")
|
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_CN">
|
||||
<context>
|
||||
<name>TestForm</name>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="20"/>
|
||||
<source>TestForm</source>
|
||||
<translation>测试窗体</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="30"/>
|
||||
<source>Basic</source>
|
||||
<translation>基础</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="35"/>
|
||||
<source>Reader</source>
|
||||
<translation>读取器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="40"/>
|
||||
<source>Controller</source>
|
||||
<translation>控制器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="45"/>
|
||||
<source>MessageBox</source>
|
||||
<translation>信息框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="50"/>
|
||||
<source>InputBox</source>
|
||||
<translation>输入框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="55"/>
|
||||
<source>FileDialog</source>
|
||||
<translation>文件框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="60"/>
|
||||
<source>ColorDialog</source>
|
||||
<translation>颜色框</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="65"/>
|
||||
<source>DataVisual</source>
|
||||
<translation>数据可视化</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TestPlugin</name>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="56"/>
|
||||
<source>Test</source>
|
||||
<translation>测试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="66"/>
|
||||
<location filename="../testplugin.cpp" line="79"/>
|
||||
<source>TestPlugin</source>
|
||||
<translation>测试插件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testplugin.cpp" line="86"/>
|
||||
<source>A Test Plugin for WingHexExplorer2.</source>
|
||||
<translation>一个用来测试羽云十六进制编辑器2的插件</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/images/TestPlugin">
|
||||
<file>images/btn.png</file>
|
||||
<file>images/test.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,28 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "testform.h"
|
||||
#include "ui_testform.h"
|
||||
|
||||
TestForm::TestForm(QWidget *parent) : QWidget(parent), ui(new Ui::TestForm) {
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
TestForm::~TestForm() { delete ui; }
|
|
@ -0,0 +1,41 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef TESTFORM_H
|
||||
#define TESTFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class TestForm;
|
||||
}
|
||||
|
||||
class TestForm : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TestForm(QWidget *parent = nullptr);
|
||||
~TestForm();
|
||||
|
||||
private:
|
||||
Ui::TestForm *ui;
|
||||
};
|
||||
|
||||
#endif // TESTFORM_H
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TestForm</class>
|
||||
<widget class="QWidget" name="TestForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TestForm</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Basic</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Reader</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Controller</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>MessageBox</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="title">
|
||||
<string>InputBox</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_6">
|
||||
<attribute name="title">
|
||||
<string>FileDialog</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_7">
|
||||
<attribute name="title">
|
||||
<string>ColorDialog</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_8">
|
||||
<attribute name="title">
|
||||
<string>DataVisual</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,116 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "testplugin.h"
|
||||
#include "testform.h"
|
||||
|
||||
TestPlugin::TestPlugin() : puid(QStringLiteral("TestPlugin2")) {
|
||||
// 在构造函数中,所有的 API 都无法调用。插件的翻译文件也不会自动加载。
|
||||
// 在构造函数中,仅适合做一些为初始化准备的操作。
|
||||
|
||||
// 插件的语言文件会在初始化前自动加载,如果初始化失败则会被卸载
|
||||
// 初始化会传递一个配置类,插件系统会统一管理放到统一的地方,使用 INI 保存
|
||||
// 你可以自行管理,但不建议,统一管理方便使用者备份和转移插件配置
|
||||
}
|
||||
|
||||
TestPlugin::~TestPlugin() {}
|
||||
|
||||
int TestPlugin::sdkVersion() const { return WingHex::SDKVERSION; }
|
||||
|
||||
const QString TestPlugin::signature() const { return WingHex::WINGSUMMER; }
|
||||
|
||||
bool TestPlugin::init(const QSettings &set) {
|
||||
auto v = set.value("Test", 0).toInt();
|
||||
// 如果你之前启动过且正常推出,这个值一定是 5
|
||||
qDebug() << v;
|
||||
|
||||
// 和日志与 UI 相关的接口此时可用,剩余的 API 初始化成功才可用
|
||||
_tform = emit createDialog(new TestForm);
|
||||
|
||||
using TBInfo = WingHex::WingRibbonToolBoxInfo;
|
||||
TBInfo::RibbonCatagories cats;
|
||||
auto tb = new QToolButton;
|
||||
|
||||
// 这里有一个约定,对于含有图片的,前缀应为:/images/插件的 PUID
|
||||
// 其他资源,前缀应为:/res/插件的 PUID 或 /resources/插件的 PUID
|
||||
// 如果想省劲,可以统一为 /插件的 PUID,但别一个 / 完事。
|
||||
// 这很容易发生资源文件冲突!!!
|
||||
tb->setIcon(QIcon(QStringLiteral(":/images/TestPlugin/images/test.png")));
|
||||
tb->setText(tr("Test"));
|
||||
connect(tb, &QToolButton::clicked, this, [=] {
|
||||
if (_tform) {
|
||||
_tform->show();
|
||||
_tform->raise();
|
||||
}
|
||||
});
|
||||
_rtbinfo = {WingHex::WingRibbonToolBoxInfo{
|
||||
.catagory = cats.PLUGIN,
|
||||
.toolboxs = {
|
||||
TBInfo::Toolbox{.name = tr("TestPlugin"), .tools = {tb}}}}};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestPlugin::unload(QSettings &set) {
|
||||
// 设个数字,那就是 5 测试一下配置是否正常工作
|
||||
set.setValue("Test", 5);
|
||||
|
||||
_tform->close();
|
||||
_tform->deleteLater();
|
||||
}
|
||||
|
||||
const QString TestPlugin::pluginName() const { return tr("TestPlugin"); }
|
||||
|
||||
const QString TestPlugin::pluginAuthor() const { return WingHex::WINGSUMMER; }
|
||||
|
||||
uint TestPlugin::pluginVersion() const { return WingHex::SDKVERSION; }
|
||||
|
||||
const QString TestPlugin::pluginComment() const {
|
||||
return tr("A Test Plugin for WingHexExplorer2.");
|
||||
}
|
||||
|
||||
QList<WingHex::WingDockWidgetInfo> TestPlugin::registeredDockWidgets() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QMenu *TestPlugin::registeredHexContextMenu() const { return _tmenu; }
|
||||
|
||||
QList<WingHex::WingRibbonToolBoxInfo>
|
||||
TestPlugin::registeredRibbonTools() const {
|
||||
return _rtbinfo;
|
||||
}
|
||||
|
||||
QHash<WingHex::SettingPage *, bool> TestPlugin::registeredSettingPages() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<WingHex::PluginPage *> TestPlugin::registeredPages() const { return {}; }
|
||||
|
||||
QList<WingHex::WingEditorViewWidget *>
|
||||
TestPlugin::registeredEditorViewWidgets() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString TestPlugin::getPuid() const { return puid; }
|
||||
|
||||
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo>
|
||||
TestPlugin::registeredScriptFn() {
|
||||
return {};
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef TESTPLUGIN_H
|
||||
#define TESTPLUGIN_H
|
||||
|
||||
#include "iwingplugin.h"
|
||||
|
||||
class TestPlugin final : public WingHex::IWingPlugin {
|
||||
Q_OBJECT
|
||||
|
||||
// 可选:用于自定义插件唯一标帜,请不要随意取名,否则很可能会和其他插件冲突导致无法加载
|
||||
// 如果不注明,则是插件的类名作为唯一标帜,所以也不要随意给插件类起名字
|
||||
// 当然,你可以在构造函数中,使用 setProperty("puid", yourID) 来实现自定义
|
||||
Q_PROPERTY(QString puid READ getPuid CONSTANT FINAL)
|
||||
|
||||
// 这两行是必须,只有后面的 "TestPlugin.json" 你根据需要修改,
|
||||
// 具体可见 QT 文档,剩下直接 CV 大法
|
||||
Q_PLUGIN_METADATA(IID "com.wingsummer.iwingplugin" FILE "TestPlugin.json")
|
||||
Q_INTERFACES(WingHex::IWingPlugin)
|
||||
|
||||
public:
|
||||
explicit TestPlugin();
|
||||
|
||||
virtual ~TestPlugin();
|
||||
|
||||
// IWingPlugin interface (必须)
|
||||
public:
|
||||
virtual int sdkVersion() const override;
|
||||
virtual const QString signature() const override;
|
||||
virtual bool init(const QSettings &set) override;
|
||||
virtual void unload(QSettings &set) override;
|
||||
virtual const QString pluginName() const override;
|
||||
virtual const QString pluginAuthor() const override;
|
||||
virtual uint pluginVersion() const override;
|
||||
virtual const QString pluginComment() const override;
|
||||
|
||||
// IWingPlugin interface (可选)
|
||||
public:
|
||||
// 有关注册开头(register 开头)的函数,插件系统不保证有且只调用一次
|
||||
// 所以最好不要为了偷懒,在实现里面 new 和做相应操作
|
||||
virtual QList<WingHex::WingDockWidgetInfo>
|
||||
registeredDockWidgets() const override;
|
||||
virtual QMenu *registeredHexContextMenu() const override;
|
||||
virtual QList<WingHex::WingRibbonToolBoxInfo>
|
||||
registeredRibbonTools() const override;
|
||||
virtual QHash<WingHex::SettingPage *, bool>
|
||||
registeredSettingPages() const override;
|
||||
virtual QList<WingHex::PluginPage *> registeredPages() const override;
|
||||
virtual QList<WingHex::WingEditorViewWidget *>
|
||||
registeredEditorViewWidgets() const override;
|
||||
virtual QHash<QString, ScriptFnInfo> registeredScriptFn() override;
|
||||
|
||||
private:
|
||||
QString getPuid() const;
|
||||
|
||||
private:
|
||||
QDialog *_tform = nullptr;
|
||||
QMenu *_tmenu = nullptr;
|
||||
const QString puid;
|
||||
|
||||
QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo;
|
||||
};
|
||||
|
||||
#endif // TESTPLUGIN_H
|
|
@ -1966,62 +1966,62 @@
|
|||
<context>
|
||||
<name>PluginSystem</name>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="57"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="69"/>
|
||||
<source>LoadingPlugin</source>
|
||||
<translation>正在加载插件:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="274"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="297"/>
|
||||
<source>ErrLoadPluginSign</source>
|
||||
<translation>插件加载失败:非法插件签名!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="278"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="301"/>
|
||||
<source>ErrLoadPluginSDKVersion</source>
|
||||
<translation>插件加载失败:非法插件 SDK 版本!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="282"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="305"/>
|
||||
<source>ErrLoadPluginNoName</source>
|
||||
<translation>插件加载失败:非法插件名称!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="289"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="310"/>
|
||||
<source>ErrLoadLoadedPlugin</source>
|
||||
<translation>插件加载失败:重复加载插件!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="295"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="331"/>
|
||||
<source>ErrLoadInitPlugin</source>
|
||||
<translation>插件加载失败:初始化插件失败!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="309"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="338"/>
|
||||
<source>PluginName :</source>
|
||||
<translation>插件名:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="310"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="339"/>
|
||||
<source>PluginAuthor :</source>
|
||||
<translation>插件作者:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="311"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="340"/>
|
||||
<source>PluginWidgetRegister</source>
|
||||
<translation>注册插件对象中……</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1778"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1836"/>
|
||||
<source>Creating UI widget is not allowed in non-UI thread</source>
|
||||
<translation>不能够在非用户界面线程创建用户界面组件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1829"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1887"/>
|
||||
<source>FoundPluginCount</source>
|
||||
<translation>总计发现插件数目:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1835"/>
|
||||
<location filename="../../src/plugin/pluginsystem.cpp" line="1900"/>
|
||||
<source>PluginLoadingFinished</source>
|
||||
<translation>加载插件完毕!</translation>
|
||||
</message>
|
||||
|
@ -5007,17 +5007,17 @@ Do you wish to keep up to date by reloading the file?</source>
|
|||
<context>
|
||||
<name>WingAngelAPI</name>
|
||||
<message>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="66"/>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="69"/>
|
||||
<source>AngelScriptService</source>
|
||||
<translation>AngelScript 服务</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="74"/>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="77"/>
|
||||
<source>A internal plugin that provides AngelScript scripts with the ability to call the host API.</source>
|
||||
<translation>为 AngelScript 脚本提供调用主机 API 能力的内部插件。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="1867"/>
|
||||
<location filename="../../src/class/wingangelapi.cpp" line="1870"/>
|
||||
<source>NotSupportedQMetaType:</source>
|
||||
<translation>不支持的 QT 数据元类型:</translation>
|
||||
</message>
|
||||
|
|
6
main.cpp
6
main.cpp
|
@ -1,6 +1,8 @@
|
|||
#include "class/appmanager.h"
|
||||
#include "class/settingmanager.h"
|
||||
|
||||
#include "define.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
/* 有关对在 QT5 的 Win 平台禁用高 dpi 支持
|
||||
* 的原因说明:
|
||||
|
@ -41,7 +43,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
return a.exec();
|
||||
} catch (int errCode) {
|
||||
return errCode;
|
||||
} catch (CrashCode errCode) {
|
||||
return int(errCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "languagemanager.h"
|
||||
|
||||
#include "class/settingmanager.h"
|
||||
#include "define.h"
|
||||
#include "wingmessagebox.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
@ -174,11 +175,28 @@ void LanguageManager::abortAndExit() {
|
|||
"solve the problem."));
|
||||
}
|
||||
|
||||
throw(-1);
|
||||
throw CrashCode::LanguageFile;
|
||||
}
|
||||
|
||||
QLocale LanguageManager::defaultLocale() const { return _defaultLocale; }
|
||||
|
||||
QTranslator *LanguageManager::try2LoadPluginLang(const QString &plgID) {
|
||||
QDir langDir(QStringLiteral(":/PLGLANG"));
|
||||
if (!langDir.cd(plgID)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto translator = new QTranslator(this);
|
||||
if (translator->load(_defaultLocale, plgID, QStringLiteral("_"),
|
||||
langDir.absolutePath())) {
|
||||
if (qApp->installTranslator(translator)) {
|
||||
return translator;
|
||||
}
|
||||
}
|
||||
|
||||
translator->deleteLater();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LanguageManager::LanguageData LanguageManager::data() const { return _data; }
|
||||
|
||||
QStringList LanguageManager::langsDisplay() const { return m_langsDisplay; }
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QLocale>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QTranslator>
|
||||
|
||||
class LanguageManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -42,6 +43,8 @@ public:
|
|||
|
||||
QLocale defaultLocale() const;
|
||||
|
||||
QTranslator *try2LoadPluginLang(const QString &plgID);
|
||||
|
||||
private:
|
||||
LanguageManager();
|
||||
|
||||
|
|
|
@ -55,12 +55,15 @@ int WingAngelAPI::sdkVersion() const { return WingHex::SDKVERSION; }
|
|||
|
||||
const QString WingAngelAPI::signature() const { return WingHex::WINGSUMMER; }
|
||||
|
||||
bool WingAngelAPI::init(const QList<WingHex::WingPluginInfo> &loadedplugin) {
|
||||
Q_UNUSED(loadedplugin);
|
||||
bool WingAngelAPI::init(const QSettings &set) {
|
||||
Q_UNUSED(set);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WingAngelAPI::unload() { this->disconnect(); }
|
||||
void WingAngelAPI::unload(QSettings &set) {
|
||||
Q_UNUSED(set);
|
||||
this->disconnect();
|
||||
}
|
||||
|
||||
const QString WingAngelAPI::pluginName() const {
|
||||
return tr("AngelScriptService");
|
||||
|
|
|
@ -39,9 +39,8 @@ public:
|
|||
public:
|
||||
virtual int sdkVersion() const override;
|
||||
virtual const QString signature() const override;
|
||||
virtual bool
|
||||
init(const QList<WingHex::WingPluginInfo> &loadedplugin) override;
|
||||
virtual void unload() override;
|
||||
virtual bool init(const QSettings &set) override;
|
||||
virtual void unload(QSettings &set) override;
|
||||
virtual const QString pluginName() const override;
|
||||
virtual const QString pluginAuthor() const override;
|
||||
virtual uint pluginVersion() const override;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
|
||||
enum class CrashCode : int { LanguageFile = 1, PluginSetting };
|
||||
|
||||
#endif // DEFINE_H
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
namespace WingHex {
|
||||
|
||||
Q_DECL_UNUSED constexpr auto SDKVERSION = 13;
|
||||
Q_DECL_UNUSED constexpr auto SDKVERSION = 14;
|
||||
|
||||
Q_DECL_UNUSED static QString PLUGINDIR() {
|
||||
return QCoreApplication::applicationDirPath() + QStringLiteral("/plugin");
|
||||
|
@ -147,8 +147,8 @@ signals:
|
|||
bool isLocked();
|
||||
qsizetype documentLines();
|
||||
qsizetype documentBytes();
|
||||
HexPosition currentPos();
|
||||
HexPosition selectionPos();
|
||||
WingHex::HexPosition currentPos();
|
||||
WingHex::HexPosition selectionPos();
|
||||
qsizetype currentRow();
|
||||
qsizetype currentColumn();
|
||||
qsizetype currentOffset();
|
||||
|
@ -191,23 +191,19 @@ signals:
|
|||
|
||||
// metadata
|
||||
bool lineHasMetadata(qsizetype line);
|
||||
QList<HexMetadataItem> getMetadatas(qsizetype offset);
|
||||
QList<WingHex::HexMetadataItem> getMetadatas(qsizetype offset);
|
||||
|
||||
// bookmark
|
||||
bool lineHasBookMark(qsizetype line);
|
||||
QList<qsizetype> getsBookmarkPos(qsizetype line);
|
||||
BookMark bookMark(qsizetype pos);
|
||||
WingHex::BookMark bookMark(qsizetype pos);
|
||||
QString bookMarkComment(qsizetype pos);
|
||||
QList<BookMark> getBookMarks();
|
||||
QList<WingHex::BookMark> getBookMarks();
|
||||
bool existBookMark(qsizetype pos);
|
||||
|
||||
// extension
|
||||
QStringList getSupportedEncodings();
|
||||
QString currentEncoding();
|
||||
|
||||
// not available for AngelScript
|
||||
// only for plugin UI extenstion
|
||||
QDialog *createDialog(QWidget *content);
|
||||
};
|
||||
|
||||
class Controller : public QObject {
|
||||
|
@ -283,21 +279,22 @@ signals:
|
|||
bool setMetaCommentVisible(bool b);
|
||||
|
||||
// mainwindow
|
||||
ErrFile newFile();
|
||||
ErrFile openFile(const QString &filename);
|
||||
ErrFile openRegionFile(const QString &filename, qsizetype start = 0,
|
||||
qsizetype length = 1024);
|
||||
ErrFile openDriver(const QString &driver);
|
||||
ErrFile closeFile(int handle, bool force = false);
|
||||
ErrFile saveFile(int handle, bool ignoreMd5 = false);
|
||||
ErrFile exportFile(int handle, const QString &savename,
|
||||
bool ignoreMd5 = false);
|
||||
WingHex::ErrFile newFile();
|
||||
WingHex::ErrFile openFile(const QString &filename);
|
||||
WingHex::ErrFile openRegionFile(const QString &filename,
|
||||
qsizetype start = 0,
|
||||
qsizetype length = 1024);
|
||||
WingHex::ErrFile openDriver(const QString &driver);
|
||||
WingHex::ErrFile closeFile(int handle, bool force = false);
|
||||
WingHex::ErrFile saveFile(int handle, bool ignoreMd5 = false);
|
||||
WingHex::ErrFile exportFile(int handle, const QString &savename,
|
||||
bool ignoreMd5 = false);
|
||||
bool exportFileGUI();
|
||||
ErrFile saveAsFile(int handle, const QString &savename,
|
||||
bool ignoreMd5 = false);
|
||||
WingHex::ErrFile saveAsFile(int handle, const QString &savename,
|
||||
bool ignoreMd5 = false);
|
||||
bool saveAsFileGUI();
|
||||
ErrFile closeCurrentFile(bool force = false);
|
||||
ErrFile saveCurrentFile(bool ignoreMd5 = false);
|
||||
WingHex::ErrFile closeCurrentFile(bool force = false);
|
||||
WingHex::ErrFile saveCurrentFile(bool ignoreMd5 = false);
|
||||
bool openFileGUI();
|
||||
bool openRegionFileGUI();
|
||||
bool openDriverGUI();
|
||||
|
@ -313,7 +310,7 @@ signals:
|
|||
bool clearBookMark();
|
||||
|
||||
// workspace
|
||||
ErrFile openWorkSpace(const QString &filename);
|
||||
WingHex::ErrFile openWorkSpace(const QString &filename);
|
||||
bool setCurrentEncoding(const QString &encoding);
|
||||
};
|
||||
|
||||
|
@ -426,14 +423,6 @@ signals:
|
|||
|
||||
} // namespace WingPlugin
|
||||
|
||||
struct WingPluginInfo {
|
||||
QString pluginName;
|
||||
QString pluginAuthor;
|
||||
uint pluginVersion;
|
||||
QString puid;
|
||||
QString pluginComment;
|
||||
};
|
||||
|
||||
const auto WINGSUMMER = QStringLiteral("wingsummer");
|
||||
|
||||
struct WingDockWidgetInfo {
|
||||
|
@ -534,8 +523,8 @@ public:
|
|||
virtual const QString signature() const = 0;
|
||||
virtual ~IWingPlugin() = default;
|
||||
|
||||
virtual bool init(const QList<WingPluginInfo> &loadedplugin) = 0;
|
||||
virtual void unload() = 0;
|
||||
virtual bool init(const QSettings &set) = 0;
|
||||
virtual void unload(QSettings &set) = 0;
|
||||
virtual const QString pluginName() const = 0;
|
||||
virtual const QString pluginAuthor() const = 0;
|
||||
virtual uint pluginVersion() const = 0;
|
||||
|
@ -569,6 +558,10 @@ signals:
|
|||
void error(const QString &message);
|
||||
void info(const QString &message);
|
||||
|
||||
// not available for AngelScript
|
||||
// only for plugin UI extenstion
|
||||
QDialog *createDialog(QWidget *content);
|
||||
|
||||
public:
|
||||
WingPlugin::Reader reader;
|
||||
WingPlugin::Controller controller;
|
||||
|
@ -581,8 +574,6 @@ public:
|
|||
|
||||
} // namespace WingHex
|
||||
|
||||
constexpr auto IWINGPLUGIN_INTERFACE_IID = "com.wingsummer.iwingplugin";
|
||||
|
||||
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, IWINGPLUGIN_INTERFACE_IID)
|
||||
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, "com.wingsummer.iwingplugin")
|
||||
|
||||
#endif // IWINGPLUGIN_H
|
||||
|
|
|
@ -18,13 +18,16 @@
|
|||
#include "pluginsystem.h"
|
||||
#include "QJsonModel/include/QJsonModel.hpp"
|
||||
#include "Qt-Advanced-Docking-System/src/DockAreaWidget.h"
|
||||
#include "class/languagemanager.h"
|
||||
#include "class/logger.h"
|
||||
#include "class/settingmanager.h"
|
||||
#include "class/wingfiledialog.h"
|
||||
#include "class/winginputdialog.h"
|
||||
#include "class/wingmessagebox.h"
|
||||
#include "control/toast.h"
|
||||
#include "define.h"
|
||||
#include "dialog/colorpickerdialog.h"
|
||||
#include "dialog/framelessdialogbase.h"
|
||||
#include "dialog/mainwindow.h"
|
||||
#include "model/qjsontablemodel.h"
|
||||
|
||||
|
@ -37,8 +40,17 @@
|
|||
PluginSystem::PluginSystem(QObject *parent) : QObject(parent) {}
|
||||
|
||||
PluginSystem::~PluginSystem() {
|
||||
QDir udir(Utilities::getAppDataPath());
|
||||
auto plgset = QStringLiteral("plgset");
|
||||
udir.mkdir(plgset);
|
||||
if (!udir.cd(plgset)) {
|
||||
qApp->exit(int(CrashCode::PluginSetting));
|
||||
}
|
||||
|
||||
for (auto &item : loadedplgs) {
|
||||
item->unload();
|
||||
QSettings set(udir.absoluteFilePath(item->metaObject()->className()),
|
||||
QSettings::Format::IniFormat);
|
||||
item->unload(set);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +61,7 @@ const IWingPlugin *PluginSystem::plugin(qsizetype index) const {
|
|||
return loadedplgs.at(index);
|
||||
}
|
||||
|
||||
void PluginSystem::loadPlugin(QFileInfo fileinfo) {
|
||||
void PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) {
|
||||
Q_ASSERT(_win);
|
||||
|
||||
if (fileinfo.exists()) {
|
||||
|
@ -59,7 +71,7 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) {
|
|||
if (Q_UNLIKELY(p == nullptr)) {
|
||||
Logger::critical(loader.errorString());
|
||||
} else {
|
||||
if (!loadPlugin(p)) {
|
||||
if (!loadPlugin(p, setdir)) {
|
||||
loader.unload();
|
||||
}
|
||||
}
|
||||
|
@ -267,8 +279,19 @@ QString PluginSystem::getScriptFnSig(const QString &fnName,
|
|||
return sig + params.join(',') + QStringLiteral(")");
|
||||
}
|
||||
|
||||
bool PluginSystem::loadPlugin(IWingPlugin *p) {
|
||||
QList<WingPluginInfo> loadedplginfos;
|
||||
QString PluginSystem::getPUID(IWingPlugin *p) {
|
||||
if (p) {
|
||||
auto prop = p->property("puid").toString().trimmed();
|
||||
auto pid = QString(p->metaObject()->className());
|
||||
return prop.isEmpty() ? pid : prop;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool PluginSystem::loadPlugin(IWingPlugin *p, const QDir &setdir) {
|
||||
QTranslator *p_tr = nullptr;
|
||||
|
||||
try {
|
||||
if (p->signature() != WINGSUMMER) {
|
||||
throw tr("ErrLoadPluginSign");
|
||||
|
@ -282,34 +305,41 @@ bool PluginSystem::loadPlugin(IWingPlugin *p) {
|
|||
throw tr("ErrLoadPluginNoName");
|
||||
}
|
||||
|
||||
auto prop = p->property("puid").toString().trimmed();
|
||||
auto puid =
|
||||
prop.isEmpty() ? QString(p->metaObject()->className()) : prop;
|
||||
auto puid = getPUID(p);
|
||||
if (loadedpuid.contains(puid)) {
|
||||
throw tr("ErrLoadLoadedPlugin");
|
||||
}
|
||||
|
||||
emit pluginLoading(p->pluginName());
|
||||
|
||||
if (!p->init(loadedplginfos)) {
|
||||
throw tr("ErrLoadInitPlugin");
|
||||
auto pid = QString(p->metaObject()->className());
|
||||
p_tr = LanguageManager::instance().try2LoadPluginLang(pid);
|
||||
|
||||
connectLoadingInterface(p);
|
||||
|
||||
QSettings *setp;
|
||||
if (setdir == QDir()) {
|
||||
setp = new QSettings;
|
||||
} else {
|
||||
setp = new QSettings(
|
||||
setdir.absoluteFilePath(p->metaObject()->className()),
|
||||
QSettings::Format::IniFormat);
|
||||
}
|
||||
|
||||
WingPluginInfo info;
|
||||
info.puid = puid;
|
||||
info.pluginName = p->pluginName();
|
||||
info.pluginAuthor = p->pluginAuthor();
|
||||
info.pluginComment = p->pluginComment();
|
||||
info.pluginVersion = p->pluginVersion();
|
||||
if (!p->init(*setp)) {
|
||||
setp->deleteLater();
|
||||
throw tr("ErrLoadInitPlugin");
|
||||
}
|
||||
setp->deleteLater();
|
||||
|
||||
loadedplginfos.push_back(info);
|
||||
loadedplgs.push_back(p);
|
||||
loadedpuid << puid;
|
||||
|
||||
Logger::warning(tr("PluginName :") + info.pluginName);
|
||||
Logger::warning(tr("PluginAuthor :") + info.pluginAuthor);
|
||||
Logger::warning(tr("PluginName :") + p->pluginName());
|
||||
Logger::warning(tr("PluginAuthor :") + p->pluginAuthor());
|
||||
Logger::warning(tr("PluginWidgetRegister"));
|
||||
|
||||
// ensure call only once
|
||||
auto ribbonToolboxInfos = p->registeredRibbonTools();
|
||||
if (!ribbonToolboxInfos.isEmpty()) {
|
||||
for (auto &item : ribbonToolboxInfos) {
|
||||
|
@ -328,7 +358,14 @@ bool PluginSystem::loadPlugin(IWingPlugin *p) {
|
|||
}
|
||||
} else {
|
||||
if (!item.toolboxs.isEmpty()) {
|
||||
auto cat = _win->m_ribbon->addTab(item.displayName);
|
||||
bool isSys = false;
|
||||
RibbonTabContent *cat;
|
||||
if (_win->m_ribbonMaps.contains(item.catagory)) {
|
||||
isSys = true;
|
||||
cat = _win->m_ribbonMaps.value(item.catagory);
|
||||
} else {
|
||||
cat = new RibbonTabContent;
|
||||
}
|
||||
bool hasAdded = false;
|
||||
for (auto &group : item.toolboxs) {
|
||||
if (group.tools.isEmpty()) {
|
||||
|
@ -340,10 +377,13 @@ bool PluginSystem::loadPlugin(IWingPlugin *p) {
|
|||
}
|
||||
hasAdded = true;
|
||||
}
|
||||
if (hasAdded) {
|
||||
_win->m_ribbonMaps[item.catagory] = cat;
|
||||
} else {
|
||||
_win->m_ribbon->removeTab(cat);
|
||||
if (!isSys) {
|
||||
if (hasAdded) {
|
||||
_win->m_ribbon->addTab(cat, item.displayName);
|
||||
_win->m_ribbonMaps[item.catagory] = cat;
|
||||
} else {
|
||||
delete cat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,20 +470,26 @@ bool PluginSystem::loadPlugin(IWingPlugin *p) {
|
|||
}
|
||||
|
||||
registerFns(p);
|
||||
|
||||
connectInterface(p);
|
||||
|
||||
m_plgviewMap.insert(p, nullptr);
|
||||
} catch (const QString &error) {
|
||||
Logger::critical(error);
|
||||
if (p_tr) {
|
||||
p_tr->deleteLater();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginSystem::connectInterface(IWingPlugin *plg) {
|
||||
connectBaseInterface(plg);
|
||||
connectReaderInterface(plg);
|
||||
connectControllerInterface(plg);
|
||||
}
|
||||
|
||||
void PluginSystem::connectLoadingInterface(IWingPlugin *plg) {
|
||||
connectBaseInterface(plg);
|
||||
connectUIInterface(plg);
|
||||
}
|
||||
|
||||
|
@ -472,6 +518,18 @@ void PluginSystem::connectBaseInterface(IWingPlugin *plg) {
|
|||
Logger::critical(
|
||||
packLogMessage(plg->metaObject()->className(), message));
|
||||
});
|
||||
connect(plg, &IWingPlugin::createDialog, this,
|
||||
[=](QWidget *w) -> QDialog * {
|
||||
if (w) {
|
||||
auto d = new FramelessDialogBase;
|
||||
d->buildUpContent(w);
|
||||
d->setWindowTitle(w->windowTitle());
|
||||
d->setWindowIcon(w->windowIcon());
|
||||
return d;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PluginSystem::connectReaderInterface(IWingPlugin *plg) {
|
||||
|
@ -1799,7 +1857,7 @@ void PluginSystem::LoadPlugin() {
|
|||
|
||||
_angelplg = new WingAngelAPI;
|
||||
|
||||
auto ret = loadPlugin(_angelplg);
|
||||
auto ret = loadPlugin(_angelplg, QDir());
|
||||
Q_ASSERT(ret);
|
||||
Q_UNUSED(ret);
|
||||
|
||||
|
@ -1828,8 +1886,15 @@ void PluginSystem::LoadPlugin() {
|
|||
auto plgs = plugindir.entryInfoList();
|
||||
Logger::info(tr("FoundPluginCount") + QString::number(plgs.count()));
|
||||
|
||||
QDir udir(Utilities::getAppDataPath());
|
||||
auto plgset = QStringLiteral("plgset");
|
||||
udir.mkdir(plgset);
|
||||
if (!udir.cd(plgset)) {
|
||||
throw CrashCode::PluginSetting;
|
||||
}
|
||||
|
||||
for (auto &item : plgs) {
|
||||
loadPlugin(item);
|
||||
loadPlugin(item, udir);
|
||||
}
|
||||
|
||||
Logger::info(tr("PluginLoadingFinished"));
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
const QList<IWingPlugin *> &plugins() const;
|
||||
const IWingPlugin *plugin(qsizetype index) const;
|
||||
|
||||
void loadPlugin(QFileInfo filename);
|
||||
void loadPlugin(const QFileInfo &filename, const QDir &setdir);
|
||||
|
||||
WingAngelAPI *angelApi() const;
|
||||
|
||||
|
@ -123,10 +123,13 @@ private:
|
|||
QString getScriptFnSig(const QString &fnName,
|
||||
const IWingPlugin::ScriptFnInfo &fninfo);
|
||||
|
||||
QString getPUID(IWingPlugin *p);
|
||||
|
||||
private:
|
||||
bool loadPlugin(IWingPlugin *p);
|
||||
bool loadPlugin(IWingPlugin *p, const QDir &setdir);
|
||||
|
||||
void connectInterface(IWingPlugin *plg);
|
||||
void connectLoadingInterface(IWingPlugin *plg);
|
||||
void connectBaseInterface(IWingPlugin *plg);
|
||||
void connectReaderInterface(IWingPlugin *plg);
|
||||
void connectControllerInterface(IWingPlugin *plg);
|
||||
|
|
Loading…
Reference in New Issue