Merge remote-tracking branch 'origin/5.6' into 5.7

Conflicts:
	src/plugins/platforms/minimalegl/qminimaleglintegration.cpp

Change-Id: Ia6ab42a6daadbf8abc085c971545904d49ea4b56
This commit is contained in:
Liang Qi 2016-10-31 09:26:35 +01:00
commit 8e20daae9f
25 changed files with 115 additions and 65 deletions

View File

@ -1,4 +1,4 @@
pre { pre, .LegaleseLeft {
background-color: #f0f0f0; background-color: #f0f0f0;
font-family: Courier, monospace; font-family: Courier, monospace;
font-weight: 600; font-weight: 600;

View File

@ -428,7 +428,7 @@ table styles
/* table with border alternative colours*/ /* table with border alternative colours*/
table, pre { table, pre, .LegaleseLeft {
-moz-border-radius: 7px 7px 7px 7px; -moz-border-radius: 7px 7px 7px 7px;
-webkit-border-radius: 7px 7px 7px 7px; -webkit-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px; border-radius: 7px 7px 7px 7px;
@ -485,6 +485,10 @@ table, pre {
margin: 0px margin: 0px
} }
.LegaleseLeft {
font-family: monospace;
white-space: pre-wrap;
}
/* table bodless & white*/ /* table bodless & white*/
.borderless { .borderless {
@ -547,7 +551,7 @@ ol.a > li{
text-align: left text-align: left
} }
.cpp { .cpp, .LegaleseLeft {
display: block; display: block;
margin: 10px; margin: 10px;
overflow: auto; overflow: auto;

View File

@ -1370,7 +1370,7 @@ div.qt_commercial {
border-top:5px solid #5caa15; border-top:5px solid #5caa15;
margin-bottom:50px margin-bottom:50px
} }
pre { pre, .LegaleseLeft {
background-color:#404244; background-color:#404244;
color:#fff; color:#fff;
display:block; display:block;
@ -1381,6 +1381,10 @@ pre {
padding:25px; padding:25px;
margin-top:0.75em margin-top:0.75em
} }
.mainContent .LegaleseLeft p {
color:#fff;
white-space: pre-wrap
}
.copy_text { .copy_text {
background-color:#46a2da; background-color:#46a2da;
color:#fff; color:#fff;

View File

@ -261,7 +261,7 @@
\snippet widgets/calculator/calculator.cpp 20 \snippet widgets/calculator/calculator.cpp 20
Like in \c additiveOperatorClicked(), we start by handing any Like in \c additiveOperatorClicked(), we start by handling any
pending multiplicative and additive operators. Then we display \c pending multiplicative and additive operators. Then we display \c
sumSoFar and reset the variable to zero. Resetting the variable sumSoFar and reset the variable to zero. Resetting the variable
to zero is necessary to avoid counting the value twice. to zero is necessary to avoid counting the value twice.

View File

@ -406,14 +406,21 @@ void NmakeMakefileGenerator::init()
project->values("QMAKE_DISTCLEAN").append(tgt + ".lib"); project->values("QMAKE_DISTCLEAN").append(tgt + ".lib");
} }
if (project->isActiveConfig("debug_info")) { if (project->isActiveConfig("debug_info")) {
// Add the compiler's PDB file. QString pdbfile;
QString pdbfile = var("OBJECTS_DIR") + project->first("TARGET") + ".vc.pdb"; QString distPdbFile = tgt + ".pdb";
if (project->isActiveConfig("staticlib")) {
// For static libraries, the compiler's pdb file and the dist pdb file are the same.
pdbfile = distPdbFile;
} else {
// Use $${TARGET}.vc.pdb in the OBJECTS_DIR for the compiler and
// $${TARGET}.pdb (the default) for the linker.
pdbfile = var("OBJECTS_DIR") + project->first("TARGET") + ".vc.pdb";
}
QString escapedPdbFile = escapeFilePath(pdbfile); QString escapedPdbFile = escapeFilePath(pdbfile);
project->values("QMAKE_CFLAGS").append("/Fd" + escapedPdbFile); project->values("QMAKE_CFLAGS").append("/Fd" + escapedPdbFile);
project->values("QMAKE_CXXFLAGS").append("/Fd" + escapedPdbFile); project->values("QMAKE_CXXFLAGS").append("/Fd" + escapedPdbFile);
project->values("QMAKE_CLEAN").append(pdbfile); project->values("QMAKE_CLEAN").append(pdbfile);
// Add the linker's PDB file to the distclean target. project->values("QMAKE_DISTCLEAN").append(distPdbFile);
project->values("QMAKE_DISTCLEAN").append(tgt + ".pdb");
} }
if (project->isActiveConfig("debug")) { if (project->isActiveConfig("debug")) {
project->values("QMAKE_CLEAN").append(tgt + ".ilk"); project->values("QMAKE_CLEAN").append(tgt + ".ilk");

View File

@ -113,9 +113,9 @@ QSet<QString> dictionary = QtConcurrent::blockingFilteredReduced(strings, allLow
//! [7] //! [7]
// keep only images with an alpha channel // keep only images with an alpha channel
QList<QImage> images = ...; QList<QImage> images = ...;
QFuture<void> alphaImages = QtConcurrent::filter(strings, &QImage::hasAlphaChannel); QFuture<void> alphaImages = QtConcurrent::filter(images, &QImage::hasAlphaChannel);
// keep only gray scale images // retrieve gray scale images
QList<QImage> images = ...; QList<QImage> images = ...;
QFuture<QImage> grayscaleImages = QtConcurrent::filtered(images, &QImage::isGrayscale); QFuture<QImage> grayscaleImages = QtConcurrent::filtered(images, &QImage::isGrayscale);

View File

@ -1901,7 +1901,7 @@ void QFontEngineFT::unlockAlphaMapForGlyph()
static inline bool is2dRotation(const QTransform &t) static inline bool is2dRotation(const QTransform &t)
{ {
return qFuzzyCompare(t.m11(), t.m22()) && qFuzzyCompare(t.m12(), -t.m21()) return qFuzzyCompare(t.m11(), t.m22()) && qFuzzyCompare(t.m12(), -t.m21())
&& qFuzzyCompare(t.m11()*t.m22() - t.m12()*t.m21(), 1.0); && qFuzzyCompare(t.m11()*t.m22() - t.m12()*t.m21(), qreal(1.0));
} }
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,

View File

@ -847,7 +847,7 @@ bool QAbstractSocketPrivate::writeToSocket()
const char *ptr = writeBuffer.readPointer(); const char *ptr = writeBuffer.readPointer();
// Attempt to write it all in one chunk. // Attempt to write it all in one chunk.
qint64 written = socketEngine->write(ptr, nextSize); qint64 written = nextSize ? socketEngine->write(ptr, nextSize) : Q_INT64_C(0);
if (written < 0) { if (written < 0) {
#if defined (QABSTRACTSOCKET_DEBUG) #if defined (QABSTRACTSOCKET_DEBUG)
qDebug() << "QAbstractSocketPrivate::writeToSocket() write error, aborting." qDebug() << "QAbstractSocketPrivate::writeToSocket() write error, aborting."
@ -2501,7 +2501,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
if (!d->isBuffered && d->socketType == TcpSocket if (!d->isBuffered && d->socketType == TcpSocket
&& d->socketEngine && d->writeBuffer.isEmpty()) { && d->socketEngine && d->writeBuffer.isEmpty()) {
// This code is for the new Unbuffered QTcpSocket use case // This code is for the new Unbuffered QTcpSocket use case
qint64 written = d->socketEngine->write(data, size); qint64 written = size ? d->socketEngine->write(data, size) : Q_INT64_C(0);
if (written < 0) { if (written < 0) {
d->setError(d->socketEngine->error(), d->socketEngine->errorString()); d->setError(d->socketEngine->error(), d->socketEngine->errorString());
} else if (written < size) { } else if (written < size) {

View File

@ -853,6 +853,10 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, const Q
/*! /*!
Writes a block of \a size bytes from \a data to the socket. Writes a block of \a size bytes from \a data to the socket.
Returns the number of bytes written, or -1 if an error occurred. Returns the number of bytes written, or -1 if an error occurred.
Passing zero as the \a size parameter on a connected UDP socket
will send an empty datagram. For other socket types results are
unspecified.
*/ */
qint64 QNativeSocketEngine::write(const char *data, qint64 size) qint64 QNativeSocketEngine::write(const char *data, qint64 size)
{ {

View File

@ -122,7 +122,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
- (void)dealloc - (void)dealloc
{ {
[self restoreOriginalContentView]; [mStolenContentView release];
[mColorPanel setDelegate:nil]; [mColorPanel setDelegate:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];

View File

@ -150,7 +150,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
- (void)dealloc - (void)dealloc
{ {
[self restoreOriginalContentView]; [mStolenContentView release];
[mFontPanel setDelegate:nil]; [mFontPanel setDelegate:nil];
[[NSFontManager sharedFontManager] setDelegate:nil]; [[NSFontManager sharedFontManager] setDelegate:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];

View File

@ -43,6 +43,9 @@
#include <QtCore/private/qabstractfileengine_p.h> #include <QtCore/private/qabstractfileengine_p.h>
Q_FORWARD_DECLARE_OBJC_CLASS(ALAsset); Q_FORWARD_DECLARE_OBJC_CLASS(ALAsset);
QT_BEGIN_NAMESPACE
class QIOSAssetData; class QIOSAssetData;
class QIOSFileEngineAssetsLibrary : public QAbstractFileEngine class QIOSFileEngineAssetsLibrary : public QAbstractFileEngine
@ -78,5 +81,7 @@ private:
ALAsset *loadAsset() const; ALAsset *loadAsset() const;
}; };
QT_END_NAMESPACE
#endif // QIOSFILEENGINEASSETSLIBRARY_H #endif // QIOSFILEENGINEASSETSLIBRARY_H

View File

@ -48,6 +48,8 @@
#include <QtCore/qset.h> #include <QtCore/qset.h>
#include <QtCore/qthreadstorage.h> #include <QtCore/qthreadstorage.h>
QT_BEGIN_NAMESPACE
static QThreadStorage<QString> g_iteratorCurrentUrl; static QThreadStorage<QString> g_iteratorCurrentUrl;
static QThreadStorage<QPointer<QIOSAssetData> > g_assetDataCache; static QThreadStorage<QPointer<QIOSAssetData> > g_assetDataCache;
@ -472,4 +474,6 @@ QAbstractFileEngine::Iterator *QIOSFileEngineAssetsLibrary::endEntryList()
return 0; return 0;
} }
QT_END_NAMESPACE
#endif #endif

View File

@ -44,6 +44,8 @@
#include <QtCore/private/qabstractfileengine_p.h> #include <QtCore/private/qabstractfileengine_p.h>
#include "qiosfileengineassetslibrary.h" #include "qiosfileengineassetslibrary.h"
QT_BEGIN_NAMESPACE
class QIOSFileEngineFactory : public QAbstractFileEngineHandler class QIOSFileEngineFactory : public QAbstractFileEngineHandler
{ {
public: public:
@ -58,4 +60,6 @@ public:
} }
}; };
QT_END_NAMESPACE
#endif // QIOSFILEENGINEFACTORY_H #endif // QIOSFILEENGINEFACTORY_H

View File

@ -58,7 +58,8 @@
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>
#include <QtGui/QScreen> #include <QtGui/QScreen>
#include <QtPlatformSupport/private/qt_egl_p.h> // this is where EGL headers are pulled in, make sure it is last
#include "qminimaleglscreen.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -40,8 +40,6 @@
#ifndef QMINIMALEGLINTEGRATION_H #ifndef QMINIMALEGLINTEGRATION_H
#define QMINIMALEGLINTEGRATION_H #define QMINIMALEGLINTEGRATION_H
#include "qminimaleglscreen.h"
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>

View File

@ -41,7 +41,6 @@
#define QMINIMALEGLWINDOW_H #define QMINIMALEGLWINDOW_H
#include "qminimaleglintegration.h" #include "qminimaleglintegration.h"
#include "qminimaleglscreen.h"
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>

View File

@ -102,6 +102,18 @@
"features": [ "features": [
"disable_desktopgl", "disable_d3d11", "disable_d3d9" "disable_desktopgl", "disable_d3d11", "disable_d3d9"
] ]
},
{
"id": 9,
"description": "Intel 945 crash (QTBUG-40991)",
"vendor_id": "0x8086",
"device_id": [ "0x27A2" ],
"os": {
"type": "win"
},
"features": [
"disable_desktopgl"
]
} }
] ]
} }

View File

@ -401,9 +401,6 @@ public:
const QRegion &rgn, const QPoint &offset, int flags, const QRegion &rgn, const QPoint &offset, int flags,
QPainter *sharedPainter, QWidgetBackingStore *backingStore); QPainter *sharedPainter, QWidgetBackingStore *backingStore);
QPainter *beginSharedPainter();
bool endSharedPainter();
#ifndef QT_NO_GRAPHICSVIEW #ifndef QT_NO_GRAPHICSVIEW
static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin); static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
#endif #endif

View File

@ -112,6 +112,7 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
if (widget != tlw) if (widget != tlw)
offset += widget->mapTo(tlw, QPoint()); offset += widget->mapTo(tlw, QPoint());
QRegion effectiveRegion = region;
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
const bool compositionWasActive = widget->d_func()->renderToTextureComposeActive; const bool compositionWasActive = widget->d_func()->renderToTextureComposeActive;
if (!widgetTextures) { if (!widgetTextures) {
@ -125,6 +126,11 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
} else { } else {
widget->d_func()->renderToTextureComposeActive = true; widget->d_func()->renderToTextureComposeActive = true;
} }
// When changing the composition status, make sure the dirty region covers
// the entire widget. Just having e.g. the shown/hidden render-to-texture
// widget's area marked as dirty is incorrect when changing flush paths.
if (compositionWasActive != widget->d_func()->renderToTextureComposeActive)
effectiveRegion = widget->rect();
// re-test since we may have been forced to this path via the dummy texture list above // re-test since we may have been forced to this path via the dummy texture list above
if (widgetTextures) { if (widgetTextures) {
@ -136,12 +142,12 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground); const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground);
// Use the tlw's context, not widget's. The difference is important with native child // Use the tlw's context, not widget's. The difference is important with native child
// widgets where tlw != widget. // widgets where tlw != widget.
backingStore->handle()->composeAndFlush(widget->windowHandle(), region, offset, widgetTextures, backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, widgetTextures,
tlw->d_func()->shareContext(), translucentBackground); tlw->d_func()->shareContext(), translucentBackground);
widget->window()->d_func()->sendComposeStatus(widget->window(), true); widget->window()->d_func()->sendComposeStatus(widget->window(), true);
} else } else
#endif #endif
backingStore->flush(region, widget->windowHandle(), offset); backingStore->flush(effectiveRegion, widget->windowHandle(), offset);
} }
#ifndef QT_NO_PAINT_DEBUG #ifndef QT_NO_PAINT_DEBUG

View File

@ -811,7 +811,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
bool translucentToplevel = false; bool translucentToplevel = false;
const QPaintDevice *paintDevice = painter->device(); const QPaintDevice *paintDevice = painter->device();
const qreal aditionalDevicePixelRatio = themeData.widget ? themeData.widget->devicePixelRatio() : 1; const qreal aditionalDevicePixelRatio = themeData.widget ? themeData.widget->devicePixelRatioF() : qreal(1);
if (paintDevice->devType() == QInternal::Widget) { if (paintDevice->devType() == QInternal::Widget) {
const QWidget *window = static_cast<const QWidget *>(paintDevice)->window(); const QWidget *window = static_cast<const QWidget *>(paintDevice)->window();
translucentToplevel = window->testAttribute(Qt::WA_TranslucentBackground); translucentToplevel = window->testAttribute(Qt::WA_TranslucentBackground);
@ -840,28 +840,28 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0); const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0);
const bool result = dc const bool result = dc
? drawBackgroundDirectly(dc, themeData, qRound(aditionalDevicePixelRatio)) ? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio)
: drawBackgroundThruNativeBuffer(themeData, qRound(aditionalDevicePixelRatio)); : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio);
painter->restore(); painter->restore();
return result; return result;
} }
static inline QRect scaleRect(const QRect &r, int factor) static inline QRectF scaleRect(const QRectF &r, qreal factor)
{ {
return r.isValid() && factor > 1 return r.isValid() && factor > 1
? QRect(r.topLeft() * factor, r.size() * factor) ? QRectF(r.topLeft() * factor, r.size() * factor)
: r; : r;
} }
static QRegion scaleRegion(const QRegion &region, int factor) static QRegion scaleRegion(const QRegion &region, qreal factor)
{ {
if (region.isEmpty() || factor == 1) if (region.isEmpty() || qFuzzyCompare(factor, qreal(1)))
return region; return region;
if (region.rectCount() == 1) if (region.rectCount() == 1)
return QRegion(scaleRect(region.boundingRect(), factor)); return QRegion(scaleRect(QRectF(region.boundingRect()), factor).toRect());
QRegion result; QRegion result;
foreach (const QRect &rect, region.rects()) foreach (const QRect &rect, region.rects())
result += QRect(rect.topLeft() * factor, rect.size() * factor); result += QRectF(QPointF(rect.topLeft()) * factor, QSizeF(rect.size() * factor)).toRect();
return result; return result;
} }
@ -870,13 +870,12 @@ static QRegion scaleRegion(const QRegion &region, int factor)
Do not use this if you need to perform other transformations on the Do not use this if you need to perform other transformations on the
resulting data. resulting data.
*/ */
bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeData, int additionalDevicePixelRatio) bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal additionalDevicePixelRatio)
{ {
QPainter *painter = themeData.painter; QPainter *painter = themeData.painter;
QPoint redirectionDelta(int(painter->deviceMatrix().dx()), const QPointF redirectionDelta(painter->deviceMatrix().dx(), painter->deviceMatrix().dy());
int(painter->deviceMatrix().dy())); const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect();
QRect area = scaleRect(themeData.rect, additionalDevicePixelRatio).translated(redirectionDelta);
QRegion sysRgn = painter->paintEngine()->systemClip(); QRegion sysRgn = painter->paintEngine()->systemClip();
if (sysRgn.isEmpty()) if (sysRgn.isEmpty())
@ -884,7 +883,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
else else
sysRgn &= area; sysRgn &= area;
if (painter->hasClipping()) if (painter->hasClipping())
sysRgn &= scaleRegion(painter->clipRegion(), additionalDevicePixelRatio).translated(redirectionDelta); sysRgn &= scaleRegion(painter->clipRegion(), additionalDevicePixelRatio).translated(redirectionDelta.toPoint());
HRGN hrgn = qt_hrgn_from_qregion(sysRgn); HRGN hrgn = qt_hrgn_from_qregion(sysRgn);
SelectClipRgn(dc, hrgn); SelectClipRgn(dc, hrgn);
@ -956,15 +955,16 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
engine). engine).
*/ */
bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData, bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData,
int additionalDevicePixelRatio) qreal additionalDevicePixelRatio)
{ {
QPainter *painter = themeData.painter; QPainter *painter = themeData.painter;
QRect rect = scaleRect(themeData.rect, additionalDevicePixelRatio); QRectF rectF = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio);
if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips. if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
rect = QRect(0, 0, rect.height(), rect.width()); rectF = QRectF(0, 0, rectF.height(), rectF.width());
} }
rect.moveTo(0,0); rectF.moveTo(0, 0);
QRect rect = rectF.toRect();
int partId = themeData.partId; int partId = themeData.partId;
int stateId = themeData.stateId; int stateId = themeData.stateId;
int w = rect.width(); int w = rect.width();

View File

@ -394,8 +394,8 @@ public:
void setTransparency(QWidget *widget, XPThemeData &themeData); void setTransparency(QWidget *widget, XPThemeData &themeData);
bool drawBackground(XPThemeData &themeData); bool drawBackground(XPThemeData &themeData);
bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, int aditionalDevicePixelRatio); bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, qreal aditionalDevicePixelRatio);
bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, int aditionalDevicePixelRatio); bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal aditionalDevicePixelRatio);
bool hasAlphaChannel(const QRect &rect); bool hasAlphaChannel(const QRect &rect);
bool fixAlphaChannel(const QRect &rect); bool fixAlphaChannel(const QRect &rect);

View File

@ -670,8 +670,10 @@ QWidget *QMainWindow::takeCentralWidget()
{ {
Q_D(QMainWindow); Q_D(QMainWindow);
QWidget *oldcentralwidget = d->layout->centralWidget(); QWidget *oldcentralwidget = d->layout->centralWidget();
if (oldcentralwidget) {
oldcentralwidget->setParent(0); oldcentralwidget->setParent(0);
d->layout->setCentralWidget(0); d->layout->setCentralWidget(0);
}
return oldcentralwidget; return oldcentralwidget;
} }

View File

@ -859,6 +859,10 @@ void tst_QMainWindow::takeCentralWidget() {
QVERIFY(!mw.centralWidget()); QVERIFY(!mw.centralWidget());
// verify that we don't crash when trying to take a non-set
// central widget but just return a null pointer instead
QVERIFY(!mw.takeCentralWidget());
mw.setCentralWidget(w1); mw.setCentralWidget(w1);
QWidget *oldCentralWidget = mw.takeCentralWidget(); QWidget *oldCentralWidget = mw.takeCentralWidget();

View File

@ -36,6 +36,7 @@
#include <qfile.h> #include <qfile.h>
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qstandardpaths.h> #include <qstandardpaths.h>
#include <qtemporaryfile.h>
#include <process.h> #include <process.h>
#include <errno.h> #include <errno.h>
@ -150,25 +151,23 @@ QString Environment::gccVersion()
QString Environment::msvcVersion() QString Environment::msvcVersion()
{ {
int returnValue = 0; int returnValue = 0;
// Extract version from standard error output of "cl /?" QString tempSourceName;
const QString command = QFile::decodeName(qgetenv("ComSpec")) { // QTemporaryFile needs to go out of scope, otherwise cl.exe refuses to open it.
+ QLatin1String(" /c ") + QLatin1String(compilerInfo(CC_MSVC2015)->executable) QTemporaryFile tempSource(QDir::tempPath() + QLatin1String("/XXXXXX.cpp"));
+ QLatin1String(" /? 2>&1"); tempSource.setAutoRemove(false);
SetEnvironmentVariable(L"CL", NULL); // May contain /nologo, which suppresses the version. if (!tempSource.open())
QString version = execute(command, &returnValue); return QString();
if (returnValue != 0) { tempSource.write("_MSC_FULL_VER\n");
cout << "Could not get cl version" << returnValue << qPrintable(version) << '\n';; tempSourceName = tempSource.fileName();
version.clear();
} else {
QRegExp versionRegexp(QStringLiteral("^.*\\b(\\d{2,2}\\.\\d{2,2}\\.\\d{5,5})\\b.*$"));
Q_ASSERT(versionRegexp.isValid());
if (versionRegexp.exactMatch(version)) {
version = versionRegexp.cap(1);
} else {
cout << "Unable to determine cl version from the output of \""
<< qPrintable(command) << "\"\n";
}
} }
QString version = execute(QLatin1String("cl /nologo /EP \"")
+ QDir::toNativeSeparators(tempSourceName) + QLatin1Char('"'),
&returnValue).trimmed();
QFile::remove(tempSourceName);
if (returnValue || version.size() < 9 || !version.at(0).isDigit())
return QString();
version.insert(4, QLatin1Char('.'));
version.insert(2, QLatin1Char('.'));
return version; return version;
} }