From a4d78b30092dd7d7ad20c34258b927ff26f813a4 Mon Sep 17 00:00:00 2001 From: roand Date: Fri, 4 Aug 2017 23:16:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=88=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=203rd?= =?UTF-8?q?party?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plugin/iplugin.h | 1 + include/plugin/pluginmanager.h | 1 + main.qbs | 124 ++++++++++ plugin.qbs | 6 + scripts/version.bat | 24 ++ scripts/version.sh | 15 ++ src/clogging.cpp | 8 + src/clogging.h | 13 + src/iplugin.cpp | 39 +++ src/iplugin.h | 192 +++++++++++++++ src/plugin.pro | 15 ++ src/plugin.qbs | 23 ++ src/pluginglobal.h | 7 + src/pluginmanager.cpp | 181 ++++++++++++++ src/pluginmanager.h | 134 ++++++++++ tests/README | 1 + tests/auto/auto.pri | 6 + tests/auto/auto.pro | 3 + tests/auto/auto.qbs | 9 + tests/auto/main.qbs | 10 + tests/auto/plugin.pro | 7 + tests/auto/tst_plugin.pri | 8 + tests/auto/tst_plugin1/icons/tst_plugin1.svg | 93 +++++++ tests/auto/tst_plugin1/imainwindow.h | 77 ++++++ tests/auto/tst_plugin1/itst_plugin1.h | 12 + tests/auto/tst_plugin1/tst_plugin1.cpp | 7 + tests/auto/tst_plugin1/tst_plugin1.h | 55 +++++ tests/auto/tst_plugin1/tst_plugin1.json | 2 + tests/auto/tst_plugin1/tst_plugin1.pro | 16 ++ tests/auto/tst_plugin1/tst_plugin1.qbs | 30 +++ tests/auto/tst_plugin1/tst_plugin1.qrc | 6 + tests/auto/tst_plugin1/tst_plugin1global.h | 9 + tests/auto/tst_plugin2/icons/tst_plugin2.svg | 93 +++++++ tests/auto/tst_plugin2/itst_plugin2.h | 12 + tests/auto/tst_plugin2/tst_plugin2.cpp | 7 + tests/auto/tst_plugin2/tst_plugin2.h | 55 +++++ tests/auto/tst_plugin2/tst_plugin2.json | 2 + tests/auto/tst_plugin2/tst_plugin2.pro | 16 ++ tests/auto/tst_plugin2/tst_plugin2.qbs | 32 +++ tests/auto/tst_plugin2/tst_plugin2.qrc | 6 + tests/auto/tst_plugin2/tst_plugin2global.h | 9 + tests/auto/tst_plugin3/icons/tst_plugin3.svg | 93 +++++++ tests/auto/tst_plugin3/itst_plugin3.h | 12 + tests/auto/tst_plugin3/tst_plugin3.cpp | 9 + tests/auto/tst_plugin3/tst_plugin3.h | 58 +++++ tests/auto/tst_plugin3/tst_plugin3.json | 2 + tests/auto/tst_plugin3/tst_plugin3.pro | 16 ++ tests/auto/tst_plugin3/tst_plugin3.qbs | 32 +++ tests/auto/tst_plugin3/tst_plugin3.qrc | 6 + tests/auto/tst_plugin3/tst_plugin3global.h | 9 + tests/auto/tst_plugin4/icons/tst_plugin4.svg | 93 +++++++ tests/auto/tst_plugin4/itst_plugin4.h | 12 + tests/auto/tst_plugin4/tst_plugin4.cpp | 9 + tests/auto/tst_plugin4/tst_plugin4.h | 55 +++++ tests/auto/tst_plugin4/tst_plugin4.json | 2 + tests/auto/tst_plugin4/tst_plugin4.pro | 15 ++ tests/auto/tst_plugin4/tst_plugin4.qbs | 32 +++ tests/auto/tst_plugin4/tst_plugin4.qrc | 6 + tests/auto/tst_plugin4/tst_plugin4global.h | 9 + .../auto/tst_pluginmanager/pluginloadlog.cpp | 27 ++ tests/auto/tst_pluginmanager/pluginloadlog.h | 25 ++ .../tst_pluginmanager/tst_pluginmanager.cpp | 232 ++++++++++++++++++ .../tst_pluginmanager/tst_pluginmanager.pro | 11 + .../tst_pluginmanager/tst_pluginmanager.qbs | 23 ++ tests/benchmarks/benchmarks.pri | 6 + tests/benchmarks/benchmarks.pro | 2 + tests/benchmarks/benchmarks.qbs | 3 + tests/benchmarks/main.qbs | 5 + tests/benchmarks/test_tmpl/main.qbs | 9 + tests/benchmarks/test_tmpl/test_tmpl.pro | 2 + tests/benchmarks/test_tmpl/test_tmpl.qbs | 3 + .../tst_test_tmpl_prf/tst_test_tmpl_prf.pro | 14 ++ .../tst_test_tmpl_prf/tst_test_tmpl_prf.qbs | 21 ++ tests/main.qbs | 6 + tests/manual/main.qbs | 10 + tests/manual/manual.pri | 2 + tests/manual/manual.pro | 4 + tests/manual/manual.qbs | 4 + tests/tests.pri | 30 +++ tests/tests.pro | 5 + tests/tests.qbs | 7 + 81 files changed, 2287 insertions(+) create mode 100644 include/plugin/iplugin.h create mode 100644 include/plugin/pluginmanager.h create mode 100644 main.qbs create mode 100644 plugin.qbs create mode 100644 scripts/version.bat create mode 100755 scripts/version.sh create mode 100644 src/clogging.cpp create mode 100644 src/clogging.h create mode 100644 src/iplugin.cpp create mode 100644 src/iplugin.h create mode 100644 src/plugin.pro create mode 100644 src/plugin.qbs create mode 100644 src/pluginglobal.h create mode 100644 src/pluginmanager.cpp create mode 100644 src/pluginmanager.h create mode 100644 tests/README create mode 100644 tests/auto/auto.pri create mode 100644 tests/auto/auto.pro create mode 100644 tests/auto/auto.qbs create mode 100644 tests/auto/main.qbs create mode 100644 tests/auto/plugin.pro create mode 100644 tests/auto/tst_plugin.pri create mode 100644 tests/auto/tst_plugin1/icons/tst_plugin1.svg create mode 100644 tests/auto/tst_plugin1/imainwindow.h create mode 100644 tests/auto/tst_plugin1/itst_plugin1.h create mode 100644 tests/auto/tst_plugin1/tst_plugin1.cpp create mode 100644 tests/auto/tst_plugin1/tst_plugin1.h create mode 100644 tests/auto/tst_plugin1/tst_plugin1.json create mode 100644 tests/auto/tst_plugin1/tst_plugin1.pro create mode 100644 tests/auto/tst_plugin1/tst_plugin1.qbs create mode 100644 tests/auto/tst_plugin1/tst_plugin1.qrc create mode 100644 tests/auto/tst_plugin1/tst_plugin1global.h create mode 100644 tests/auto/tst_plugin2/icons/tst_plugin2.svg create mode 100644 tests/auto/tst_plugin2/itst_plugin2.h create mode 100644 tests/auto/tst_plugin2/tst_plugin2.cpp create mode 100644 tests/auto/tst_plugin2/tst_plugin2.h create mode 100644 tests/auto/tst_plugin2/tst_plugin2.json create mode 100644 tests/auto/tst_plugin2/tst_plugin2.pro create mode 100644 tests/auto/tst_plugin2/tst_plugin2.qbs create mode 100644 tests/auto/tst_plugin2/tst_plugin2.qrc create mode 100644 tests/auto/tst_plugin2/tst_plugin2global.h create mode 100644 tests/auto/tst_plugin3/icons/tst_plugin3.svg create mode 100644 tests/auto/tst_plugin3/itst_plugin3.h create mode 100644 tests/auto/tst_plugin3/tst_plugin3.cpp create mode 100644 tests/auto/tst_plugin3/tst_plugin3.h create mode 100644 tests/auto/tst_plugin3/tst_plugin3.json create mode 100644 tests/auto/tst_plugin3/tst_plugin3.pro create mode 100644 tests/auto/tst_plugin3/tst_plugin3.qbs create mode 100644 tests/auto/tst_plugin3/tst_plugin3.qrc create mode 100644 tests/auto/tst_plugin3/tst_plugin3global.h create mode 100644 tests/auto/tst_plugin4/icons/tst_plugin4.svg create mode 100644 tests/auto/tst_plugin4/itst_plugin4.h create mode 100644 tests/auto/tst_plugin4/tst_plugin4.cpp create mode 100644 tests/auto/tst_plugin4/tst_plugin4.h create mode 100644 tests/auto/tst_plugin4/tst_plugin4.json create mode 100644 tests/auto/tst_plugin4/tst_plugin4.pro create mode 100644 tests/auto/tst_plugin4/tst_plugin4.qbs create mode 100644 tests/auto/tst_plugin4/tst_plugin4.qrc create mode 100644 tests/auto/tst_plugin4/tst_plugin4global.h create mode 100644 tests/auto/tst_pluginmanager/pluginloadlog.cpp create mode 100644 tests/auto/tst_pluginmanager/pluginloadlog.h create mode 100644 tests/auto/tst_pluginmanager/tst_pluginmanager.cpp create mode 100644 tests/auto/tst_pluginmanager/tst_pluginmanager.pro create mode 100644 tests/auto/tst_pluginmanager/tst_pluginmanager.qbs create mode 100644 tests/benchmarks/benchmarks.pri create mode 100644 tests/benchmarks/benchmarks.pro create mode 100644 tests/benchmarks/benchmarks.qbs create mode 100644 tests/benchmarks/main.qbs create mode 100644 tests/benchmarks/test_tmpl/main.qbs create mode 100644 tests/benchmarks/test_tmpl/test_tmpl.pro create mode 100644 tests/benchmarks/test_tmpl/test_tmpl.qbs create mode 100644 tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.pro create mode 100644 tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.qbs create mode 100644 tests/main.qbs create mode 100644 tests/manual/main.qbs create mode 100644 tests/manual/manual.pri create mode 100644 tests/manual/manual.pro create mode 100644 tests/manual/manual.qbs create mode 100644 tests/tests.pri create mode 100644 tests/tests.pro create mode 100644 tests/tests.qbs diff --git a/include/plugin/iplugin.h b/include/plugin/iplugin.h new file mode 100644 index 0000000..80a7768 --- /dev/null +++ b/include/plugin/iplugin.h @@ -0,0 +1 @@ +#include "../../src/iplugin.h" \ No newline at end of file diff --git a/include/plugin/pluginmanager.h b/include/plugin/pluginmanager.h new file mode 100644 index 0000000..e64ce24 --- /dev/null +++ b/include/plugin/pluginmanager.h @@ -0,0 +1 @@ +#include "../../src/pluginmanager.h" \ No newline at end of file diff --git a/main.qbs b/main.qbs new file mode 100644 index 0000000..f7912a7 --- /dev/null +++ b/main.qbs @@ -0,0 +1,124 @@ +import qbs +import qbs.File +import qbs.FileInfo +import qbs.Process + +Product { + type: "dynamiclibrary" + + property string productname: "" + property string version: "1" + property string description: "" + property string company: "" + property string copyright: "" + + property string applicationPath: "bin/" + property string includePath: "include/" + name + "/" + property string docPath: "share/doc/" + name + "/" + + Properties { + condition: qbs.targetOS.contains("linux") + property string rLibraryPath: "../lib/" + name + "/" + property string rLibraryTestPath: "../../../lib/" + name + "/" + } + Properties { + condition: qbs.targetOS.contains("windows") + property string rLibraryPath: "" + property string rLibraryTestPath: "" + } + + property string pubIncludePath: sourceDirectory + "/../include" + + + cpp.defines: [ + "APP_VERSION=" + "\"" + product.version + "\"", + "APP_COMPANY=" + "\"" + product.company + "\"", + "APP_PRODUCT=" + "\"" + product.productname + "\"", + "APP_DESCRIPTION=" + "\"" + product.description + "\"", + "APP_COPYRIGHT=" + "\"" + product.copyright + "\"", + "APP_NAME=" + "\"" + product.name + "\"" + ] + Depends { name: "cpp" } + + Export { + Depends { name: "cpp" } + cpp.includePaths: product.pubIncludePath + cpp.rpaths: [product.rLibraryPath, product.rLibraryTestPath] + } + + + Group { + fileTagsFilter: [ + "dynamiclibrary", + "dynamiclibrary_symlink", + "dynamiclibrary_import" + ] + qbs.install: true + qbs.installDir: product.applicationPath + "/" + product.rLibraryPath + } + + + FileTagger { + condition: publicInclude.value.length > 0 + patterns: publicInclude.value + fileTags: ["publicInclude"] + } + + Group { + fileTagsFilter: ["publicInclude"] + qbs.install: true + qbs.installDir: product.includePath + } + + Probe { + id: publicInclude + property stringList value + property string prjDir: project.sourceDirectory + property string incDir: product.pubIncludePath + "/" + product.name + + property int hack: { + //A bit of a hack to make qbs re-resolve (see QBS-996) + return File.lastModified(prjDir + "/.git/logs/HEAD"); + } + + configure: { + var list = File.directoryEntries(incDir, File.Files); + for(var dir in list) { + list[dir] = FileInfo.fileName(list[dir]); + } + value = list; + } + } + + + Probe { + id: version + property string prjDir: project.sourceDirectory + property string prdDir: product.sourceDirectory + property int hack: { + //A bit of a hack to make qbs re-resolve (see QBS-996) + return File.lastModified(prjDir + "/.git/logs/HEAD"); + } + configure: { + var cmd; + var args; + if (qbs.targetOS.contains("windows")) { + cmd = "cmd"; + args = ["/c", prjDir+"/scripts/version.bat"]; + } + if (qbs.targetOS.contains("linux")) { + cmd = "/usr/bin/sh"; + args = ["-c", prjDir+"/scripts/version.sh"]; + } + + var p = new Process(); + p.setWorkingDirectory(prdDir) + if (0 === p.exec(cmd, args)) { + found = true; + } else { + found = false; + } + p.close(); + } + } +} diff --git a/plugin.qbs b/plugin.qbs new file mode 100644 index 0000000..4bca195 --- /dev/null +++ b/plugin.qbs @@ -0,0 +1,6 @@ +Project { + references: [ + "src/plugin.qbs", + "tests/tests.qbs" + ] +} diff --git a/scripts/version.bat b/scripts/version.bat new file mode 100644 index 0000000..5999c5d --- /dev/null +++ b/scripts/version.bat @@ -0,0 +1,24 @@ +@echo off + +for /f "tokens=*" %%m in ('git rev-list -1 HEAD -- .') do ( + set commit=%%m +) +for /f "tokens=*" %%i in ('git describe --tags --always %commit%') do ( + set ver=%%i +) +set test=- +if exist src\version.h ( + for /F "TOKENS=2,3*" %%j in (version.h) do ( + set test=%%j + ) +) +for /f "tokens=*" %%k in ('git show -s --format^=format:%%ci %ver%') do ( + set datever=%%k +) + +if not %test%=="%ver%" ( + echo #ifndef VERSION_H > src\version.h + echo #define VERSION_H >> src\version.h + echo #define VER_REV "%datever% (%ver%)" >> src\version.h + echo #endif >> src\version.h +) \ No newline at end of file diff --git a/scripts/version.sh b/scripts/version.sh new file mode 100755 index 0000000..d6e2d6c --- /dev/null +++ b/scripts/version.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +TVER=`cat src/version.h | grep '#define VER_REV'` +COMMIT=`git rev-list -1 HEAD -- .` +VER=`git describe --tags --always $COMMIT` + +if [ "$TVER" != "#define VER_REV \"$VER\"" ]; then + DATE_REV=`git show -s --format=format:"%ci" $VER` + echo "#ifndef VERSION_H" > src/version.h + echo "#define VERSION_H" >> src/version.h + echo "#define VER_REV \"$DATE_REV ($VER)\"" >> src/version.h + echo "#endif" >> src/version.h +fi + + diff --git a/src/clogging.cpp b/src/clogging.cpp new file mode 100644 index 0000000..f52a375 --- /dev/null +++ b/src/clogging.cpp @@ -0,0 +1,8 @@ +#include "clogging.h" + +namespace RTPTechGroup { +namespace Plugin { + +Q_LOGGING_CATEGORY(lcPlugin,"RTPTechGroup.Plugin") + +}} diff --git a/src/clogging.h b/src/clogging.h new file mode 100644 index 0000000..6ff0c82 --- /dev/null +++ b/src/clogging.h @@ -0,0 +1,13 @@ +#ifndef CLOGGING_H +#define CLOGGING_H + +#include + +namespace RTPTechGroup { +namespace Plugin { + +Q_DECLARE_LOGGING_CATEGORY(lcPlugin) + +}} + +#endif // CLOGGING_H diff --git a/src/iplugin.cpp b/src/iplugin.cpp new file mode 100644 index 0000000..aa01a39 --- /dev/null +++ b/src/iplugin.cpp @@ -0,0 +1,39 @@ +#include "iplugin.h" + +using namespace RTPTechGroup::Plugin; + +IPlugin::IPlugin(const QString& depInterfaces) +{ + PluginManager *pluginManager = PluginManager::instance(); + m_depModulList = depInterfaces.split(" "); + foreach (const QString &depPlugin, depModulList()) { + if (!depPlugin.isEmpty()) + pluginManager->nextLoadPlugins(depPlugin); + } + if (pluginManager->settings()) + setSettings(pluginManager->settings()); +} + +IPlugin::~IPlugin() +{ + // NOTE: Возможно надо сделать на цикле for + foreach (IPlugin *plug,PluginManager::instance()->dependentPlugins(this)) { + if (!PluginManager::instance()->dependentPlugins(this).isEmpty()) + if (plug) + delete plug; + } +} + +void IPlugin::setSettings(QSettings *s){ + m_settings = s; +} + +QSettings *IPlugin::settings() +{ + return m_settings; +} + +const QStringList &IPlugin::depModulList() const +{ + return m_depModulList; +} diff --git a/src/iplugin.h b/src/iplugin.h new file mode 100644 index 0000000..c26758a --- /dev/null +++ b/src/iplugin.h @@ -0,0 +1,192 @@ +#ifndef IPLUGIN_H +#define IPLUGIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pluginmanager.h" + +QT_BEGIN_NAMESPACE +class QWidget; +class QString; +class QStringList; +class QObject; +QT_END_NAMESPACE + +#define PLUG_INTERFACES(x) QStringList interfaces(){return QString(#x).split(" ");} +#undef Q_INTERFACES +#define Q_INTERFACES(x) PLUG_INTERFACES(x) + +//! Класс плагина +/*! Этот класс предназначен для создания пользовательского + плагина путем наследования данного класса. Работа с + плагинами производится при помощи класса PluginManager + \n + Пример: \n + \b exampleplug.h + \code + #ifndef PLUG_EXAMPLE_H + #define PLUG_EXAMPLE_H + + #include + #include + + class ExamplePlug: + public QObject, + public IPlugin + { + Q_OBJECT + Q_INTERFACES(IPlugin) + Q_PLUGIN_METADATA( + IID "com.RTPTechGroup.Raindrop.Example" FILE "example.json") + #endif + + public: + + ExamplePlug(QObject *parent = 0); + + // IPlugin + //! Получение имени плагина + QString name() {return tr("Пример плагина");} + + //! Получение иконки плагина + QIcon icon() {return QIcon(":/example");} + + //! Описание продукта + QString product() {return tr("");} + + //! Авторские права + QString copyright() {return tr("");} + + //! Описание плагина + QString descript() {return tr("");} + + //! Категория в которой состоит плагин + QString category() {return tr("");} + + //! Версия плагина + QString version() {return tr("");} + + //! Производитель плагина + QString vendor() {return tr("");} + + MainWindow *window; + }; + #endif + \endcode + \b exampleplug.cpp + \code + #include "exampleplug.h" + + ExamplePlug::ExamplePlug(QObject *parent): + QObject(parent), IPlugin("IMainWindow ITreeDockWidget") + { + // Получение интерфейса ITreeDockWidget + PluginManager *pluginManager = PluginManager::instance(); + ITreeDockWidget *dockWidget + = pluginManager->interfaceObject( + "ITreeDockWidget"); + } + + void ExamplePlug::readSettings() + { + window->resize(settings->value("size", QSize(687, 582)).toSize()); + } + + void ExamplePlug::writeSettings() + { + settings->setValue("size", window->size()); + } + Q_EXPORT_PLUGIN2(example, ExamplePlug) + + \endcode +*/ + +class PLUGINLIB IPlugin +{ + +public: + //! Конструктор плагина + explicit IPlugin(const QString &depInterfaces); + + //! Деструктор плагина + virtual ~IPlugin(); + + //! Получение экземпляра + virtual QObject *instance() {return dynamic_cast(this);} + + //! Получение экземпляра с приведением типа + template T instance() {return dynamic_cast(this);} + + //! Получение определенных интерфейсов + virtual QStringList interfaces() = 0; + + //! Список зависимостей плагина + /*! Список плагинов от которых зависит текущий плагин + */ + const QStringList& depModulList() const; + + //! Устанавливает ссылку на объект для сохранения настроек + virtual void setSettings(QSettings *settings); + + //! Получает ссылку на объект для сохранения настроек + virtual QSettings *settings(); + + //! Получение имени плагина + /*! Получение наименования плагина для + отображения + */ + virtual QString name() = 0; + + //! Получение иконки плагина + /*! Получение иконки плагина для + отображения + */ + virtual QIcon icon() = 0; + + //! Описание плагина + /*! Получение описания плагина для + отображения + */ + virtual QString descript() = 0; + + //! Категория в которой состоит плагин + /*! Категория плагинов предназначена для группировки плагинов + * по смыслу в одну группу. + */ + virtual QString category() = 0; + + //! Версия плагина + virtual QString version() = 0; + + //! Производитель плагина + virtual QString vendor() = 0; + + //! Описание продукта + virtual QString product() = 0; + + //! Авторские права + virtual QString copyright() = 0; + +private: + //! Настройки + QSettings *m_settings; + + //! Список зависимостей плагина + QStringList m_depModulList; +}; + +QT_BEGIN_NAMESPACE + +#define IPlugin_iid "com.RTPTechGroup.Raindrop.IPlugin" +Q_DECLARE_INTERFACE(IPlugin, IPlugin_iid) + +QT_END_NAMESPACE + +#endif diff --git a/src/plugin.pro b/src/plugin.pro new file mode 100644 index 0000000..43caa8a --- /dev/null +++ b/src/plugin.pro @@ -0,0 +1,15 @@ +VERSION = 1.0.0 +QMAKE_TARGET_COMPANY = "RTPTechGroup" +QMAKE_TARGET_PRODUCT = "Plugin Library" +QMAKE_TARGET_DESCRIPTION = "Plugin Library" +QMAKE_TARGET_COPYRIGHT = "Copyright (C) RTPTechGroup" + +include(../libs.pri) +DEFINES += PLUGIN_LIBRARY + +greaterThan(QT_MAJOR_VERSION, 4) { + QT += widgets +} + +HEADERS = *.h +SOURCES = *.cpp diff --git a/src/plugin.qbs b/src/plugin.qbs new file mode 100644 index 0000000..5c8cdac --- /dev/null +++ b/src/plugin.qbs @@ -0,0 +1,23 @@ +import "../main.qbs" as LibProduct + +LibProduct { + name: "plugin" + + productname: "Plugin Library" + version: "1.0.0" + description: "Plugin Library" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.defines: base.concat([ + "PLUGIN_LIBRARY" + ]) + Depends { name: "Qt"; submodules: ["widgets"] } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] +} diff --git a/src/pluginglobal.h b/src/pluginglobal.h new file mode 100644 index 0000000..cc549a9 --- /dev/null +++ b/src/pluginglobal.h @@ -0,0 +1,7 @@ +#include + +#if defined(PLUGIN_LIBRARY) +# define PLUGINLIB Q_DECL_EXPORT +#else +# define PLUGINLIB Q_DECL_IMPORT +#endif diff --git a/src/pluginmanager.cpp b/src/pluginmanager.cpp new file mode 100644 index 0000000..699adae --- /dev/null +++ b/src/pluginmanager.cpp @@ -0,0 +1,181 @@ +#include "pluginmanager.h" + +#include + +#include "clogging.h" + +namespace RTPTechGroup { +namespace Plugin { + +PluginManager::PluginManager(QObject *parent) : + QObject(parent) +{ + m_instance = this; + m_settings = NULL; + m_lockFiles = NULL; + + m_pluginsDir = QDir(qApp->applicationDirPath() + "/plugins/"); +} + +PluginManager *PluginManager::m_instance = 0; + +PluginManager *PluginManager::instance() +{ + return m_instance; +} + +QObject *PluginManager::interfaceObject(QString interfaceName) +{ + return m_interfaces.value(interfaceName, NULL); +} + +QList PluginManager::interfaceObjects(QString interfaceName) +{ + return m_interfaces.values(interfaceName); +} + +PluginManager::~PluginManager() +{ + QObject *plug = interfaceObject("IPlugin"); + while (plug) { + delete plug; + plug = interfaceObject("IPlugin"); + } + delete [] m_lockFiles; +} + +QSettings *PluginManager::settings() const +{ + return m_settings; +} + +QList PluginManager::dependPlugins(IPlugin *plugin) +{ + QHash pluginList; + + if (plugin) + foreach (const QString &depInterfaceName, plugin->depModulList()) + foreach (QObject *objInterfacePlugin, interfaceObjects(depInterfaceName)) { + IPlugin *interfacePlugin = qobject_cast(objInterfacePlugin); + if (interfacePlugin) + pluginList[objInterfacePlugin->objectName()] = interfacePlugin; + } + return pluginList.values(); +} + +QList PluginManager::dependentPlugins(IPlugin *plugin) +{ + QHash pluginList; + + foreach (QObject *objPlug, m_interfaces.values("IPlugin")) { + IPlugin *plug = qobject_cast(objPlug); + if (plug && plug!=plugin) + foreach (IPlugin *interfacePlugin,dependPlugins(plug)) + if (plugin == interfacePlugin) + pluginList[objPlug->objectName()] = plug; + } + return pluginList.values(); +} + +bool PluginManager::loadPlugins() +{ + if (!m_pluginsDir.exists()) + { + qCWarning(lcPlugin) << tr("Не найден каталог с модулями ") + + m_pluginsDir.absolutePath(); + return false; + } + m_fileList = m_pluginsDir.entryList(QDir::Files); + + qint32 count = m_fileList.count(); + m_lockFiles = new bool[count]; + for (qint32 i = 0; i < count; ++i) m_lockFiles[i] = false; + + nextLoadPlugins(); + emit endLoadingPlugins(); + + return true; +} + +bool PluginManager::nextLoadPlugins(QString iid) +{ + bool result = false; + for (qint32 fileNum = m_fileList.count()-1; fileNum >= 0 ; --fileNum) + { + if (!m_lockFiles[fileNum]) { + m_lockFiles[fileNum] = true; + bool isLoad = loadPlugin(m_fileList.at(fileNum), iid); + if (!isLoad) + m_lockFiles[fileNum] = false; + result = result || isLoad; + } + } + return result; +} + +bool PluginManager::loadPlugin(QString fileName, QString iid) +{ + fileName = m_pluginsDir.absoluteFilePath(fileName); + if (!QLibrary::isLibrary(fileName)) { + qCWarning(lcPlugin) << tr("Файл не является модулем ") + fileName; + return false; + } + + QPluginLoader loader(fileName); + + QString plugIid = loader.metaData().value("IID").toString(); + QRegExp checkIid("\\."+iid+"([\\.\\][0-9]+.?[0-9]*)?"); + if (!plugIid.isEmpty() && !plugIid.contains(checkIid)) { + return false; + } + + QObject *plugin = loader.instance(); + if (plugin) + { + IPlugin *corePlugin = qobject_cast(plugin); + if (corePlugin){ + connect(plugin, &QObject::destroyed, + this, &PluginManager::removePlugin); + plugin->setObjectName(plugin->metaObject()->className()); + + foreach (const QString &interface, corePlugin->interfaces()) + m_interfaces.insert(interface, plugin); + + emit loadedPlugin(plugin); + qCDebug(lcPlugin) << tr("Загружен модуль ") + plugin->objectName(); + return true; + } else + delete plugin; + } + qCWarning(lcPlugin) << loader.errorString(); + return false; +} + +void PluginManager::setSettings(QSettings *s) +{ + m_settings = s; +} + +void PluginManager::removePlugin(QObject *obj) +{ + foreach (const QString &interface, m_interfaces.keys()) + foreach (QObject *plug,m_interfaces.values(interface)) + if (plug == obj) { + m_interfaces.remove(interface, plug); + qCDebug(lcPlugin) << tr("Очищен модуль ") + plug->objectName(); + } + qCDebug(lcPlugin) << tr("Выгружен модуль ") + obj->objectName(); + emit removedPlugin(obj); +} + +QDir PluginManager::pluginsDir() const +{ + return m_pluginsDir; +} + +void PluginManager::setPluginsDir(const QDir &pluginsDir) +{ + m_pluginsDir = pluginsDir; +} + +}} diff --git a/src/pluginmanager.h b/src/pluginmanager.h new file mode 100644 index 0000000..c9c23a8 --- /dev/null +++ b/src/pluginmanager.h @@ -0,0 +1,134 @@ +#ifndef PLUGINMANAGER_H +#define PLUGINMANAGER_H + +#include +#include "pluginglobal.h" +#include "iplugin.h" + +class IPlugin; + +namespace RTPTechGroup { +namespace Plugin { + +//! Класс для управления плагинами +/*! Данный класс предназначен для загрузки плагинов, + получения объектов плагина, сохранение настроек плагина.\n + Пример:\n + \code + QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, + QLatin1String("RTPTechGroup"), QLatin1String("UniversalPlatform")); + PluginManager pluginManager; + pluginManager.setSettings(settings); + pluginManager.loadPlugins(); + \endcode + +*/ + +class PLUGINLIB PluginManager : public QObject +{ + Q_OBJECT + + friend class IPlugin; + +public: + //! Получение экземпляра менеджера плагинов + static PluginManager *instance(); + + //! Конструктор плагина + /*! Производит инициализацию плагина при его создании + */ + explicit PluginManager(QObject *parent = 0); + + //! Деструктор плагина + /*! Производит завершающие действия при удалении плагина + */ + ~PluginManager(); + + //! Получение объекта для указанного интерфейса + QObject *interfaceObject(QString interfaceName); + + //! Получение объекта для указанного интерфейса с приведением типа + template T interfaceObject(QString interfaceName) + { + return qobject_cast(m_interfaces.value(interfaceName, NULL)); + } + + //! Получение объектов для указанного интерфейса + QList interfaceObjects(QString interfaceName); + + //! Получить зависимые плагины + /*! Позволяет получить список зависимых плагинов от указанного + */ + QList dependentPlugins(IPlugin *plugin); + + //! Получить от каких плагинов зависит + /*! Позволяет получить список плагинов от которых зависит указанный плвгин + */ + QList dependPlugins(IPlugin *plugin); + + //! Загрузка плагинов + /*! Производит поиск плагина на диске в каталоге + plugins запущенного приложения и его загрузку + */ + bool loadPlugins(); + + //! Загрузка указанного плагина + bool loadPlugin(QString fileName, QString iid = ""); + + //! Загрузка следующего плагина + bool nextLoadPlugins(QString iid = ""); + + //! Устанавливает ссылку на объект для сохранения настроек + void setSettings(QSettings *s); + + //! Получает ссылку на объект для сохранения настроек + QSettings *settings() const; + + //! Получение каталога для плагина + QDir pluginsDir() const; + + //! Установка каталога для плагина + void setPluginsDir(const QDir &pluginsDir); + +signals: + + //! Сигнал о загрузке плагина + void loadedPlugin(QObject *plugin); + + //! Сигнал об удалении плагина + void removedPlugin(QObject *plugin); + + //! Сигнал об окончании загрузки плагинов + void endLoadingPlugins(); + +private slots: + //! Удаляет указанный плагин + void removePlugin(QObject *obj); + +private: + + //! Экземпляр менеджера плагинов + static PluginManager *m_instance; + + //! Настройки + QSettings *m_settings; + + //! Список плагинов + /*! В списке плагинов хранятся загруженные плагины, которые можно получить + * по интерфейсам + */ + QMultiHash m_interfaces; + + //! Каталог нахождения плагинов + QDir m_pluginsDir; + + //! Список файлов в каталоге плагина + QStringList m_fileList; + + //! Множество заблокированных файлов + bool *m_lockFiles; +}; + +}} + +#endif // PLUGINMANAGER_H diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..711d4ba --- /dev/null +++ b/tests/README @@ -0,0 +1 @@ + Unit \ No newline at end of file diff --git a/tests/auto/auto.pri b/tests/auto/auto.pri new file mode 100644 index 0000000..12e0d8f --- /dev/null +++ b/tests/auto/auto.pri @@ -0,0 +1,6 @@ +include(../tests.pri) +INCLUDEPATH += $$PWD +QT += testlib +CONFIG += qt warn_on console depend_includepath testcase +CONFIG -= app_bundle +DEFINES -= QT_NO_CAST_FROM_ASCII diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro new file mode 100644 index 0000000..b1933ce --- /dev/null +++ b/tests/auto/auto.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS += plugin +SUBDIRS += treexmlmodel diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs new file mode 100644 index 0000000..e0162a3 --- /dev/null +++ b/tests/auto/auto.qbs @@ -0,0 +1,9 @@ +Project { + references: [ + "tst_plugin1/tst_plugin1.qbs", + "tst_plugin2/tst_plugin2.qbs", + "tst_plugin3/tst_plugin3.qbs", + "tst_plugin4/tst_plugin4.qbs", + "tst_pluginmanager/tst_pluginmanager.qbs" + ] +} diff --git a/tests/auto/main.qbs b/tests/auto/main.qbs new file mode 100644 index 0000000..0cc2de3 --- /dev/null +++ b/tests/auto/main.qbs @@ -0,0 +1,10 @@ +import "../main.qbs" as TestProduct +TestProduct { + name: "auto" + type: "application" + Group { + fileTagsFilter: ["application"] + qbs.install: true + qbs.installDir: "tests/auto/plugin/" + } +} diff --git a/tests/auto/plugin.pro b/tests/auto/plugin.pro new file mode 100644 index 0000000..ff1a63e --- /dev/null +++ b/tests/auto/plugin.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS += tst_plugin1 +SUBDIRS += tst_plugin2 +SUBDIRS += tst_plugin3 +SUBDIRS += tst_plugin4 +SUBDIRS += tst_pluginmanager diff --git a/tests/auto/tst_plugin.pri b/tests/auto/tst_plugin.pri new file mode 100644 index 0000000..47132cc --- /dev/null +++ b/tests/auto/tst_plugin.pri @@ -0,0 +1,8 @@ +LIBS += -lplugin +include(../auto.pri) + +DEPENDPATH += . +INCLUDEPATH += . +QT += widgets + +DESTDIR = $$DESTDIR/../plugins diff --git a/tests/auto/tst_plugin1/icons/tst_plugin1.svg b/tests/auto/tst_plugin1/icons/tst_plugin1.svg new file mode 100644 index 0000000..af8592e --- /dev/null +++ b/tests/auto/tst_plugin1/icons/tst_plugin1.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/tst_plugin1/imainwindow.h b/tests/auto/tst_plugin1/imainwindow.h new file mode 100644 index 0000000..3c53a60 --- /dev/null +++ b/tests/auto/tst_plugin1/imainwindow.h @@ -0,0 +1,77 @@ +#ifndef IMAINWINDOW_H +#define IMAINWINDOW_H + +#include +#include +#include + +//! Класс главного окна +class IMainWindow +{ + +public: + + //! Получение подокна + /*! Предназначено для получения подокна + */ + virtual QMdiSubWindow *subWindow(QString objName) = 0; + + //! Получение списка подокон + /*! Предназначено для получения списка подокон + */ + virtual QList subWindowList() const = 0; + +public slots: + + //! Добавления QAction для использования в главном окне + virtual void addAction(QString category, QAction *action) = 0; + + //! Удаление QAction из главного окна + virtual void removeAction(QAction *action) = 0; + + //! Запись настроек меню + virtual void writeBarSettings() = 0; + + //! Чтение настроек меню + virtual void readBarSettings() = 0; + + //! Чтение и применение настроек главного окна + virtual void readSettings() = 0; + + //! Запись настроек главного окна + virtual void writeSettings() = 0; + + //! Слот обработки события закрытия главного окна + virtual void closeEvent(QCloseEvent *event) = 0; + + //! Слот обновления меню управления окнами + /*! Слот предназаначен для изменения состояния + пунктов меню при изменении состояния приложения + */ + virtual void updateMenus() = 0; + + //! Слот установки оконного режима + /*! Слот предназначен переключение приложения в закладочный + или оконный режим + */ + virtual void setWindowModeEnable(bool mode) = 0; + + //! Слот добавления подчиненного окна + /*! Слот предназаначен для добавления подчиненного окна(закладки) + в главное окно. Возращает добавленное подокно QMdiSubWindow + */ + virtual QMdiSubWindow *addSubWindow(QWidget *widget) = 0; + + //! Слот установки активного окна по имени + /*! Слот предназначен для установки активного подокна в главном окне + по его имени + */ + virtual QMdiSubWindow *setActiveSubWindow(QString objName) = 0; + + //! Получение области подокон + virtual MdiExtArea *getMdiArea() = 0; +}; + +Q_DECLARE_INTERFACE(IMainWindow,"com.RTPTechGroup.Raindrop.IMainWindow/1.0") + +#endif // IMAINWINDOW_H diff --git a/tests/auto/tst_plugin1/itst_plugin1.h b/tests/auto/tst_plugin1/itst_plugin1.h new file mode 100644 index 0000000..1db33a8 --- /dev/null +++ b/tests/auto/tst_plugin1/itst_plugin1.h @@ -0,0 +1,12 @@ +#ifndef ITST_PLUGIN1_H +#define ITST_PLUGIN1_H + +class Itst_plugin1 +{ + +}; + +#define Itst_plugin1_iid "com.RTPTechGroup.Raindrop.Itst_plugin1/1.0" +Q_DECLARE_INTERFACE(Itst_plugin1, Itst_plugin1_iid) + +#endif // IMAINWINDOW_H diff --git a/tests/auto/tst_plugin1/tst_plugin1.cpp b/tests/auto/tst_plugin1/tst_plugin1.cpp new file mode 100644 index 0000000..b9e0f98 --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.cpp @@ -0,0 +1,7 @@ +#include "tst_plugin1.h" + +tst_plugin1::tst_plugin1(QObject *parent): + QObject(parent), IPlugin("Itst_plugin4") +{ + +} diff --git a/tests/auto/tst_plugin1/tst_plugin1.h b/tests/auto/tst_plugin1/tst_plugin1.h new file mode 100644 index 0000000..f873e6b --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.h @@ -0,0 +1,55 @@ +#ifndef TST_PLUGIN1_H +#define TST_PLUGIN1_H + +#include +#include +#include "tst_plugin1global.h" +#include "itst_plugin1.h" + +class TST_PLUGIN1LIB tst_plugin1: + public QObject, + public IPlugin, + public Itst_plugin1 +{ + Q_OBJECT + Q_INTERFACES(IPlugin Itst_plugin1) + + Q_PLUGIN_METADATA(IID Itst_plugin1_iid FILE "tst_plugin1.json") + +public: + + //! Конструктор плагина + explicit tst_plugin1(QObject *parent = 0); + + // IPlugin + + //! Получение экземпляра + QObject *instance() { return this; } + + //! Получение имени плагина + QString name() {return APP_NAME;}; + + //! Получение иконки плагина + QIcon icon() {return QIcon(":/tst_plugin1");}; + + //! Описание продукта + QString product() {return tr(APP_PRODUCT);}; + + //! Авторские права + QString copyright() {return tr(APP_COPYRIGHT);}; + + //! Описание плагина + QString descript() {return tr(APP_DESCRIPTION);}; + + //! Категория в которой состоит плагин + QString category() {return tr("");}; + + //! Версия плагина + QString version() {return APP_VERSION;}; + + //! Производитель плагина + QString vendor() {return tr(APP_COMPANY);}; +}; + +#endif + diff --git a/tests/auto/tst_plugin1/tst_plugin1.json b/tests/auto/tst_plugin1/tst_plugin1.json new file mode 100644 index 0000000..311847d --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.json @@ -0,0 +1,2 @@ +{} + diff --git a/tests/auto/tst_plugin1/tst_plugin1.pro b/tests/auto/tst_plugin1/tst_plugin1.pro new file mode 100644 index 0000000..403988f --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.pro @@ -0,0 +1,16 @@ +include(../tst_plugin.pri) +CONFIG += plugin +TEMPLATE = lib +DEFINES += TST_PLUGIN1_LIBRARY + +VERSION = 1.0.0 +QMAKE_TARGET_COMPANY = "RTPTechGroup" +QMAKE_TARGET_PRODUCT = "TST_PLUGIN1" +QMAKE_TARGET_DESCRIPTION = "TST_PLUGIN1" +QMAKE_TARGET_COPYRIGHT = "Copyright (C) RTPTechGroup" + +# Input +HEADERS = *.h +SOURCES = *.cpp +RESOURCES = *.qrc + diff --git a/tests/auto/tst_plugin1/tst_plugin1.qbs b/tests/auto/tst_plugin1/tst_plugin1.qbs new file mode 100644 index 0000000..35f1d4e --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.qbs @@ -0,0 +1,30 @@ +import "../main.qbs" as PluginProduct + +PluginProduct { + name: "tst_plugin1" + type: "dynamiclibrary" + + productname: "TST_PLUGIN1" + version: "1.0.0" + description: "TST_PLUGIN1" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.defines: base.concat(["TST_PLUGIN1_LIBRARY"]) + cpp.includePaths: base.concat(['.']) + + Depends { name: "Qt"; submodules: ["widgets"] } + Depends { name: "plugin" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] + Group { + fileTagsFilter: ["dynamiclibrary"] + qbs.install: true + qbs.installDir: "tests/auto/plugin/plugins" + } +} diff --git a/tests/auto/tst_plugin1/tst_plugin1.qrc b/tests/auto/tst_plugin1/tst_plugin1.qrc new file mode 100644 index 0000000..5db3b40 --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1.qrc @@ -0,0 +1,6 @@ + + + icons/tst_plugin1.svg + + + diff --git a/tests/auto/tst_plugin1/tst_plugin1global.h b/tests/auto/tst_plugin1/tst_plugin1global.h new file mode 100644 index 0000000..ad47332 --- /dev/null +++ b/tests/auto/tst_plugin1/tst_plugin1global.h @@ -0,0 +1,9 @@ +#ifndef TST_PLUGIN1GLOBAL_H +#define TST_PLUGIN1GLOBAL_H +#if defined(TST_PLUGIN1_LIBRARY) +# define TST_PLUGIN1LIB Q_DECL_EXPORT +#else +# define TST_PLUGIN1LIB Q_DECL_IMPORT +#endif +#endif // TST_PLUGIN1GLOBAL_H + diff --git a/tests/auto/tst_plugin2/icons/tst_plugin2.svg b/tests/auto/tst_plugin2/icons/tst_plugin2.svg new file mode 100644 index 0000000..af8592e --- /dev/null +++ b/tests/auto/tst_plugin2/icons/tst_plugin2.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/tst_plugin2/itst_plugin2.h b/tests/auto/tst_plugin2/itst_plugin2.h new file mode 100644 index 0000000..79767b7 --- /dev/null +++ b/tests/auto/tst_plugin2/itst_plugin2.h @@ -0,0 +1,12 @@ +#ifndef ITST_PLUGIN2_H +#define ITST_PLUGIN2_H + +class Itst_plugin2 +{ + +}; + +#define Itst_plugin2_iid "com.RTPTechGroup.Raindrop.Itst_plugin2/1.0" +Q_DECLARE_INTERFACE(Itst_plugin2, Itst_plugin2_iid) + +#endif // IMAINWINDOW_H diff --git a/tests/auto/tst_plugin2/tst_plugin2.cpp b/tests/auto/tst_plugin2/tst_plugin2.cpp new file mode 100644 index 0000000..0aee4ce --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.cpp @@ -0,0 +1,7 @@ +#include "tst_plugin2.h" + +tst_plugin2::tst_plugin2(QObject *parent): + QObject(parent), IPlugin("Itst_plugin3") +{ + +} diff --git a/tests/auto/tst_plugin2/tst_plugin2.h b/tests/auto/tst_plugin2/tst_plugin2.h new file mode 100644 index 0000000..a92ff79 --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.h @@ -0,0 +1,55 @@ +#ifndef TST_PLUGIN2_H +#define TST_PLUGIN2_H + +#include +#include +#include "tst_plugin2global.h" +#include "itst_plugin2.h" + +class TST_PLUGIN2LIB tst_plugin2: + public QObject, + public IPlugin, + public Itst_plugin2 +{ + Q_OBJECT + Q_INTERFACES(IPlugin Itst_plugin2) + + Q_PLUGIN_METADATA(IID Itst_plugin2_iid FILE "tst_plugin2.json") + +public: + + //! Конструктор плагина + explicit tst_plugin2(QObject *parent = 0); + + // IPlugin + + //! Получение экземпляра + QObject *instance() { return this; } + + //! Получение имени плагина + QString name() {return APP_NAME;}; + + //! Получение иконки плагина + QIcon icon() {return QIcon(":/tst_plugin2");}; + + //! Описание продукта + QString product() {return tr(APP_PRODUCT);}; + + //! Авторские права + QString copyright() {return tr(APP_COPYRIGHT);}; + + //! Описание плагина + QString descript() {return tr(APP_DESCRIPTION);}; + + //! Категория в которой состоит плагин + QString category() {return tr("");}; + + //! Версия плагина + QString version() {return APP_VERSION;}; + + //! Производитель плагина + QString vendor() {return tr(APP_COMPANY);}; +}; + +#endif + diff --git a/tests/auto/tst_plugin2/tst_plugin2.json b/tests/auto/tst_plugin2/tst_plugin2.json new file mode 100644 index 0000000..311847d --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.json @@ -0,0 +1,2 @@ +{} + diff --git a/tests/auto/tst_plugin2/tst_plugin2.pro b/tests/auto/tst_plugin2/tst_plugin2.pro new file mode 100644 index 0000000..bc416bb --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.pro @@ -0,0 +1,16 @@ +include(../tst_plugin.pri) +CONFIG += plugin +TEMPLATE = lib +DEFINES += TST_PLUGIN2_LIBRARY + +VERSION = 1.0.0 +QMAKE_TARGET_COMPANY = "RTPTechGroup" +QMAKE_TARGET_PRODUCT = "TST_PLUGIN2" +QMAKE_TARGET_DESCRIPTION = "TST_PLUGIN2" +QMAKE_TARGET_COPYRIGHT = "Copyright (C) RTPTechGroup" + +# Input +HEADERS = *.h +SOURCES = *.cpp +RESOURCES = *.qrc + diff --git a/tests/auto/tst_plugin2/tst_plugin2.qbs b/tests/auto/tst_plugin2/tst_plugin2.qbs new file mode 100644 index 0000000..d0965bd --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.qbs @@ -0,0 +1,32 @@ +import "../main.qbs" as PluginProduct + +PluginProduct { + name: "tst_plugin2" + type: "dynamiclibrary" + + productname: "TST_PLUGIN2" + version: "1.0.0" + description: "TST_PLUGIN2" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.defines: base.concat(["TST_PLUGIN2_LIBRARY"]) + cpp.includePaths: base.concat(['.']) + + Depends { name: "Qt"; submodules: ["widgets"] } + Depends { name: "plugin" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] + Group { + fileTagsFilter: [ + "dynamiclibrary", + "dynamiclibrary_import"] + qbs.install: true + qbs.installDir: "tests/auto/plugin/plugins" + } +} diff --git a/tests/auto/tst_plugin2/tst_plugin2.qrc b/tests/auto/tst_plugin2/tst_plugin2.qrc new file mode 100644 index 0000000..74c84d5 --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2.qrc @@ -0,0 +1,6 @@ + + + icons/tst_plugin2.svg + + + diff --git a/tests/auto/tst_plugin2/tst_plugin2global.h b/tests/auto/tst_plugin2/tst_plugin2global.h new file mode 100644 index 0000000..ff5c348 --- /dev/null +++ b/tests/auto/tst_plugin2/tst_plugin2global.h @@ -0,0 +1,9 @@ +#ifndef TST_PLUGIN2GLOBAL_H +#define TST_PLUGIN2GLOBAL_H +#if defined(TST_PLUGIN2_LIBRARY) +# define TST_PLUGIN2LIB Q_DECL_EXPORT +#else +# define TST_PLUGIN2LIB Q_DECL_IMPORT +#endif +#endif // TST_PLUGIN2GLOBAL_H + diff --git a/tests/auto/tst_plugin3/icons/tst_plugin3.svg b/tests/auto/tst_plugin3/icons/tst_plugin3.svg new file mode 100644 index 0000000..af8592e --- /dev/null +++ b/tests/auto/tst_plugin3/icons/tst_plugin3.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/tst_plugin3/itst_plugin3.h b/tests/auto/tst_plugin3/itst_plugin3.h new file mode 100644 index 0000000..26bc3c1 --- /dev/null +++ b/tests/auto/tst_plugin3/itst_plugin3.h @@ -0,0 +1,12 @@ +#ifndef ITST_PLUGIN3_H +#define ITST_PLUGIN3_H + +class Itst_plugin3 +{ + +}; + +#define Itst_plugin3_iid "com.RTPTechGroup.Raindrop.Itst_plugin3/1.0" +Q_DECLARE_INTERFACE(Itst_plugin3, Itst_plugin3_iid) + +#endif // IMAINWINDOW_H diff --git a/tests/auto/tst_plugin3/tst_plugin3.cpp b/tests/auto/tst_plugin3/tst_plugin3.cpp new file mode 100644 index 0000000..9aa2a6d --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.cpp @@ -0,0 +1,9 @@ +#include "tst_plugin3.h" + +tst_plugin3::tst_plugin3(QObject *parent): + QObject(parent), IPlugin("") +{ + +} + + diff --git a/tests/auto/tst_plugin3/tst_plugin3.h b/tests/auto/tst_plugin3/tst_plugin3.h new file mode 100644 index 0000000..72a6271 --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.h @@ -0,0 +1,58 @@ +#ifndef TST_PLUGIN3_H +#define TST_PLUGIN3_H + +#include +#include +#include "tst_plugin3global.h" +#include "itst_plugin3.h" +#include "../tst_plugin4/itst_plugin4.h" + +class TST_PLUGIN3LIB tst_plugin3: + public QObject, + public IPlugin, + public Itst_plugin3, + public Itst_plugin4 + +{ + Q_OBJECT + Q_INTERFACES(IPlugin Itst_plugin3 Itst_plugin4) + + Q_PLUGIN_METADATA(IID Itst_plugin3_iid FILE "tst_plugin3.json") + +public: + + //! Конструктор плагина + explicit tst_plugin3(QObject *parent = 0); + + // IPlugin + + //! Получение экземпляра + QObject *instance() { return this; } + + //! Получение имени плагина + QString name() {return APP_NAME;}; + + //! Получение иконки плагина + QIcon icon() {return QIcon(":/tst_plugin3");}; + + //! Описание продукта + QString product() {return tr(APP_PRODUCT);}; + + //! Авторские права + QString copyright() {return tr(APP_COPYRIGHT);}; + + //! Описание плагина + QString descript() {return tr(APP_DESCRIPTION);}; + + //! Категория в которой состоит плагин + QString category() {return tr("");}; + + //! Версия плагина + QString version() {return APP_VERSION;}; + + //! Производитель плагина + QString vendor() {return tr(APP_COMPANY);};; +}; + +#endif + diff --git a/tests/auto/tst_plugin3/tst_plugin3.json b/tests/auto/tst_plugin3/tst_plugin3.json new file mode 100644 index 0000000..311847d --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.json @@ -0,0 +1,2 @@ +{} + diff --git a/tests/auto/tst_plugin3/tst_plugin3.pro b/tests/auto/tst_plugin3/tst_plugin3.pro new file mode 100644 index 0000000..f9f4b7c --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.pro @@ -0,0 +1,16 @@ +include(../tst_plugin.pri) +CONFIG += plugin +TEMPLATE = lib +DEFINES += TST_PLUGIN3_LIBRARY + +VERSION = 1.0.0 +QMAKE_TARGET_COMPANY = "RTPTechGroup" +QMAKE_TARGET_PRODUCT = "TST_PLUGIN3" +QMAKE_TARGET_DESCRIPTION = "TST_PLUGIN3" +QMAKE_TARGET_COPYRIGHT = "Copyright (C) RTPTechGroup" + +# Input +HEADERS = *.h +SOURCES = *.cpp +RESOURCES = *.qrc + diff --git a/tests/auto/tst_plugin3/tst_plugin3.qbs b/tests/auto/tst_plugin3/tst_plugin3.qbs new file mode 100644 index 0000000..bbc787c --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.qbs @@ -0,0 +1,32 @@ +import "../main.qbs" as PluginProduct + +PluginProduct { + name: "tst_plugin3" + type: "dynamiclibrary" + + productname: "TST_PLUGIN3" + version: "1.0.0" + description: "TST_PLUGIN3" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.defines: base.concat(["TST_PLUGIN3_LIBRARY"]) + cpp.includePaths: base.concat(['.']) + + Depends { name: "Qt"; submodules: ["widgets"] } + Depends { name: "plugin" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] + Group { + fileTagsFilter: [ + "dynamiclibrary", + "dynamiclibrary_import"] + qbs.install: true + qbs.installDir: "tests/auto/plugin/plugins" + } +} diff --git a/tests/auto/tst_plugin3/tst_plugin3.qrc b/tests/auto/tst_plugin3/tst_plugin3.qrc new file mode 100644 index 0000000..84fc635 --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3.qrc @@ -0,0 +1,6 @@ + + + icons/tst_plugin3.svg + + + diff --git a/tests/auto/tst_plugin3/tst_plugin3global.h b/tests/auto/tst_plugin3/tst_plugin3global.h new file mode 100644 index 0000000..26316fd --- /dev/null +++ b/tests/auto/tst_plugin3/tst_plugin3global.h @@ -0,0 +1,9 @@ +#ifndef TST_PLUGIN3GLOBAL_H +#define TST_PLUGIN3GLOBAL_H +#if defined(TST_PLUGIN3_LIBRARY) +# define TST_PLUGIN3LIB Q_DECL_EXPORT +#else +# define TST_PLUGIN3LIB Q_DECL_IMPORT +#endif +#endif // TST_PLUGIN3GLOBAL_H + diff --git a/tests/auto/tst_plugin4/icons/tst_plugin4.svg b/tests/auto/tst_plugin4/icons/tst_plugin4.svg new file mode 100644 index 0000000..af8592e --- /dev/null +++ b/tests/auto/tst_plugin4/icons/tst_plugin4.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/tst_plugin4/itst_plugin4.h b/tests/auto/tst_plugin4/itst_plugin4.h new file mode 100644 index 0000000..bce024b --- /dev/null +++ b/tests/auto/tst_plugin4/itst_plugin4.h @@ -0,0 +1,12 @@ +#ifndef ITST_PLUGIN4_H +#define ITST_PLUGIN4_H + +class Itst_plugin4 +{ + +}; + +#define Itst_plugin4_iid "com.RTPTechGroup.Raindrop.Itst_plugin4/1.0" +Q_DECLARE_INTERFACE(Itst_plugin4, Itst_plugin4_iid) + +#endif // IMAINWINDOW_H diff --git a/tests/auto/tst_plugin4/tst_plugin4.cpp b/tests/auto/tst_plugin4/tst_plugin4.cpp new file mode 100644 index 0000000..a0cc08b --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.cpp @@ -0,0 +1,9 @@ +#include "tst_plugin4.h" + +tst_plugin4::tst_plugin4(QObject *parent): + QObject(parent), IPlugin("Itst_plugin3") +{ + +} + + diff --git a/tests/auto/tst_plugin4/tst_plugin4.h b/tests/auto/tst_plugin4/tst_plugin4.h new file mode 100644 index 0000000..22e5ff6 --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.h @@ -0,0 +1,55 @@ +#ifndef TST_PLUGIN4_H +#define TST_PLUGIN4_H + +#include +#include +#include "tst_plugin4global.h" +#include "itst_plugin4.h" + +class TST_PLUGIN4LIB tst_plugin4: + public QObject, + public IPlugin, + public Itst_plugin4 +{ + Q_OBJECT + Q_INTERFACES(IPlugin Itst_plugin4) + + Q_PLUGIN_METADATA(IID Itst_plugin4_iid FILE "tst_plugin4.json") + +public: + + //! Конструктор плагина + explicit tst_plugin4(QObject *parent = 0); + + // IPlugin + + //! Получение экземпляра + QObject *instance() { return this; } + + //! Получение имени плагина + QString name() {return APP_NAME;}; + + //! Получение иконки плагина + QIcon icon() {return QIcon(":/tst_plugin4");}; + + //! Описание продукта + QString product() {return tr(APP_PRODUCT);}; + + //! Авторские права + QString copyright() {return tr(APP_COPYRIGHT);}; + + //! Описание плагина + QString descript() {return tr(APP_DESCRIPTION);}; + + //! Категория в которой состоит плагин + QString category() {return tr("");}; + + //! Версия плагина + QString version() {return APP_VERSION;}; + + //! Производитель плагина + QString vendor() {return tr(APP_COMPANY);}; +}; + +#endif + diff --git a/tests/auto/tst_plugin4/tst_plugin4.json b/tests/auto/tst_plugin4/tst_plugin4.json new file mode 100644 index 0000000..311847d --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.json @@ -0,0 +1,2 @@ +{} + diff --git a/tests/auto/tst_plugin4/tst_plugin4.pro b/tests/auto/tst_plugin4/tst_plugin4.pro new file mode 100644 index 0000000..9a53b31 --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.pro @@ -0,0 +1,15 @@ +include(../tst_plugin.pri) +CONFIG += plugin +TEMPLATE = lib +DEFINES += TST_PLUGIN4_LIBRARY + +VERSION = 1.0.0 +QMAKE_TARGET_COMPANY = "RTPTechGroup" +QMAKE_TARGET_PRODUCT = "TST_PLUGIN4" +QMAKE_TARGET_DESCRIPTION = "TST_PLUGIN4" +QMAKE_TARGET_COPYRIGHT = "Copyright (C) RTPTechGroup" + +# Input +HEADERS = *.h +SOURCES = *.cpp +RESOURCES = *.qrc diff --git a/tests/auto/tst_plugin4/tst_plugin4.qbs b/tests/auto/tst_plugin4/tst_plugin4.qbs new file mode 100644 index 0000000..e616237 --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.qbs @@ -0,0 +1,32 @@ +import "../main.qbs" as PluginProduct + +PluginProduct { + name: "tst_plugin4" + type: "dynamiclibrary" + + productname: "TST_PLUGIN4" + version: "1.0.0" + description: "TST_PLUGIN4" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.defines: base.concat(["TST_PLUGIN4_LIBRARY"]) + cpp.includePaths: base.concat(['.']) + + Depends { name: "Qt"; submodules: ["widgets"] } + Depends { name: "plugin" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] + Group { + fileTagsFilter: [ + "dynamiclibrary", + "dynamiclibrary_import"] + qbs.install: true + qbs.installDir: "tests/auto/plugin/plugins" + } +} diff --git a/tests/auto/tst_plugin4/tst_plugin4.qrc b/tests/auto/tst_plugin4/tst_plugin4.qrc new file mode 100644 index 0000000..77b7ee0 --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4.qrc @@ -0,0 +1,6 @@ + + + icons/tst_plugin4.svg + + + diff --git a/tests/auto/tst_plugin4/tst_plugin4global.h b/tests/auto/tst_plugin4/tst_plugin4global.h new file mode 100644 index 0000000..95e0a81 --- /dev/null +++ b/tests/auto/tst_plugin4/tst_plugin4global.h @@ -0,0 +1,9 @@ +#ifndef TST_PLUGIN4GLOBAL_H +#define TST_PLUGIN4GLOBAL_H +#if defined(TST_PLUGIN4_LIBRARY) +# define TST_PLUGIN4LIB Q_DECL_EXPORT +#else +# define TST_PLUGIN4LIB Q_DECL_IMPORT +#endif +#endif // TST_PLUGIN4GLOBAL_H + diff --git a/tests/auto/tst_pluginmanager/pluginloadlog.cpp b/tests/auto/tst_pluginmanager/pluginloadlog.cpp new file mode 100644 index 0000000..c7c6f1b --- /dev/null +++ b/tests/auto/tst_pluginmanager/pluginloadlog.cpp @@ -0,0 +1,27 @@ +#include "pluginloadlog.h" + +PluginLoadLog::PluginLoadLog(QObject *parent) : + QObject(parent) +{ + +} + +PluginLoadLog::~PluginLoadLog() +{ + m_loadedPlugins.clear(); +} + +QStringList PluginLoadLog::loadedPlugins() +{ + return m_loadedPlugins; +} + +void PluginLoadLog::clearLoadedPlugins() +{ + m_loadedPlugins.clear(); +} + +void PluginLoadLog::loadPlugin(QObject *plugin) +{ + m_loadedPlugins.append(plugin->objectName()); +} diff --git a/tests/auto/tst_pluginmanager/pluginloadlog.h b/tests/auto/tst_pluginmanager/pluginloadlog.h new file mode 100644 index 0000000..bfc7da2 --- /dev/null +++ b/tests/auto/tst_pluginmanager/pluginloadlog.h @@ -0,0 +1,25 @@ +#ifndef PLUGINLOADLOG_H +#define PLUGINLOADLOG_H + +#include +#include + +class PluginLoadLog : public QObject +{ + Q_OBJECT +public: + explicit PluginLoadLog(QObject *parent = 0); + virtual ~PluginLoadLog(); + + QStringList loadedPlugins(); + void clearLoadedPlugins(); + +public slots: + void loadPlugin(QObject *plugin); + +private: + QStringList m_loadedPlugins; + +}; + +#endif // PLUGINLOADLOG_H diff --git a/tests/auto/tst_pluginmanager/tst_pluginmanager.cpp b/tests/auto/tst_pluginmanager/tst_pluginmanager.cpp new file mode 100644 index 0000000..17f4dea --- /dev/null +++ b/tests/auto/tst_pluginmanager/tst_pluginmanager.cpp @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include "pluginloadlog.h" + +using namespace RTPTechGroup::Plugin; + +class tst_PluginManager : public QObject +{ + Q_OBJECT + +public: + + //! Конструктор теста + explicit tst_PluginManager(QObject *parent = 0); + + //! Конструктор теста + virtual ~tst_PluginManager(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void instance(); + void interfaceObject(); + void interfaceObjects(); + void dependentPlugins(); + void dependPlugins(); + void loadPlugins(); + void settings(); + +private: + PluginManager m_pluginManager; + PluginLoadLog *m_pluginLoadLog; +}; + +tst_PluginManager::tst_PluginManager(QObject *parent) +{ + Q_UNUSED(parent) + m_pluginLoadLog = NULL; +} + +tst_PluginManager::~tst_PluginManager() +{ + +} + +void tst_PluginManager::initTestCase() +{ +#if QT_VERSION < 0x050000 + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +#endif + + // Подключение перевода для Qt + QString translatorFileName = QLatin1String("qt_"); + translatorFileName += QLocale::system().name(); + QTranslator *translator = new QTranslator(this); + if (translator->load(translatorFileName, + QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + QApplication::installTranslator(translator); + + m_pluginLoadLog = new PluginLoadLog(); + connect(PluginManager::instance(), &PluginManager::loadedPlugin, + m_pluginLoadLog, &PluginLoadLog::loadPlugin); + m_pluginManager.setPluginsDir(QDir(qApp->applicationDirPath() + "/plugins/")); + m_pluginManager.loadPlugins(); +} + +void tst_PluginManager::cleanupTestCase() +{ + PluginLoadLog *pluginUnloadLog = new PluginLoadLog(); + connect(PluginManager::instance(), &PluginManager::removedPlugin, + pluginUnloadLog, &PluginLoadLog::loadPlugin); + delete m_pluginManager.interfaceObject("Itst_plugin3"); + QStringList plugins = pluginUnloadLog->loadedPlugins(); + QCOMPARE(plugins.count(), 4); + if (plugins.at(0) == "tst_plugin2") { + QVERIFY(plugins.at(0) == "tst_plugin2"); + QVERIFY(plugins.at(1) == "tst_plugin1"); + QVERIFY(plugins.at(2) == "tst_plugin4"); + } else { + QVERIFY(plugins.at(0) == "tst_plugin1"); + QVERIFY(plugins.at(1) == "tst_plugin2" + || plugins.at(1) == "tst_plugin4"); + QVERIFY(plugins.at(2) == "tst_plugin2" + || plugins.at(2) == "tst_plugin4"); + } + QVERIFY(plugins.at(3) == "tst_plugin3"); + delete pluginUnloadLog; + + delete m_pluginLoadLog; +} + +void tst_PluginManager::init() +{ + +} + +void tst_PluginManager::cleanup() +{ + +} + +void tst_PluginManager::instance() +{ + QCOMPARE(&m_pluginManager, PluginManager::instance()); +} + +void tst_PluginManager::interfaceObject() +{ + QCOMPARE (m_pluginManager.interfaceObject("Itst_plugin1")->metaObject()->className(), + "tst_plugin1"); + QCOMPARE (m_pluginManager.interfaceObject("Itst_plugin2")->metaObject()->className(), + "tst_plugin2"); + QCOMPARE (m_pluginManager.interfaceObject("Itst_plugin3")->metaObject()->className(), + "tst_plugin3"); +} + +void tst_PluginManager::interfaceObjects() +{ + QList listObject = m_pluginManager.interfaceObjects("Itst_plugin4"); + QVERIFY(listObject.count() == 2); + + QStringList objectName; + objectName << "tst_plugin3" << "tst_plugin4"; + + foreach (QObject *interfaceObject, listObject) { + QVERIFY(objectName.removeOne(interfaceObject->metaObject()->className())); + } +} + +void tst_PluginManager::dependentPlugins() +{ + QStringList dependentName1; + QStringList dependentName2; + + QStringList dependentName3; + dependentName3 << "tst_plugin1" << "tst_plugin2" << "tst_plugin4"; + + QStringList dependentName4; + dependentName4 << "tst_plugin1"; + + QList plugins = m_pluginManager.interfaceObjects("IPlugin"); + foreach (QObject *plugin, plugins) { + IPlugin *iplugin = qobject_cast(plugin); + QList listDependent = m_pluginManager.dependentPlugins(iplugin); + foreach (IPlugin *pluginDependent, listDependent) { + if (iplugin->name() == QString("tst_plugin1")) { + QVERIFY(dependentName1.removeOne(pluginDependent->name())); + } else if (iplugin->name() == QString("tst_plugin2")) { + QVERIFY(dependentName2.removeOne(pluginDependent->name())); + } else if (iplugin->name() == QString("tst_plugin3")) { + QVERIFY(dependentName3.removeOne(pluginDependent->name())); + } else if (iplugin->name() == QString("tst_plugin4")) { + QVERIFY(dependentName4.removeOne(pluginDependent->name())); + } + } + } + QCOMPARE(dependentName1.count(),0); + QCOMPARE(dependentName2.count(),0); + QCOMPARE(dependentName3.count(),0); + QCOMPARE(dependentName4.count(),0); +} + +void tst_PluginManager::dependPlugins() +{ + QStringList dependName1; + dependName1 << "tst_plugin3" << "tst_plugin4"; + + QStringList dependName2; + dependName2 << "tst_plugin3"; + + QStringList dependName3; + + QStringList dependName4; + dependName4 << "tst_plugin3"; + + QList plugins = m_pluginManager.interfaceObjects("IPlugin"); + foreach (QObject *plugin, plugins) { + IPlugin *iplugin = qobject_cast(plugin); + QList listDepend = m_pluginManager.dependPlugins(iplugin); + foreach (IPlugin *pluginDepend, listDepend) { + if (iplugin->name() == QString("tst_plugin1")) { + QVERIFY(dependName1.removeOne(pluginDepend->name())); + } else if (iplugin->name() == QString("tst_plugin2")) { + QVERIFY(dependName2.removeOne(pluginDepend->name())); + } else if (iplugin->name() == QString("tst_plugin3")) { + QVERIFY(dependName3.removeOne(pluginDepend->name())); + } else if (iplugin->name() == QString("tst_plugin4")) { + QVERIFY(dependName4.removeOne(pluginDepend->name())); + } + } + } + QCOMPARE(dependName1.count(),0); + QCOMPARE(dependName2.count(),0); + QCOMPARE(dependName3.count(),0); + QCOMPARE(dependName4.count(),0); +} + +void tst_PluginManager::loadPlugins() +{ + QStringList plugins = m_pluginLoadLog->loadedPlugins(); + QCOMPARE(plugins.count(), 4); + + QVERIFY(plugins.at(0) == "tst_plugin3"); + + QVERIFY( + (plugins.at(1) == "tst_plugin2" + && (plugins.at(2) == "tst_plugin1" || plugins.at(3) == "tst_plugin1")) + || (plugins.at(2) == "tst_plugin2" && plugins.at(3) == "tst_plugin1") + ); + + QVERIFY(plugins.at(3) == "tst_plugin1" || plugins.at(3) == "tst_plugin4"); +} + +void tst_PluginManager::settings() +{ + QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, + QLatin1String("RTPTechGroup"), QLatin1String("Raindrop")); + m_pluginManager.setSettings(settings); + + QCOMPARE(settings, m_pluginManager.settings()); +} +QTEST_MAIN(tst_PluginManager) +#include "tst_pluginmanager.moc" + diff --git a/tests/auto/tst_pluginmanager/tst_pluginmanager.pro b/tests/auto/tst_pluginmanager/tst_pluginmanager.pro new file mode 100644 index 0000000..9ab7372 --- /dev/null +++ b/tests/auto/tst_pluginmanager/tst_pluginmanager.pro @@ -0,0 +1,11 @@ +include(../tst_plugin.pri) +TEMPLATE = app +CONFIG += plugin +DESTDIR = $$DESTDIR/../ + +greaterThan(QT_MAJOR_VERSION, 4) { + QT += widgets +} +LIBS += -lplugin +HEADERS = *.h +SOURCES = *.cpp diff --git a/tests/auto/tst_pluginmanager/tst_pluginmanager.qbs b/tests/auto/tst_pluginmanager/tst_pluginmanager.qbs new file mode 100644 index 0000000..99327dd --- /dev/null +++ b/tests/auto/tst_pluginmanager/tst_pluginmanager.qbs @@ -0,0 +1,23 @@ +import "../main.qbs" as PluginProduct + +PluginProduct { + name: "tst_pluginmanager" + + productname: "" + version: "1.0.0" + description: "" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + cpp.includePaths: base.concat(['.']) + + Depends { name: "Qt"; submodules: ["widgets", "testlib"] } + Depends { name: "plugin" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] +} diff --git a/tests/benchmarks/benchmarks.pri b/tests/benchmarks/benchmarks.pri new file mode 100644 index 0000000..12e0d8f --- /dev/null +++ b/tests/benchmarks/benchmarks.pri @@ -0,0 +1,6 @@ +include(../tests.pri) +INCLUDEPATH += $$PWD +QT += testlib +CONFIG += qt warn_on console depend_includepath testcase +CONFIG -= app_bundle +DEFINES -= QT_NO_CAST_FROM_ASCII diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro new file mode 100644 index 0000000..f2f48a1 --- /dev/null +++ b/tests/benchmarks/benchmarks.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += test_tmpl diff --git a/tests/benchmarks/benchmarks.qbs b/tests/benchmarks/benchmarks.qbs new file mode 100644 index 0000000..23f0613 --- /dev/null +++ b/tests/benchmarks/benchmarks.qbs @@ -0,0 +1,3 @@ +Project { + references: [] +} diff --git a/tests/benchmarks/main.qbs b/tests/benchmarks/main.qbs new file mode 100644 index 0000000..2cdcea8 --- /dev/null +++ b/tests/benchmarks/main.qbs @@ -0,0 +1,5 @@ +import "../main.qbs" as TestProduct +TestProduct { + name: "manual" + type: "application" +} diff --git a/tests/benchmarks/test_tmpl/main.qbs b/tests/benchmarks/test_tmpl/main.qbs new file mode 100644 index 0000000..aa171c3 --- /dev/null +++ b/tests/benchmarks/test_tmpl/main.qbs @@ -0,0 +1,9 @@ +import "../main.qbs" as LibProduct +LibProduct { + name: "test_tmpl" + Group { + fileTagsFilter: ["application"] + qbs.install: true + qbs.installDir: "tests/benchmarks/test_tmpl/" + } +} diff --git a/tests/benchmarks/test_tmpl/test_tmpl.pro b/tests/benchmarks/test_tmpl/test_tmpl.pro new file mode 100644 index 0000000..05a9fe8 --- /dev/null +++ b/tests/benchmarks/test_tmpl/test_tmpl.pro @@ -0,0 +1,2 @@ +TEMPLATE=subdirs +#SUBDIRS=tst_test_tmpl_prf diff --git a/tests/benchmarks/test_tmpl/test_tmpl.qbs b/tests/benchmarks/test_tmpl/test_tmpl.qbs new file mode 100644 index 0000000..23f0613 --- /dev/null +++ b/tests/benchmarks/test_tmpl/test_tmpl.qbs @@ -0,0 +1,3 @@ +Project { + references: [] +} diff --git a/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.pro b/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.pro new file mode 100644 index 0000000..6f63fb3 --- /dev/null +++ b/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.pro @@ -0,0 +1,14 @@ +include(../../manual.pri) + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = tst_test_tmpl_prf +TEMPLATE = app + +LIBS += + +# HEADERS = *.h +# SOURCES = *.cpp +# FORMS = *.ui diff --git a/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.qbs b/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.qbs new file mode 100644 index 0000000..1b4968a --- /dev/null +++ b/tests/benchmarks/test_tmpl/tst_test_tmpl_prf/tst_test_tmpl_prf.qbs @@ -0,0 +1,21 @@ +import "../main.qbs" as TestTmpl + +TestTmpl { + name: "tst_test_tmpl_prf" + + productname: "" + version: "1.0.0" + description: "" + company: "RTPTechGroup" + copyright: "Copyright (C) RTPTechGroup" + + Depends { name: "Qt"; submodules: ["core", "gui", "widgets", "sql"] } + Depends { name: "sqlextension" } + + files: [ + "*.h", + "*.cpp", + "*.ui", + "*.qrc" + ] +} diff --git a/tests/main.qbs b/tests/main.qbs new file mode 100644 index 0000000..11ee226 --- /dev/null +++ b/tests/main.qbs @@ -0,0 +1,6 @@ +import qbs.FileInfo +import "../main.qbs" as MainProduct +MainProduct { + name: "tests" + builtByDefault: false +} diff --git a/tests/manual/main.qbs b/tests/manual/main.qbs new file mode 100644 index 0000000..8119577 --- /dev/null +++ b/tests/manual/main.qbs @@ -0,0 +1,10 @@ +import "../main.qbs" as TestProduct +TestProduct { + name: "manual" + type: "application" + Group { + fileTagsFilter: ["application"] + qbs.install: true + qbs.installDir: "tests/manual/plugin/" + } +} \ No newline at end of file diff --git a/tests/manual/manual.pri b/tests/manual/manual.pri new file mode 100644 index 0000000..423314c --- /dev/null +++ b/tests/manual/manual.pri @@ -0,0 +1,2 @@ +include(../tests.pri) +INCLUDEPATH += $$PWD \ No newline at end of file diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro new file mode 100644 index 0000000..26faaa9 --- /dev/null +++ b/tests/manual/manual.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS += treexmlmodel +SUBDIRS += tilingframe +SUBDIRS += sqlextension \ No newline at end of file diff --git a/tests/manual/manual.qbs b/tests/manual/manual.qbs new file mode 100644 index 0000000..641b6ff --- /dev/null +++ b/tests/manual/manual.qbs @@ -0,0 +1,4 @@ +Project { + references: [ + ] +} diff --git a/tests/tests.pri b/tests/tests.pri new file mode 100644 index 0000000..7626588 --- /dev/null +++ b/tests/tests.pri @@ -0,0 +1,30 @@ +!greaterThan(QT_MAJOR_VERSION, 4) { + load(qttest_p4) +} + +include(../main.pri) +INCLUDEPATH += $$PWD/../src/libs $$PWD/../src/shared $$PWD/../src/plugins + +QMAKE_RPATHDIR += $$LIBRARY_PATH +unix { + QMAKE_LFLAGS += -Wl,-z,origin \'-Wl,-rpath,$${QMAKE_RPATHDIR}\' +} + +LIBS +=-L$$LIBRARY_PATH +LIBS +=-L$$PLUGINS_PATH + +TEMPLATE = app +# DESTDIR = $$APP_PATH + +# prefix test binary with tst_ +!contains(TARGET, ^tst_.*):TARGET = $$join(TARGET,,"tst_") +win32 { + lib = $$APP_PATH;$$APP_PATH/plugins + lib ~= s,/,\\,g + # the below gets added to later by testcase.prf + check.commands = cd . & set PATH=$$lib;%PATH%& cmd /c +} + +sub_dir = $$_PRO_FILE_PWD_ +sub_dir ~= s,^$${PWD},, +DESTDIR = $$TESTS_PATH$$sub_dir diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 0000000..a5a050d --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS += auto +SUBDIRS += benchmarks +SUBDIRS += manual + diff --git a/tests/tests.qbs b/tests/tests.qbs new file mode 100644 index 0000000..1944969 --- /dev/null +++ b/tests/tests.qbs @@ -0,0 +1,7 @@ +Project { + references: [ + "auto/auto.qbs", + "benchmarks/benchmarks.qbs", + "manual/manual.qbs" + ] +}