summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-12-12 18:28:26 +0100
committerLiang Qi <liang.qi@qt.io>2016-12-12 18:28:26 +0100
commiteecd6b2baca331c33a948d9a81f93dd1b47ff14d (patch)
tree024ac0e7dba08dc8ef26d62824a7a4c431a5c850
parent7561e9b64aeb649ffb3d091b1bf615efff56c730 (diff)
parent4ae6d1db64d29bb3bba07c64dc51606a2c974691 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
-rw-r--r--src/assistant/clucene/qdocument.cpp2
-rw-r--r--src/designer/src/components/formeditor/formeditor.pri2
-rw-r--r--src/designer/src/components/formeditor/formeditor.qrc5
-rw-r--r--src/designer/src/components/formeditor/formwindow.cpp19
-rw-r--r--src/designer/src/components/formeditor/formwindow.h4
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo.pngbin594 -> 0 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo16x16.pngbin0 -> 1263 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo24x24.pngbin0 -> 349 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo32x32.pngbin0 -> 15518 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo64x64.pngbin0 -> 1936 bytes
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.cpp105
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.h78
-rw-r--r--src/designer/src/components/widgetbox/widgetboxtreewidget.cpp5
-rw-r--r--src/designer/src/designer/doc/src/designer-manual.qdoc2
-rw-r--r--src/designer/src/designer/main.cpp3
-rw-r--r--src/designer/src/lib/shared/formwindowbase.cpp61
-rw-r--r--src/designer/src/lib/shared/formwindowbase_p.h4
-rw-r--r--src/designer/src/lib/shared/iconloader.cpp21
-rw-r--r--src/designer/src/lib/shared/iconloader_p.h1
-rw-r--r--src/designer/src/lib/shared/plugindialog.cpp11
-rw-r--r--src/designer/src/lib/shared/plugindialog_p.h1
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotion.cpp16
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet.cpp35
-rw-r--r--src/kmap2qmap/kmap2qmap.pro2
-rw-r--r--src/kmap2qmap/main.cpp2
-rw-r--r--src/linguist/lconvert/main.cpp2
-rw-r--r--src/linguist/linguist/doc/src/linguist-manual.qdoc34
-rw-r--r--src/linguist/linguist/mainwindow.cpp2
-rw-r--r--src/linguist/lupdate/main.cpp132
-rw-r--r--src/linguist/shared/exclusive_builds.prf6
-rw-r--r--src/linguist/shared/numerus.cpp5
-rw-r--r--src/linguist/shared/po.cpp4
-rw-r--r--src/linguist/shared/proparser.pri3
-rw-r--r--src/linguist/shared/proparser.qrc5
-rw-r--r--src/linguist/shared/qm.cpp2
-rw-r--r--src/linguist/shared/qmakeevaluator.cpp39
-rw-r--r--src/linguist/shared/qph.cpp2
-rw-r--r--src/linguist/shared/translator.h6
-rw-r--r--src/linguist/shared/ts.cpp2
-rw-r--r--src/linguist/shared/xliff.cpp2
-rw-r--r--src/macdeployqt/shared/shared.cpp34
-rw-r--r--src/pixeltool/qpixeltool.cpp27
-rw-r--r--src/qdoc/doc/qdoc-manual-markupcmds.qdoc46
-rw-r--r--src/qdoc/htmlgenerator.cpp2
-rw-r--r--src/qdoc/node.cpp65
-rw-r--r--src/qdoc/qdoc.pro3
-rw-r--r--src/qdoc/qdocdatabase.cpp1
-rw-r--r--src/qdoc/qmlvisitor.cpp31
-rw-r--r--src/qtattributionsscanner/jsongenerator.cpp2
-rw-r--r--src/qtattributionsscanner/package.h5
-rw-r--r--src/qtattributionsscanner/packagefilter.cpp5
-rw-r--r--src/qtattributionsscanner/qdocgenerator.cpp85
-rw-r--r--src/qtattributionsscanner/scanner.cpp31
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.cpp2
-rw-r--r--src/windeployqt/utils.cpp3
-rw-r--r--src/winrtrunner/appxengine_p.h2
-rw-r--r--sync.profile13
-rw-r--r--tests/auto/linguist/lconvert/tst_lconvert.cpp14
-rw-r--r--tests/auto/linguist/lrelease/tst_lrelease.cpp14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/main.cpp42
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/main.js1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/main.qml40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/project.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/project.qrc5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqrc/project.ts.result25
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/resources_cmdline/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.js1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.qml40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.qrc6
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/tst_lupdate.cpp2
-rw-r--r--tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json1
-rw-r--r--tests/auto/qtattributionsscanner/testdata/good/expected.json6
-rw-r--r--tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json2
-rw-r--r--tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json2
75 files changed, 756 insertions, 452 deletions
diff --git a/src/assistant/clucene/qdocument.cpp b/src/assistant/clucene/qdocument.cpp
index 55b8526e5..b91c483ef 100644
--- a/src/assistant/clucene/qdocument.cpp
+++ b/src/assistant/clucene/qdocument.cpp
@@ -186,7 +186,7 @@ QStringList QCLuceneDocument::getValues(const QString &name) const
retValue.append(TCharToQString((const TCHAR*)values[i]));
delete [] values[i]; values[i] = 0;
}
- delete values;
+ delete [] values;
}
delete [] fieldName;
diff --git a/src/designer/src/components/formeditor/formeditor.pri b/src/designer/src/components/formeditor/formeditor.pri
index 6b5156157..7e4afd021 100644
--- a/src/designer/src/components/formeditor/formeditor.pri
+++ b/src/designer/src/components/formeditor/formeditor.pri
@@ -8,7 +8,6 @@ FORMS += $$PWD/deviceprofiledialog.ui \
$$PWD/templateoptionspage.ui
HEADERS += $$PWD/qdesigner_resource.h \
- $$PWD/qdesignerundostack.h \
$$PWD/formwindow.h \
$$PWD/formwindow_widgetstack.h \
$$PWD/formwindow_dnditem.h \
@@ -38,7 +37,6 @@ HEADERS += $$PWD/qdesigner_resource.h \
$$PWD/templateoptionspage.h
SOURCES += $$PWD/qdesigner_resource.cpp \
- $$PWD/qdesignerundostack.cpp \
$$PWD/formwindow.cpp \
$$PWD/formwindow_widgetstack.cpp \
$$PWD/formwindow_dnditem.cpp \
diff --git a/src/designer/src/components/formeditor/formeditor.qrc b/src/designer/src/components/formeditor/formeditor.qrc
index 38fbb6200..351658088 100644
--- a/src/designer/src/components/formeditor/formeditor.qrc
+++ b/src/designer/src/components/formeditor/formeditor.qrc
@@ -61,7 +61,10 @@
<file>images/mac/forward.png</file>
<file>images/mac/down.png</file>
<file>images/mac/up.png</file>
- <file>images/qtlogo.png</file>
+ <file>images/qtlogo16x16.png</file>
+ <file>images/qtlogo24x24.png</file>
+ <file>images/qtlogo32x32.png</file>
+ <file>images/qtlogo64x64.png</file>
<file>images/qt3logo.png</file>
<file>images/resetproperty.png</file>
<file>images/cleartext.png</file>
diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp
index 2c1936e53..d969d6a54 100644
--- a/src/designer/src/components/formeditor/formwindow.cpp
+++ b/src/designer/src/components/formeditor/formwindow.cpp
@@ -329,6 +329,10 @@ FormWindow::~FormWindow()
if (resourceSet())
core()->resourceModel()->removeResourceSet(resourceSet());
delete m_selection;
+
+ if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager()))
+ manager->undoGroup()->removeStack(&m_undoStack);
+ m_undoStack.disconnect();
}
QDesignerFormEditorInterface *FormWindow::core() const
@@ -384,7 +388,7 @@ void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
void FormWindow::init()
{
if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
- manager->undoGroup()->addStack(m_undoStack.qundoStack());
+ manager->undoGroup()->addStack(&m_undoStack);
}
m_blockSelectionChanged = false;
@@ -417,9 +421,9 @@ void FormWindow::init()
m_mainContainer = 0;
m_currentWidget = 0;
- connect(&m_undoStack, &QDesignerUndoStack::changed,
+ connect(&m_undoStack, &QUndoStack::cleanChanged,
this, &QDesignerFormWindowInterface::changed);
- connect(&m_undoStack, &QDesignerUndoStack::changed,
+ connect(&m_undoStack, &QUndoStack::cleanChanged,
this, &FormWindow::checkSelection);
core()->metaDataBase()->add(this);
@@ -2435,12 +2439,15 @@ FormWindow *FormWindow::findFormWindow(QWidget *w)
bool FormWindow::isDirty() const
{
- return m_undoStack.isDirty();
+ return !m_undoStack.isClean();
}
void FormWindow::setDirty(bool dirty)
{
- m_undoStack.setDirty(dirty);
+ if (dirty)
+ m_undoStack.resetClean();
+ else
+ m_undoStack.setClean();
}
QWidget *FormWindow::containerAt(const QPoint &pos)
@@ -2975,7 +2982,7 @@ QWidget *FormWindow::formContainer() const
QUndoStack *FormWindow::commandHistory() const
{
- return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack();
+ return &const_cast<QUndoStack &>(m_undoStack);
}
} // namespace
diff --git a/src/designer/src/components/formeditor/formwindow.h b/src/designer/src/components/formeditor/formwindow.h
index 9fd3e2cd4..c577fe1ab 100644
--- a/src/designer/src/components/formeditor/formwindow.h
+++ b/src/designer/src/components/formeditor/formwindow.h
@@ -30,10 +30,10 @@
#define FORMWINDOW_H
#include "formeditor_global.h"
-#include "qdesignerundostack.h"
#include <formwindowbase_p.h>
// Qt
+#include <QtWidgets/QUndoStack>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QMap>
@@ -325,7 +325,7 @@ private:
QPoint m_startPos;
- QDesignerUndoStack m_undoStack;
+ QUndoStack m_undoStack;
QString m_fileName;
diff --git a/src/designer/src/components/formeditor/images/qtlogo.png b/src/designer/src/components/formeditor/images/qtlogo.png
deleted file mode 100644
index 7d472572b..000000000
--- a/src/designer/src/components/formeditor/images/qtlogo.png
+++ /dev/null
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qtlogo16x16.png b/src/designer/src/components/formeditor/images/qtlogo16x16.png
new file mode 100644
index 000000000..30bcb45ed
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qtlogo16x16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qtlogo24x24.png b/src/designer/src/components/formeditor/images/qtlogo24x24.png
new file mode 100644
index 000000000..058bf6972
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qtlogo24x24.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qtlogo32x32.png b/src/designer/src/components/formeditor/images/qtlogo32x32.png
new file mode 100644
index 000000000..d609c1e1e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qtlogo32x32.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qtlogo64x64.png b/src/designer/src/components/formeditor/images/qtlogo64x64.png
new file mode 100644
index 000000000..3bc03b7c7
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qtlogo64x64.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.cpp b/src/designer/src/components/formeditor/qdesignerundostack.cpp
deleted file mode 100644
index 5e6f13581..000000000
--- a/src/designer/src/components/formeditor/qdesignerundostack.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qdesignerundostack.h"
-
-#include <QtWidgets/QUndoStack>
-#include <QtWidgets/QUndoCommand>
-
-QT_BEGIN_NAMESPACE
-
-namespace qdesigner_internal {
-
-QDesignerUndoStack::QDesignerUndoStack(QObject *parent) :
- QObject(parent),
- m_undoStack(new QUndoStack),
- m_fakeDirty(false)
-{
- connect(m_undoStack, &QUndoStack::indexChanged, this, &QDesignerUndoStack::changed);
-}
-
-QDesignerUndoStack::~QDesignerUndoStack()
-{ // QUndoStack is managed by the QUndoGroup
-}
-
-void QDesignerUndoStack::clear()
-{
- m_fakeDirty = false;
- m_undoStack->clear();
-}
-
-void QDesignerUndoStack::push(QUndoCommand * cmd)
-{
- m_undoStack->push(cmd);
-}
-
-void QDesignerUndoStack::beginMacro(const QString &text)
-{
- m_undoStack->beginMacro(text);
-}
-
-void QDesignerUndoStack::endMacro()
-{
- m_undoStack->endMacro();
-}
-
-int QDesignerUndoStack::index() const
-{
- return m_undoStack->index();
-}
-
-const QUndoStack *QDesignerUndoStack::qundoStack() const
-{
- return m_undoStack;
-}
-QUndoStack *QDesignerUndoStack::qundoStack()
-{
- return m_undoStack;
-}
-
-bool QDesignerUndoStack::isDirty() const
-{
- return m_fakeDirty || !m_undoStack->isClean();
-}
-
-void QDesignerUndoStack::setDirty(bool v)
-{
- if (isDirty() == v)
- return;
- if (v) {
- m_fakeDirty = true;
- emit changed();
- } else {
- m_fakeDirty = false;
- m_undoStack->setClean();
- }
-}
-
-} // namespace qdesigner_internal
-
-QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.h b/src/designer/src/components/formeditor/qdesignerundostack.h
deleted file mode 100644
index 4ecf16cc8..000000000
--- a/src/designer/src/components/formeditor/qdesignerundostack.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef QDESIGNERUNDOSTACK_H
-#define QDESIGNERUNDOSTACK_H
-
-#include <QtCore/QObject>
-
-QT_BEGIN_NAMESPACE
-class QUndoStack;
-class QUndoCommand;
-
-namespace qdesigner_internal {
-
-/* QDesignerUndoStack: A QUndoStack extended by a way of setting it to
- * "dirty" indepently of commands (by modifications without commands
- * such as resizing). Accomplished via bool m_fakeDirty flag. The
- * lifecycle of the QUndoStack is managed by the QUndoGroup. */
-class QDesignerUndoStack : public QObject
-{
- Q_DISABLE_COPY(QDesignerUndoStack)
- Q_OBJECT
-public:
- explicit QDesignerUndoStack(QObject *parent = 0);
- virtual ~QDesignerUndoStack();
-
- void clear();
- void push(QUndoCommand * cmd);
- void beginMacro(const QString &text);
- void endMacro();
- int index() const;
-
- const QUndoStack *qundoStack() const;
- QUndoStack *qundoStack();
-
- bool isDirty() const;
-
-signals:
- void changed();
-
-public slots:
- void setDirty(bool);
-
-private:
- QUndoStack *m_undoStack;
- bool m_fakeDirty;
-};
-
-} // namespace qdesigner_internal
-
-QT_END_NAMESPACE
-
-#endif // QDESIGNERUNDOSTACK_H
diff --git a/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
index 0132ea2d7..4fa7222d0 100644
--- a/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
+++ b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
@@ -67,7 +67,6 @@ static const char *defaultTypeValueC = "default";
static const char *customValueC = "custom";
static const char *iconPrefixC = "__qt_icon__";
static const char *scratchPadValueC = "scratchpad";
-static const char *qtLogoC = "qtlogo.png";
static const char *invisibleNameC = "[invisible]";
enum TopLevelRole { NORMAL_ITEM, SCRATCHPAD_ITEM, CUSTOM_ITEM };
@@ -110,7 +109,7 @@ WidgetBoxTreeWidget::WidgetBoxTreeWidget(QDesignerFormEditorInterface *core, QWi
QIcon WidgetBoxTreeWidget::iconForWidget(QString iconName) const
{
if (iconName.isEmpty())
- iconName = QLatin1String(qtLogoC);
+ return qdesigner_internal::qtLogoIcon();
if (iconName.startsWith(QLatin1String(iconPrefixC))) {
const IconCache::const_iterator it = m_pluginIcons.constFind(iconName);
@@ -647,8 +646,6 @@ WidgetBoxTreeWidget::CategoryList WidgetBoxTreeWidget::loadCustomCategoryList()
icon_name = iconPrefix;
icon_name += pluginName;
m_pluginIcons.insert(icon_name, icon);
- } else {
- icon_name = QLatin1String(qtLogoC);
}
cat.addWidget(Widget(displayName, dom_xml, icon_name, Widget::Custom));
diff --git a/src/designer/src/designer/doc/src/designer-manual.qdoc b/src/designer/src/designer/doc/src/designer-manual.qdoc
index 39d0d5451..55fb81c32 100644
--- a/src/designer/src/designer/doc/src/designer-manual.qdoc
+++ b/src/designer/src/designer/doc/src/designer-manual.qdoc
@@ -89,7 +89,7 @@
Some source code in \QD is licensed under specific highly permissive
licenses from the original authors. The Qt team gratefully acknowledges
- these contributions to \QD and all uses of \QD should also acknowledge
+ these contributions to \QD and all users of \QD should also acknowledge
these contributions and quote the following license statements in an
appendix to the documentation.
diff --git a/src/designer/src/designer/main.cpp b/src/designer/src/designer/main.cpp
index 46dc3817e..236f24138 100644
--- a/src/designer/src/designer/main.cpp
+++ b/src/designer/src/designer/main.cpp
@@ -38,6 +38,9 @@ int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(designer);
+ // required for QWebEngineView
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+
QDesigner app(argc, argv);
switch (app.parseCommandLineArguments()) {
case QDesigner::ParseArgumentsSuccess:
diff --git a/src/designer/src/lib/shared/formwindowbase.cpp b/src/designer/src/lib/shared/formwindowbase.cpp
index e702d777a..d8f422a0a 100644
--- a/src/designer/src/lib/shared/formwindowbase.cpp
+++ b/src/designer/src/lib/shared/formwindowbase.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/QList>
+#include <QtCore/QSet>
#include <QtCore/QTimer>
#include <QtWidgets/QMenu>
#include <QtWidgets/QListWidget>
@@ -112,6 +113,15 @@ FormWindowBase::FormWindowBase(QDesignerFormEditorInterface *core, QWidget *pare
FormWindowBase::~FormWindowBase()
{
+ QSet<QDesignerPropertySheet *> sheets = m_d->m_reloadableResources.keys().toSet();
+ sheets |= m_d->m_reloadablePropertySheets.keys().toSet();
+
+ m_d->m_reloadableResources.clear();
+ m_d->m_reloadablePropertySheets.clear();
+
+ for (QDesignerPropertySheet *sheet : sheets)
+ disconnectSheet(sheet);
+
delete m_d;
}
@@ -137,14 +147,17 @@ void FormWindowBase::setResourceSet(QtResourceSet *resourceSet)
void FormWindowBase::addReloadableProperty(QDesignerPropertySheet *sheet, int index)
{
+ connectSheet(sheet);
m_d->m_reloadableResources[sheet][index] = true;
}
void FormWindowBase::removeReloadableProperty(QDesignerPropertySheet *sheet, int index)
{
m_d->m_reloadableResources[sheet].remove(index);
- if (m_d->m_reloadableResources[sheet].count() == 0)
+ if (!m_d->m_reloadableResources[sheet].count()) {
m_d->m_reloadableResources.remove(sheet);
+ disconnectSheet(sheet);
+ }
}
void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object)
@@ -152,13 +165,53 @@ void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, Q
if (qobject_cast<QTreeWidget *>(object) ||
qobject_cast<QTableWidget *>(object) ||
qobject_cast<QListWidget *>(object) ||
- qobject_cast<QComboBox *>(object))
+ qobject_cast<QComboBox *>(object)) {
+ connectSheet(sheet);
m_d->m_reloadablePropertySheets[sheet] = object;
+ }
}
-void FormWindowBase::removeReloadablePropertySheet(QDesignerPropertySheet *sheet)
+void FormWindowBase::connectSheet(QDesignerPropertySheet *sheet)
{
- m_d->m_reloadablePropertySheets.remove(sheet);
+ if (m_d->m_reloadableResources.contains(sheet)
+ || m_d->m_reloadablePropertySheets.contains(sheet)) {
+ // already connected
+ return;
+ }
+ connect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed);
+}
+
+void FormWindowBase::disconnectSheet(QDesignerPropertySheet *sheet)
+{
+ if (m_d->m_reloadableResources.contains(sheet)
+ || m_d->m_reloadablePropertySheets.contains(sheet)) {
+ // still need to be connected
+ return;
+ }
+ disconnect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed);
+}
+
+void FormWindowBase::sheetDestroyed(QObject *object)
+{
+ // qobject_cast<QDesignerPropertySheet *>(object)
+ // will fail since the destructor of QDesignerPropertySheet
+ // has already finished
+
+ for (auto it = m_d->m_reloadableResources.begin();
+ it != m_d->m_reloadableResources.end(); ++it) {
+ if (it.key() == object) {
+ m_d->m_reloadableResources.erase(it);
+ break;
+ }
+ }
+
+ for (auto it = m_d->m_reloadablePropertySheets.begin();
+ it != m_d->m_reloadablePropertySheets.end(); ++it) {
+ if (it.key() == object) {
+ m_d->m_reloadablePropertySheets.erase(it);
+ break;
+ }
+ }
}
void FormWindowBase::reloadProperties()
diff --git a/src/designer/src/lib/shared/formwindowbase_p.h b/src/designer/src/lib/shared/formwindowbase_p.h
index 0740e48a6..ceb8beb80 100644
--- a/src/designer/src/lib/shared/formwindowbase_p.h
+++ b/src/designer/src/lib/shared/formwindowbase_p.h
@@ -138,7 +138,6 @@ public:
void addReloadableProperty(QDesignerPropertySheet *sheet, int index);
void removeReloadableProperty(QDesignerPropertySheet *sheet, int index);
void addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object);
- void removeReloadablePropertySheet(QDesignerPropertySheet *sheet);
void reloadProperties();
void emitWidgetRemoved(QWidget *w);
@@ -167,9 +166,12 @@ public slots:
private slots:
void triggerDefaultAction(QWidget *w);
+ void sheetDestroyed(QObject *object);
private:
void syncGridFeature();
+ void connectSheet(QDesignerPropertySheet *sheet);
+ void disconnectSheet(QDesignerPropertySheet *sheet);
FormWindowBasePrivate *m_d;
};
diff --git a/src/designer/src/lib/shared/iconloader.cpp b/src/designer/src/lib/shared/iconloader.cpp
index 9ac8e96b9..6af620372 100644
--- a/src/designer/src/lib/shared/iconloader.cpp
+++ b/src/designer/src/lib/shared/iconloader.cpp
@@ -60,6 +60,27 @@ QDESIGNER_SHARED_EXPORT QIcon emptyIcon()
return QIcon(QStringLiteral(":/qt-project.org/formeditor/images/emptyicon.png"));
}
+static QIcon buildIcon(const QString &prefix, const int *sizes, size_t sizeCount)
+{
+ QIcon result;
+ for (size_t i = 0; i < sizeCount; ++i) {
+ const QString size = QString::number(sizes[i]);
+ const QPixmap pixmap(prefix + size + QLatin1Char('x') + size + QStringLiteral(".png"));
+ Q_ASSERT(!pixmap.size().isEmpty());
+ result.addPixmap(pixmap);
+ }
+ return result;
+}
+
+QDESIGNER_SHARED_EXPORT QIcon qtLogoIcon()
+{
+ static const int sizes[] = {16, 24, 32, 64};
+ static const QIcon result =
+ buildIcon(QStringLiteral(":/qt-project.org/formeditor/images/qtlogo"),
+ sizes, sizeof(sizes) / sizeof(sizes[0]));
+ return result;
+}
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/iconloader_p.h b/src/designer/src/lib/shared/iconloader_p.h
index 8596bb4f4..5932a18c1 100644
--- a/src/designer/src/lib/shared/iconloader_p.h
+++ b/src/designer/src/lib/shared/iconloader_p.h
@@ -51,6 +51,7 @@ namespace qdesigner_internal {
QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name);
QDESIGNER_SHARED_EXPORT QIcon emptyIcon();
+QDESIGNER_SHARED_EXPORT QIcon qtLogoIcon();
} // namespace qdesigner_internal
diff --git a/src/designer/src/lib/shared/plugindialog.cpp b/src/designer/src/lib/shared/plugindialog.cpp
index 827dd8c68..1d948aee6 100644
--- a/src/designer/src/lib/shared/plugindialog.cpp
+++ b/src/designer/src/lib/shared/plugindialog.cpp
@@ -29,6 +29,7 @@
#include "plugindialog_p.h"
#include "pluginmanager_p.h"
+#include "iconloader_p.h"
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerIntegrationInterface>
@@ -129,14 +130,6 @@ void PluginDialog::populateTreeWidget()
}
}
-QIcon PluginDialog::pluginIcon(const QIcon &icon)
-{
- if (icon.isNull())
- return QIcon(QStringLiteral(":/qt-project.org/formeditor/images/qtlogo.png"));
-
- return icon;
-}
-
QTreeWidgetItem* PluginDialog::setTopLevelItem(const QString &itemName)
{
QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui.treeWidget);
@@ -170,7 +163,7 @@ void PluginDialog::setItem(QTreeWidgetItem *pluginItem, const QString &name,
item->setText(0, name);
item->setToolTip(0, toolTip);
item->setWhatsThis(0, whatsThis);
- item->setIcon(0, pluginIcon(icon));
+ item->setIcon(0, icon.isNull() ? qtLogoIcon() : icon);
}
void PluginDialog::updateCustomWidgetPlugins()
diff --git a/src/designer/src/lib/shared/plugindialog_p.h b/src/designer/src/lib/shared/plugindialog_p.h
index 4a8eae98a..ddd352164 100644
--- a/src/designer/src/lib/shared/plugindialog_p.h
+++ b/src/designer/src/lib/shared/plugindialog_p.h
@@ -59,7 +59,6 @@ private slots:
private:
void populateTreeWidget();
- QIcon pluginIcon(const QIcon &icon);
QTreeWidgetItem* setTopLevelItem(const QString &itemName);
QTreeWidgetItem* setPluginItem(QTreeWidgetItem *topLevelItem,
const QString &itemName, const QFont &font);
diff --git a/src/designer/src/lib/shared/qdesigner_promotion.cpp b/src/designer/src/lib/shared/qdesigner_promotion.cpp
index fabca5514..61c7675cf 100644
--- a/src/designer/src/lib/shared/qdesigner_promotion.cpp
+++ b/src/designer/src/lib/shared/qdesigner_promotion.cpp
@@ -116,6 +116,13 @@ namespace {
}
}
+static void markFormsDirty(const QDesignerFormEditorInterface *core)
+{
+ const QDesignerFormWindowManagerInterface *fwm = core->formWindowManager();
+ for (int f = 0, count = fwm->formWindowCount(); f < count; ++f)
+ fwm->formWindow(f)->setDirty(true);
+}
+
namespace qdesigner_internal {
QDesignerPromotion::QDesignerPromotion(QDesignerFormEditorInterface *core) :
@@ -153,6 +160,7 @@ namespace qdesigner_internal {
promotedItem->setExtends(baseClass);
promotedItem->setIncludeFile(includeFile);
widgetDataBase->append(promotedItem);
+ markFormsDirty(m_core);
return true;
}
@@ -303,6 +311,7 @@ namespace qdesigner_internal {
}
}
widgetDataBase->remove(index);
+ markFormsDirty(m_core);
return true;
}
@@ -344,6 +353,7 @@ namespace qdesigner_internal {
if (foundReferences)
refreshObjectInspector();
+ markFormsDirty(m_core);
return true;
}
@@ -358,8 +368,10 @@ namespace qdesigner_internal {
QDesignerWidgetDataBaseItemInterface *dbItem = promotedWidgetDataBaseItem(widgetDataBase, className, errorMessage);
if (!dbItem)
return false;
-
- dbItem->setIncludeFile(includeFile);
+ if (dbItem->includeFile() != includeFile) {
+ dbItem->setIncludeFile(includeFile);
+ markFormsDirty(m_core);
+ }
return true;
}
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
index 3caaba690..6a0910e2a 100644
--- a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -699,8 +699,6 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
QDesignerPropertySheet::~QDesignerPropertySheet()
{
- if (d->m_fwb)
- d->m_fwb->removeReloadablePropertySheet(this);
delete d;
}
@@ -1627,8 +1625,6 @@ struct QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate {
typedef QMap<QObject*, QObject*> ExtensionMap;
ExtensionMap m_extensions;
- typedef QHash<QObject*, bool> ExtendedSet;
- ExtendedSet m_extended;
};
QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate::PropertySheetFactoryPrivate() :
@@ -1653,30 +1649,20 @@ QDesignerAbstractPropertySheetFactory::~QDesignerAbstractPropertySheetFactory()
QObject *QDesignerAbstractPropertySheetFactory::extension(QObject *object, const QString &iid) const
{
- typedef PropertySheetFactoryPrivate::ExtensionMap ExtensionMap;
if (!object)
return 0;
if (iid != m_impl->m_propertySheetId && iid != m_impl->m_dynamicPropertySheetId)
return 0;
- ExtensionMap::iterator it = m_impl->m_extensions.find(object);
- if (it == m_impl->m_extensions.end()) {
- if (QObject *ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this))) {
- connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
- it = m_impl->m_extensions.insert(object, ext);
- }
- }
-
- if (!m_impl->m_extended.contains(object)) {
+ QObject *ext = m_impl->m_extensions.value(object, 0);
+ if (!ext && (ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this)))) {
+ connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
connect(object, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
- m_impl->m_extended.insert(object, true);
+ m_impl->m_extensions.insert(object, ext);
}
- if (it == m_impl->m_extensions.end())
- return 0;
-
- return it.value();
+ return ext;
}
void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
@@ -1684,14 +1670,15 @@ void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
QMutableMapIterator<QObject*, QObject*> it(m_impl->m_extensions);
while (it.hasNext()) {
it.next();
-
- QObject *o = it.key();
- if (o == object || object == it.value()) {
+ if (it.key() == object || it.value() == object) {
+ if (it.key() == object) {
+ QObject *ext = it.value();
+ disconnect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed);
+ delete ext;
+ }
it.remove();
}
}
-
- m_impl->m_extended.remove(object);
}
QT_END_NAMESPACE
diff --git a/src/kmap2qmap/kmap2qmap.pro b/src/kmap2qmap/kmap2qmap.pro
index 7ccdc2c24..d08ec6bb4 100644
--- a/src/kmap2qmap/kmap2qmap.pro
+++ b/src/kmap2qmap/kmap2qmap.pro
@@ -1,4 +1,4 @@
-QT = core platformsupport-private
+QT = core input_support-private
CONFIG += console
SOURCES += main.cpp
diff --git a/src/kmap2qmap/main.cpp b/src/kmap2qmap/main.cpp
index 453d20a0a..9fd7e9ae8 100644
--- a/src/kmap2qmap/main.cpp
+++ b/src/kmap2qmap/main.cpp
@@ -38,7 +38,7 @@
#include <QStringList>
#include <QTextStream>
-#include <QtPlatformSupport/private/qevdevkeyboardhandler_p.h>
+#include <QtInputSupport/private/qevdevkeyboardhandler_p.h>
using namespace std;
diff --git a/src/linguist/lconvert/main.cpp b/src/linguist/lconvert/main.cpp
index 565154520..4e26adbbb 100644
--- a/src/linguist/lconvert/main.cpp
+++ b/src/linguist/lconvert/main.cpp
@@ -50,7 +50,7 @@ static int usage(const QStringList &args)
QString loaders;
QString line(QLatin1String(" %1 - %2\n"));
foreach (Translator::FileFormat format, Translator::registeredFileFormats())
- loaders += line.arg(format.extension, -5).arg(format.description);
+ loaders += line.arg(format.extension, -5).arg(format.description());
std::cout << qPrintable(LC::tr("\nUsage:\n"
" lconvert [options] <infile> [<infile>...]\n\n"
diff --git a/src/linguist/linguist/doc/src/linguist-manual.qdoc b/src/linguist/linguist/doc/src/linguist-manual.qdoc
index d5492a1ae..a035827f2 100644
--- a/src/linguist/linguist/doc/src/linguist-manual.qdoc
+++ b/src/linguist/linguist/doc/src/linguist-manual.qdoc
@@ -847,7 +847,8 @@
The \c lupdate tool extracts user interface strings from your application.
It reads the application .pro file to identify which source files
contain text to be translated. This means your source files must be listed
- in the \c SOURCES or \c HEADERS entry in the .pro file. If your files are
+ in the \c SOURCES or \c HEADERS entry in the .pro file, or in resource
+ files listed in the \c RESOURCE entry. If your files are
not listed, the text in them will not be found.
An example of a complete \c .pro file with four translation source
@@ -870,37 +871,6 @@
\snippet doc_src_linguist-manual.cpp 3
- \section2 Use a Conditional to Hide QML Source From the Compiler
-
- The SOURCES variable is intended for C++ source files. If you list QML
- or JavaScript source files there, the compiler tries to build them as though
- they are C++ files. As a workaround, you can use an \c lupdate_only{...}
- conditional statement so the \c lupdate tool sees the .qml files but the C++
- compiler ignores them.
-
- For example, the following .pro file snippet specifies two .qml files in
- the application:
-
- \code
- lupdate_only {
- SOURCES = main.qml \
- MainPage.qml
- }
- \endcode
-
- You can also specify the .qml source files with a wildcard match. The
- search is not recursive so you need to specify each directory where there
- are user interface strings in the source code:
-
- \code
- lupdate_only {
- SOURCES = *.qml \
- *.js \
- content/*.qml \
- content/*.js
- }
- \endcode
-
\section1 Internationalizing Applications
Design your application so that it can be adapted to various languages and
diff --git a/src/linguist/linguist/mainwindow.cpp b/src/linguist/linguist/mainwindow.cpp
index 282e2adea..cd460711b 100644
--- a/src/linguist/linguist/mainwindow.cpp
+++ b/src/linguist/linguist/mainwindow.cpp
@@ -743,7 +743,7 @@ static QString fileFilters(bool allFirst)
QString filter;
foreach (const Translator::FileFormat &format, Translator::registeredFileFormats()) {
if (format.fileType == Translator::FileFormat::TranslationSource && format.priority >= 0) {
- filter.append(pattern.arg(format.description).arg(format.extension));
+ filter.append(pattern.arg(format.description(), format.extension));
allExtensions.append(QLatin1String("*.") + format.extension);
}
}
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index 3e6a4fd5b..04730ddd7 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QStringList>
#include <QtCore/QTranslator>
#include <QtCore/QLibraryInfo>
+#include <QtCore/QXmlStreamReader>
#include <iostream>
@@ -390,6 +391,73 @@ public:
static EvalHandler evalHandler;
+static bool isSupportedExtension(const QString &ext)
+{
+ return ext == QLatin1String("qml")
+ || ext == QLatin1String("js") || ext == QLatin1String("qs")
+ || ext == QLatin1String("ui") || ext == QLatin1String("jui");
+}
+
+static QStringList getResources(const QString &resourceFile, QMakeVfs *vfs)
+{
+ Q_ASSERT(vfs);
+ if (!vfs->exists(resourceFile))
+ return QStringList();
+ QString content;
+ QString errStr;
+ if (!vfs->readFile(resourceFile, &content, &errStr)) {
+ printErr(LU::tr("lupdate error: Can not read %1: %2\n").arg(resourceFile, errStr));
+ return QStringList();
+ }
+ QStringList fileList;
+ QString dirPath = QFileInfo(resourceFile).path();
+ QXmlStreamReader reader(content);
+ bool isFileTag = false;
+ QStringList tagStack;
+ tagStack << QLatin1String("RCC") << QLatin1String("qresource") << QLatin1String("file");
+ int curDepth = 0;
+ while (!reader.atEnd()) {
+ QXmlStreamReader::TokenType t = reader.readNext();
+ switch (t) {
+ case QXmlStreamReader::StartElement:
+ if (curDepth >= tagStack.count() || reader.name() != tagStack.at(curDepth)) {
+ printErr(LU::tr("unexpected <%1> tag\n").arg(reader.name().toString()));
+ continue;
+ }
+ if (++curDepth == tagStack.count())
+ isFileTag = true;
+ break;
+
+ case QXmlStreamReader::EndElement:
+ isFileTag = false;
+ if (curDepth == 0 || reader.name() != tagStack.at(curDepth - 1)) {
+ printErr(LU::tr("unexpected closing <%1> tag\n").arg(reader.name().toString()));
+ continue;
+ }
+ --curDepth;
+ break;
+
+ case QXmlStreamReader::Characters:
+ if (isFileTag) {
+ QString fn = reader.text().toString();
+ if (!QFileInfo(fn).isAbsolute())
+ fn = dirPath + QLatin1Char('/') + fn;
+ QFileInfo cfi(fn);
+ if (isSupportedExtension(cfi.suffix()))
+ fileList << cfi.filePath();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (reader.error() != QXmlStreamReader::NoError)
+ printErr(LU::tr("lupdate error: %1:%2: %3\n")
+ .arg(resourceFile, QString::number(reader.lineNumber()), reader.errorString()));
+ return fileList;
+}
+
static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths,
const QString &projectDir, const ProFileEvaluator &visitor)
{
@@ -400,7 +468,7 @@ static QStringList getSources(const char *var, const char *vvar, const QStringLi
}
static QStringList getSources(const ProFileEvaluator &visitor, const QString &projectDir,
- const QStringList &excludes)
+ const QStringList &excludes, QMakeVfs *vfs)
{
QStringList baseVPaths;
baseVPaths += visitor.absolutePathValues(QLatin1String("VPATH"), projectDir);
@@ -415,6 +483,10 @@ static QStringList getSources(const ProFileEvaluator &visitor, const QString &pr
sourceFiles += getSources("FORMS", "VPATH_FORMS", baseVPaths, projectDir, visitor);
+ QStringList resourceFiles = getSources("RESOURCES", "VPATH_RESOURCES", baseVPaths, projectDir, visitor);
+ foreach (const QString &resource, resourceFiles)
+ sourceFiles += getResources(resource, vfs);
+
QStringList installs = visitor.values(QLatin1String("INSTALLS"))
+ visitor.values(QLatin1String("DEPLOYMENT"));
installs.removeDuplicates();
@@ -440,12 +512,8 @@ static QStringList getSources(const ProFileEvaluator &visitor, const QString &pr
while (iterator.hasNext()) {
iterator.next();
QFileInfo cfi = iterator.fileInfo();
- QString ext = cfi.suffix();
- if (ext == QLatin1String("qml")
- || ext == QLatin1String("js") || ext == QLatin1String("qs")
- || ext == QLatin1String("ui") || ext == QLatin1String("jui")) {
+ if (isSupportedExtension(cfi.suffix()))
sourceFiles << cfi.filePath();
- }
}
}
}
@@ -607,7 +675,7 @@ static void processProject(
cd.m_sourceIsUtf16 = options & SourceIsUtf16;
cd.m_includePath = visitor.absolutePathValues(QLatin1String("INCLUDEPATH"), proPath);
cd.m_excludes = getExcludes(visitor, proPath);
- QStringList sourceFiles = getSources(visitor, proPath, cd.m_excludes);
+ QStringList sourceFiles = getSources(visitor, proPath, cd.m_excludes, vfs);
QSet<QString> sourceDirs;
sourceDirs.insert(proPath + QLatin1Char('/'));
foreach (const QString &sf, sourceFiles)
@@ -718,7 +786,7 @@ int main(int argc, char **argv)
#endif // Q_OS_WIN32
#endif
- m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml");
+ m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml,qrc");
QStringList args = app.arguments();
QStringList tsFileNames;
@@ -728,6 +796,7 @@ int main(int argc, char **argv)
QMultiHash<QString, QString> allCSources;
QSet<QString> projectRoots;
QStringList sourceFiles;
+ QStringList resourceFiles;
QStringList includePath;
QStringList alienFiles;
QString targetLanguage;
@@ -981,25 +1050,33 @@ int main(int argc, char **argv)
int scanRootLen = dir.absolutePath().length();
foreach (const QFileInfo &fi, fileinfolist) {
QString fn = QDir::cleanPath(fi.absoluteFilePath());
- sourceFiles << fn;
-
- if (!fn.endsWith(QLatin1String(".java"))
- && !fn.endsWith(QLatin1String(".jui"))
- && !fn.endsWith(QLatin1String(".ui"))
- && !fn.endsWith(QLatin1String(".js"))
- && !fn.endsWith(QLatin1String(".qs"))
- && !fn.endsWith(QLatin1String(".qml"))) {
- int offset = 0;
- int depth = 0;
- do {
- offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
- QString ffn = fn.mid(offset + 1);
- allCSources.insert(ffn, fn);
- } while (++depth < 3 && offset > scanRootLen);
+ if (fn.endsWith(QLatin1String(".qrc"), Qt::CaseInsensitive)) {
+ resourceFiles << fn;
+ } else {
+ sourceFiles << fn;
+
+ if (!fn.endsWith(QLatin1String(".java"))
+ && !fn.endsWith(QLatin1String(".jui"))
+ && !fn.endsWith(QLatin1String(".ui"))
+ && !fn.endsWith(QLatin1String(".js"))
+ && !fn.endsWith(QLatin1String(".qs"))
+ && !fn.endsWith(QLatin1String(".qml"))) {
+ int offset = 0;
+ int depth = 0;
+ do {
+ offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
+ QString ffn = fn.mid(offset + 1);
+ allCSources.insert(ffn, fn);
+ } while (++depth < 3 && offset > scanRootLen);
+ }
}
}
} else {
- sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
+ QString fn = QDir::cleanPath(fi.absoluteFilePath());
+ if (fn.endsWith(QLatin1String(".qrc"), Qt::CaseInsensitive))
+ resourceFiles << fn;
+ else
+ sourceFiles << fn;
projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
}
}
@@ -1029,11 +1106,16 @@ int main(int argc, char **argv)
cd.m_projectRoots = projectRoots;
cd.m_includePath = includePath;
cd.m_allCSources = allCSources;
+ if (!resourceFiles.isEmpty()) {
+ QMakeVfs vfs;
+ foreach (const QString &resource, resourceFiles)
+ sourceFiles << getResources(resource, &vfs);
+ }
processSources(fetchedTor, sourceFiles, cd);
updateTsFiles(fetchedTor, tsFileNames, alienFiles,
sourceLanguage, targetLanguage, options, &fail);
} else {
- if (!sourceFiles.isEmpty() || !includePath.isEmpty()) {
+ if (!sourceFiles.isEmpty() || !resourceFiles.isEmpty() || !includePath.isEmpty()) {
printErr(LU::tr("lupdate error:"
" Both project and source files / include paths specified.\n"));
return 1;
diff --git a/src/linguist/shared/exclusive_builds.prf b/src/linguist/shared/exclusive_builds.prf
new file mode 100644
index 000000000..b312a4c58
--- /dev/null
+++ b/src/linguist/shared/exclusive_builds.prf
@@ -0,0 +1,6 @@
+# Lupdate doesn't execute the build passes, so prevent that they are
+# created in the first place. This tricks for example resources.prf
+# into actually creating the QML resource file, so we can scan it.
+
+defineTest(addExclusiveBuilds) {
+}
diff --git a/src/linguist/shared/numerus.cpp b/src/linguist/shared/numerus.cpp
index d8562f20b..6a1ca8130 100644
--- a/src/linguist/shared/numerus.cpp
+++ b/src/linguist/shared/numerus.cpp
@@ -124,7 +124,6 @@ static const char * const tagalogForms[] =
#define EOL QLocale::C
static const QLocale::Language japaneseStyleLanguages[] = {
- QLocale::Armenian,
QLocale::Bislama,
QLocale::Burmese,
QLocale::Chinese,
@@ -141,6 +140,7 @@ static const QLocale::Language japaneseStyleLanguages[] = {
QLocale::Oromo,
QLocale::Persian,
QLocale::Sundanese,
+ QLocale::Tatar,
QLocale::Thai,
QLocale::Tibetan,
QLocale::Turkish,
@@ -227,7 +227,6 @@ static const QLocale::Language englishStyleLanguages[] = {
QLocale::Swedish,
QLocale::Tajik,
QLocale::Tamil,
- QLocale::Tatar,
QLocale::Telugu,
QLocale::Tongan,
QLocale::Tsonga,
@@ -246,6 +245,7 @@ static const QLocale::Language englishStyleLanguages[] = {
};
static const QLocale::Language frenchStyleLanguages[] = {
// keep synchronized with frenchStyleCountries
+ QLocale::Armenian,
QLocale::Breton,
QLocale::French,
QLocale::Portuguese,
@@ -298,6 +298,7 @@ static const QLocale::Country frenchStyleCountries[] = {
// keep synchronized with frenchStyleLanguages
QLocale::AnyCountry,
QLocale::AnyCountry,
+ QLocale::AnyCountry,
QLocale::Brazil,
QLocale::AnyCountry,
QLocale::AnyCountry,
diff --git a/src/linguist/shared/po.cpp b/src/linguist/shared/po.cpp
index a6fd895ec..5bbaf97c0 100644
--- a/src/linguist/shared/po.cpp
+++ b/src/linguist/shared/po.cpp
@@ -883,14 +883,14 @@ int initPO()
{
Translator::FileFormat format;
format.extension = QLatin1String("po");
- format.description = FMT::tr("GNU Gettext localization files");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "GNU Gettext localization files");
format.loader = &loadPO;
format.saver = &savePO;
format.fileType = Translator::FileFormat::TranslationSource;
format.priority = 1;
Translator::registerFileFormat(format);
format.extension = QLatin1String("pot");
- format.description = FMT::tr("GNU Gettext localization template files");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "GNU Gettext localization template files");
format.loader = &loadPO;
format.saver = &savePOT;
format.fileType = Translator::FileFormat::TranslationSource;
diff --git a/src/linguist/shared/proparser.pri b/src/linguist/shared/proparser.pri
index 124227bc4..f3fcad515 100644
--- a/src/linguist/shared/proparser.pri
+++ b/src/linguist/shared/proparser.pri
@@ -23,3 +23,6 @@ SOURCES += \
$$PWD/qmakeevaluator.cpp \
$$PWD/qmakebuiltins.cpp \
$$PWD/profileevaluator.cpp
+
+RESOURCES += $$PWD/proparser.qrc
+DEFINES += QMAKE_BUILTIN_PRFS QMAKE_OVERRIDE_PRFS
diff --git a/src/linguist/shared/proparser.qrc b/src/linguist/shared/proparser.qrc
new file mode 100644
index 000000000..77ffd258a
--- /dev/null
+++ b/src/linguist/shared/proparser.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qmake/override_features" >
+ <file>exclusive_builds.prf</file>
+ </qresource>
+</RCC>
diff --git a/src/linguist/shared/qm.cpp b/src/linguist/shared/qm.cpp
index 95708ef4f..cdca3a113 100644
--- a/src/linguist/shared/qm.cpp
+++ b/src/linguist/shared/qm.cpp
@@ -721,7 +721,7 @@ int initQM()
Translator::FileFormat format;
format.extension = QLatin1String("qm");
- format.description = FMT::tr("Compiled Qt translations");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Compiled Qt translations");
format.fileType = Translator::FileFormat::TranslationBinary;
format.priority = 0;
format.loader = &loadQM;
diff --git a/src/linguist/shared/qmakeevaluator.cpp b/src/linguist/shared/qmakeevaluator.cpp
index 3ec44de09..4830bcc96 100644
--- a/src/linguist/shared/qmakeevaluator.cpp
+++ b/src/linguist/shared/qmakeevaluator.cpp
@@ -1941,23 +1941,34 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
// needs to be determined. Failed lookups are represented via non-null empty strings.
QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
if (fnp->isNull()) {
- int start_root = 0;
- const QStringList &paths = m_featureRoots->paths;
- if (!currFn.isEmpty()) {
- QStringRef currPath = IoUtils::pathName(currFn);
- for (int root = 0; root < paths.size(); ++root)
- if (currPath == paths.at(root)) {
- start_root = root + 1;
- break;
- }
- }
- for (int root = start_root; root < paths.size(); ++root) {
- QString fname = paths.at(root) + fn;
- if (IoUtils::exists(fname)) {
- fn = fname;
+#ifdef QMAKE_OVERRIDE_PRFS
+ {
+ QString ovrfn(QLatin1String(":/qmake/override_features/") + fn);
+ if (QFileInfo::exists(ovrfn)) {
+ fn = ovrfn;
goto cool;
}
}
+#endif
+ {
+ int start_root = 0;
+ const QStringList &paths = m_featureRoots->paths;
+ if (!currFn.isEmpty()) {
+ QStringRef currPath = IoUtils::pathName(currFn);
+ for (int root = 0; root < paths.size(); ++root)
+ if (currPath == paths.at(root)) {
+ start_root = root + 1;
+ break;
+ }
+ }
+ for (int root = start_root; root < paths.size(); ++root) {
+ QString fname = paths.at(root) + fn;
+ if (IoUtils::exists(fname)) {
+ fn = fname;
+ goto cool;
+ }
+ }
+ }
#ifdef QMAKE_BUILTIN_PRFS
fn.prepend(QLatin1String(":/qmake/features/"));
if (QFileInfo::exists(fn))
diff --git a/src/linguist/shared/qph.cpp b/src/linguist/shared/qph.cpp
index 26b511201..da5d20e2a 100644
--- a/src/linguist/shared/qph.cpp
+++ b/src/linguist/shared/qph.cpp
@@ -178,7 +178,7 @@ int initQPH()
Translator::FileFormat format;
format.extension = QLatin1String("qph");
- format.description = FMT::tr("Qt Linguist 'Phrase Book'");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Qt Linguist 'Phrase Book'");
format.fileType = Translator::FileFormat::TranslationSource;
format.priority = 0;
format.loader = &loadQPH;
diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h
index be412180a..ff6bd9578 100644
--- a/src/linguist/shared/translator.h
+++ b/src/linguist/shared/translator.h
@@ -180,9 +180,11 @@ public:
typedef bool (*SaveFunction)(const Translator &, QIODevice &out, ConversionData &data);
typedef bool (*LoadFunction)(Translator &, QIODevice &in, ConversionData &data);
struct FileFormat {
- FileFormat() : loader(0), saver(0), priority(-1) {}
+ FileFormat() : untranslatedDescription(nullptr), loader(0), saver(0), priority(-1) {}
QString extension; // such as "ts", "xlf", ...
- QString description; // human-readable description
+ const char *untranslatedDescription;
+ // human-readable description
+ QString description() const { return FMT::tr(untranslatedDescription); }
LoadFunction loader;
SaveFunction saver;
enum FileType { TranslationSource, TranslationBinary } fileType;
diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp
index fc71ededb..cfbbd4384 100644
--- a/src/linguist/shared/ts.cpp
+++ b/src/linguist/shared/ts.cpp
@@ -687,7 +687,7 @@ int initTS()
format.extension = QLatin1String("ts");
format.fileType = Translator::FileFormat::TranslationSource;
format.priority = 0;
- format.description = FMT::tr("Qt translation sources");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Qt translation sources");
format.loader = &loadTS;
format.saver = &saveTS;
Translator::registerFileFormat(format);
diff --git a/src/linguist/shared/xliff.cpp b/src/linguist/shared/xliff.cpp
index 1478cd42c..025b222b4 100644
--- a/src/linguist/shared/xliff.cpp
+++ b/src/linguist/shared/xliff.cpp
@@ -833,7 +833,7 @@ int initXLIFF()
{
Translator::FileFormat format;
format.extension = QLatin1String("xlf");
- format.description = FMT::tr("XLIFF localization files");
+ format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "XLIFF localization files");
format.fileType = Translator::FileFormat::TranslationSource;
format.priority = 1;
format.loader = &loadXLIFF;
diff --git a/src/macdeployqt/shared/shared.cpp b/src/macdeployqt/shared/shared.cpp
index 47bd70e17..e57bc785d 100644
--- a/src/macdeployqt/shared/shared.cpp
+++ b/src/macdeployqt/shared/shared.cpp
@@ -996,6 +996,22 @@ DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringLis
}
}
+QString getLibInfix(const QStringList &deployedFrameworks)
+{
+ QString libInfix;
+ foreach (const QString &framework, deployedFrameworks) {
+ if (framework.startsWith(QStringLiteral("QtCore"))) {
+ Q_ASSERT(framework.length() >= 16);
+ // 16 == "QtCore" + ".framework"
+ const int lengthOfLibInfix = framework.length() - 16;
+ if (lengthOfLibInfix)
+ libInfix = framework.mid(6, lengthOfLibInfix);
+ break;
+ }
+ }
+ return libInfix;
+}
+
void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath,
const QString pluginDestinationPath, DeploymentInfo deploymentInfo, bool useDebugLibs)
{
@@ -1013,8 +1029,11 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
// Cocoa print support
pluginList.append("printsupport/libcocoaprintersupport.dylib");
+ // Check if Qt was configured with -libinfix
+ const QString libInfixWithFramework = getLibInfix(deploymentInfo.deployedFrameworks) + QStringLiteral(".framework");
+
// Network
- if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtNetwork.framework"))) {
+ if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtNetwork") + libInfixWithFramework)) {
QStringList bearerPlugins = QDir(pluginSourcePath + QStringLiteral("/bearer")).entryList(QStringList() << QStringLiteral("*.dylib"));
foreach (const QString &plugin, bearerPlugins) {
if (!plugin.endsWith(QStringLiteral("_debug.dylib")))
@@ -1026,7 +1045,7 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.dylib"));
foreach (const QString &plugin, imagePlugins) {
if (plugin.contains(QStringLiteral("qsvg"))) {
- if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSvg.framework")))
+ if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSvg") + libInfixWithFramework))
pluginList.append(QStringLiteral("imageformats/") + plugin);
} else if (!plugin.endsWith(QStringLiteral("_debug.dylib"))) {
pluginList.append(QStringLiteral("imageformats/") + plugin);
@@ -1034,7 +1053,7 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
}
// Sql plugins if QtSql.framework is in use
- if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSql.framework"))) {
+ if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSql") + libInfixWithFramework)) {
QStringList sqlPlugins = QDir(pluginSourcePath + QStringLiteral("/sqldrivers")).entryList(QStringList() << QStringLiteral("*.dylib"));
foreach (const QString &plugin, sqlPlugins) {
if (plugin.endsWith(QStringLiteral("_debug.dylib")))
@@ -1054,7 +1073,7 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
}
// multimedia plugins if QtMultimedia.framework is in use
- if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtMultimedia.framework"))) {
+ if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtMultimedia") + libInfixWithFramework)) {
QStringList plugins = QDir(pluginSourcePath + QStringLiteral("/mediaservice")).entryList(QStringList() << QStringLiteral("*.dylib"));
foreach (const QString &plugin, plugins) {
if (!plugin.endsWith(QStringLiteral("_debug.dylib")))
@@ -1252,7 +1271,12 @@ bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInf
// 2) QtQuick.Controls is used
// The intended failure mode is that libwidgetsplugin.dylib will be present
// in the app bundle but not used at run-time.
- if (deploymentInfo.deployedFrameworks.contains("QtWidgets.framework") && qtQuickContolsInUse) {
+
+ // Check if Qt was configured with -libinfix
+ const QString libInfixWithFramework = getLibInfix(deploymentInfo.deployedFrameworks) + QStringLiteral(".framework");
+
+ if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtWidgets") + libInfixWithFramework)
+ && qtQuickContolsInUse) {
LogNormal() << "Deploying QML import QtQuick.PrivateWidgets";
QString name = "QtQuick/PrivateWidgets";
QString path = qmlImportsPath + QLatin1Char('/') + name;
diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp
index cd39bdde4..e02fa0eb8 100644
--- a/src/pixeltool/qpixeltool.cpp
+++ b/src/pixeltool/qpixeltool.cpp
@@ -51,6 +51,18 @@
QT_BEGIN_NAMESPACE
+static QPoint initialPos(const QSettings &settings, const QSize &initialSize)
+{
+ const QDesktopWidget *desktopWidget = QApplication::desktop();
+ const QPoint defaultPos = desktopWidget->availableGeometry().topLeft();
+ const QPoint savedPos =
+ settings.value(QLatin1String("position"), QVariant(defaultPos)).toPoint();
+ const int savedScreen = desktopWidget->screenNumber(savedPos);
+ return savedScreen >= 0
+ && desktopWidget->availableGeometry(savedScreen).intersects(QRect(savedPos, initialSize))
+ ? savedPos : defaultPos;
+}
+
QPixelTool::QPixelTool(QWidget *parent)
: QWidget(parent)
, m_freeze(false)
@@ -70,7 +82,7 @@ QPixelTool::QPixelTool(QWidget *parent)
m_zoom = settings.value(QLatin1String("zoom"), 4).toInt();
m_initialSize = settings.value(QLatin1String("initialSize"), QSize(250, 200)).toSize();
- move(settings.value(QLatin1String("position")).toPoint());
+ move(initialPos(settings, m_initialSize));
setMouseTracking(true);
setAttribute(Qt::WA_NoBackground);
@@ -426,11 +438,14 @@ void QPixelTool::grabScreen()
int x = mousePos.x() - w/2;
int y = mousePos.y() - h/2;
+ const QBrush darkBrush = palette().color(QPalette::Dark);
const QDesktopWidget *desktopWidget = QApplication::desktop();
-
- QScreen *screen = QGuiApplication::screens().at(desktopWidget->screenNumber(this));
- m_buffer = screen->grabWindow(desktopWidget->winId(), x, y, w, h);
-
+ if (QScreen *screen = QGuiApplication::screens().value(desktopWidget->screenNumber(this), Q_NULLPTR)) {
+ m_buffer = screen->grabWindow(desktopWidget->winId(), x, y, w, h);
+ } else {
+ m_buffer = QPixmap(w, h);
+ m_buffer.fill(darkBrush.color());
+ }
QRegion geom(x, y, w, h);
QRect screenRect;
for (int i = 0; i < desktopWidget->numScreens(); ++i)
@@ -441,7 +456,7 @@ void QPixelTool::grabScreen()
QPainter p(&m_buffer);
p.translate(-x, -y);
p.setPen(Qt::NoPen);
- p.setBrush(palette().color(QPalette::Dark));
+ p.setBrush(darkBrush);
p.drawRects(rects);
}
diff --git a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
index 2552b9c1c..4f7cbf735 100644
--- a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -3277,9 +3277,14 @@
Elsewhere, the documentation identified as \e{\\legalese} command
can be accumulated using \l {generatelist-command} {\\generatelist}
- with \c {legalese-command} as the argument. This is useful for
- generating an overview of the license agreements associated with
- the source code.
+ with \c {legalese} as the argument. This is useful for generating
+ an overview of the license agreements associated with the source
+ code.
+
+ \note The output of the \c {\generatelist legalese} command includes
+ the \\legalese texts in the current documentation project only. If
+ the current documentation project depends on other modules, their
+ license texts will not be listed.
\target warning-command
\section1 \\warning
@@ -3548,38 +3553,9 @@
\section2 \c legalese
- The \c legalese argument tells QDoc to generate a complete list of
- licenses in the documentation. Each license is identified using
- the \l {legalese-command} {\\legalese} command. This command is
- used to generate the \e {Qt license information}
- page this way:
-
- \code
- / *!
- \page licenses.html
- \title Other Licenses Used in Qt
- \ingroup licensing
- \brief Information about other licenses used for Qt components and third-party code.
-
- Qt contains some code that is not provided under the
- \l{GNU General Public License (GPL)},
- \l{GNU Lesser General Public License (LGPL)} or the
- \l{Qt Commercial Edition}{Qt Commercial License Agreement}, but rather under
- specific licenses from the original authors. Some pieces of code were developed
- by The Qt Company and others originated from third parties.
- This page lists the licenses used, names the authors, and links
- to the places where it is used.
-
- The Qt Company gratefully acknowledges these and other contributions
- to Qt. We recommend that programs that use Qt also acknowledge
- these contributions, and quote these license statements in an
- appendix to the documentation.
-
- See also: \l{Licenses for Fonts Used in Qt for Embedded Linux}
-
- \generatelist legalese
- * /
- \endcode
+ The \c legalese argument tells QDoc to generate a list of licenses in
+ the current documentation project. Each license is identified using
+ the \l {legalese-command} {\\legalese} command.
\section2 \c overviews
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index 9e318dee3..19466a9dd 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -3548,7 +3548,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
}
else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
par1 = QStringRef();
- if (arg.at(0) == QChar('&'))
+ if (arg.startsWith(QLatin1Char('&')))
html += arg;
else {
const Node* n = qdb_->findNodeForInclude(QStringList(arg.toString()));
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index 7bec46843..2babb94ab 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -75,6 +75,39 @@ void Node::initialize()
bool Node::nodeNameLessThan(const Node *n1, const Node *n2)
{
+ if (n1->isDocumentNode() && n2->isDocumentNode()) {
+ const DocumentNode* f1 = static_cast<const DocumentNode*>(n1);
+ const DocumentNode* f2 = static_cast<const DocumentNode*>(n2);
+ if (f1->fullTitle() < f2->fullTitle())
+ return true;
+ else if (f1->fullTitle() > f2->fullTitle())
+ return false;
+ }
+
+ if (n1->isCollectionNode() && n2->isCollectionNode()) {
+ const CollectionNode* f1 = static_cast<const CollectionNode*>(n1);
+ const CollectionNode* f2 = static_cast<const CollectionNode*>(n2);
+ if (f1->fullTitle() < f2->fullTitle())
+ return true;
+ else if (f1->fullTitle() > f2->fullTitle())
+ return false;
+ }
+
+ if (n1->type() == Node::Function && n2->type() == Node::Function) {
+ const FunctionNode* f1 = static_cast<const FunctionNode*>(n1);
+ const FunctionNode* f2 = static_cast<const FunctionNode*>(n2);
+
+ if (f1->isConst() < f2->isConst())
+ return true;
+ else if (f1->isConst() > f2->isConst())
+ return false;
+
+ if (f1->signature(false) < f2->signature(false))
+ return true;
+ else if (f1->signature(false) > f2->signature(false))
+ return false;
+ }
+
if (n1->location().filePath() < n2->location().filePath())
return true;
else if (n1->location().filePath() > n2->location().filePath())
@@ -95,38 +128,6 @@ bool Node::nodeNameLessThan(const Node *n1, const Node *n2)
else if (n1->access() > n2->access())
return false;
- if (n1->type() == Node::Function && n2->type() == Node::Function) {
- const FunctionNode* f1 = static_cast<const FunctionNode*>(n1);
- const FunctionNode* f2 = static_cast<const FunctionNode*>(n2);
-
- if (f1->isConst() < f2->isConst())
- return true;
- else if (f1->isConst() > f2->isConst())
- return false;
-
- if (f1->signature(false) < f2->signature(false))
- return true;
- else if (f1->signature(false) > f2->signature(false))
- return false;
- }
-
- if (n1->isDocumentNode() && n2->isDocumentNode()) {
- const DocumentNode* f1 = static_cast<const DocumentNode*>(n1);
- const DocumentNode* f2 = static_cast<const DocumentNode*>(n2);
- if (f1->fullTitle() < f2->fullTitle())
- return true;
- else if (f1->fullTitle() > f2->fullTitle())
- return false;
- }
- else if (n1->isCollectionNode() && n2->isCollectionNode()) {
- const CollectionNode* f1 = static_cast<const CollectionNode*>(n1);
- const CollectionNode* f2 = static_cast<const CollectionNode*>(n2);
- if (f1->fullTitle() < f2->fullTitle())
- return true;
- else if (f1->fullTitle() > f2->fullTitle())
- return false;
- }
-
return false;
}
diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro
index 52b40bccb..8cf4b44dd 100644
--- a/src/qdoc/qdoc.pro
+++ b/src/qdoc/qdoc.pro
@@ -1,6 +1,5 @@
!force_bootstrap {
- load(qfeatures)
- requires(!contains(QT_DISABLED_FEATURES, xmlstreamwriter))
+ requires(qtConfig(xmlstreamwriter))
}
option(host_build)
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index 3a6d0c340..c6650e830 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -842,6 +842,7 @@ void QDocDatabase::processForest()
findAllObsoleteThings(t->root());
findAllLegaleseTexts(t->root());
findAllSince(t->root());
+ findAllAttributions(t->root());
t->setTreeHasBeenAnalyzed();
t = forest_.nextTree();
}
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index 033b37e43..ac64348d6 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -652,6 +652,30 @@ void QmlDocVisitor::endVisit(QQmlJS::AST::UiArrayBinding *)
{
}
+template <typename T>
+QString qualifiedIdToString(T node);
+
+template <>
+QString qualifiedIdToString(QStringRef node)
+{
+ return node.toString();
+}
+
+template <>
+QString qualifiedIdToString(QQmlJS::AST::UiQualifiedId *node)
+{
+ QString s;
+
+ for (QQmlJS::AST::UiQualifiedId *it = node; it; it = it->next) {
+ s.append(it->name);
+
+ if (it->next)
+ s.append(QLatin1Char('.'));
+ }
+
+ return s;
+}
+
/*!
Visits the public \a member declaration, which can be a
signal or a property. It is a custom signal or property.
@@ -674,8 +698,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
QVector<Parameter> parameters;
for (QQmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) {
- if (!it->type.isEmpty() && !it->name.isEmpty())
- parameters.append(Parameter(it->type.toString(), QString(), it->name.toString()));
+ const QString type = qualifiedIdToString(it->type);
+ if (!type.isEmpty() && !it->name.isEmpty())
+ parameters.append(Parameter(type, QString(), it->name.toString()));
}
qmlSignal->setParameters(parameters);
@@ -686,7 +711,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
}
case QQmlJS::AST::UiPublicMember::Property:
{
- QString type = member->memberType.toString();
+ QString type = qualifiedIdToString(member->memberType);
QString name = member->name.toString();
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode *qmlType = static_cast<QmlTypeNode *>(current);
diff --git a/src/qtattributionsscanner/jsongenerator.cpp b/src/qtattributionsscanner/jsongenerator.cpp
index f50a9c1bf..d5b0249a5 100644
--- a/src/qtattributionsscanner/jsongenerator.cpp
+++ b/src/qtattributionsscanner/jsongenerator.cpp
@@ -42,9 +42,11 @@ static QJsonObject generate(Package package)
obj.insert(QStringLiteral("Id"), package.id);
obj.insert(QStringLiteral("Path"), package.path);
+ obj.insert(QStringLiteral("Files"), package.files.join(QLatin1Char(' ')));
obj.insert(QStringLiteral("QDocModule"), package.qdocModule);
obj.insert(QStringLiteral("Name"), package.name);
obj.insert(QStringLiteral("QtUsage"), package.qtUsage);
+ obj.insert(QStringLiteral("QtParts"), QJsonArray::fromStringList(package.qtParts));
obj.insert(QStringLiteral("Description"), package.description);
obj.insert(QStringLiteral("Homepage"), package.homepage);
diff --git a/src/qtattributionsscanner/package.h b/src/qtattributionsscanner/package.h
index 5cf624307..a0cb82fdd 100644
--- a/src/qtattributionsscanner/package.h
+++ b/src/qtattributionsscanner/package.h
@@ -35,10 +35,13 @@
struct Package {
QString id; // Usually a lowercase, no-spaces version of the name. Mandatory.
QString path; // Source directory. Optional.
- // Default is the directory of the qt_attribution.json ile.
+ // Default is the directory of the qt_attribution.json file.
+ QStringList files; // Files in path. Optional.
QString name; // Descriptive name of the package. Will be used as the title. Mandatory.
QString qdocModule; // QDoc module where the documentation should be included. Mandatory.
QString qtUsage; // How the package is used in Qt. Any way to disable? Mandatory.
+ QStringList qtParts; // Possible values are "examples", "tests", "tools", or "libs".
+ // "libs" is the default.
QString description; // A short description of what the package is and is used for. Optional.
QString homepage; // Homepage of the upstream project. Optional.
diff --git a/src/qtattributionsscanner/packagefilter.cpp b/src/qtattributionsscanner/packagefilter.cpp
index 30dd3daef..26fdfffc0 100644
--- a/src/qtattributionsscanner/packagefilter.cpp
+++ b/src/qtattributionsscanner/packagefilter.cpp
@@ -33,9 +33,10 @@
PackageFilter::PackageFilter(const QString &expression)
: type(InvalidFilter)
{
- if (expression.startsWith(QLatin1String("QDocModule="))) {
+ const QLatin1String filter("QDocModule=");
+ if (expression.startsWith(filter)) {
type = QDocModuleFilter;
- this->expression = expression.mid(strlen("QDocModule="));
+ this->expression = expression.mid(filter.size());
} else {
std::cerr << qPrintable(tr("Invalid filter expression \"%1\"").arg(expression)) << std::endl;
std::cerr << qPrintable(tr("Currently only \"QDocModule=*\" is supported.")) << std::endl;
diff --git a/src/qtattributionsscanner/qdocgenerator.cpp b/src/qtattributionsscanner/qdocgenerator.cpp
index 92a2a9a48..c78ebd4b9 100644
--- a/src/qtattributionsscanner/qdocgenerator.cpp
+++ b/src/qtattributionsscanner/qdocgenerator.cpp
@@ -34,14 +34,58 @@
namespace QDocGenerator {
+// See definition of idstring and licenseid in https://spdx.org/spdx-specification-21-web-version
+static bool isSpdxLicenseId(const QString &str) {
+ if (str.isEmpty())
+ return false;
+ for (auto iter(str.cbegin()); iter != str.cend(); ++iter) {
+ const QChar c = *iter;
+ if (!((c >= QLatin1Char('A') && c <= QLatin1Char('Z'))
+ || (c >= QLatin1Char('a') && c <= QLatin1Char('z'))
+ || (c >= QLatin1Char('0') && c <= QLatin1Char('9'))
+ || (c == QLatin1Char('-')) || (c == QLatin1Char('.'))))
+ return false;
+ }
+ return true;
+}
+
+static QString languageJoin(const QStringList &list)
+{
+ QString result;
+ for (int i = 0; i < list.size(); ++i) {
+ QString delimiter = QStringLiteral(", ");
+ if (i == list.size() - 1) // last item
+ delimiter.clear();
+ else if (list.size() == 2)
+ delimiter = QStringLiteral(" and ");
+ else if (list.size() > 2 && i == list.size() - 2)
+ delimiter = QStringLiteral(", and "); // oxford comma
+ result += list[i] + delimiter;
+ }
+
+ return result;
+}
+
static void generate(QTextStream &out, const Package &package, const QDir &baseDir,
LogLevel logLevel)
{
out << "/*!\n\n";
out << "\\contentspage attributions.html\n";
- out << "\\ingroup attributions-" << package.qdocModule << "\n";
- out << "\\page attribution-" << package.id << ".html attribution\n";
- out << "\\target "<< package.id << "\n\n";
+ for (const QString &part: package.qtParts)
+ out << "\\ingroup attributions-" << part << "\n";
+
+ if (package.qtParts.contains(QLatin1String("libs"))) {
+ // show up in xxx-index.html page of module
+ out << "\\ingroup attributions-" << package.qdocModule << "\n";
+ // include in '\generatelist annotatedattributions'
+ out << "\\page " << package.qdocModule << "-attribution-" << package.id
+ << ".html attribution\n";
+ } else {
+ out << "\\page " << package.qdocModule << "-attribution-" << package.id
+ << ".html \n";
+ }
+
+ out << "\\target " << package.id << "\n\n";
out << "\\title " << package.name << "\n";
out << "\\brief " << package.license << "\n\n";
@@ -51,16 +95,41 @@ static void generate(QTextStream &out, const Package &package, const QDir &baseD
if (!package.qtUsage.isEmpty())
out << package.qtUsage << "\n\n";
- out << "The sources can be found in "
- << baseDir.relativeFilePath(package.path) << ".\n\n";
+ QStringList sourcePaths;
+ if (package.files.isEmpty()) {
+ sourcePaths << baseDir.relativeFilePath(package.path);
+ } else {
+ const QDir packageDir(package.path);
+ for (const QString &filePath: package.files) {
+ const QString absolutePath = packageDir.absoluteFilePath(filePath);
+ sourcePaths << baseDir.relativeFilePath(absolutePath);
+ }
+ }
+
+ out << "The sources can be found in " << languageJoin(sourcePaths) << ".\n\n";
+
+ const bool hasPackageVersion = !package.version.isEmpty();
+ const bool hasPackageDownloadLocation = !package.downloadLocation.isEmpty();
+ if (!package.homepage.isEmpty()) {
+ out << "\\l{" << package.homepage << "}{Project Homepage}";
+ if (hasPackageVersion)
+ out << ", ";
+ }
+ if (hasPackageVersion) {
+ out << "upstream version: ";
+ if (hasPackageDownloadLocation)
+ out << "\\l{" << package.downloadLocation << "}{";
+ out << package.version;
+ if (hasPackageDownloadLocation)
+ out << "}";
+ }
- if (!package.homepage.isEmpty())
- out << "\\l{" << package.homepage << "}{Project Homepage}\n\n";
+ out << "\n\n";
if (!package.copyright.isEmpty())
out << "\n\\badcode\n" << package.copyright << "\n\\endcode\n\n";
- if (!package.licenseId.isEmpty() && package.licenseId != QLatin1String("NONE"))
+ if (isSpdxLicenseId(package.licenseId) && package.licenseId != QLatin1String("NONE"))
out << "\\l{https://spdx.org/licenses/" << package.licenseId << ".html}"
<< "{" << package.license << "}.\n\n";
else
diff --git a/src/qtattributionsscanner/scanner.cpp b/src/qtattributionsscanner/scanner.cpp
index 823d9a8c3..a405b2b03 100644
--- a/src/qtattributionsscanner/scanner.cpp
+++ b/src/qtattributionsscanner/scanner.cpp
@@ -34,7 +34,6 @@
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qvariant.h>
-
#include <iostream>
namespace Scanner {
@@ -54,7 +53,7 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L
for (auto iter = object.constBegin(); iter != object.constEnd(); ++iter) {
const QString key = iter.key();
- if (!iter.value().isString()) {
+ if (!iter.value().isString() && key != QLatin1String("QtParts")) {
if (logLevel != SilentLog)
std::cerr << qPrintable(tr("File %1: Expected JSON string as value of %2.").arg(
QDir::toNativeSeparators(filePath), key)) << std::endl;
@@ -65,6 +64,8 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L
p.name = value;
} else if (key == QLatin1String("Path")) {
p.path = QDir(directory).absoluteFilePath(value);
+ } else if (key == QLatin1String("Files")) {
+ p.files = value.split(QRegExp(QStringLiteral("\\s")), QString::SkipEmptyParts);
} else if (key == QLatin1String("Id")) {
p.id = value;
} else if (key == QLatin1String("Homepage")) {
@@ -87,6 +88,16 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L
p.description = value;
} else if (key == QLatin1String("QtUsage")) {
p.qtUsage = value;
+ } else if (key == QLatin1String("QtParts")) {
+ const QVariantList variantList = iter.value().toArray().toVariantList();
+ for (const QVariant &v: variantList) {
+ if (v.type() != QMetaType::QString && logLevel != SilentLog) {
+ std::cerr << qPrintable(tr("File %1: Expected JSON string in array of %2.").arg(
+ QDir::toNativeSeparators(filePath), key))
+ << std::endl;
+ }
+ p.qtParts.append(v.toString());
+ }
} else {
if (logLevel != SilentLog)
std::cerr << qPrintable(tr("File %1: Unknown key %2.").arg(
@@ -108,6 +119,22 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L
missingPropertyWarning(filePath, QStringLiteral("License"));
if (p.copyright.isEmpty())
missingPropertyWarning(filePath, QStringLiteral("Copyright"));
+ if (p.qtParts.isEmpty())
+ p.qtParts << QStringLiteral("libs");
+
+ foreach (const QString &part, p.qtParts) {
+ if (part != QLatin1String("examples")
+ && part != QLatin1String("tests")
+ && part != QLatin1String("tools")
+ && part != QLatin1String("libs")
+ && logLevel != SilentLog) {
+ std::cerr << qPrintable(tr("File %1: Property 'QtPart' contains unknown element "
+ "'%2'. Valid entries are 'examples', 'tests', 'tools' "
+ "and 'libs'.").arg(
+ QDir::toNativeSeparators(filePath), part))
+ << std::endl;
+ }
+ }
}
return p;
}
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.cpp b/src/shared/qttoolbardialog/qttoolbardialog.cpp
index 14e4f7832..e082acc24 100644
--- a/src/shared/qttoolbardialog/qttoolbardialog.cpp
+++ b/src/shared/qttoolbardialog/qttoolbardialog.cpp
@@ -724,7 +724,7 @@ QByteArray QtFullToolBarManager::saveState(int version) const
{
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
- stream << QtFullToolBarManagerPrivate::VersionMarker;
+ stream << int(QtFullToolBarManagerPrivate::VersionMarker);
stream << version;
d_ptr->saveState(stream);
return data;
diff --git a/src/windeployqt/utils.cpp b/src/windeployqt/utils.cpp
index c0a6f8526..667dad064 100644
--- a/src/windeployqt/utils.cpp
+++ b/src/windeployqt/utils.cpp
@@ -192,7 +192,8 @@ static HANDLE createInheritableTemporaryFile()
securityAttributes.bInheritHandle = TRUE;
return CreateFile(name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
- TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
+ TRUNCATE_EXISTING,
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
}
// runProcess helper: Rewind and read out a temporary file for stdout/stderr.
diff --git a/src/winrtrunner/appxengine_p.h b/src/winrtrunner/appxengine_p.h
index 6ff41fed6..71424b518 100644
--- a/src/winrtrunner/appxengine_p.h
+++ b/src/winrtrunner/appxengine_p.h
@@ -63,7 +63,9 @@ public:
virtual ~AppxEnginePrivate()
{
+ uriFactory.Reset();
packageFactory.Reset();
+ manifestReader.Reset();
CoUninitialize();
}
diff --git a/sync.profile b/sync.profile
index 28a3d1b9a..9dcaf8ce7 100644
--- a/sync.profile
+++ b/sync.profile
@@ -19,16 +19,3 @@
"QDesignerExportWidget" => "QtUiPlugin/QDesignerExportWidget"
}
);
-# Module dependencies.
-# Every module that is required to build this module should have one entry.
-# Each of the module version specifiers can take one of the following values:
-# - A specific Git revision.
-# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
-# - an empty string to use the same branch under test (dependencies will become "refs/heads/master" if we are in the master branch)
-#
-%dependencies = (
- "qtbase" => "",
- "qtxmlpatterns" => "",
- "qtdeclarative" => "",
- "qtactiveqt" => "",
-);
diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp
index fad27ab04..bf4ca9510 100644
--- a/tests/auto/linguist/lconvert/tst_lconvert.cpp
+++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp
@@ -34,7 +34,9 @@ class tst_lconvert : public QObject
Q_OBJECT
public:
- tst_lconvert() : dataDir(QFINDTESTDATA("data/")), binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {}
+ tst_lconvert()
+ : dataDir(QFINDTESTDATA("data/"))
+ , lconvert(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/lconvert") {}
private slots:
void initTestCase();
@@ -61,7 +63,7 @@ private:
const QList<QStringList> &args);
QString dataDir;
- QString binDir;
+ QString lconvert;
};
void tst_lconvert::initTestCase()
@@ -140,7 +142,7 @@ void tst_lconvert::doCompare(QIODevice *actualDev, const QString &expectedFn)
void tst_lconvert::verifyReadFail(const QString &fn)
{
QProcess cvt;
- cvt.start(binDir + "/lconvert", QStringList() << (dataDir + fn));
+ cvt.start(lconvert, QStringList() << (dataDir + fn));
QVERIFY(cvt.waitForFinished(10000));
QVERIFY(cvt.exitStatus() == QProcess::NormalExit);
QVERIFY2(cvt.exitCode() == 2, "Accepted invalid input");
@@ -167,7 +169,7 @@ void tst_lconvert::convertChain(const QString &_inFileName, const QString &_outF
if (!argList.isEmpty())
args += argList[i];
args << "-if" << stations[i] << "-i" << "-" << "-of" << stations[i + 1];
- cvts.at(i)->start(binDir + "/lconvert", args, QIODevice::ReadWrite | QIODevice::Text);
+ cvts.at(i)->start(lconvert, args, QIODevice::ReadWrite | QIODevice::Text);
}
int st = 0;
foreach (QProcess *cvt, cvts)
@@ -233,7 +235,7 @@ void tst_lconvert::converts()
QString outFileNameFq = dataDir + outFileName;
QProcess cvt;
- cvt.start(binDir + "/lconvert",
+ cvt.start(lconvert,
QStringList() << "-i" << (dataDir + inFileName) << "-of" << format,
QIODevice::ReadWrite | QIODevice::Text);
doWait(&cvt, 0);
@@ -328,7 +330,7 @@ void tst_lconvert::merge()
QProcess cvt;
QStringList args;
args << (dataDir + "idxmerge.ts") << (dataDir + "idxmerge-add.ts");
- cvt.start(binDir + "/lconvert", args, QIODevice::ReadWrite | QIODevice::Text);
+ cvt.start(lconvert, args, QIODevice::ReadWrite | QIODevice::Text);
doWait(&cvt, 1);
if (!QTest::currentTestFailed())
doCompare(&cvt, dataDir + "idxmerge.ts.out");
diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp
index 2da0435d3..19ed47f52 100644
--- a/tests/auto/linguist/lrelease/tst_lrelease.cpp
+++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp
@@ -39,7 +39,7 @@ class tst_lrelease : public QObject
public:
tst_lrelease()
- : binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath))
+ : lrelease(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/lrelease")
, dataDir(QFINDTESTDATA("testdata/"))
{}
@@ -55,7 +55,7 @@ private slots:
private:
void doCompare(const QStringList &actual, const QString &expectedFn);
- QString binDir;
+ QString lrelease;
QString dataDir;
};
@@ -109,7 +109,7 @@ void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedF
void tst_lrelease::translate()
{
- QVERIFY(!QProcess::execute(binDir + "/lrelease " + dataDir + "translate.ts"));
+ QVERIFY(!QProcess::execute(lrelease, QStringList() << (dataDir + "translate.ts")));
QTranslator translator;
QVERIFY(translator.load(dataDir + "translate.qm"));
@@ -159,7 +159,7 @@ void tst_lrelease::translate()
void tst_lrelease::compressed()
{
- QVERIFY(!QProcess::execute(binDir + "/lrelease -compress " + dataDir + "compressed.ts"));
+ QVERIFY(!QProcess::execute(lrelease, QStringList() << "-compress" << (dataDir + "compressed.ts")));
QTranslator translator;
QVERIFY(translator.load(dataDir + "compressed.qm"));
@@ -176,7 +176,7 @@ void tst_lrelease::compressed()
void tst_lrelease::idbased()
{
- QVERIFY(!QProcess::execute(binDir + "/lrelease -idbased " + dataDir + "idbased.ts"));
+ QVERIFY(!QProcess::execute(lrelease, QStringList() << "-idbased" << (dataDir + "idbased.ts")));
QTranslator translator;
QVERIFY(translator.load(dataDir + "idbased.qm"));
@@ -188,7 +188,7 @@ void tst_lrelease::idbased()
void tst_lrelease::markuntranslated()
{
- QVERIFY(!QProcess::execute(binDir + "/lrelease -markuntranslated # -idbased " + dataDir + "idbased.ts"));
+ QVERIFY(!QProcess::execute(lrelease, QStringList() << "-markuntranslated" << "#" << "-idbased" << (dataDir + "idbased.ts")));
QTranslator translator;
QVERIFY(translator.load(dataDir + "idbased.qm"));
@@ -201,7 +201,7 @@ void tst_lrelease::markuntranslated()
void tst_lrelease::dupes()
{
QProcess proc;
- proc.start(binDir + "/lrelease " + dataDir + "dupes.ts", QIODevice::ReadWrite | QIODevice::Text);
+ proc.start(lrelease, QStringList() << (dataDir + "dupes.ts"), QIODevice::ReadWrite | QIODevice::Text);
QVERIFY(proc.waitForFinished());
QVERIFY(proc.exitStatus() == QProcess::NormalExit);
doCompare(QString(proc.readAllStandardError()).trimmed().split('\n'), dataDir + "dupes.errors");
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.cpp
new file mode 100644
index 000000000..7108f6784
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.js b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.js
new file mode 100644
index 000000000..b2e1dd9e0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.js
@@ -0,0 +1 @@
+qsTr("From JavaScript file");
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.qml b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.qml
new file mode 100644
index 000000000..ea2258343
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/main.qml
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+QtObject {
+ function translate() {
+ qsTr("From QML file in root");
+ }
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.pro
new file mode 100644
index 000000000..5000c7396
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.pro
@@ -0,0 +1,7 @@
+
+SOURCES += main.cpp
+
+RESOURCES += project.qrc
+RESOURCES += main.qml
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.qrc b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.qrc
new file mode 100644
index 000000000..87bacf228
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>main.js</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.ts.result
new file mode 100644
index 000000000..6dcd8c2a5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqrc/project.ts.result
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="39"/>
+ <source>Hello world</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.js" line="1"/>
+ <source>From JavaScript file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="38"/>
+ <source>From QML file in root</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/lupdatecmd
new file mode 100644
index 000000000..f3709944b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/lupdatecmd
@@ -0,0 +1 @@
+lupdate project.qrc -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.js b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.js
new file mode 100644
index 000000000..b2e1dd9e0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.js
@@ -0,0 +1 @@
+qsTr("From JavaScript file");
diff --git a/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.qml b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.qml
new file mode 100644
index 000000000..ea2258343
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/main.qml
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+QtObject {
+ function translate() {
+ qsTr("From QML file in root");
+ }
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.qrc b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.qrc
new file mode 100644
index 000000000..c5bf15067
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>main.qml</file>
+ <file>main.js</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.ts.result
new file mode 100644
index 000000000..82719c026
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/resources_cmdline/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.qml" line="38"/>
+ <source>From QML file in root</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="1"/>
+ <source>From JavaScript file</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp
index 71d42dbb3..ea049a1f9 100644
--- a/tests/auto/linguist/lupdate/tst_lupdate.cpp
+++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp
@@ -283,7 +283,7 @@ void tst_lupdate::good()
QProcess proc;
proc.setWorkingDirectory(workDir);
proc.setProcessChannelMode(QProcess::MergedChannels);
- const QString command = m_cmdLupdate + QLatin1Char(' ') + lupdatecmd;
+ const QString command = QLatin1Char('"') + m_cmdLupdate + QLatin1String("\" ") + lupdatecmd;
proc.start(command, QIODevice::ReadWrite | QIODevice::Text);
QVERIFY2(proc.waitForStarted(), qPrintable(command + QLatin1String(" :") + proc.errorString()));
QVERIFY2(proc.waitForFinished(30000), qPrintable(command));
diff --git a/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json b/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json
index eaebdb9ef..f8e7b1c68 100644
--- a/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json
+++ b/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json
@@ -2,6 +2,7 @@
"Id": "complete",
"Name": "Complete",
"QDocModule": "qtest",
+ "QtParts": ["examples"],
"License": "License",
"Copyright": "Copyright",
diff --git a/tests/auto/qtattributionsscanner/testdata/good/expected.json b/tests/auto/qtattributionsscanner/testdata/good/expected.json
index ed6d94344..2914dcc4b 100644
--- a/tests/auto/qtattributionsscanner/testdata/good/expected.json
+++ b/tests/auto/qtattributionsscanner/testdata/good/expected.json
@@ -9,7 +9,9 @@
"LicenseId": "xxx",
"Name": "Complete",
"Path": "%{PWD}/complete",
+ "Files": "",
"QDocModule": "qtest",
+ "QtParts": [ "examples" ],
"QtUsage": "Multi\nLine\nUsage",
"Version": "1.0",
"DownloadLocation": "www.qt.io/1.0"
@@ -24,7 +26,11 @@
"LicenseId": "",
"Name": "Minimal",
"Path": "%{PWD}/minimal",
+ "Files": "",
"QDocModule": "qtest",
+ "QtParts": [
+ "libs"
+ ],
"QtUsage": "Usage",
"Version": "",
"DownloadLocation": ""
diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json
index 0ee9ba07f..a28547bfe 100644
--- a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json
+++ b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json
@@ -9,7 +9,9 @@
"LicenseId": "",
"Name": "",
"Path": "%{PWD}",
+ "Files": "",
"QDocModule": "",
+ "QtParts": [ "libs" ],
"QtUsage": "",
"Version": "",
"DownloadLocation": ""
diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json
index 7ce485b82..151af4093 100644
--- a/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json
+++ b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json
@@ -9,7 +9,9 @@
"LicenseId": "",
"Name": "Unknown",
"Path": "%{PWD}",
+ "Files": "",
"QDocModule": "qtest",
+ "QtParts": [ "libs" ],
"QtUsage": "Usage",
"Version": "",
"DownloadLocation": ""