Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: Ia3591d7288bac3bf441f27e486d35e2c5c481993bb10
commit
b176a6a159
|
|
@ -1156,6 +1156,66 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS
|
|||
}
|
||||
#endif
|
||||
|
||||
static NSColor *qt_convertColorForContext(CGContextRef context, NSColor *color)
|
||||
{
|
||||
Q_ASSERT(color);
|
||||
Q_ASSERT(context);
|
||||
|
||||
CGColorSpaceRef targetCGColorSpace = CGBitmapContextGetColorSpace(context);
|
||||
NSColorSpace *targetNSColorSpace = [[NSColorSpace alloc] initWithCGColorSpace:targetCGColorSpace];
|
||||
NSColor *adjusted = [color colorUsingColorSpace:targetNSColorSpace];
|
||||
[targetNSColorSpace release];
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
static NSColor *qt_colorForContext(CGContextRef context, const CGFloat (&rgba)[4])
|
||||
{
|
||||
Q_ASSERT(context);
|
||||
|
||||
auto colorSpace = CGBitmapContextGetColorSpace(context);
|
||||
if (!colorSpace)
|
||||
return nil;
|
||||
|
||||
return qt_convertColorForContext(context, [NSColor colorWithSRGBRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]]);
|
||||
}
|
||||
|
||||
static void qt_drawDisclosureButton(CGContextRef context, NSInteger state, bool selected, CGRect rect)
|
||||
{
|
||||
Q_ASSERT(context);
|
||||
|
||||
static const CGFloat gray[] = {0.55, 0.55, 0.55, 0.97};
|
||||
static const CGFloat white[] = {1.0, 1.0, 1.0, 0.9};
|
||||
|
||||
NSColor *fillColor = qt_colorForContext(context, selected ? white : gray);
|
||||
[fillColor setFill];
|
||||
|
||||
if (state == NSOffState) {
|
||||
static NSBezierPath *triangle = [[NSBezierPath alloc] init];
|
||||
[triangle removeAllPoints];
|
||||
// In off state, a disclosure button is an equilateral triangle
|
||||
// ('pointing' to the right) with a bound rect that can be described
|
||||
// as NSMakeRect(0, 0, 8, 9). Inside the 'rect' it's translated by
|
||||
// (2, 4).
|
||||
[triangle moveToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4)];
|
||||
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4 + 9)];
|
||||
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2 + 8, rect.origin.y + 4 + 4.5)];
|
||||
[triangle closePath];
|
||||
[triangle fill];
|
||||
} else {
|
||||
static NSBezierPath *openTriangle = [[NSBezierPath alloc] init];
|
||||
[openTriangle removeAllPoints];
|
||||
// In 'on' state, the button is an equilateral triangle (looking down)
|
||||
// with the bounding rect NSMakeRect(0, 0, 9, 8). Inside the 'rect'
|
||||
// it's translated by (1, 4).
|
||||
[openTriangle moveToPoint:NSMakePoint(rect.origin.x + 1, rect.origin.y + 4 + 8)];
|
||||
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 9, rect.origin.y + 4 + 8)];
|
||||
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 4.5, rect.origin.y + 4)];
|
||||
[openTriangle closePath];
|
||||
[openTriangle fill];
|
||||
}
|
||||
}
|
||||
|
||||
void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const
|
||||
{
|
||||
QPainterPath focusRingPath;
|
||||
|
|
@ -3241,8 +3301,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
|||
CGContextScaleCTM(cg, 1, -1);
|
||||
CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y);
|
||||
|
||||
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
|
||||
|
||||
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave && !qt_mac_applicationIsInDarkMode()) {
|
||||
// When the real system theme is one of the 'Dark' themes, and an application forces the 'Aqua' theme,
|
||||
// under some conditions (see QTBUG-74515 for more details) NSButtonCell seems to select the 'Dark'
|
||||
// code path and is becoming transparent, thus 'invisible' on the white background. To workaround this,
|
||||
// we draw the disclose triangle manually:
|
||||
qt_drawDisclosureButton(cg, triangleCell.state, (opt->state & State_Selected) && viewHasFocus, rect);
|
||||
} else {
|
||||
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
|
||||
}
|
||||
d->restoreNSGraphicsContext(cg);
|
||||
break; }
|
||||
|
||||
|
|
|
|||
|
|
@ -83,56 +83,56 @@ void QAppleTestLogger::leaveTestFunction()
|
|||
testFunctionActivity.leave();
|
||||
}
|
||||
|
||||
typedef QPair<QtMsgType, const char *> IncidentClassification;
|
||||
static IncidentClassification incidentTypeToClassification(QAbstractTestLogger::IncidentTypes type)
|
||||
struct MessageData
|
||||
{
|
||||
switch (type) {
|
||||
case QAbstractTestLogger::Pass:
|
||||
return IncidentClassification(QtInfoMsg, "pass");
|
||||
case QAbstractTestLogger::XFail:
|
||||
return IncidentClassification(QtInfoMsg, "xfail");
|
||||
case QAbstractTestLogger::Fail:
|
||||
return IncidentClassification(QtCriticalMsg, "fail");
|
||||
case QAbstractTestLogger::XPass:
|
||||
return IncidentClassification(QtInfoMsg, "xpass");
|
||||
case QAbstractTestLogger::BlacklistedPass:
|
||||
return IncidentClassification(QtWarningMsg, "bpass");
|
||||
case QAbstractTestLogger::BlacklistedFail:
|
||||
return IncidentClassification(QtInfoMsg, "bfail");
|
||||
case QAbstractTestLogger::BlacklistedXPass:
|
||||
return IncidentClassification(QtWarningMsg, "bxpass");
|
||||
case QAbstractTestLogger::BlacklistedXFail:
|
||||
return IncidentClassification(QtInfoMsg, "bxfail");
|
||||
QtMsgType messageType = QtFatalMsg;
|
||||
const char *categorySuffix = nullptr;
|
||||
|
||||
void generateCategory(QTestCharBuffer *category)
|
||||
{
|
||||
if (categorySuffix)
|
||||
QTest::qt_asprintf(category, "qt.test.%s", categorySuffix);
|
||||
else
|
||||
QTest::qt_asprintf(category, "qt.test");
|
||||
}
|
||||
return IncidentClassification(QtFatalMsg, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void QAppleTestLogger::addIncident(IncidentTypes type, const char *description,
|
||||
const char *file, int line)
|
||||
{
|
||||
|
||||
IncidentClassification incidentClassification = incidentTypeToClassification(type);
|
||||
MessageData messageData = [=]() {
|
||||
switch (type) {
|
||||
case QAbstractTestLogger::Pass:
|
||||
return MessageData{QtInfoMsg, "pass"};
|
||||
case QAbstractTestLogger::XFail:
|
||||
return MessageData{QtInfoMsg, "xfail"};
|
||||
case QAbstractTestLogger::Fail:
|
||||
return MessageData{QtCriticalMsg, "fail"};
|
||||
case QAbstractTestLogger::XPass:
|
||||
return MessageData{QtInfoMsg, "xpass"};
|
||||
case QAbstractTestLogger::BlacklistedPass:
|
||||
return MessageData{QtWarningMsg, "bpass"};
|
||||
case QAbstractTestLogger::BlacklistedFail:
|
||||
return MessageData{QtInfoMsg, "bfail"};
|
||||
case QAbstractTestLogger::BlacklistedXPass:
|
||||
return MessageData{QtWarningMsg, "bxpass"};
|
||||
case QAbstractTestLogger::BlacklistedXFail:
|
||||
return MessageData{QtInfoMsg, "bxfail"};
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
}();
|
||||
|
||||
QTestCharBuffer category;
|
||||
QTest::qt_asprintf(&category, "qt.test.%s", incidentClassification.second);
|
||||
messageData.generateCategory(&category);
|
||||
|
||||
QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
|
||||
|
||||
QTestCharBuffer subsystemBuffer;
|
||||
// It would be nice to have the data tag as part of the subsystem too, but that
|
||||
// will for some tests results in hundreds of thousands of log objects being
|
||||
// created, so we limit the subsystem to test functions, which we can hope
|
||||
// are reasonably limited.
|
||||
generateTestIdentifier(&subsystemBuffer, TestObject | TestFunction);
|
||||
QString subsystem = QString::fromLatin1(subsystemBuffer.data());
|
||||
|
||||
// We still want the full identifier as part of the message though
|
||||
QTestCharBuffer testIdentifier;
|
||||
generateTestIdentifier(&testIdentifier);
|
||||
QString message = QString::fromLatin1(testIdentifier.data());
|
||||
QString message = testIdentifier();
|
||||
if (qstrlen(description))
|
||||
message += QLatin1Char('\n') % QString::fromLatin1(description);
|
||||
|
||||
AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem);
|
||||
AppleUnifiedLogger::messageHandler(messageData.messageType, context, message, subsystem());
|
||||
}
|
||||
|
||||
void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||
|
|
@ -140,6 +140,62 @@ void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &cont
|
|||
AppleUnifiedLogger::messageHandler(type, context, message);
|
||||
}
|
||||
|
||||
void QAppleTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line)
|
||||
{
|
||||
MessageData messageData = [=]() {
|
||||
switch (type) {
|
||||
case QAbstractTestLogger::Warn:
|
||||
case QAbstractTestLogger::QWarning:
|
||||
return MessageData{QtWarningMsg, nullptr};
|
||||
case QAbstractTestLogger::QDebug:
|
||||
return MessageData{QtDebugMsg, nullptr};
|
||||
case QAbstractTestLogger::QSystem:
|
||||
return MessageData{QtWarningMsg, "system"};
|
||||
case QAbstractTestLogger::QFatal:
|
||||
return MessageData{QtFatalMsg, nullptr};
|
||||
case QAbstractTestLogger::Skip:
|
||||
return MessageData{QtInfoMsg, "skip"};
|
||||
case QAbstractTestLogger::Info:
|
||||
case QAbstractTestLogger::QInfo:
|
||||
return MessageData{QtInfoMsg, nullptr};
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
}();
|
||||
|
||||
QTestCharBuffer category;
|
||||
messageData.generateCategory(&category);
|
||||
|
||||
QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
|
||||
QString msg = message;
|
||||
|
||||
if (type == Skip) {
|
||||
if (!message.isNull())
|
||||
msg.prepend(testIdentifier() + QLatin1Char('\n'));
|
||||
else
|
||||
msg = testIdentifier();
|
||||
}
|
||||
|
||||
AppleUnifiedLogger::messageHandler(messageData.messageType, context, msg, subsystem());
|
||||
}
|
||||
|
||||
QString QAppleTestLogger::subsystem() const
|
||||
{
|
||||
QTestCharBuffer buffer;
|
||||
// It would be nice to have the data tag as part of the subsystem too, but that
|
||||
// will for some tests result in hundreds of thousands of log objects being
|
||||
// created, so we limit the subsystem to test functions, which we can hope
|
||||
// are reasonably limited.
|
||||
generateTestIdentifier(&buffer, TestObject | TestFunction);
|
||||
return QString::fromLatin1(buffer.data());
|
||||
}
|
||||
|
||||
QString QAppleTestLogger::testIdentifier() const
|
||||
{
|
||||
QTestCharBuffer buffer;
|
||||
generateTestIdentifier(&buffer);
|
||||
return QString::fromLatin1(buffer.data());
|
||||
}
|
||||
|
||||
#endif // QT_USE_APPLE_UNIFIED_LOGGING
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -73,11 +73,14 @@ public:
|
|||
void addMessage(QtMsgType, const QMessageLogContext &,
|
||||
const QString &) override;
|
||||
void addMessage(MessageTypes type, const QString &message,
|
||||
const char *file = 0, int line = 0) override
|
||||
{ Q_UNUSED(type); Q_UNUSED(message); Q_UNUSED(file); Q_UNUSED(line); Q_UNREACHABLE(); }
|
||||
const char *file = 0, int line = 0) override;
|
||||
|
||||
void addBenchmarkResult(const QBenchmarkResult &result) override
|
||||
{ Q_UNUSED(result); }
|
||||
|
||||
private:
|
||||
QString subsystem() const;
|
||||
QString testIdentifier() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include <QProcess>
|
||||
#include <QDir>
|
||||
|
||||
static QString targetName( BuildType buildMode, const QString& target, const QString& version )
|
||||
QString TestCompiler::targetName(BuildType buildMode, const QString& target, const QString& version)
|
||||
{
|
||||
Q_UNUSED(version);
|
||||
QString targetName = target;
|
||||
|
|
@ -257,7 +257,8 @@ bool TestCompiler::qmakeProject( const QString &workDir, const QString &proName
|
|||
return runCommand(qmakeCmd_, QStringList() << "-project" << "-o" << projectFile << "DESTDIR=./");
|
||||
}
|
||||
|
||||
bool TestCompiler::qmake( const QString &workDir, const QString &proName, const QString &buildDir )
|
||||
bool TestCompiler::qmake(const QString &workDir, const QString &proName, const QString &buildDir,
|
||||
const QStringList &additionalArguments)
|
||||
{
|
||||
QDir D;
|
||||
D.setCurrent( workDir );
|
||||
|
|
@ -274,7 +275,8 @@ bool TestCompiler::qmake( const QString &workDir, const QString &proName, const
|
|||
makeFile += "Makefile";
|
||||
|
||||
// Now start qmake and generate the makefile
|
||||
return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile);
|
||||
return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile
|
||||
<< additionalArguments);
|
||||
}
|
||||
|
||||
bool TestCompiler::make( const QString &workPath, const QString &target, bool expectFail )
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ public:
|
|||
void resetEnvironment();
|
||||
void addToEnvironment( QString varAssignment );
|
||||
|
||||
static QString targetName(BuildType buildMode, const QString& target, const QString& version);
|
||||
|
||||
// executes a make clean in the specified workPath
|
||||
bool makeClean( const QString &workPath );
|
||||
// executes a make dist clean in the specified workPath
|
||||
|
|
@ -56,7 +58,8 @@ public:
|
|||
// executes a qmake -project on the specified workDir
|
||||
bool qmakeProject( const QString &workDir, const QString &proName );
|
||||
// executes a qmake on proName in the specified workDir, output goes to buildDir or workDir if it's null
|
||||
bool qmake( const QString &workDir, const QString &proName, const QString &buildDir = QString() );
|
||||
bool qmake(const QString &workDir, const QString &proName, const QString &buildDir = QString(),
|
||||
const QStringList &additionalArguments = QStringList());
|
||||
// executes a make in the specified workPath, with an optional target (eg. install)
|
||||
bool make( const QString &workPath, const QString &target = QString(), bool expectFail = false );
|
||||
// checks if the executable exists in destDir
|
||||
|
|
|
|||
|
|
@ -5,3 +5,8 @@ SOURCES = test_file.cpp \
|
|||
RESOURCES = test.qrc
|
||||
TARGET = "simple app"
|
||||
DESTDIR = "dest dir"
|
||||
|
||||
target.path = $$OUT_PWD/dist
|
||||
INSTALLS += target
|
||||
|
||||
!build_pass:msvc:CONFIG(debug, debug|release):message("check for pdb, please")
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ private slots:
|
|||
void simple_app();
|
||||
void simple_app_shadowbuild();
|
||||
void simple_app_shadowbuild2();
|
||||
void simple_app_versioned();
|
||||
void simple_lib();
|
||||
void simple_dll();
|
||||
void subdirs();
|
||||
|
|
@ -173,10 +174,15 @@ void tst_qmake::simple_app()
|
|||
{
|
||||
QString workDir = base_path + "/testdata/simple_app";
|
||||
QString destDir = workDir + "/dest dir";
|
||||
QString installDir = workDir + "/dist";
|
||||
|
||||
QVERIFY( test_compiler.qmake( workDir, "simple_app" ));
|
||||
QVERIFY( test_compiler.qmake( workDir, "simple_app", QString() ));
|
||||
QVERIFY( test_compiler.make( workDir ));
|
||||
QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" ));
|
||||
|
||||
QVERIFY(test_compiler.make(workDir, "install"));
|
||||
QVERIFY(test_compiler.exists(installDir, "simple app", Exe, "1.0.0"));
|
||||
|
||||
QVERIFY( test_compiler.makeClean( workDir ));
|
||||
QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" )); // Should still exist after a make clean
|
||||
QVERIFY( test_compiler.makeDistClean( workDir ));
|
||||
|
|
@ -216,6 +222,43 @@ void tst_qmake::simple_app_shadowbuild2()
|
|||
QVERIFY( test_compiler.removeMakefile( buildDir ) );
|
||||
}
|
||||
|
||||
void tst_qmake::simple_app_versioned()
|
||||
{
|
||||
QString workDir = base_path + "/testdata/simple_app";
|
||||
QString buildDir = base_path + "/testdata/simple_app_versioned_build";
|
||||
QString destDir = buildDir + "/dest dir";
|
||||
QString installDir = buildDir + "/dist";
|
||||
|
||||
QString version = "4.5.6";
|
||||
QVERIFY(test_compiler.qmake(workDir, "simple_app", buildDir, QStringList{ "VERSION=" + version }));
|
||||
QString qmakeOutput = test_compiler.commandOutput();
|
||||
QVERIFY(test_compiler.make(buildDir));
|
||||
QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version));
|
||||
|
||||
QString pdbFilePath;
|
||||
bool checkPdb = qmakeOutput.contains("Project MESSAGE: check for pdb, please");
|
||||
if (checkPdb) {
|
||||
QString targetBase = QFileInfo(TestCompiler::targetName(Exe, "simple app", version))
|
||||
.completeBaseName();
|
||||
pdbFilePath = destDir + '/' + targetBase + ".pdb";
|
||||
QVERIFY2(QFile::exists(pdbFilePath), qPrintable(pdbFilePath));
|
||||
QVERIFY(test_compiler.make(buildDir, "install"));
|
||||
QString installedPdbFilePath = installDir + '/' + targetBase + ".pdb";
|
||||
QEXPECT_FAIL("", "QTBUG-74265", Continue);
|
||||
QVERIFY2(QFile::exists(installedPdbFilePath), qPrintable(installedPdbFilePath));
|
||||
}
|
||||
|
||||
QVERIFY(test_compiler.makeClean(buildDir));
|
||||
QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version));
|
||||
QVERIFY(test_compiler.makeDistClean(buildDir));
|
||||
QVERIFY(!test_compiler.exists(destDir, "simple app", Exe, version));
|
||||
if (checkPdb) {
|
||||
QEXPECT_FAIL("", "QTBUG-74265", Continue);
|
||||
QVERIFY(!QFile::exists(pdbFilePath));
|
||||
}
|
||||
QVERIFY(test_compiler.removeMakefile(buildDir));
|
||||
}
|
||||
|
||||
void tst_qmake::simple_dll()
|
||||
{
|
||||
QString workDir = base_path + "/testdata/simple_dll";
|
||||
|
|
|
|||
Loading…
Reference in New Issue