Merge remote-tracking branch 'origin/5.12' into dev

Change-Id: I799e2ca2fefa140c8b73b73aa959c6ed8da6eae6
This commit is contained in:
Qt Forward Merge Bot 2018-09-07 01:00:48 +02:00
commit f21330b749
18 changed files with 300 additions and 39 deletions

View File

@ -306,8 +306,11 @@ const QMap<int, QVariant> QStandardItemPrivate::itemData() const
{
QMap<int, QVariant> result;
QVector<QStandardItemData>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it)
result.insert((*it).role, (*it).value);
for (it = values.cbegin(); it != values.cend(); ++it){
// Qt::UserRole - 1 is used internally to store the flags
if (it->role != Qt::UserRole - 1)
result.insert(it->role, it->value);
}
return result;
}
@ -2939,8 +2942,10 @@ bool QStandardItemModel::insertRows(int row, int count, const QModelIndex &paren
QMap<int, QVariant> QStandardItemModel::itemData(const QModelIndex &index) const
{
Q_D(const QStandardItemModel);
QStandardItem *item = d->itemFromIndex(index);
return item ? item->d_func()->itemData() : QMap<int, QVariant>();
const QStandardItem *const item = d->itemFromIndex(index);
if (!item || item == d->root.data())
return QMap<int, QVariant>();
return item->d_func()->itemData();
}
/*!

View File

@ -153,6 +153,7 @@ public:
void maybeStopCFRunLoopTimer();
static void runLoopTimerCallback(CFRunLoopTimerRef, void *info);
static void activateTimersSourceCallback(void *info);
bool processTimers();
// Set 'blockSendPostedEvents' to true if you _really_ need
// to make sure that qt events are not posted while calling

View File

@ -120,11 +120,17 @@ void QCocoaEventDispatcherPrivate::runLoopTimerCallback(CFRunLoopTimerRef, void
void QCocoaEventDispatcherPrivate::activateTimersSourceCallback(void *info)
{
QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
(void) d->timerInfoList.activateTimers();
d->maybeStartCFRunLoopTimer();
d->processTimers();
d->maybeCancelWaitForMoreEvents();
}
bool QCocoaEventDispatcherPrivate::processTimers()
{
int activated = timerInfoList.activateTimers();
maybeStartCFRunLoopTimer();
return activated > 0;
}
void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer()
{
if (timerInfoList.isEmpty()) {
@ -500,10 +506,9 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
} while (!d->interrupt && event);
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
// when called "manually", always send posted events and timers
// When called "manually", always process posted events and timers
d->processPostedEvents();
retVal = d->timerInfoList.activateTimers() > 0 || retVal;
d->maybeStartCFRunLoopTimer();
retVal = d->processTimers() || retVal;
}
// be sure to return true if the posted event source fired

View File

@ -74,7 +74,7 @@ public:
private:
static NSOpenGLPixelFormat *pixelFormatForSurfaceFormat(const QSurfaceFormat &format);
bool setActiveWindow(QWindow *window);
bool setDrawable(QPlatformSurface *surface);
void updateSurfaceFormat();
NSOpenGLContext *m_context = nil;

View File

@ -336,11 +336,8 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
return true;
}
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
if (!setActiveWindow(window)) {
qCDebug(lcQpaOpenGLContext) << "Failed to activate window, skipping makeCurrent";
if (!setDrawable(surface))
return false;
}
[m_context makeCurrentContext];
@ -365,8 +362,15 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
return true;
}
bool QCocoaGLContext::setActiveWindow(QWindow *window)
/*!
Sets the drawable object of the NSOpenGLContext, which is the
frame buffer that is the target of OpenGL drawing operations.
*/
bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
{
Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window);
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
if (window == m_currentWindow.data())
return true;
@ -375,11 +379,11 @@ bool QCocoaGLContext::setActiveWindow(QWindow *window)
NSView *view = cocoaWindow->view();
if ((m_context.view = view) != view) {
qCDebug(lcQpaOpenGLContext) << "Associating" << view << "with" << m_context << "failed";
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
return false;
}
qCDebug(lcQpaOpenGLContext) << m_context << "now associated with" << m_context.view;
qCInfo(lcQpaOpenGLContext) << "Set drawable for" << m_context << "to" << m_context.view;
if (m_currentWindow && m_currentWindow.data()->handle())
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
@ -408,9 +412,9 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
if (surface->surface()->surfaceClass() == QSurface::Offscreen)
return; // Nothing to do
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
if (!setActiveWindow(window)) {
qCWarning(lcQpaOpenGLContext) << "Failed to activate window, skipping swapBuffers";
if (!setDrawable(surface)) {
qCWarning(lcQpaOpenGLContext) << "Can't flush" << m_context
<< "without" << surface << "as drawable";
return;
}
@ -435,7 +439,7 @@ void QCocoaGLContext::windowWasHidden()
{
// If the window is hidden, we need to unset the m_currentWindow
// variable so that succeeding makeCurrent's will not abort prematurely
// because of the optimization in setActiveWindow.
// because of the optimization in setDrawable.
// Doing a full doneCurrent here is not preferable, because the GL context
// might be rendering in a different thread at this time.
m_currentWindow.clear();

View File

@ -40,13 +40,17 @@
#ifndef QCOCOAVULKANINSTANCE_H
#define QCOCOAVULKANINSTANCE_H
// Include mvk_vulkan.h first. The order is important since
// mvk_vulkan.h just defines VK_USE_PLATFORM_MACOS_MVK (or the IOS
// variant) and includes vulkan.h. If something else included vulkan.h
// before this then we wouldn't get the MVK specifics...
#include <MoltenVK/mvk_vulkan.h>
#include <QtCore/QHash>
#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
#include <AppKit/AppKit.h>
#include <MoltenVK/mvk_vulkan.h>
QT_BEGIN_NAMESPACE
class QCocoaVulkanInstance : public QBasicPlatformVulkanInstance

View File

@ -1645,6 +1645,53 @@ static void writeResourceIcon(QTextStream &output,
}
}
void WriteInitialization::writePixmapFunctionIcon(QTextStream &output,
const QString &iconName,
const QString &indent,
const DomResourceIcon *i) const
{
if (i->hasElementNormalOff()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementNormalOff()->text())
<< ", QIcon::Normal, QIcon::Off);\n";
}
if (i->hasElementNormalOn()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementNormalOn()->text())
<< ", QIcon::Normal, QIcon::On);\n";
}
if (i->hasElementDisabledOff()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementDisabledOff()->text())
<< ", QIcon::Disabled, QIcon::Off);\n";
}
if (i->hasElementDisabledOn()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementDisabledOn()->text())
<< ", QIcon::Disabled, QIcon::On);\n";
}
if (i->hasElementActiveOff()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementActiveOff()->text())
<< ", QIcon::Active, QIcon::Off);\n";
}
if (i->hasElementActiveOn()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementActiveOn()->text())
<< ", QIcon::Active, QIcon::On);\n";
}
if (i->hasElementSelectedOff()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementSelectedOff()->text())
<< ", QIcon::Selected, QIcon::Off);\n";
}
if (i->hasElementSelectedOn()) {
output << indent << iconName << ".addPixmap("
<< pixCall(QLatin1String("QPixmap"), i->elementSelectedOn()->text())
<< ", QIcon::Selected, QIcon::On);\n";
}
}
QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
{
// check cache
@ -1661,7 +1708,10 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
if (i->attributeTheme().isEmpty()) {
// No theme: Write resource icon as is
m_output << m_indent << "QIcon " << iconName << ";\n";
writeResourceIcon(m_output, iconName, m_indent, i);
if (m_uic->pixmapFunction().isEmpty())
writeResourceIcon(m_output, iconName, m_indent, i);
else
writePixmapFunctionIcon(m_output, iconName, m_indent, i);
} else {
// Theme: Generate code to check the theme and default to resource
const QString themeIconName = fixString(i->attributeTheme(), QString());
@ -1683,7 +1733,10 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
<< ")) {\n"
<< m_dindent << iconName << " = QIcon::fromTheme(" << themeNameStringVariableC << ");\n"
<< m_indent << "} else {\n";
writeResourceIcon(m_output, iconName, m_dindent, i);
if (m_uic->pixmapFunction().isEmpty())
writeResourceIcon(m_output, iconName, m_dindent, i);
else
writePixmapFunctionIcon(m_output, iconName, m_dindent, i);
m_output << m_indent << "}\n";
} else {
// Theme, but no state pixmaps: Construct from theme directly.

View File

@ -230,6 +230,8 @@ private:
private:
QString writeFontProperties(const DomFont *f);
QString writeIconProperties(const DomResourceIcon *i);
void writePixmapFunctionIcon(QTextStream &output, const QString &iconName,
const QString &indent, const DomResourceIcon *i) const;
QString writeSizePolicy(const DomSizePolicy *sp);
QString writeBrushInitialization(const DomBrush *brush);
void addButtonGroup(const DomWidget *node, const QString &varName);

View File

@ -2968,8 +2968,10 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
margin += style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this) +
style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
if (d->textElideMode != Qt::ElideNone)
opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin);
if (d->textElideMode != Qt::ElideNone) {
const QRect textRect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this);
opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode, textRect.width() - margin);
}
QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::ForegroundRole);

View File

@ -3724,9 +3724,14 @@ void QTreeViewPrivate::updateScrollBars()
int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
{
Q_Q(const QTreeView);
executePostedLayout();
int x = pos.x();
int column = header->logicalIndexAt(x);
bool spanned = false;
if (!spanningIndexes.isEmpty()) {
const QModelIndex index = q->indexAt(pos);
spanned = q->isFirstColumnSpanned(index.row(), index.parent());
}
const int column = spanned ? 0 : header->logicalIndexAt(pos.x());
if (!isTreePosition(column))
return -1; // no logical index at x

View File

@ -760,7 +760,7 @@ void QWidgetBackingStore::updateLists(QWidget *cur)
QList<QObject*> children = cur->children();
for (int i = 0; i < children.size(); ++i) {
QWidget *child = qobject_cast<QWidget*>(children.at(i));
if (!child)
if (!child || child->isWindow())
continue;
updateLists(child);

View File

@ -3870,17 +3870,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if(hasStyleRule(w, PseudoElement_HeaderViewSection)) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw()
|| subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont) {
|| subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont || subRule.hasBorder()) {
ParentStyle::drawControl(ce, opt, p, w);
return;
}
if (subRule.hasFont) {
const QFont oldFont = p->font();
p->setFont(subRule.font.resolve(p->font()));
baseStyle()->drawControl(ce, opt, p, w);
p->setFont(oldFont);
return;
}
}
break;
case CE_HeaderSection:

View File

@ -32,6 +32,7 @@
#include <QtCore/QCoreApplication>
#include <QtGui/QStandardItem>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QTreeView>
#include <QtWidgets/QTableView>
@ -506,6 +507,58 @@ void tst_QSortFilterProxyModel::prependRow()
QCOMPARE(proxy.rowCount(QModelIndex()), 1); //only the "root" item is there
}
void tst_QSortFilterProxyModel::appendRowFromCombobox_data()
{
QTest::addColumn<QString>("pattern");
QTest::addColumn<QStringList>("initial");
QTest::addColumn<QString>("newitem");
QTest::addColumn<QStringList>("expected");
QTest::newRow("filter_out_second_last_item")
<< "^[0-9]*$"
<< (QStringList() << "a" << "1")
<< "2"
<< (QStringList() << "a" << "1" << "2");
QTest::newRow("filter_out_everything")
<< "^c*$"
<< (QStringList() << "a" << "b")
<< "c"
<< (QStringList() << "a" << "b" << "c");
QTest::newRow("no_filter")
<< ""
<< (QStringList() << "0" << "1")
<< "2"
<< (QStringList() << "0" << "1" << "2");
QTest::newRow("filter_out_last_item")
<< "^[a-z]*$"
<< (QStringList() << "a" << "1")
<< "b"
<< (QStringList() << "a" << "1" << "b");
}
void tst_QSortFilterProxyModel::appendRowFromCombobox()
{
QFETCH(QString, pattern);
QFETCH(QStringList, initial);
QFETCH(QString, newitem);
QFETCH(QStringList, expected);
QStringListModel model(initial);
QSortFilterProxyModel proxy;
proxy.setSourceModel(&model);
proxy.setFilterRegExp(pattern);
QComboBox comboBox;
comboBox.setModel(&proxy);
comboBox.addItem(newitem);
QCOMPARE(model.stringList(), expected);
}
void tst_QSortFilterProxyModel::removeRows_data()
{
QTest::addColumn<QStringList>("initial");

View File

@ -72,6 +72,8 @@ private slots:
void insertRows_data();
void insertRows();
void prependRow();
void appendRowFromCombobox_data();
void appendRowFromCombobox();
void removeRows_data();
void removeRows();
void removeColumns_data();

View File

@ -750,7 +750,11 @@ void tst_QStandardItemModel::data()
QCOMPARE(m_model->data(m_model->index(0, 0), Qt::DisplayRole).toString(), QLatin1String("initialitem"));
QCOMPARE(m_model->data(m_model->index(0, 0), Qt::ToolTipRole).toString(), QLatin1String("tooltip"));
const QMap<int, QVariant> itmData = m_model->itemData(m_model->index(0, 0));
QCOMPARE(itmData.value(Qt::DisplayRole), QLatin1String("initialitem"));
QCOMPARE(itmData.value(Qt::ToolTipRole), QLatin1String("tooltip"));
QVERIFY(!itmData.contains(Qt::UserRole - 1));
QVERIFY(m_model->itemData(QModelIndex()).isEmpty());
}
void tst_QStandardItemModel::clearItemData()

View File

@ -131,6 +131,13 @@ public:
setAutoBufferSwap(false);
}
void resizeEvent(QResizeEvent *e)
{
m_thread->lock();
QGLWidget::resizeEvent(e);
m_thread->unlock();
}
void paintEvent(QPaintEvent *)
{
m_thread->lock();

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>149</width>
<height>112</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>labelPixmap</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
<property name="icon">
<iconset>
<normaloff>buttonIconNormalOff</normaloff>
<normalon>buttonIconNormalOn</normalon>
<disabledoff>buttonIconDisabledOff</disabledoff>
<disabledon>buttonIconDisabledOn</disabledon>
</iconset>
</property>
</widget>
</item>
</layout>
</widget>
<pixmapfunction>pixmapFunction</pixmapfunction>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,74 @@
/********************************************************************************
** Form generated from reading UI file 'pixmapfunction.ui'
**
** Created by: Qt User Interface Compiler version 5.12.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef PIXMAPFUNCTION_H
#define PIXMAPFUNCTION_H
#include <QtCore/QVariant>
#include <QtGui/QIcon>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Form
{
public:
QVBoxLayout *verticalLayout;
QLabel *label;
QPushButton *pushButton;
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(149, 112);
verticalLayout = new QVBoxLayout(Form);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
label = new QLabel(Form);
label->setObjectName(QString::fromUtf8("label"));
label->setPixmap(QPixmap(pixmapFunction("labelPixmap")));
verticalLayout->addWidget(label);
pushButton = new QPushButton(Form);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
QIcon icon;
icon.addPixmap(QPixmap(pixmapFunction("buttonIconNormalOff")), QIcon::Normal, QIcon::Off);
icon.addPixmap(QPixmap(pixmapFunction("buttonIconNormalOn")), QIcon::Normal, QIcon::On);
icon.addPixmap(QPixmap(pixmapFunction("buttonIconDisabledOff")), QIcon::Disabled, QIcon::Off);
icon.addPixmap(QPixmap(pixmapFunction("buttonIconDisabledOn")), QIcon::Disabled, QIcon::On);
pushButton->setIcon(icon);
verticalLayout->addWidget(pushButton);
retranslateUi(Form);
QMetaObject::connectSlotsByName(Form);
} // setupUi
void retranslateUi(QWidget *Form)
{
Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr));
label->setText(QString());
pushButton->setText(QApplication::translate("Form", "PushButton", nullptr));
} // retranslateUi
};
namespace Ui {
class Form: public Ui_Form {};
} // namespace Ui
QT_END_NAMESPACE
#endif // PIXMAPFUNCTION_H