diff --git a/autotests/minimaltest.cpp b/autotests/minimaltest.cpp index fb4ef62..53795c4 100644 --- a/autotests/minimaltest.cpp +++ b/autotests/minimaltest.cpp @@ -1,112 +1,112 @@ /* * Copyright 2014 Alex Merry * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include static bool widgetLessThan(QDesignerCustomWidgetInterface* w1, QDesignerCustomWidgetInterface* w2) { return w1->name() < w2->name(); } class MinimalTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { QPluginLoader loader(QStringLiteral(MINIMAL_PLUGIN)); m_pluginInstance = loader.instance(); QVERIFY2(m_pluginInstance, qPrintable(loader.errorString())); m_collection = qobject_cast(m_pluginInstance); QVERIFY(m_collection); m_widgets = m_collection->customWidgets(); std::sort(m_widgets.begin(), m_widgets.end(), widgetLessThan); } void testPluginName() { QCOMPARE(m_pluginInstance->metaObject()->className(), "WidgetsPlugin"); } void testWidgetList() { QCOMPARE(m_widgets.count(), 2); } void testWidget_data() { QTest::addColumn("index"); QTest::addColumn("name"); QTest::addColumn("includefile"); QTest::addColumn("domxml"); QTest::newRow("QCheckBox") << 0 << "QCheckBox" << "qcheckbox.h" << ""; QTest::newRow("QPushButton") << 1 << "QPushButton" << "qpushbutton.h" << ""; } void testWidget() { QFETCH(int, index); QFETCH(QString, name); QFETCH(QString, includefile); QFETCH(QString, domxml); QVERIFY(m_widgets.count() > index); QDesignerCustomWidgetInterface *wiface = m_widgets.at(index); QVERIFY(wiface); QCOMPARE(wiface->name(), name); QCOMPARE(wiface->group(), QString("Custom")); QCOMPARE(wiface->toolTip(), QString(name + " Widget")); QCOMPARE(wiface->whatsThis(), QString(name + " Widget")); QCOMPARE(wiface->includeFile(), includefile); QVERIFY(!wiface->icon().isNull()); QVERIFY(!wiface->isContainer()); QCOMPARE(wiface->codeTemplate(), QString()); QCOMPARE(wiface->domXml(), domxml); QVERIFY(!wiface->isInitialized()); - wiface->initialize(0); + wiface->initialize(nullptr); - QWidget *widget = wiface->createWidget(0); + QWidget *widget = wiface->createWidget(nullptr); QVERIFY(widget); QCOMPARE(widget->metaObject()->className(), name.toLatin1().constData()); } private: QDesignerCustomWidgetCollectionInterface *m_collection; QObject *m_pluginInstance; QList m_widgets; }; QTEST_MAIN(MinimalTest) #include diff --git a/autotests/plugintest.cpp b/autotests/plugintest.cpp index c280384..054c0b8 100644 --- a/autotests/plugintest.cpp +++ b/autotests/plugintest.cpp @@ -1,199 +1,199 @@ /* * Copyright 2014 Alex Merry * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include #include static bool widgetLessThan(QDesignerCustomWidgetInterface* w1, QDesignerCustomWidgetInterface* w2) { return w1->name() < w2->name(); } class PluginTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { QPluginLoader loader(QStringLiteral(TEST_PLUGIN)); m_pluginInstance = loader.instance(); QVERIFY2(m_pluginInstance, qPrintable(loader.errorString())); m_collection = qobject_cast(m_pluginInstance); QVERIFY(m_collection); m_widgets = m_collection->customWidgets(); std::sort(m_widgets.begin(), m_widgets.end(), widgetLessThan); } void testPluginName() { QCOMPARE(m_pluginInstance->metaObject()->className(), "SomeClass"); } void testWidgetList() { QCOMPARE(m_widgets.count(), 4); } void testWidget_data() { QTest::addColumn("index"); QTest::addColumn("name"); QTest::addColumn("implclass"); QTest::addColumn("group"); QTest::addColumn("tooltip"); QTest::addColumn("whatsthis"); QTest::addColumn("includefile"); QTest::addColumn("codetemplate"); QTest::addColumn("domxml"); QTest::addColumn("iscontainer"); QTest::addColumn("inittoggles"); QTest::newRow("QCheckBox") << 0 << "QCheckBox" << "QCheckBox" << "The default group" << "The check box tooltip" << "The check box whats this text" << "qcheckbox.h" << "" << "" << false << true; QTest::newRow("QGroupBox") << 1 << "QGroupBox" << "QGroupBox" << "The default group" << "QGroupBox Widget" << "QGroupBox Widget" << "qgroupbox.h" << "" << "" << true << false; // 2 is QLabel, but the widget creation will fail QTest::newRow("QPushButton") << 3 << "QPushButton" << "QCommandLinkButton" << "A group for QPushButton" << "A tooltip for QPushButton" << "A whatsthis for QPushButton" << "QCommandLinkButton" << "" << "" << false << false; } void testWidget() { QFETCH(int, index); QFETCH(QString, name); QFETCH(QString, implclass); QFETCH(QString, group); QFETCH(QString, tooltip); QFETCH(QString, whatsthis); QFETCH(QString, includefile); QFETCH(QString, codetemplate); QFETCH(QString, domxml); QFETCH(bool, iscontainer); QFETCH(bool, inittoggles); QVERIFY(m_widgets.count() > index); QDesignerCustomWidgetInterface *wiface = m_widgets.at(index); QVERIFY(wiface); QCOMPARE(wiface->name(), name); QCOMPARE(wiface->group(), group); QCOMPARE(wiface->toolTip(), tooltip); QCOMPARE(wiface->whatsThis(), whatsthis); QCOMPARE(wiface->includeFile(), includefile); QVERIFY(!wiface->icon().isNull()); QCOMPARE(wiface->isContainer(), iscontainer); QCOMPARE(wiface->codeTemplate(), codetemplate); QCOMPARE(wiface->domXml(), domxml); QVERIFY(!wiface->isInitialized()); - wiface->initialize(0); + wiface->initialize(nullptr); QVERIFY(wiface->isInitialized()); - wiface->initialize(0); + wiface->initialize(nullptr); if (inittoggles) { QVERIFY(!wiface->isInitialized()); } else { QVERIFY(wiface->isInitialized()); } - QWidget *widget = wiface->createWidget(0); + QWidget *widget = wiface->createWidget(nullptr); QVERIFY(widget); QCOMPARE(widget->metaObject()->className(), implclass.toLatin1().constData()); } void testConstructorArgs() { // QGroupBox QVERIFY(m_widgets.count() > 1); QDesignerCustomWidgetInterface *wiface = m_widgets.at(1); QVERIFY(wiface); - QGroupBox *box = qobject_cast(wiface->createWidget(0)); + QGroupBox *box = qobject_cast(wiface->createWidget(nullptr)); QVERIFY(box); QCOMPARE(box->title(), QString("the title")); } void testCreateWidget() { // QLabel QVERIFY(m_widgets.count() > 2); QDesignerCustomWidgetInterface *wiface = m_widgets.at(2); QVERIFY(wiface); - QVERIFY(!wiface->createWidget(0)); + QVERIFY(!wiface->createWidget(nullptr)); QWidget widget; QCOMPARE(wiface->createWidget(&widget), &widget); } void testIcon() { QVERIFY(m_widgets.count() > 3); QDesignerCustomWidgetInterface *checkboxiface = m_widgets.at(0); QVERIFY(checkboxiface); QIcon checkboxIcon(":/sth.png"); QCOMPARE(checkboxiface->icon().pixmap(22,22), checkboxIcon.pixmap(22,22)); QDesignerCustomWidgetInterface *pushbuttoniface = m_widgets.at(3); QVERIFY(pushbuttoniface); QIcon pushbuttonIcon(":/pics/pushbuttonview.png"); QCOMPARE(pushbuttoniface->icon().pixmap(22,22), pushbuttonIcon.pixmap(22,22)); } private: QDesignerCustomWidgetCollectionInterface *m_collection; QObject *m_pluginInstance; QList m_widgets; }; QTEST_MAIN(PluginTest) #include diff --git a/src/kgendesignerplugin.cpp b/src/kgendesignerplugin.cpp index d7fecbd..8c72615 100644 --- a/src/kgendesignerplugin.cpp +++ b/src/kgendesignerplugin.cpp @@ -1,237 +1,237 @@ /* Copyright (C) 2004-2005 ian reinhart geiser */ #include #include #include #include #include #include #include #include #include #include #include #include #include static const char classHeader[] = "/**\n" "* This file was autogenerated by kgendesignerplugin. Any changes will be lost!\n" "* The generated code in this file is licensed under the same license that the\n" "* input file.\n" "*/\n" "#include \n" "#include \n" "#if QT_VERSION >= 0x050500\n" "# include \n" "#else\n" "# include \n" "#endif\n" "#include \n" "#include \n"; static const char collClassDef[] = "class %CollName : public QObject, public QDesignerCustomWidgetCollectionInterface\n" "{\n" " Q_OBJECT\n" " Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)\n" " Q_PLUGIN_METADATA(IID \"org.qt-project.Qt.QDesignerCustomWidgetInterface\")\n" "public:\n" " %CollName(QObject *parent = 0);\n" " virtual ~%CollName() {}\n" " QList customWidgets() const Q_DECL_OVERRIDE { return m_plugins; } \n" " \n" "private:\n" " QList m_plugins;\n" "};\n\n" ; static const char collClassImpl[] = "%CollName::%CollName(QObject *parent)\n" " : QObject(parent)" "{\n" "%CollectionAdd\n" "}\n\n"; static const char classDef[] = "class %PluginName : public QObject, public QDesignerCustomWidgetInterface\n" "{\n" " Q_OBJECT\n" " Q_INTERFACES(QDesignerCustomWidgetInterface)\n" "public:\n" " %PluginName(QObject *parent = 0) :\n QObject(parent), mInitialized(false) {}\n" " virtual ~%PluginName() {}\n" " \n" " bool isContainer() const Q_DECL_OVERRIDE { return %IsContainer; }\n" " bool isInitialized() const Q_DECL_OVERRIDE { return mInitialized; }\n" " QIcon icon() const Q_DECL_OVERRIDE { return QIcon(QStringLiteral(\"%IconName\")); }\n" " QString codeTemplate() const Q_DECL_OVERRIDE { return QStringLiteral(\"%CodeTemplate\"); }\n" " QString domXml() const Q_DECL_OVERRIDE { return %DomXml; }\n" " QString group() const Q_DECL_OVERRIDE { return QStringLiteral(\"%Group\"); }\n" " QString includeFile() const Q_DECL_OVERRIDE { return QStringLiteral(\"%IncludeFile\"); }\n" " QString name() const Q_DECL_OVERRIDE { return QStringLiteral(\"%Class\"); }\n" " QString toolTip() const Q_DECL_OVERRIDE { return QStringLiteral(\"%ToolTip\"); }\n" " QString whatsThis() const Q_DECL_OVERRIDE { return QStringLiteral(\"%WhatsThis\"); }\n\n" " QWidget* createWidget( QWidget* parent ) Q_DECL_OVERRIDE \n {%CreateWidget\n }\n" " void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE \n {%Initialize\n }\n" "\n" "private:\n" " bool mInitialized;\n" "};\n\n"; static QString denamespace(const QString &str); static QString buildCollClass(KConfig &input, const QStringList &classes, const QString &group); static QString buildWidgetClass(const QString &name, KConfig &input, const QString &group); static QString buildWidgetInclude(const QString &name, KConfig &input); static void buildFile(QTextStream &stream, const QString &group, const QString &fileName, const QString &pluginName); int main(int argc, char **argv) { QCoreApplication app(argc, argv); QString description = QCoreApplication::translate("main", "Builds Qt widget plugins from an ini style description file."); const char version[] = "0.5"; app.setApplicationVersion(version); QCommandLineParser parser; parser.addVersionOption(); parser.addHelpOption(); parser.addPositionalArgument("file", QCoreApplication::translate("main", "Input file.")); parser.addOption(QCommandLineOption(QStringList() << "o", QCoreApplication::translate("main", "Output file."), "file")); parser.addOption(QCommandLineOption(QStringList() << "n", QCoreApplication::translate("main", "Name of the plugin class to generate (deprecated, use PluginName in the input file)."), "name", "WidgetsPlugin")); parser.addOption(QCommandLineOption(QStringList() << "g", QCoreApplication::translate("main", "Default widget group name to display in designer (deprecated, use DefaultGroup in the input file)."), "group", "Custom")); KAboutData about("kgendesignerplugin", QCoreApplication::translate("kgendesignerplugin about data", "kgendesignerplugin"), version, description, KAboutLicense::GPL, QCoreApplication::translate("kgendesignerplugin about data", "(C) 2004-2005 Ian Reinhart Geiser"), QString(), - 0, + nullptr, "geiseri@kde.org"); about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Ian Reinhart Geiser"), QString(), "geiseri@kde.org"); about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Daniel Molkentin"), QString(), "molkentin@kde.org"); about.setupCommandLine(&parser); parser.process(app); about.processCommandLine(&parser); if (parser.positionalArguments().count() < 1) { parser.showHelp(); return 1; } QFileInfo fi(parser.positionalArguments().at(0)); QString outputFile = parser.value("o"); QString pluginName = parser.value("n"); QString group = parser.value("g"); QString fileName = fi.absoluteFilePath(); if (parser.isSet("o")) { QFile output(outputFile); if (output.open(QIODevice::WriteOnly)) { QTextStream ts(&output); buildFile(ts, group, fileName, pluginName); QString mocFile = output.fileName(); mocFile.replace(".cpp", ".moc"); ts << QString("#include <%1>\n").arg(mocFile) << endl; } output.close(); } else { QTextStream ts(stdout, QIODevice::WriteOnly); buildFile(ts, group, fileName, pluginName); } } void buildFile(QTextStream &ts, const QString &group, const QString &fileName, const QString &pluginName) { KConfig input(fileName, KConfig::NoGlobals); KConfigGroup cg(&input, "Global"); ts << classHeader << endl; QString defaultGroup = cg.readEntry("DefaultGroup", group); QStringList includes = cg.readEntry("Includes", QStringList()); QStringList classes = input.groupList(); classes.removeAll("Global"); foreach (const QString &myInclude, classes) { includes += buildWidgetInclude(myInclude, input); } foreach (const QString &myInclude, includes) { ts << "#include <" << myInclude << ">" << endl; } ts << QLatin1String("\n\n"); // Autogenerate widget defs here foreach (const QString &myClass, classes) { ts << buildWidgetClass(myClass, input, defaultGroup) << endl; } ts << buildCollClass(input, classes, pluginName); } QString denamespace(const QString &str) { QString denamespaced = str; denamespaced.remove("::"); return denamespaced; } QString buildCollClass(KConfig &_input, const QStringList &classes, const QString &pluginName) { KConfigGroup input(&_input, "Global"); QHash defMap; const QString collName = input.readEntry("PluginName", pluginName); Q_ASSERT(!collName.isEmpty()); defMap.insert("CollName", collName); QString genCode; foreach (const QString &myClass, classes) { genCode += QString(" m_plugins.append( new %1(this) );\n").arg(denamespace(myClass) + "Plugin"); } defMap.insert("CollectionAdd", genCode); QString str = KMacroExpander::expandMacros(collClassDef, defMap); str += KMacroExpander::expandMacros(collClassImpl, defMap); return str; } QString buildWidgetClass(const QString &name, KConfig &_input, const QString &group) { KConfigGroup input(&_input, name); QHash defMap; defMap.insert("Group", input.readEntry("Group", group).replace('\"', "\\\"")); defMap.insert("IncludeFile", input.readEntry("IncludeFile", QString(name.toLower() + ".h")).remove(':')); defMap.insert("ToolTip", input.readEntry("ToolTip", QString(name + " Widget")).replace('\"', "\\\"")); defMap.insert("WhatsThis", input.readEntry("WhatsThis", QString(name + " Widget")).replace('\"', "\\\"")); defMap.insert("IsContainer", input.readEntry("IsContainer", "false")); defMap.insert("IconName", input.readEntry("IconName", QString::fromLatin1(":/pics/%1.png").arg(denamespace(name).toLower()))); defMap.insert("Class", name); defMap.insert("PluginName", denamespace(name) + QLatin1String("Plugin")); // FIXME: ### make this more useful, i.e. outsource to separate file QString domXml = input.readEntry("DomXML", QString()); // If domXml is empty then we should call base class function if (domXml.isEmpty()) { domXml = QStringLiteral("QDesignerCustomWidgetInterface::domXml()"); } else { domXml = QStringLiteral("QStringLiteral(\"%1\")").arg(domXml.replace('\"', "\\\"")); } defMap.insert("DomXml", domXml); defMap.insert("CodeTemplate", input.readEntry("CodeTemplate")); defMap.insert("CreateWidget", input.readEntry("CreateWidget", QString("\n return new %1%2;") .arg(input.readEntry("ImplClass", name)) .arg(input.readEntry("ConstructorArgs", "( parent )")))); defMap.insert("Initialize", input.readEntry("Initialize", "\n Q_UNUSED(core);\n if (mInitialized) return;\n mInitialized=true;")); return KMacroExpander::expandMacros(classDef, defMap); } QString buildWidgetInclude(const QString &name, KConfig &_input) { KConfigGroup input(&_input, name); return input.readEntry("IncludeFile", QString(name.toLower() + ".h")); }