summaryrefslogtreecommitdiffstats
path: root/src/designer/src/lib/shared/widgetdatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/designer/src/lib/shared/widgetdatabase.cpp')
-rw-r--r--src/designer/src/lib/shared/widgetdatabase.cpp249
1 files changed, 129 insertions, 120 deletions
diff --git a/src/designer/src/lib/shared/widgetdatabase.cpp b/src/designer/src/lib/shared/widgetdatabase.cpp
index 8621f2840..97df98f4d 100644
--- a/src/designer/src/lib/shared/widgetdatabase.cpp
+++ b/src/designer/src/lib/shared/widgetdatabase.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Designer of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "widgetdatabase_p.h"
#include "widgetfactory_p.h"
@@ -40,23 +15,34 @@
#include <QtDesigner/abstractformeditor.h>
#include <QtUiPlugin/customwidget.h>
+#include <QtWidgets/QtWidgets>
+#ifdef QT_OPENGLWIDGETS_LIB
+#include <QtOpenGLWidgets/qopenglwidget.h>
+#endif
#include <QtCore/qxmlstream.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qset.h>
+#include <QtCore/qstring.h>
#include <QtCore/qtextstream.h>
#include <QtCore/qcoreapplication.h>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
namespace {
enum { debugWidgetDataBase = 0 };
}
namespace qdesigner_internal {
+using namespace Qt::StringLiterals;
+
// ----------------------------------------------------------
WidgetDataBaseItem::WidgetDataBaseItem(const QString &name, const QString &group)
: m_name(name),
@@ -247,6 +233,27 @@ WidgetDataBaseItem *WidgetDataBaseItem::clone(const QDesignerWidgetDataBaseItemI
return rc;
}
+QString WidgetDataBaseItem::baseClassName() const
+{
+ return m_extends.isEmpty() ? m_baseClassName : m_extends;
+}
+
+void WidgetDataBaseItem::setBaseClassName(const QString &b)
+{
+ m_baseClassName = b;
+}
+
+static void addWidgetItem(WidgetDataBase *wdb, const char *name, const QMetaObject &mo,
+ const char *comment)
+{
+ auto *item = new WidgetDataBaseItem(QString::fromUtf8(name));
+ if (auto *base = mo.superClass())
+ item->setBaseClassName(QString::fromUtf8(base->className()));
+ if (comment[0])
+ item->setToolTip(QString::fromUtf8(comment));
+ wdb->append(item);
+}
+
// ----------------------------------------------------------
WidgetDataBase::WidgetDataBase(QDesignerFormEditorInterface *core, QObject *parent)
: QDesignerWidgetDataBaseInterface(parent),
@@ -254,7 +261,7 @@ WidgetDataBase::WidgetDataBase(QDesignerFormEditorInterface *core, QObject *pare
{
#define DECLARE_LAYOUT(L, C)
#define DECLARE_COMPAT_WIDGET(W, C) DECLARE_WIDGET(W, C)
-#define DECLARE_WIDGET(W, C) append(new WidgetDataBaseItem(QString::fromUtf8(#W)));
+#define DECLARE_WIDGET(W, C) addWidgetItem(this, #W, W::staticMetaObject, C);
#include <widgets.table>
@@ -263,47 +270,65 @@ WidgetDataBase::WidgetDataBase(QDesignerFormEditorInterface *core, QObject *pare
#undef DECLARE_WIDGET
#undef DECLARE_WIDGET_1
- append(new WidgetDataBaseItem(QString::fromUtf8("Line")));
- append(new WidgetDataBaseItem(QString::fromUtf8("Spacer")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QSplitter")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QLayoutWidget")));
+ const QString msgAbstractClass =
+ QCoreApplication::translate("WidgetDataBase",
+ "Abstract base class that cannot be instantiated. For promotion/custom widget usage only.");
+
+#if QT_CONFIG(abstractbutton)
+ auto *abItem = new WidgetDataBaseItem(u"QAbstractButton"_s);
+ abItem->setToolTip(msgAbstractClass);
+ abItem->setBaseClassName(u"QWidget"_s);
+ append(abItem);
+#endif // QT_CONFIG(abstractbutton)
+
+#if QT_CONFIG(itemviews)
+ auto *aivItem = new WidgetDataBaseItem(u"QAbstractItemView"_s);
+ aivItem->setBaseClassName(u"QAbstractScrollArea"_s);
+ aivItem->setToolTip(msgAbstractClass);
+ append(aivItem);
+#endif // QT_CONFIG(itemviews)
+
+ append(new WidgetDataBaseItem(u"Line"_s));
+ append(new WidgetDataBaseItem(u"Spacer"_s));
+ append(new WidgetDataBaseItem(u"QSplitter"_s));
+ append(new WidgetDataBaseItem(u"QLayoutWidget"_s));
// QDesignerWidget is used as central widget and as container for tab widgets, etc.
- WidgetDataBaseItem *designerWidgetItem = new WidgetDataBaseItem(QString::fromUtf8("QDesignerWidget"));
+ WidgetDataBaseItem *designerWidgetItem = new WidgetDataBaseItem(u"QDesignerWidget"_s);
designerWidgetItem->setContainer(true);
append(designerWidgetItem);
- append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerDialog")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerMenu")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerMenuBar")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerDockWidget")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QAction")));
- append(new WidgetDataBaseItem(QString::fromUtf8("QButtonGroup")));
+ append(new WidgetDataBaseItem(u"QDesignerDialog"_s));
+ append(new WidgetDataBaseItem(u"QDesignerMenu"_s));
+ append(new WidgetDataBaseItem(u"QDesignerMenuBar"_s));
+ append(new WidgetDataBaseItem(u"QDesignerDockWidget"_s));
+ append(new WidgetDataBaseItem(u"QAction"_s));
+ append(new WidgetDataBaseItem(u"QButtonGroup"_s));
// ### remove me
// ### check the casts
#if 0 // ### enable me after 4.1
- item(indexOfClassName(QStringLiteral("QToolBar")))->setContainer(true);
+ item(indexOfClassName(u"QToolBar"_s))->setContainer(true);
#endif
- item(indexOfClassName(QStringLiteral("QTabWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QGroupBox")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QScrollArea")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QStackedWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QToolBox")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QFrame")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QLayoutWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QDesignerWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QDesignerDialog")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QSplitter")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QMainWindow")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QDockWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QDesignerDockWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QMdiArea")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QWizard")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QWizardPage")))->setContainer(true);
-
- item(indexOfClassName(QStringLiteral("QWidget")))->setContainer(true);
- item(indexOfClassName(QStringLiteral("QDialog")))->setContainer(true);
+ item(indexOfClassName(u"QTabWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QGroupBox"_s))->setContainer(true);
+ item(indexOfClassName(u"QScrollArea"_s))->setContainer(true);
+ item(indexOfClassName(u"QStackedWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QToolBox"_s))->setContainer(true);
+ item(indexOfClassName(u"QFrame"_s))->setContainer(true);
+ item(indexOfClassName(u"QLayoutWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QDesignerWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QDesignerDialog"_s))->setContainer(true);
+ item(indexOfClassName(u"QSplitter"_s))->setContainer(true);
+ item(indexOfClassName(u"QMainWindow"_s))->setContainer(true);
+ item(indexOfClassName(u"QDockWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QDesignerDockWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QMdiArea"_s))->setContainer(true);
+ item(indexOfClassName(u"QWizard"_s))->setContainer(true);
+ item(indexOfClassName(u"QWizardPage"_s))->setContainer(true);
+
+ item(indexOfClassName(u"QWidget"_s))->setContainer(true);
+ item(indexOfClassName(u"QDialog"_s))->setContainer(true);
}
WidgetDataBase::~WidgetDataBase() = default;
@@ -347,22 +372,18 @@ static WidgetDataBaseItem *createCustomWidgetItem(const QDesignerCustomWidgetInt
void WidgetDataBase::loadPlugins()
{
- typedef QMap<QString, int> NameIndexMap;
- using ItemList = QList<QDesignerWidgetDataBaseItemInterface *>;
- using NameSet = QSet<QString>;
// 1) create a map of existing custom classes
- NameIndexMap existingCustomClasses;
- NameSet nonCustomClasses;
- const int count = m_items.size();
- for (int i = 0; i < count; i++) {
- const QDesignerWidgetDataBaseItemInterface* item = m_items[i];
+ QMap<QString, qsizetype> existingCustomClasses;
+ QSet<QString> nonCustomClasses;
+ for (qsizetype i = 0, count = m_items.size(); i < count; ++i) {
+ const QDesignerWidgetDataBaseItemInterface* item = m_items.at(i);
if (item->isCustom() && !item->isPromoted())
existingCustomClasses.insert(item->name(), i);
else
nonCustomClasses.insert(item->name());
}
// 2) create a list plugins
- ItemList pluginList;
+ QList<QDesignerWidgetDataBaseItemInterface *> pluginList;
const QDesignerPluginManager *pm = m_core->pluginManager();
const auto &customWidgets = pm->registeredCustomWidgets();
for (QDesignerCustomWidgetInterface* c : customWidgets)
@@ -374,10 +395,10 @@ void WidgetDataBase::loadPlugins()
unsigned addedPlugins = 0;
unsigned removedPlugins = 0;
if (!pluginList.isEmpty()) {
- for (QDesignerWidgetDataBaseItemInterface *pluginItem : qAsConst(pluginList)) {
+ for (QDesignerWidgetDataBaseItemInterface *pluginItem : std::as_const(pluginList)) {
const QString pluginName = pluginItem->name();
- NameIndexMap::iterator existingIt = existingCustomClasses.find(pluginName);
- if (existingIt == existingCustomClasses.end()) {
+ const auto existingIt = existingCustomClasses.constFind(pluginName);
+ if (existingIt == existingCustomClasses.cend()) {
// Add new class.
if (nonCustomClasses.contains(pluginName)) {
designerWarning(tr("A custom widget plugin whose class name (%1) matches that of an existing class has been found.").arg(pluginName));
@@ -387,7 +408,7 @@ void WidgetDataBase::loadPlugins()
}
} else {
// replace existing info
- const int existingIndex = existingIt.value();
+ const auto existingIndex = existingIt.value();
delete m_items[existingIndex];
m_items[existingIndex] = pluginItem;
existingCustomClasses.erase(existingIt);
@@ -397,16 +418,14 @@ void WidgetDataBase::loadPlugins()
}
}
// 4) remove classes that have not been matched. The stored indexes become invalid while deleting.
- if (!existingCustomClasses.isEmpty()) {
- NameIndexMap::const_iterator cend = existingCustomClasses.constEnd();
- for (NameIndexMap::const_iterator it = existingCustomClasses.constBegin();it != cend; ++it ) {
- const int index = indexOfClassName(it.key());
- if (index != -1) {
- remove(index);
- removedPlugins++;
- }
+ for (auto it = existingCustomClasses.cbegin(), cend = existingCustomClasses.cend(); it != cend; ++it ) {
+ const int index = indexOfClassName(it.key());
+ if (index != -1) {
+ remove(index);
+ removedPlugins++;
}
}
+
if (debugWidgetDataBase)
qDebug() << "WidgetDataBase::loadPlugins(): " << addedPlugins << " added, " << replacedPlugins << " replaced, " << removedPlugins << "deleted.";
}
@@ -456,7 +475,6 @@ void WidgetDataBase::grabStandardWidgetBoxIcons()
// At this point, grab the default icons for the non-custom widgets from
// the widget box. They will show up in the object inspector.
if (const QDesignerWidgetBox *wb = qobject_cast<const QDesignerWidgetBox *>(m_core->widgetBox())) {
- const QString qWidgetClass = QStringLiteral("QWidget");
const int itemCount = count();
for (int i = 0; i < itemCount; ++i) {
QDesignerWidgetDataBaseItemInterface *dbItem = item(i);
@@ -464,8 +482,8 @@ void WidgetDataBase::grabStandardWidgetBoxIcons()
// Careful not to catch the layout icons when looking for
// QWidget
const QString name = dbItem->name();
- if (name == qWidgetClass) {
- dbItem->setIcon(wb->iconForWidget(name, QStringLiteral("Containers")));
+ if (name == "QWidget"_L1) {
+ dbItem->setIcon(wb->iconForWidget(name, u"Containers"_s));
} else {
dbItem->setIcon(wb->iconForWidget(name));
}
@@ -481,7 +499,7 @@ enum { NewFormWidth = 400, NewFormHeight = 300 };
// Check if class is suitable to generate a form from
static inline bool isExistingTemplate(const QString &className)
{
- return className == QStringLiteral("QWidget") || className == QStringLiteral("QDialog") || className == QStringLiteral("QMainWindow");
+ return className == "QWidget"_L1 || className == "QDialog"_L1 || className == "QMainWindow"_L1;
}
// Check if class is suitable to generate a form from
@@ -489,9 +507,9 @@ static inline bool suitableForNewForm(const QString &className)
{
if (className.isEmpty()) // Missing custom widget information
return false;
- if (className == QStringLiteral("QSplitter"))
+ if (className == "QSplitter"_L1)
return false;
- if (className.startsWith(QStringLiteral("QDesigner")) || className.startsWith(QStringLiteral("QLayout")))
+ if (className.startsWith("QDesigner"_L1) || className.startsWith("QLayout"_L1))
return false;
return true;
}
@@ -537,8 +555,6 @@ QStringList WidgetDataBase::customFormWidgetClasses(const QDesignerFormEditorInt
// properties to be suitable for new forms
static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const QString &className, const QString &objectName)
{
- using PropertyList = QList<DomProperty *>;
-
QDesignerWidgetBoxInterface::Widget widget;
const bool found = QDesignerWidgetBox::findWidget(core->widgetBox(), className, QString(), &widget);
if (!found)
@@ -546,22 +562,20 @@ static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const
QScopedPointer<DomUI> domUI(QDesignerWidgetBox::xmlToUi(className, widget.domXml(), false));
if (domUI.isNull())
return QString();
- domUI->setAttributeVersion(QStringLiteral("4.0"));
+ domUI->setAttributeVersion(u"4.0"_s);
DomWidget *domWidget = domUI->elementWidget();
if (!domWidget)
return QString();
// Properties: Remove the "objectName" property in favour of the name attribute and check geometry.
domWidget->setAttributeName(objectName);
- const QString geometryProperty = QStringLiteral("geometry");
- const QString objectNameProperty = QStringLiteral("objectName");
- PropertyList properties = domWidget->elementProperty();
- for (PropertyList::iterator it = properties.begin(); it != properties.end(); ) {
+ QList<DomProperty *> properties = domWidget->elementProperty();
+ for (auto it = properties.begin(); it != properties.end(); ) {
DomProperty *property = *it;
- if (property->attributeName() == objectNameProperty) { // remove "objectName"
+ if (property->attributeName() == "objectName"_L1) { // remove "objectName"
it = properties.erase(it);
delete property;
} else {
- if (property->attributeName() == geometryProperty) { // Make sure form is at least 400, 300
+ if (property->attributeName() == "geometry"_L1) { // Make sure form is at least 400, 300
if (DomRect *geom = property->elementRect()) {
if (geom->elementWidth() < NewFormWidth)
geom->setElementWidth(NewFormWidth);
@@ -576,7 +590,7 @@ static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const
DomString *windowTitleString = new DomString;
windowTitleString->setText(objectName);
DomProperty *windowTitleProperty = new DomProperty;
- windowTitleProperty->setAttributeName(QStringLiteral("windowTitle"));
+ windowTitleProperty->setAttributeName(u"windowTitle"_s);
windowTitleProperty->setElementString(windowTitleString);
properties.push_back(windowTitleProperty);
// ------
@@ -607,11 +621,11 @@ static QString generateNewFormXML(const QString &className, const QString &simil
<< NewFormWidth << "</width><height>" << NewFormHeight << "</height></rect></property>"
<< R"(<property name="windowTitle"><string>)" << name << "</string></property>\n";
- if (similarClassName == QLatin1String("QMainWindow")) {
+ if (similarClassName == "QMainWindow"_L1) {
str << R"(<widget class="QWidget" name="centralwidget"/>)";
- } else if (similarClassName == QLatin1String("QWizard")) {
+ } else if (similarClassName == "QWizard"_L1) {
str << R"(<widget class="QWizardPage" name="wizardPage1"/><widget class="QWizardPage" name="wizardPage2"/>)";
- } else if (similarClassName == QLatin1String("QDockWidget")) {
+ } else if (similarClassName == "QDockWidget"_L1) {
str << R"(<widget class="QWidget" name="dockWidgetContents"/>)";
}
str << "</widget></ui>\n";
@@ -629,7 +643,7 @@ QString WidgetDataBase::formTemplate(const QDesignerFormEditorInterface *core, c
// 2) If that fails, only custom main windows, custom dialogs and unsupported Qt Widgets should
// be left over. Generate something that is similar to the default templates. Find a similar class.
const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
- QString similarClass = QStringLiteral("QWidget");
+ QString similarClass = u"QWidget"_s;
const int index = wdb->indexOfClassName(className);
if (index != -1) {
const QDesignerWidgetDataBaseItemInterface *item = wdb->item(index);
@@ -643,16 +657,16 @@ QString WidgetDataBase::formTemplate(const QDesignerFormEditorInterface *core, c
// Set a fixed size on a XML template
QString WidgetDataBase::scaleFormTemplate(const QString &xml, const QSize &size, bool fixed)
{
- QScopedPointer<DomUI> domUI(QDesignerWidgetBox::xmlToUi(QStringLiteral("Form"), xml, false));
+ QScopedPointer<DomUI> domUI(QDesignerWidgetBox::xmlToUi(u"Form"_s, xml, false));
if (!domUI)
return QString();
DomWidget *domWidget = domUI->elementWidget();
if (!domWidget)
return QString();
// Properties: Find/Ensure the geometry, minimum and maximum sizes properties
- const QString geometryPropertyName = QStringLiteral("geometry");
- const QString minimumSizePropertyName = QStringLiteral("minimumSize");
- const QString maximumSizePropertyName = QStringLiteral("maximumSize");
+ const QString geometryPropertyName = u"geometry"_s;
+ const QString minimumSizePropertyName = u"minimumSize"_s;
+ const QString maximumSizePropertyName = u"maximumSize"_s;
DomProperty *geomProperty = nullptr;
DomProperty *minimumSizeProperty = nullptr;
DomProperty *maximumSizeProperty = nullptr;
@@ -662,13 +676,10 @@ QString WidgetDataBase::scaleFormTemplate(const QString &xml, const QSize &size,
const QString name = p->attributeName();
if (name == geometryPropertyName) {
geomProperty = p;
- } else {
- if (name == minimumSizePropertyName) {
- minimumSizeProperty = p;
- } else {
- if (name == maximumSizePropertyName)
- maximumSizeProperty = p;
- }
+ } else if (name == minimumSizePropertyName) {
+ minimumSizeProperty = p;
+ } else if (name == maximumSizePropertyName) {
+ maximumSizeProperty = p;
}
}
if (!geomProperty) {
@@ -727,20 +738,19 @@ QString WidgetDataBase::scaleFormTemplate(const QString &xml, const QSize &size,
// ---- free functions
QDESIGNER_SHARED_EXPORT IncludeSpecification includeSpecification(QString includeFile)
{
- const bool global = !includeFile.isEmpty() &&
- includeFile[0] == QLatin1Char('<') &&
- includeFile[includeFile.size() - 1] == QLatin1Char('>');
+ const bool global = includeFile.startsWith(u'<') && includeFile.endsWith(u'>');
if (global) {
- includeFile.remove(includeFile.size() - 1, 1);
+ includeFile.chop(1);
includeFile.remove(0, 1);
}
return IncludeSpecification(includeFile, global ? IncludeGlobal : IncludeLocal);
}
-QDESIGNER_SHARED_EXPORT QString buildIncludeFile(QString includeFile, IncludeType includeType) {
+QDESIGNER_SHARED_EXPORT QString buildIncludeFile(QString includeFile, IncludeType includeType)
+{
if (includeType == IncludeGlobal && !includeFile.isEmpty()) {
- includeFile.append(QLatin1Char('>'));
- includeFile.insert(0, QLatin1Char('<'));
+ includeFile.append(u'>');
+ includeFile.prepend(u'<');
}
return includeFile;
}
@@ -803,8 +813,7 @@ QDESIGNER_SHARED_EXPORT QDesignerWidgetDataBaseItemInterface *
derivedItem = WidgetDataBaseItem::clone(baseItem);
// Sort of hack: If base class is QWidget, we most likely
// do not want to inherit the container attribute.
- static const QString qWidgetName = QStringLiteral("QWidget");
- if (baseItem->name() == qWidgetName)
+ if (baseItem->name() == "QWidget"_L1)
derivedItem->setContainer(false);
// set new props
derivedItem->setName(className);