summaryrefslogtreecommitdiffstats
path: root/src/tools/uic/python/pythonwriteimports.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/uic/python/pythonwriteimports.cpp')
-rw-r--r--src/tools/uic/python/pythonwriteimports.cpp138
1 files changed, 79 insertions, 59 deletions
diff --git a/src/tools/uic/python/pythonwriteimports.cpp b/src/tools/uic/python/pythonwriteimports.cpp
index afa5c55da7..b122c0f895 100644
--- a/src/tools/uic/python/pythonwriteimports.cpp
+++ b/src/tools/uic/python/pythonwriteimports.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "pythonwriteimports.h"
@@ -35,12 +10,16 @@
#include <ui4.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
#include <QtCore/qtextstream.h>
#include <algorithm>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
// Generate imports for Python. Note some things differ from C++:
// - qItemView->header()->setFoo() does not require QHeaderView to be imported
// - qLabel->setFrameShape(QFrame::Box) however requires QFrame to be imported
@@ -77,20 +56,6 @@ static WriteImports::ClassesPerModule defaultClasses()
};
}
-// Change the name of a qrc file "dir/foo.qrc" file to the Python
-// module name "foo_rc" according to project conventions.
-static QString pythonResource(QString resource)
-{
- const int lastSlash = resource.lastIndexOf(QLatin1Char('/'));
- if (lastSlash != -1)
- resource.remove(0, lastSlash + 1);
- if (resource.endsWith(QLatin1String(".qrc"))) {
- resource.chop(4);
- resource.append(QLatin1String("_rc"));
- }
- return resource;
-}
-
// Helpers for WriteImports::ClassesPerModule maps
static void insertClass(const QString &module, const QString &className,
WriteImports::ClassesPerModule *c)
@@ -137,7 +102,7 @@ WriteImports::WriteImports(Uic *uic) : WriteIncludesBase(uic),
m_qtClasses(defaultClasses())
{
for (const auto &e : classInfoEntries())
- m_classToModule.insert(QLatin1String(e.klass), QLatin1String(e.module));
+ m_classToModule.insert(QLatin1StringView(e.klass), QLatin1StringView(e.module));
}
void WriteImports::acceptUI(DomUI *node)
@@ -163,27 +128,67 @@ void WriteImports::acceptUI(DomUI *node)
const auto includes = resources->elementInclude();
for (auto include : includes) {
if (include->hasAttributeLocation())
- writeImport(pythonResource(include->attributeLocation()));
+ writeResourceImport(include->attributeLocation());
}
output << '\n';
}
}
-void WriteImports::writeImport(const QString &module)
+QString WriteImports::resourceAbsolutePath(QString resource) const
+{
+ // If we know the project root, generate an absolute Python import
+ // to the resource. options. pythonRoot is the Python path component
+ // under which the UI file is.
+ const auto &options = uic()->option();
+ if (!options.inputFile.isEmpty() && !options.pythonRoot.isEmpty()) {
+ resource = QDir::cleanPath(QFileInfo(options.inputFile).canonicalPath() + u'/' + resource);
+ if (resource.size() > options.pythonRoot.size())
+ resource.remove(0, options.pythonRoot.size() + 1);
+ }
+ // If nothing is known, we assume the directory pointed by "../" is the root
+ while (resource.startsWith(u"../"))
+ resource.remove(0, 3);
+ resource.replace(u'/', u'.');
+ return resource;
+}
+
+void WriteImports::writeResourceImport(const QString &module)
{
- if (uic()->option().fromImports)
- uic()->output() << "from . ";
- uic()->output() << "import " << module << '\n';
+ const auto &options = uic()->option();
+ auto &str = uic()->output();
+
+ QString resource = QDir::cleanPath(module);
+ if (resource.endsWith(u".qrc"))
+ resource.chop(4);
+ const qsizetype basePos = resource.lastIndexOf(u'/') + 1;
+ // Change the name of a qrc file "dir/foo.qrc" file to the Python
+ // module name "foo_rc" according to project conventions.
+ if (options.rcPrefix)
+ resource.insert(basePos, u"rc_");
+ else
+ resource.append(u"_rc");
+
+ switch (options.pythonResourceImport) {
+ case Option::PythonResourceImport::Default:
+ str << "import " << QStringView{resource}.sliced(basePos) << '\n';
+ break;
+ case Option::PythonResourceImport::FromDot:
+ str << "from . import " << QStringView{resource}.sliced(basePos) << '\n';
+ break;
+ case Option::PythonResourceImport::Absolute:
+ str << "import " << resourceAbsolutePath(resource) << '\n';
+ break;
+ }
}
void WriteImports::doAdd(const QString &className, const DomCustomWidget *dcw)
{
const CustomWidgetsInfo *cwi = uic()->customWidgetsInfo();
- if (cwi->extends(className, QLatin1String("QListWidget")))
+ if (cwi->extends(className, "QListWidget"))
add(QStringLiteral("QListWidgetItem"));
- else if (cwi->extends(className, QLatin1String("QTreeWidget")))
+ else if (cwi->extends(className, "QTreeWidget"))
add(QStringLiteral("QTreeWidgetItem"));
- else if (cwi->extends(className, QLatin1String("QTableWidget")))
+ else if (cwi->extends(className, "QTableWidget"))
add(QStringLiteral("QTableWidgetItem"));
if (dcw != nullptr) {
@@ -210,7 +215,7 @@ bool WriteImports::addQtClass(const QString &className)
void WriteImports::addPythonCustomWidget(const QString &className, const DomCustomWidget *node)
{
- if (className.contains(QLatin1String("::")))
+ if (className.contains("::"_L1))
return; // Exclude namespaced names (just to make tests pass).
if (addQtClass(className)) // Qt custom widgets like QQuickWidget, QAxWidget, etc
@@ -223,9 +228,9 @@ void WriteImports::addPythonCustomWidget(const QString &className, const DomCust
} else { // When we do have elementHeader, we know it's a relative import.
QString modulePath = node->elementHeader()->text();
// Replace the '/' by '.'
- modulePath.replace(QLatin1Char('/'), QLatin1Char('.'));
+ modulePath.replace(u'/', u'.');
// '.h' is added by default on headers for <customwidget>
- if (modulePath.endsWith(QLatin1String(".h")))
+ if (modulePath.endsWith(".h"_L1))
modulePath.chop(2);
insertClass(modulePath, className, &m_customWidgets);
}
@@ -233,16 +238,31 @@ void WriteImports::addPythonCustomWidget(const QString &className, const DomCust
void WriteImports::acceptProperty(DomProperty *node)
{
- if (node->kind() == DomProperty::Enum) {
- // Add base classes like QFrame for QLabel::frameShape()
- const QString &enumV = node->elementEnum();
- const auto colonPos = enumV.indexOf(u"::");
- if (colonPos > 0)
- addQtClass(enumV.left(colonPos));
+ switch (node->kind()) {
+ case DomProperty::Enum:
+ addEnumBaseClass(node->elementEnum());
+ break;
+ case DomProperty::Set:
+ addEnumBaseClass(node->elementSet());
+ break;
+ default:
+ break;
}
+
WriteIncludesBase::acceptProperty(node);
}
+void WriteImports::addEnumBaseClass(const QString &v)
+{
+ // Add base classes like QFrame for QLabel::frameShape()
+ const auto colonPos = v.indexOf(u"::");
+ if (colonPos > 0) {
+ const QString base = v.left(colonPos);
+ if (base.startsWith(u'Q') && base != u"Qt")
+ addQtClass(base);
+ }
+}
+
} // namespace Python
QT_END_NAMESPACE