diff options
Diffstat (limited to 'src')
154 files changed, 1755 insertions, 1264 deletions
diff --git a/src/3rdparty/libjpeg.pri b/src/3rdparty/libjpeg.pri index a61f28dc5a..0d35bf8941 100644 --- a/src/3rdparty/libjpeg.pri +++ b/src/3rdparty/libjpeg.pri @@ -7,10 +7,8 @@ DEFINES += \ JPEG_LIB_VERSION=80 \ SIZEOF_SIZE_T=__SIZEOF_SIZE_T__ -#Disable warnings in 3rdparty code due to unused arguments -contains(QMAKE_CC, gcc): { - QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main -} +# Disable warnings in 3rdparty code due to unused arguments +gcc: QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main INCLUDEPATH += $$PWD/libjpeg/src diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index 792ea387ac..844aa9daa7 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -499,7 +499,7 @@ bool QFseventsFileSystemWatcherEngine::startStream() DEBUG() << "Starting stream with paths" << watchingState.watchedPaths.keys(); - NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchingState.watchedPaths.size()]; + NSMutableArray<NSString *> *pathsToWatch = [NSMutableArray<NSString *> arrayWithCapacity:watchingState.watchedPaths.size()]; for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(), ei = watchingState.watchedPaths.end(); i != ei; ++i) [pathsToWatch addObject:i.key().toNSString()]; diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 24d73fa8be..b91b5e76be 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -87,19 +87,20 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY QT_END_NAMESPACE QT_USE_NAMESPACE @interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject -{ +@end + +@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) { NSAutoreleasePool **m_pool; } --(id)initWithPool:(NSAutoreleasePool**)pool; -@end -@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) --(id)initWithPool:(NSAutoreleasePool**)pool + +- (instancetype)initWithPool:(NSAutoreleasePool **)pool { - if (self = [super init]) + if ((self = [self init])) m_pool = pool; return self; } --(void)dealloc + +- (void)dealloc { if (*m_pool) { // The pool is still valid, which means we're not being drained from diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 8499b3fd57..35b2390c6d 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -58,18 +58,18 @@ QT_USE_NAMESPACE -@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject { - QStack<CFStringRef> m_runLoopModes; -} +@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject @end QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker); -@implementation RunLoopModeTracker +@implementation RunLoopModeTracker { + QStack<CFStringRef> m_runLoopModes; +} -- (id) init +- (instancetype)init { - if (self = [super init]) { + if ((self = [super init])) { m_runLoopModes.push(kCFRunLoopDefaultMode); [[NSNotificationCenter defaultCenter] @@ -77,21 +77,21 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker); selector:@selector(receivedNotification:) name:nil #ifdef Q_OS_OSX - object:[NSApplication sharedApplication]]; + object:NSApplication.sharedApplication]; #elif defined(Q_OS_WATCHOS) - object:[WKExtension sharedExtension]]; + object:WKExtension.sharedExtension]; #else // Use performSelector so this can work in an App Extension - object:[[UIApplication class] performSelector:@selector(sharedApplication)]]; + object:[UIApplication.class performSelector:@selector(sharedApplication)]]; #endif } return self; } -- (void) dealloc +- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; [super dealloc]; } @@ -100,13 +100,13 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) { for (NSString *key in dictionary) { if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode"))) - return (CFStringRef)[dictionary objectForKey: key]; + return (CFStringRef)dictionary[key]; } return nil; } -- (void) receivedNotification:(NSNotification *) notification +- (void)receivedNotification:(NSNotification *)notification { if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) { if (CFStringRef mode = runLoopMode(notification.userInfo)) @@ -116,7 +116,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) } else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) { CFStringRef mode = runLoopMode(notification.userInfo); - if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo) + if (CFStringCompare(mode, self.currentMode, 0) == kCFCompareEqualTo) m_runLoopModes.pop(); else qCWarning(lcEventDispatcher) << "Tried to pop run loop mode" @@ -126,7 +126,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) } } -- (CFStringRef) currentMode +- (CFStringRef)currentMode { return m_runLoopModes.top(); } diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index 8f419a4a46..54d1ae816b 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -564,6 +564,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_5_9 Same as Qt_5_6 \value Qt_5_10 Same as Qt_5_6 \value Qt_5_11 Same as Qt_5_6 + \value Qt_5_12 Same as Qt_5_6 \omitvalue Qt_DefaultCompiledVersion \sa setVersion(), version() diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index 1f1b13686c..85a2177652 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -98,10 +98,11 @@ public: Qt_5_9 = Qt_5_8, Qt_5_10 = Qt_5_9, Qt_5_11 = Qt_5_10, -#if QT_VERSION >= 0x050c00 + Qt_5_12 = Qt_5_11, +#if QT_VERSION >= 0x050d00 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion #endif - Qt_DefaultCompiledVersion = Qt_5_11 + Qt_DefaultCompiledVersion = Qt_5_12 }; enum ByteOrder { diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index adfa939cc6..4ae4e687a0 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -958,7 +958,7 @@ static inline char qToLower(char c) $LC_CTYPE is set, most Unix systems do "the right thing".) Functions that this affects include contains(), indexOf(), lastIndexOf(), operator<(), operator<=(), operator>(), - operator>=(), toLower() and toUpper(). + operator>=(), isLower(), isUpper(), toLower() and toUpper(). This issue does not apply to \l{QString}s since they represent characters using Unicode. @@ -2949,6 +2949,78 @@ bool QByteArray::endsWith(const char *str) const return qstrncmp(d->data() + d->size - len, str, len) == 0; } +/*! + Returns true if \a c is an uppercase Latin1 letter. + \note The multiplication sign 0xD7 and the sz ligature 0xDF are not + treated as uppercase Latin1. + */ +static inline bool isUpperCaseLatin1(char c) +{ + if (c >= 'A' && c <= 'Z') + return true; + + return (uchar(c) >= 0xC0 && uchar(c) <= 0xDE && uchar(c) != 0xD7); +} + +/*! + Returns \c true if this byte array contains only uppercase letters, + otherwise returns \c false. The byte array is interpreted as a Latin-1 + encoded string. + \since 5.12 + + \sa isLower(), toUpper() +*/ +bool QByteArray::isUpper() const +{ + if (isEmpty()) + return false; + + const char *d = data(); + + for (int i = 0, max = size(); i < max; ++i) { + if (!isUpperCaseLatin1(d[i])) + return false; + } + + return true; +} + +/*! + Returns true if \a c is an lowercase Latin1 letter. + \note The division sign 0xF7 is not treated as lowercase Latin1, + but the small y dieresis 0xFF is. + */ +static inline bool isLowerCaseLatin1(char c) +{ + if (c >= 'a' && c <= 'z') + return true; + + return (uchar(c) >= 0xD0 && uchar(c) != 0xF7); +} + +/*! + Returns \c true if this byte array contains only lowercase letters, + otherwise returns \c false. The byte array is interpreted as a Latin-1 + encoded string. + \since 5.12 + + \sa isUpper(), toLower() + */ +bool QByteArray::isLower() const +{ + if (isEmpty()) + return false; + + const char *d = data(); + + for (int i = 0, max = size(); i < max; ++i) { + if (!isLowerCaseLatin1(d[i])) + return false; + } + + return true; +} + /*! \overload Returns \c true if this byte array ends with character \a ch; @@ -3060,7 +3132,7 @@ QByteArray QByteArray::mid(int pos, int len) const Example: \snippet code/src_corelib_tools_qbytearray.cpp 30 - \sa toUpper(), {8-bit Character Comparisons} + \sa isLower(), toUpper(), {8-bit Character Comparisons} */ // prevent the compiler from inlining the function in each of @@ -3114,7 +3186,7 @@ QByteArray QByteArray::toLower_helper(QByteArray &a) Example: \snippet code/src_corelib_tools_qbytearray.cpp 31 - \sa toLower(), {8-bit Character Comparisons} + \sa isUpper(), toLower(), {8-bit Character Comparisons} */ QByteArray QByteArray::toUpper_helper(const QByteArray &a) diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 300f795469..bed710c597 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -245,6 +245,9 @@ public: bool endsWith(char c) const; bool endsWith(const char *c) const; + bool isUpper() const; + bool isLower() const; + void truncate(int pos); void chop(int n); diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index eb7bdfe95c..59650ed2f7 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -312,12 +312,14 @@ qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const Q_ASSERT(maxLength >= 0 && pos >= 0); qint64 readSoFar = 0; - for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) { - qint64 blockLength = buffers[i].size(); + for (const QRingChunk &chunk : buffers) { + if (readSoFar == maxLength) + break; + qint64 blockLength = chunk.size(); if (pos < blockLength) { blockLength = qMin(blockLength - pos, maxLength - readSoFar); - memcpy(data + readSoFar, buffers[i].data() + pos, blockLength); + memcpy(data + readSoFar, chunk.data() + pos, blockLength); readSoFar += blockLength; pos = 0; } else { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b56ad34546..ed56f99771 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4887,6 +4887,50 @@ bool QString::endsWith(QChar c, Qt::CaseSensitivity cs) const return qt_ends_with(*this, c, cs); } +/*! + Returns \c true if the string only contains uppercase letters, + otherwise returns \c false. + \since 5.12 + + \sa QChar::isUpper(), isLower() +*/ +bool QString::isUpper() const +{ + if (isEmpty()) + return false; + + const QChar *d = data(); + + for (int i = 0, max = size(); i < max; ++i) { + if (!d[i].isUpper()) + return false; + } + + return true; +} + +/*! + Returns \c true if the string only contains lowercase letters, + otherwise returns \c false. + \since 5.12 + + \sa QChar::isLower(), isUpper() + */ +bool QString::isLower() const +{ + if (isEmpty()) + return false; + + const QChar *d = data(); + + for (int i = 0, max = size(); i < max; ++i) { + if (!d[i].isLower()) + return false; + } + + return true; +} + static QByteArray qt_convert_to_latin1(QStringView string); QByteArray QString::toLatin1_helper(const QString &string) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 0138ae4098..d93891248f 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -409,6 +409,9 @@ public: bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + bool isUpper() const; + bool isLower() const; + Q_REQUIRED_RESULT QString leftJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const; Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const; diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index daa7dc1531..445ddeb31d 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -66,11 +66,10 @@ static QTimeZonePrivate *newBackendTimeZone() return new QAndroidTimeZonePrivate(); #elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED) return new QTzTimeZonePrivate(); - // Registry based timezone backend not available on WinRT -#elif defined Q_OS_WIN - return new QWinTimeZonePrivate(); #elif QT_CONFIG(icu) return new QIcuTimeZonePrivate(); +#elif defined Q_OS_WIN + return new QWinTimeZonePrivate(); #else return new QUtcTimeZonePrivate(); #endif // System Locales @@ -93,11 +92,10 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId) return new QAndroidTimeZonePrivate(ianaId); #elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED) return new QTzTimeZonePrivate(ianaId); - // Registry based timezone backend not available on WinRT -#elif defined Q_OS_WIN - return new QWinTimeZonePrivate(ianaId); #elif QT_CONFIG(icu) return new QIcuTimeZonePrivate(ianaId); +#elif defined Q_OS_WIN + return new QWinTimeZonePrivate(ianaId); #else return new QUtcTimeZonePrivate(ianaId); #endif // System Locales diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index 8bde07c710..ec91b7e8a8 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE #ifndef Q_OS_WINRT +// The registry-based timezone backend is not available on WinRT, which falls back to equivalent APIs. #define QT_USE_REGISTRY_TIMEZONE 1 #endif diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 72224f280d..88708851d7 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -159,16 +159,18 @@ qtConfig(timezone) { SOURCES += \ tools/qtimezone.cpp \ tools/qtimezoneprivate.cpp - !nacl:darwin: \ + !nacl:darwin: { SOURCES += tools/qtimezoneprivate_mac.mm - else: android:!android-embedded: \ + } else: android:!android-embedded: { SOURCES += tools/qtimezoneprivate_android.cpp - else: unix: \ + } else: unix: { SOURCES += tools/qtimezoneprivate_tz.cpp - else: win32: \ - SOURCES += tools/qtimezoneprivate_win.cpp - qtConfig(icu): \ + qtConfig(icu): SOURCES += tools/qtimezoneprivate_icu.cpp + } else: qtConfig(icu): { SOURCES += tools/qtimezoneprivate_icu.cpp + } else: win32: { + SOURCES += tools/qtimezoneprivate_win.cpp + } } qtConfig(datetimeparser) { diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 76aba944b2..b4942f06d4 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -9,6 +9,7 @@ HEADERS += \ image/qimage_p.h \ image/qimageiohandler.h \ image/qimagereader.h \ + image/qimagereaderwriterhelpers_p.h \ image/qimagewriter.h \ image/qpaintengine_pic_p.h \ image/qpicture.h \ @@ -33,6 +34,7 @@ SOURCES += \ image/qimage_conversions.cpp \ image/qimageiohandler.cpp \ image/qimagereader.cpp \ + image/qimagereaderwriterhelpers.cpp \ image/qimagewriter.cpp \ image/qpaintengine_pic.cpp \ image/qpicture.cpp \ diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp index e8405a6d11..2453242fa8 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -189,9 +189,7 @@ QBitmap &QBitmap::operator=(const QPixmap &pixmap) } else if (pixmap.depth() == 1) { // 1-bit pixmap QPixmap::operator=(pixmap); // shallow assignment } else { // n-bit depth pixmap - QImage image; - image = pixmap.toImage(); // convert pixmap to image - *this = fromImage(image); // will dither image + *this = fromImage(pixmap.toImage()); // will dither image } return *this; } @@ -223,6 +221,24 @@ QBitmap::operator QVariant() const return QVariant(QVariant::Bitmap, this); } +static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags) +{ + // make sure image.color(0) == Qt::color0 (white) + // and image.color(1) == Qt::color1 (black) + const QRgb c0 = QColor(Qt::black).rgb(); + const QRgb c1 = QColor(Qt::white).rgb(); + if (image.color(0) == c0 && image.color(1) == c1) { + image.invertPixels(); + image.setColor(0, c1); + image.setColor(1, c0); + } + + QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType)); + + data->fromImageInPlace(image, flags | Qt::MonoOnly); + return QPixmap(data.take()); +} + /*! Returns a copy of the given \a image converted to a bitmap using the specified image conversion \a flags. @@ -234,22 +250,24 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) if (image.isNull()) return QBitmap(); - QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags); + return makeBitmap(image.convertToFormat(QImage::Format_MonoLSB, flags), flags); +} - // make sure image.color(0) == Qt::color0 (white) - // and image.color(1) == Qt::color1 (black) - const QRgb c0 = QColor(Qt::black).rgb(); - const QRgb c1 = QColor(Qt::white).rgb(); - if (img.color(0) == c0 && img.color(1) == c1) { - img.invertPixels(); - img.setColor(0, c1); - img.setColor(1, c0); - } +/*! + \since 5.12 + \overload - QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType)); + Returns a copy of the given \a image converted to a bitmap using + the specified image conversion \a flags. - data->fromImage(img, flags | Qt::MonoOnly); - return QPixmap(data.take()); + \sa fromData() +*/ +QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags) +{ + if (image.isNull()) + return QBitmap(); + + return makeBitmap(std::move(image).convertToFormat(QImage::Format_MonoLSB, flags), flags); } /*! @@ -277,7 +295,7 @@ QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format m int bytesPerLine = (size.width() + 7) / 8; for (int y = 0; y < size.height(); ++y) memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine); - return QBitmap::fromImage(image); + return QBitmap::fromImage(std::move(image)); } /*! diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h index 6a8c8b3457..188064fccf 100644 --- a/src/gui/image/qbitmap.h +++ b/src/gui/image/qbitmap.h @@ -72,6 +72,7 @@ public: inline void clear() { fill(Qt::color0); } static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor); + static QBitmap fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor); static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat = QImage::Format_MonoLSB); diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 7fcae12cbd..5ef65dd0cc 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3457,8 +3457,7 @@ void QImage::rgbSwapped_inplace() bool QImage::load(const QString &fileName, const char* format) { - QImage image = QImageReader(fileName, format).read(); - operator=(image); + *this = QImageReader(fileName, format).read(); return !isNull(); } @@ -3471,8 +3470,7 @@ bool QImage::load(const QString &fileName, const char* format) bool QImage::load(QIODevice* device, const char* format) { - QImage image = QImageReader(device, format).read(); - operator=(image); + *this = QImageReader(device, format).read(); return !isNull(); } @@ -3492,8 +3490,7 @@ bool QImage::load(QIODevice* device, const char* format) bool QImage::loadFromData(const uchar *data, int len, const char *format) { - QImage image = fromData(data, len, format); - operator=(image); + *this = fromData(data, len, format); return !isNull(); } diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 7086e102ea..e77c6f019c 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -164,73 +164,13 @@ #include <private/qpnghandler_p.h> #endif +#include <private/qimagereaderwriterhelpers_p.h> + #include <algorithm> QT_BEGIN_NAMESPACE -#ifndef QT_NO_IMAGEFORMATPLUGIN -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) -#endif - -enum _qt_BuiltInFormatType { -#ifndef QT_NO_IMAGEFORMAT_PNG - _qt_PngFormat, -#endif -#ifndef QT_NO_IMAGEFORMAT_BMP - _qt_BmpFormat, -#endif -#ifndef QT_NO_IMAGEFORMAT_PPM - _qt_PpmFormat, - _qt_PgmFormat, - _qt_PbmFormat, -#endif -#ifndef QT_NO_IMAGEFORMAT_XBM - _qt_XbmFormat, -#endif -#ifndef QT_NO_IMAGEFORMAT_XPM - _qt_XpmFormat, -#endif - _qt_NumFormats, - _qt_NoFormat = -1 -}; - -#if !defined(QT_NO_IMAGEFORMAT_PPM) -# define MAX_MT_SIZE 20 -#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM) -# define MAX_MT_SIZE 10 -#else -# define MAX_MT_SIZE 4 -#endif - -struct _qt_BuiltInFormatStruct -{ - char extension[4]; - char mimeType[MAX_MT_SIZE]; -}; - -#undef MAX_MT_SIZE - -static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = { -#ifndef QT_NO_IMAGEFORMAT_PNG - {"png", "png"}, -#endif -#ifndef QT_NO_IMAGEFORMAT_BMP - {"bmp", "bmp"}, -#endif -#ifndef QT_NO_IMAGEFORMAT_PPM - {"ppm", "x-portable-pixmap"}, - {"pgm", "x-portable-graymap"}, - {"pbm", "x-portable-bitmap"}, -#endif -#ifndef QT_NO_IMAGEFORMAT_XBM - {"xbm", "x-xbitmap"}, -#endif -#ifndef QT_NO_IMAGEFORMAT_XPM - {"xpm", "x-xpixmap"}, -#endif -}; -Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats); +using namespace QImageReaderWriterHelpers; static QImageIOHandler *createReadHandlerHelper(QIODevice *device, const QByteArray &format, @@ -251,7 +191,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, typedef QMultiMap<int, QString> PluginKeyMap; // check if we have plugins that support the image format - QFactoryLoader *l = loader(); + auto l = QImageReaderWriterHelpers::pluginLoader(); const PluginKeyMap keyMap = l->keyMap(); #ifdef QIMAGEREADER_DEBUG @@ -1565,16 +1505,6 @@ QByteArray QImageReader::imageFormat(QIODevice *device) return format; } -#ifndef QT_NO_IMAGEFORMATPLUGIN -void supportedImageHandlerFormats(QFactoryLoader *loader, - QImageIOPlugin::Capability cap, - QList<QByteArray> *result); - -void supportedImageHandlerMimeTypes(QFactoryLoader *loader, - QImageIOPlugin::Capability cap, - QList<QByteArray> *result); -#endif - /*! Returns the list of image formats supported by QImageReader. @@ -1605,18 +1535,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QList<QByteArray> QImageReader::supportedImageFormats() { - QList<QByteArray> formats; - formats.reserve(_qt_NumFormats); - for (int i = 0; i < _qt_NumFormats; ++i) - formats << _qt_BuiltInFormats[i].extension; - -#ifndef QT_NO_IMAGEFORMATPLUGIN - supportedImageHandlerFormats(loader(), QImageIOPlugin::CanRead, &formats); -#endif // QT_NO_IMAGEFORMATPLUGIN - - std::sort(formats.begin(), formats.end()); - formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); - return formats; + return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanRead); } /*! @@ -1630,18 +1549,24 @@ QList<QByteArray> QImageReader::supportedImageFormats() QList<QByteArray> QImageReader::supportedMimeTypes() { - QList<QByteArray> mimeTypes; - mimeTypes.reserve(_qt_NumFormats); - for (const auto &fmt : _qt_BuiltInFormats) - mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType); + return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanRead); +} -#ifndef QT_NO_IMAGEFORMATPLUGIN - supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes); -#endif // QT_NO_IMAGEFORMATPLUGIN +/*! + \since 5.12 - std::sort(mimeTypes.begin(), mimeTypes.end()); - mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); - return mimeTypes; + Returns the list of image formats corresponding to \mimeType. + + Note that the QGuiApplication instance must be created before this function is + called. + + \sa supportedImageFormats(), supportedMimeTypes() +*/ + +QList<QByteArray> QImageReader::imageFormatsForMimeType(const QByteArray &mimeType) +{ + return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType, + QImageReaderWriterHelpers::CanRead); } QT_END_NAMESPACE diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 9d6c1e0b1e..4e9a08b6e6 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -144,6 +144,7 @@ public: static QByteArray imageFormat(QIODevice *device); static QList<QByteArray> supportedImageFormats(); static QList<QByteArray> supportedMimeTypes(); + static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType); private: Q_DISABLE_COPY(QImageReader) diff --git a/src/gui/image/qimagereaderwriterhelpers.cpp b/src/gui/image/qimagereaderwriterhelpers.cpp new file mode 100644 index 0000000000..a5b7fb6449 --- /dev/null +++ b/src/gui/image/qimagereaderwriterhelpers.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "private/qimagereaderwriterhelpers_p.h" + +#include <qjsonarray.h> +#include <qmutex.h> +#include <private/qfactoryloader_p.h> + +QT_BEGIN_NAMESPACE + +namespace QImageReaderWriterHelpers { + +#ifndef QT_NO_IMAGEFORMATPLUGIN + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) +Q_GLOBAL_STATIC(QMutex, loaderMutex) + +static void appendImagePluginFormats(QFactoryLoader *loader, + QImageIOPlugin::Capability cap, + QList<QByteArray> *result) +{ + typedef QMultiMap<int, QString> PluginKeyMap; + typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; + + const PluginKeyMap keyMap = loader->keyMap(); + const PluginKeyMapConstIterator cend = keyMap.constEnd(); + int i = -1; + QImageIOPlugin *plugin = 0; + result->reserve(result->size() + keyMap.size()); + for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) { + if (it.key() != i) { + i = it.key(); + plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i)); + } + const QByteArray key = it.value().toLatin1(); + if (plugin && (plugin->capabilities(0, key) & cap) != 0) + result->append(key); + } +} + +static void appendImagePluginMimeTypes(QFactoryLoader *loader, + QImageIOPlugin::Capability cap, + QList<QByteArray> *result, + QList<QByteArray> *resultKeys = nullptr) +{ + QList<QJsonObject> metaDataList = loader->metaData(); + + const int pluginCount = metaDataList.size(); + for (int i = 0; i < pluginCount; ++i) { + const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject(); + const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray(); + const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray(); + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i)); + const int keyCount = keys.size(); + for (int k = 0; k < keyCount; ++k) { + const QByteArray key = keys.at(k).toString().toLatin1(); + if (plugin && (plugin->capabilities(0, key) & cap) != 0) { + result->append(mimeTypes.at(k).toString().toLatin1()); + if (resultKeys) + resultKeys->append(key); + } + } + } +} + +QSharedPointer<QFactoryLoader> pluginLoader() +{ + loaderMutex()->lock(); + return QSharedPointer<QFactoryLoader>(loader(), [](QFactoryLoader *) { + loaderMutex()->unlock(); + }); +} + +static inline QImageIOPlugin::Capability pluginCapability(Capability cap) +{ + return cap == CanRead ? QImageIOPlugin::CanRead : QImageIOPlugin::CanWrite; +} + +#endif // QT_NO_IMAGEFORMATPLUGIN + +QList<QByteArray> supportedImageFormats(Capability cap) +{ + QList<QByteArray> formats; + formats.reserve(_qt_NumFormats); + for (int i = 0; i < _qt_NumFormats; ++i) + formats << _qt_BuiltInFormats[i].extension; + +#ifndef QT_NO_IMAGEFORMATPLUGIN + appendImagePluginFormats(loader(), pluginCapability(cap), &formats); +#endif // QT_NO_IMAGEFORMATPLUGIN + + std::sort(formats.begin(), formats.end()); + formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); + return formats; +} + +QList<QByteArray> supportedMimeTypes(Capability cap) +{ + QList<QByteArray> mimeTypes; + mimeTypes.reserve(_qt_NumFormats); + for (const auto &fmt : _qt_BuiltInFormats) + mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType); + +#ifndef QT_NO_IMAGEFORMATPLUGIN + appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes); +#endif // QT_NO_IMAGEFORMATPLUGIN + + std::sort(mimeTypes.begin(), mimeTypes.end()); + mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); + return mimeTypes; +} + +QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap) +{ + QList<QByteArray> formats; + if (mimeType.startsWith("image/")) { + const QByteArray type = mimeType.mid(sizeof("image/") - 1); + for (const auto &fmt : _qt_BuiltInFormats) { + if (fmt.mimeType == type && !formats.contains(fmt.extension)) + formats << fmt.extension; + } + } + +#ifndef QT_NO_IMAGEFORMATPLUGIN + QList<QByteArray> mimeTypes; + QList<QByteArray> keys; + appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes, &keys); + for (int i = 0; i < mimeTypes.size(); ++i) { + if (mimeTypes.at(i) == mimeType) { + const auto &key = keys.at(i); + if (!formats.contains(key)) + formats << key; + } + } +#endif // QT_NO_IMAGEFORMATPLUGIN + + return formats; +} + +} // QImageReaderWriterHelpers + +QT_END_NAMESPACE diff --git a/src/gui/image/qimagereaderwriterhelpers_p.h b/src/gui/image/qimagereaderwriterhelpers_p.h new file mode 100644 index 0000000000..6fe418a8ab --- /dev/null +++ b/src/gui/image/qimagereaderwriterhelpers_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIMAGEREADERWRITERHELPERS_P_H +#define QIMAGEREADERWRITERHELPERS_P_H + +#include <QtGui/private/qtguiglobal_p.h> +#include <qsharedpointer.h> +#include "qimageiohandler.h" + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QFactoryLoader; + +namespace QImageReaderWriterHelpers { + +enum _qt_BuiltInFormatType { +#ifndef QT_NO_IMAGEFORMAT_PNG + _qt_PngFormat, +#endif +#ifndef QT_NO_IMAGEFORMAT_BMP + _qt_BmpFormat, +#endif +#ifndef QT_NO_IMAGEFORMAT_PPM + _qt_PpmFormat, + _qt_PgmFormat, + _qt_PbmFormat, +#endif +#ifndef QT_NO_IMAGEFORMAT_XBM + _qt_XbmFormat, +#endif +#ifndef QT_NO_IMAGEFORMAT_XPM + _qt_XpmFormat, +#endif + _qt_NumFormats, + _qt_NoFormat = -1 +}; + +#if !defined(QT_NO_IMAGEFORMAT_PPM) +# define MAX_MT_SIZE 20 +#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM) +# define MAX_MT_SIZE 10 +#else +# define MAX_MT_SIZE 4 +#endif + +struct _qt_BuiltInFormatStruct +{ + char extension[4]; + char mimeType[MAX_MT_SIZE]; +}; + +#undef MAX_MT_SIZE + +static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = { +#ifndef QT_NO_IMAGEFORMAT_PNG + {"png", "png"}, +#endif +#ifndef QT_NO_IMAGEFORMAT_BMP + {"bmp", "bmp"}, +#endif +#ifndef QT_NO_IMAGEFORMAT_PPM + {"ppm", "x-portable-pixmap"}, + {"pgm", "x-portable-graymap"}, + {"pbm", "x-portable-bitmap"}, +#endif +#ifndef QT_NO_IMAGEFORMAT_XBM + {"xbm", "x-xbitmap"}, +#endif +#ifndef QT_NO_IMAGEFORMAT_XPM + {"xpm", "x-xpixmap"}, +#endif +}; +Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats); + +#ifndef QT_NO_IMAGEFORMATPLUGIN +QSharedPointer<QFactoryLoader> pluginLoader(); +#endif + +enum Capability { + CanRead, + CanWrite +}; +QList<QByteArray> supportedImageFormats(Capability cap); +QList<QByteArray> supportedMimeTypes(Capability cap); +QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap); + +} + +QT_END_NAMESPACE + +#endif // QIMAGEREADERWRITERHELPERS_P_H diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index a39d204677..30ec224158 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -102,7 +102,6 @@ #include <qfileinfo.h> #include <qimage.h> #include <qimageiohandler.h> -#include <qjsonarray.h> #include <qset.h> #include <qvariant.h> @@ -119,15 +118,12 @@ #include <private/qpnghandler_p.h> #endif +#include <private/qimagereaderwriterhelpers_p.h> + #include <algorithm> QT_BEGIN_NAMESPACE -#ifndef QT_NO_IMAGEFORMATPLUGIN -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) -#endif - static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, const QByteArray &format) { @@ -139,7 +135,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, typedef QMultiMap<int, QString> PluginKeyMap; // check if any plugins can write the image - QFactoryLoader *l = loader(); + auto l = QImageReaderWriterHelpers::pluginLoader(); const PluginKeyMap keyMap = l->keyMap(); int suffixPluginIndex = -1; #endif @@ -824,52 +820,6 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const return d->handler->supportsOption(option); } - -#ifndef QT_NO_IMAGEFORMATPLUGIN -void supportedImageHandlerFormats(QFactoryLoader *loader, - QImageIOPlugin::Capability cap, - QList<QByteArray> *result) -{ - typedef QMultiMap<int, QString> PluginKeyMap; - typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; - - const PluginKeyMap keyMap = loader->keyMap(); - const PluginKeyMapConstIterator cend = keyMap.constEnd(); - int i = -1; - QImageIOPlugin *plugin = 0; - result->reserve(result->size() + keyMap.size()); - for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) { - if (it.key() != i) { - i = it.key(); - plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i)); - } - const QByteArray key = it.value().toLatin1(); - if (plugin && (plugin->capabilities(0, key) & cap) != 0) - result->append(key); - } -} - -void supportedImageHandlerMimeTypes(QFactoryLoader *loader, - QImageIOPlugin::Capability cap, - QList<QByteArray> *result) -{ - QList<QJsonObject> metaDataList = loader->metaData(); - - const int pluginCount = metaDataList.size(); - for (int i = 0; i < pluginCount; ++i) { - const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject(); - const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray(); - const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray(); - QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i)); - const int keyCount = keys.size(); - for (int k = 0; k < keyCount; ++k) { - if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0) - result->append(mimeTypes.at(k).toString().toLatin1()); - } - } -} -#endif // QT_NO_IMAGEFORMATPLUGIN - /*! Returns the list of image formats supported by QImageWriter. @@ -897,30 +847,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, */ QList<QByteArray> QImageWriter::supportedImageFormats() { - QList<QByteArray> formats; -#ifndef QT_NO_IMAGEFORMAT_BMP - formats << "bmp"; -#endif -#ifndef QT_NO_IMAGEFORMAT_PPM - formats << "pbm" << "pgm" << "ppm"; -#endif -#ifndef QT_NO_IMAGEFORMAT_XBM - formats << "xbm"; -#endif -#ifndef QT_NO_IMAGEFORMAT_XPM - formats << "xpm"; -#endif -#ifndef QT_NO_IMAGEFORMAT_PNG - formats << "png"; -#endif - -#ifndef QT_NO_IMAGEFORMATPLUGIN - supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats); -#endif // QT_NO_IMAGEFORMATPLUGIN - - std::sort(formats.begin(), formats.end()); - formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); - return formats; + return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanWrite); } /*! @@ -933,32 +860,24 @@ QList<QByteArray> QImageWriter::supportedImageFormats() */ QList<QByteArray> QImageWriter::supportedMimeTypes() { - QList<QByteArray> mimeTypes; -#ifndef QT_NO_IMAGEFORMAT_BMP - mimeTypes << "image/bmp"; -#endif -#ifndef QT_NO_IMAGEFORMAT_PPM - mimeTypes << "image/x-portable-bitmap"; - mimeTypes << "image/x-portable-graymap"; - mimeTypes << "image/x-portable-pixmap"; -#endif -#ifndef QT_NO_IMAGEFORMAT_XBM - mimeTypes << "image/x-xbitmap"; -#endif -#ifndef QT_NO_IMAGEFORMAT_XPM - mimeTypes << "image/x-xpixmap"; -#endif -#ifndef QT_NO_IMAGEFORMAT_PNG - mimeTypes << "image/png"; -#endif + return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanWrite); +} -#ifndef QT_NO_IMAGEFORMATPLUGIN - supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes); -#endif // QT_NO_IMAGEFORMATPLUGIN +/*! + \since 5.12 - std::sort(mimeTypes.begin(), mimeTypes.end()); - mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); - return mimeTypes; + Returns the list of image formats corresponding to \mimeType. + + Note that the QGuiApplication instance must be created before this function is + called. + + \sa supportedImageFormats(), supportedMimeTypes() +*/ + +QList<QByteArray> QImageWriter::imageFormatsForMimeType(const QByteArray &mimeType) +{ + return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType, + QImageReaderWriterHelpers::CanWrite); } QT_END_NAMESPACE diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index fd1fdd07e8..29c06ccdd2 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -116,6 +116,7 @@ public: static QList<QByteArray> supportedImageFormats(); static QList<QByteArray> supportedMimeTypes(); + static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType); private: Q_DISABLE_COPY(QImageWriter) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 5b3e3985a7..4cd8befc1b 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -248,9 +248,9 @@ QPixmap::QPixmap(const char * const xpm[]) QImage image(xpm); if (!image.isNull()) { if (data && data->pixelType() == QPlatformPixmap::BitmapType) - *this = QBitmap::fromImage(image); + *this = QBitmap::fromImage(std::move(image)); else - *this = fromImage(image); + *this = fromImage(std::move(image)); } } #endif @@ -691,7 +691,7 @@ QBitmap QPixmap::createHeuristicMask(bool clipTight) const QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const { QImage image = toImage().convertToFormat(QImage::Format_ARGB32); - return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode)); + return QBitmap::fromImage(std::move(image).createMaskFromColor(maskColor.rgba(), mode)); } /*! @@ -1018,9 +1018,9 @@ QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap) if (image.isNull()) { pixmap = QPixmap(); } else if (image.depth() == 1) { - pixmap = QBitmap::fromImage(image); + pixmap = QBitmap::fromImage(std::move(image)); } else { - pixmap = QPixmap::fromImage(image); + pixmap = QPixmap::fromImage(std::move(image)); } return stream; } diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index 155a4f88b4..24d86e116d 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -241,7 +241,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const } } } -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#ifdef Q_CC_MSVC strcpy_s(p, sizeof(" };\n"), " };\n"); #else strcpy(p, " };\n"); diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index 9c54b9ada4..17272ffe69 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -741,10 +741,6 @@ static const struct XPMRGBData { { QRGB(139,139, 0), "yellow4" }, { QRGB(154,205, 50), "yellowgreen" } }; -#if defined(Q_CC_MSVC) && _MSC_VER < 1600 -inline bool operator<(const XPMRGBData &data1, const XPMRGBData &data2) -{ return qstrcmp(data1.name, data2.name) < 0; } -#endif inline bool operator<(const char *name, const XPMRGBData &data) { return qstrcmp(name, data.name) < 0; } diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h index f58dcf17f0..64b703e524 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -150,6 +150,7 @@ public: MacModelessLayout, AndroidLayout }; + Q_ENUM(ButtonLayout) QPlatformDialogHelper(); virtual ~QPlatformDialogHelper(); diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index a66420c364..a3046a9b44 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -340,6 +340,20 @@ void QPlatformWindow::setWindowFilePath(const QString &filePath) { Q_UNUSED(file void QPlatformWindow::setWindowIcon(const QIcon &icon) { Q_UNUSED(icon); } /*! + Reimplement to let the platform handle non-spontaneous window close. + + When reimplementing make sure to call the base class implementation + or QWindowSystemInterface::handleCloseEvent(), which will prompt the + user to accept the window close (if needed) and then close the QWindow. +*/ +bool QPlatformWindow::close() +{ + bool accepted = false; + QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window(), &accepted); + return accepted; +} + +/*! Reimplement to be able to let Qt raise windows to the top of the desktop */ void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); } diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 84dff681d5..bba6390694 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -100,6 +100,7 @@ public: virtual void setWindowTitle(const QString &title); virtual void setWindowFilePath(const QString &title); virtual void setWindowIcon(const QIcon &icon); + virtual bool close(); virtual void raise(); virtual void lower(); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 2c7e061bcf..5db740acb9 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2144,10 +2144,7 @@ bool QWindow::close() if (!d->platformWindow) return true; - bool accepted = false; - QWindowSystemInterface::handleCloseEvent(this, &accepted); - QWindowSystemInterface::flushWindowSystemEvents(); - return accepted; + return d->platformWindow->close(); } /*! diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 318a280a40..e5cd0be519 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -335,12 +335,12 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleExposeEvent, QWindow *window, const QReg QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); } -void QWindowSystemInterface::handleCloseEvent(QWindow *window, bool *accepted) +QT_DEFINE_QPA_EVENT_HANDLER(void, handleCloseEvent, QWindow *window, bool *accepted) { if (window) { QWindowSystemInterfacePrivate::CloseEvent *e = new QWindowSystemInterfacePrivate::CloseEvent(window, accepted); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); + QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); } } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index b22495f9d0..d584374fca 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -193,6 +193,7 @@ public: template<typename Delivery = QWindowSystemInterface::DefaultDelivery> static void handleExposeEvent(QWindow *window, const QRegion ®ion); + template<typename Delivery = QWindowSystemInterface::DefaultDelivery> static void handleCloseEvent(QWindow *window, bool *accepted = nullptr); template<typename Delivery = QWindowSystemInterface::DefaultDelivery> diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index b4657fa118..3a2393ea58 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -239,7 +239,7 @@ typedef unsigned long long int uint64_t; typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600)) +#elif defined(_WIN32) && (defined(__GNUC__) || defined(_MSC_VER)) #include <stdint.h> #elif defined(_WIN32) typedef __int32 int32_t; diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index c55bcb12c9..1d7375d1df 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -304,11 +304,6 @@ static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData); #undef rgb -#if defined(Q_CC_MSVC) && _MSC_VER < 1600 -inline bool operator<(const RGBData &data1, const RGBData &data2) -{ return qstrcmp(data1.name, data2.name) < 0; } -#endif - inline bool operator<(const char *name, const RGBData &data) { return qstrcmp(name, data.name) < 0; } inline bool operator<(const RGBData &data, const char *name) diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 1c7d6471b6..613a686848 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -42,6 +42,41 @@ QT_BEGIN_NAMESPACE +class QDummyPagedPaintDevicePrivate : public QPagedPaintDevicePrivate +{ + bool setPageLayout(const QPageLayout &newPageLayout) override + { + m_pageLayout = newPageLayout; + return m_pageLayout.isEquivalentTo(newPageLayout); + } + + bool setPageSize(const QPageSize &pageSize) override + { + m_pageLayout.setPageSize(pageSize); + return m_pageLayout.pageSize().isEquivalentTo(pageSize); + } + + bool setPageOrientation(QPageLayout::Orientation orientation) override + { + m_pageLayout.setOrientation(orientation); + return m_pageLayout.orientation() == orientation; + } + + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override + { + m_pageLayout.setUnits(units); + m_pageLayout.setMargins(margins); + return m_pageLayout.margins() == margins && m_pageLayout.units() == units; + } + + QPageLayout pageLayout() const override + { + return m_pageLayout; + } + + QPageLayout m_pageLayout; +}; + QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate() { } @@ -61,9 +96,11 @@ QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate() /*! Constructs a new paged paint device. + + \deprecated */ QPagedPaintDevice::QPagedPaintDevice() - : d(new QPagedPaintDevicePrivate) + : d(new QDummyPagedPaintDevicePrivate) { } @@ -263,7 +300,7 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd() */ void QPagedPaintDevice::setPageSize(PageSize size) { - d->m_pageLayout.setPageSize(QPageSize(QPageSize::PageSizeId(size))); + d->setPageSize(QPageSize(QPageSize::PageSizeId(size))); } /*! @@ -271,7 +308,7 @@ void QPagedPaintDevice::setPageSize(PageSize size) */ QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const { - return PageSize(d->m_pageLayout.pageSize().id()); + return PageSize(d->pageLayout().pageSize().id()); } /*! @@ -282,7 +319,7 @@ QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const */ void QPagedPaintDevice::setPageSizeMM(const QSizeF &size) { - d->m_pageLayout.setPageSize(QPageSize(size, QPageSize::Millimeter)); + d->setPageSize(QPageSize(size, QPageSize::Millimeter)); } /*! @@ -290,7 +327,7 @@ void QPagedPaintDevice::setPageSizeMM(const QSizeF &size) */ QSizeF QPagedPaintDevice::pageSizeMM() const { - return d->m_pageLayout.pageSize().size(QPageSize::Millimeter); + return d->pageLayout().pageSize().size(QPageSize::Millimeter); } /*! @@ -305,8 +342,7 @@ QSizeF QPagedPaintDevice::pageSizeMM() const */ void QPagedPaintDevice::setMargins(const Margins &margins) { - d->m_pageLayout.setUnits(QPageLayout::Millimeter); - d->m_pageLayout.setMargins(QMarginsF(margins.left, margins.top, margins.right, margins.bottom)); + d->setPageMargins(QMarginsF(margins.left, margins.top, margins.right, margins.bottom), QPageLayout::Millimeter); } /*! @@ -318,7 +354,7 @@ void QPagedPaintDevice::setMargins(const Margins &margins) */ QPagedPaintDevice::Margins QPagedPaintDevice::margins() const { - QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Millimeter); + QMarginsF margins = d->pageLayout().margins(QPageLayout::Millimeter); Margins result; result.left = margins.left(); result.top = margins.top(); @@ -413,7 +449,7 @@ bool QPagedPaintDevice::setPageOrientation(QPageLayout::Orientation orientation) bool QPagedPaintDevice::setPageMargins(const QMarginsF &margins) { - return d->setPageMargins(margins); + return setPageMargins(margins, pageLayout().units()); } /*! @@ -458,23 +494,30 @@ QPageLayout QPagedPaintDevice::pageLayout() const /*! \internal + \deprecated + Returns the internal device page layout. */ QPageLayout QPagedPaintDevice::devicePageLayout() const { - return d->m_pageLayout; + qWarning("QPagedPaintDevice::devicePageLayout() is deprecated, just use QPagedPaintDevice::pageLayout()"); + return d->pageLayout(); } /*! \internal + \deprecated + Returns the internal device page layout. */ QPageLayout &QPagedPaintDevice::devicePageLayout() { - return d->m_pageLayout; + qWarning("QPagedPaintDevice::devicePageLayout() is deprecated, you shouldn't be using this at all."); + static QPageLayout dummy; + return dummy; } QT_END_NAMESPACE diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h index 66dd6fa8cf..c8957edab8 100644 --- a/src/gui/painting/qpagedpaintdevice.h +++ b/src/gui/painting/qpagedpaintdevice.h @@ -55,7 +55,7 @@ class QPagedPaintDevicePrivate; class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice { public: - QPagedPaintDevice(); + QT_DEPRECATED QPagedPaintDevice(); ~QPagedPaintDevice(); virtual bool newPage() = 0; @@ -243,8 +243,8 @@ public: protected: QPagedPaintDevice(QPagedPaintDevicePrivate *dd); QPagedPaintDevicePrivate *dd(); - QPageLayout devicePageLayout() const; - QPageLayout &devicePageLayout(); + QT_DEPRECATED QPageLayout devicePageLayout() const; + QT_DEPRECATED QPageLayout &devicePageLayout(); friend class QPagedPaintDevicePrivate; QPagedPaintDevicePrivate *d; }; diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h index a993ea4cac..3a43bd7828 100644 --- a/src/gui/painting/qpagedpaintdevice_p.h +++ b/src/gui/painting/qpagedpaintdevice_p.h @@ -60,8 +60,7 @@ class Q_GUI_EXPORT QPagedPaintDevicePrivate { public: QPagedPaintDevicePrivate() - : m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0)), - fromPage(0), + : fromPage(0), toPage(0), pageOrderAscending(true), printSelectionOnly(false) @@ -70,46 +69,19 @@ public: virtual ~QPagedPaintDevicePrivate(); - // ### Qt6 Remove these and make public class methods virtual - virtual bool setPageLayout(const QPageLayout &newPageLayout) - { - m_pageLayout = newPageLayout; - return m_pageLayout.isEquivalentTo(newPageLayout);; - } - virtual bool setPageSize(const QPageSize &pageSize) - { - m_pageLayout.setPageSize(pageSize); - return m_pageLayout.pageSize().isEquivalentTo(pageSize); - } + virtual bool setPageLayout(const QPageLayout &newPageLayout) = 0; - virtual bool setPageOrientation(QPageLayout::Orientation orientation) - { - m_pageLayout.setOrientation(orientation); - return m_pageLayout.orientation() == orientation; - } + virtual bool setPageSize(const QPageSize &pageSize) = 0; - virtual bool setPageMargins(const QMarginsF &margins) - { - return setPageMargins(margins, m_pageLayout.units()); - } + virtual bool setPageOrientation(QPageLayout::Orientation orientation) = 0; - virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) - { - m_pageLayout.setUnits(units); - m_pageLayout.setMargins(margins); - return m_pageLayout.margins() == margins && m_pageLayout.units() == units; - } + virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) = 0; - virtual QPageLayout pageLayout() const - { - return m_pageLayout; - } + virtual QPageLayout pageLayout() const = 0; static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; } - QPageLayout m_pageLayout; - // These are currently required to keep QPrinter functionality working in QTextDocument::print() int fromPage; int toPage; diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index 2f24c7efcb..e6c5cabd7f 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -83,41 +83,28 @@ public: { // Try to set the paint engine page layout pd->engine->setPageLayout(newPageLayout); - // Set QPagedPaintDevice layout to match the current paint engine layout - m_pageLayout = pd->engine->pageLayout(); - return m_pageLayout.isEquivalentTo(newPageLayout); + return pageLayout().isEquivalentTo(newPageLayout); } bool setPageSize(const QPageSize &pageSize) override { // Try to set the paint engine page size pd->engine->setPageSize(pageSize); - // Set QPagedPaintDevice layout to match the current paint engine layout - m_pageLayout = pd->engine->pageLayout(); - return m_pageLayout.pageSize().isEquivalentTo(pageSize); + return pageLayout().pageSize().isEquivalentTo(pageSize); } bool setPageOrientation(QPageLayout::Orientation orientation) override { // Set the print engine value pd->engine->setPageOrientation(orientation); - // Set QPagedPaintDevice layout to match the current paint engine layout - m_pageLayout = pd->engine->pageLayout(); - return m_pageLayout.orientation() == orientation; - } - - bool setPageMargins(const QMarginsF &margins) override - { - return setPageMargins(margins, pageLayout().units()); + return pageLayout().orientation() == orientation; } bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override { // Try to set engine margins pd->engine->setPageMargins(margins, units); - // Set QPagedPaintDevice layout to match the current paint engine layout - m_pageLayout = pd->engine->pageLayout(); - return m_pageLayout.margins() == margins && m_pageLayout.units() == units; + return pageLayout().margins() == margins && pageLayout().units() == units; } QPageLayout pageLayout() const override @@ -150,9 +137,6 @@ QPdfWriter::QPdfWriter(const QString &filename) Q_D(QPdfWriter); d->engine->setOutputFilename(filename); - - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); } /*! @@ -165,9 +149,6 @@ QPdfWriter::QPdfWriter(QIODevice *device) Q_D(QPdfWriter); d->engine->d_func()->outDevice = device; - - // Set QPagedPaintDevice layout to match the current paint engine layout - devicePageLayout() = d->engine->pageLayout(); } /*! diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 64adeaa260..70623939e1 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -345,13 +345,6 @@ static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = { { "none", StyleFeature_None } }; -#if defined(Q_CC_MSVC) && _MSC_VER < 1600 -static bool operator<(const QCssKnownValue &prop1, const QCssKnownValue &prop2) -{ - return QString::compare(QString::fromLatin1(prop1.name), QLatin1String(prop2.name), Qt::CaseInsensitive) < 0; -} -#endif - static bool operator<(const QString &name, const QCssKnownValue &prop) { return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 9877a23fa6..d04dd08058 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -399,26 +399,6 @@ static bool operator<(const QCheckPoint &checkPoint, int pos) return checkPoint.positionInFrame < pos; } -#if defined(Q_CC_MSVC) && _MSC_VER < 1600 -//The STL implementation of MSVC 2008 requires the definitions - -static bool operator<(const QCheckPoint &checkPoint1, const QCheckPoint &checkPoint2) -{ - return checkPoint1.y < checkPoint2.y; -} - -static bool operator<(QFixed y, const QCheckPoint &checkPoint) -{ - return y < checkPoint.y; -} - -static bool operator<(int pos, const QCheckPoint &checkPoint) -{ - return pos < checkPoint.positionInFrame; -} - -#endif - static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, const QPointF &origin, const QRectF &gradientRect = QRectF()) { p->save(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 5e38311fa1..99d0fe20eb 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3652,11 +3652,12 @@ int QTextEngine::lineNumberForTextPosition(int pos) return -1; } -void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints) +std::vector<int> QTextEngine::insertionPointsForLine(int lineNum) { QTextLineItemIterator iterator(this, lineNum); - insertionPoints.reserve(iterator.line.length); + std::vector<int> insertionPoints; + insertionPoints.reserve(size_t(iterator.line.length)); bool lastLine = lineNum >= lines.size() - 1; @@ -3674,25 +3675,22 @@ void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoi insertionPoints.push_back(i); } } + return insertionPoints; } int QTextEngine::endOfLine(int lineNum) { - QVector<int> insertionPoints; - insertionPointsForLine(lineNum, insertionPoints); - + const auto insertionPoints = insertionPointsForLine(lineNum); if (insertionPoints.size() > 0) - return insertionPoints.constLast(); + return insertionPoints.back(); return 0; } int QTextEngine::beginningOfLine(int lineNum) { - QVector<int> insertionPoints; - insertionPointsForLine(lineNum, insertionPoints); - + const auto insertionPoints = insertionPointsForLine(lineNum); if (insertionPoints.size() > 0) - return insertionPoints.constFirst(); + return insertionPoints.front(); return 0; } @@ -3709,10 +3707,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation if (lineNum < 0) return pos; - QVector<int> insertionPoints; - insertionPointsForLine(lineNum, insertionPoints); - int i, max = insertionPoints.size(); - for (i = 0; i < max; i++) + const auto insertionPoints = insertionPointsForLine(lineNum); + for (size_t i = 0, max = insertionPoints.size(); i < max; ++i) if (pos == insertionPoints[i]) { if (moveRight) { if (i + 1 < max) diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index f9eb055478..42061deff5 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -74,6 +74,7 @@ #include <private/qunicodetools_p.h> #include <stdlib.h> +#include <vector> QT_BEGIN_NAMESPACE @@ -632,7 +633,7 @@ public: int nextLogicalPosition(int oldPos) const; int lineNumberForTextPosition(int pos); int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op); - void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints); + std::vector<int> insertionPointsForLine(int lineNum); void resetFontEngineCache(); void enableDelayDecorations(bool enable = true) { delayDecorations = enable; } diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 9154182df1..4be800b251 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -448,13 +448,6 @@ static const QTextHtmlElement elements[Html_NumElements]= { { "var", Html_var, QTextHtmlElement::DisplayInline }, }; -#if defined(Q_CC_MSVC) && _MSC_VER < 1600 -static bool operator<(const QTextHtmlElement &e1, const QTextHtmlElement &e2) -{ - return QLatin1String(e1.name) < QLatin1String(e2.name); -} -#endif - static bool operator<(const QString &str, const QTextHtmlElement &e) { return str < QLatin1String(e.name); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 6e824b2ed1..cd1990dfb9 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1006,10 +1006,8 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo } if (lastSelectionWidth > 0) { - QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); - rect.moveLeft(qFloor(rect.left())); - rect.moveTop(qFloor(rect.top())); - region->addRect(rect); + const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); + region->addRect(rect.toAlignedRect()); } lastSelectionX = selectionX; @@ -1017,10 +1015,8 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo } } if (lastSelectionWidth > 0) { - QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); - rect.moveLeft(qFloor(rect.left())); - rect.moveTop(qFloor(rect.top())); - region->addRect(rect); + const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); + region->addRect(rect.toAlignedRect()); } } @@ -2135,7 +2131,7 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q QBrush bg = chf.background(); if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool()) - p->fillRect(QRectF(qFloor(r.x()), qFloor(r.y()), r.width(), r.height()), bg); + p->fillRect(r.toAlignedRect(), bg); if (c.style() != Qt::NoBrush) { p->setPen(QPen(c, 0)); } @@ -2845,9 +2841,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const bool rtl = eng->isRightToLeft(); eng->shapeLine(line); - QVector<int> insertionPoints; - if (visual && rtl) - eng->insertionPointsForLine(lineNum, insertionPoints); + const auto insertionPoints = (visual && rtl) ? eng->insertionPointsForLine(lineNum) : std::vector<int>(); int nchars = 0; for (int i = 0; i < nItems; ++i) { int item = visualOrder[i]+firstItem; @@ -2979,7 +2973,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const continue; } if (rtl && nchars > 0) - return insertionPoints[lastLine ? nchars : nchars - 1]; + return insertionPoints[size_t(lastLine ? nchars : nchars - 1)]; } return eng->positionInLigature(&si, end, x, pos, -1, cpos == QTextLine::CursorOnCharacter); diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index c5404e4221..269845ed39 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -102,8 +102,8 @@ public: }; QNetworkAccessFtpBackend::QNetworkAccessFtpBackend() - : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), - supportsSize(false), supportsMdtm(false), state(Idle) + : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1), + supportsSize(false), supportsMdtm(false), supportsPwd(false), state(Idle) { } @@ -302,13 +302,38 @@ void QNetworkAccessFtpBackend::ftpDone() if (state == LoggingIn) { state = CheckingFeatures; - if (operation() == QNetworkAccessManager::GetOperation) { - // send help command to find out if server supports "SIZE" and "MDTM" + // send help command to find out if server supports SIZE, MDTM, and PWD + if (operation() == QNetworkAccessManager::GetOperation + || operation() == QNetworkAccessManager::PutOperation) { helpId = ftp->rawCommand(QLatin1String("HELP")); // get supported commands } else { ftpDone(); } } else if (state == CheckingFeatures) { + // If a URL path starts with // prefix (/%2F decoded), the resource will + // be retrieved by an absolute path starting with the root directory. + // For the other URLs, the working directory is retrieved by PWD command + // and prepended to the resource path as an absolute path starting with + // the working directory. + state = ResolvingPath; + QString path = url().path(); + if (path.startsWith(QLatin1String("//")) || supportsPwd == false) { + ftpDone(); // no commands sent, move to the next state + } else { + // If a path starts with /~/ prefix, its prefix will be replaced by + // the working directory as an absolute path starting with working + // directory. + if (path.startsWith(QLatin1String("/~/"))) { + // Remove leading /~ symbols + QUrl newUrl = url(); + newUrl.setPath(path.mid(2)); + setUrl(newUrl); + } + + // send PWD command to retrieve the working directory + pwdId = ftp->rawCommand(QLatin1String("PWD")); + } + } else if (state == ResolvingPath) { state = Statting; if (operation() == QNetworkAccessManager::GetOperation) { // logged in successfully, send the stat requests (if supported) @@ -366,6 +391,34 @@ void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text) supportsSize = true; if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive)) supportsMdtm = true; + if (text.contains(QLatin1String("PWD"), Qt::CaseSensitive)) + supportsPwd = true; + } else if (id == pwdId && code == 257) { + QString pwdPath; + int startIndex = text.indexOf('"'); + int stopIndex = text.lastIndexOf('"'); + if (stopIndex - startIndex) { + // The working directory is a substring between \" symbols. + startIndex++; // skip the first \" symbol + pwdPath = text.mid(startIndex, stopIndex - startIndex); + } else { + // If there is no or only one \" symbol, use all the characters of + // text. + pwdPath = text; + } + + // If a URL path starts with the working directory prefix, its resource + // will be retrieved from the working directory. Otherwise, the path of + // the working directory is prepended to the resource path. + QString urlPath = url().path(); + if (!urlPath.startsWith(pwdPath)) { + if (pwdPath.endsWith(QLatin1Char('/'))) + pwdPath.chop(1); + // Prepend working directory to the URL path + QUrl newUrl = url(); + newUrl.setPath(pwdPath % urlPath); + setUrl(newUrl); + } } else if (code == 213) { // file status if (id == sizeId) { // reply to the size command diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h index 4bd082fb67..0b3d35dcd3 100644 --- a/src/network/access/qnetworkaccessftpbackend_p.h +++ b/src/network/access/qnetworkaccessftpbackend_p.h @@ -76,6 +76,7 @@ public: //Connecting, LoggingIn, CheckingFeatures, + ResolvingPath, Statting, Transferring, Disconnecting @@ -107,8 +108,8 @@ private: QPointer<QNetworkAccessCachedFtpConnection> ftp; QIODevice *uploadDevice; qint64 totalBytes; - int helpId, sizeId, mdtmId; - bool supportsSize, supportsMdtm; + int helpId, sizeId, mdtmId, pwdId; + bool supportsSize, supportsMdtm, supportsPwd; State state; }; diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 09901ba0a5..caa2ccc6e5 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -536,13 +536,13 @@ QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList // Read RTF into to NSAttributedString, then convert the string to HTML NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.at(0).toNSData() - options:[NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + options:@{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType} documentAttributes:nil error:nil]; NSError *error; NSRange range = NSMakeRange(0, [string length]); - NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSDictionary *dict = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSData *htmlData = [string dataFromRange:range documentAttributes:dict error:&error]; return QByteArray::fromNSData(htmlData); } @@ -554,13 +554,13 @@ QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime return ret; NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.toByteArray().toNSData() - options:[NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil]; NSError *error; NSRange range = NSMakeRange(0, [string length]); - NSDictionary *dict = [NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSDictionary *dict = @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}; NSData *rtfData = [string dataFromRange:range documentAttributes:dict error:&error]; ret << QByteArray::fromNSData(rtfData); return ret; @@ -853,8 +853,8 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q QImage img = qvariant_cast<QImage>(variant); NSDictionary *props = @{ - static_cast<NSString *>(kCGImagePropertyPixelWidth) : [NSNumber numberWithInt:img.width()], - static_cast<NSString *>(kCGImagePropertyPixelHeight) : [NSNumber numberWithInt:img.height()] + static_cast<NSString *>(kCGImagePropertyPixelWidth): @(img.width()), + static_cast<NSString *>(kCGImagePropertyPixelHeight): @(img.height()) }; CGImageDestinationAddImage(imageDestination, qt_mac_toCGImage(img), static_cast<CFDictionaryRef>(props)); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 5eb5cd8a30..85d213ad46 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -101,14 +101,14 @@ enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) } #ifdef Q_OS_OSX static NSInteger languageMapSort(id obj1, id obj2, void *context) { - NSArray *map1 = (NSArray *) obj1; - NSArray *map2 = (NSArray *) obj2; - NSArray *languages = (NSArray *) context; + NSArray<NSString *> *map1 = reinterpret_cast<NSArray<NSString *> *>(obj1); + NSArray<NSString *> *map2 = reinterpret_cast<NSArray<NSString *> *>(obj2); + NSArray<NSString *> *languages = reinterpret_cast<NSArray<NSString *> *>(context); - NSString *lang1 = [map1 objectAtIndex: 0]; - NSString *lang2 = [map2 objectAtIndex: 0]; + NSString *lang1 = [map1 objectAtIndex:0]; + NSString *lang2 = [map2 objectAtIndex:0]; - return [languages indexOfObject: lang1] - [languages indexOfObject: lang2]; + return [languages indexOfObject:lang1] - [languages indexOfObject:lang2]; } #endif @@ -184,23 +184,9 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase() CFRelease(ref); } -static CFArrayRef availableFamilyNames() -{ -#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(1060, 100000, 100000, 30000) - if (&CTFontManagerCopyAvailableFontFamilyNames) - return CTFontManagerCopyAvailableFontFamilyNames(); -#endif -#if defined(QT_PLATFORM_UIKIT) - CFMutableArrayRef familyNames = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, (CFArrayRef)[UIFont familyNames]); - CFArrayAppendValue(familyNames, CFSTR(".PhoneFallback")); - return familyNames; -#endif - Q_UNREACHABLE(); -} - void QCoreTextFontDatabase::populateFontDatabase() { - QCFType<CFArrayRef> familyNames = availableFamilyNames(); + QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames(); for (NSString *familyName in familyNames.as<const NSArray *>()) QPlatformFontDatabase::registerFontFamily(QString::fromNSString(familyName)); @@ -220,7 +206,7 @@ bool QCoreTextFontDatabase::populateFamilyAliases() if (m_hasPopulatedAliases) return false; - QCFType<CFArrayRef> familyNames = availableFamilyNames(); + QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames(); for (NSString *familyName in familyNames.as<const NSArray *>()) { NSFontManager *fontManager = [NSFontManager sharedFontManager]; NSString *localizedFamilyName = [fontManager localizedNameForFamily:familyName face:nil]; @@ -570,21 +556,21 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo if (!didPopulateStyleFallbacks) { #if defined(Q_OS_MACX) NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"]; + NSArray<NSString *> *languages = [defaults stringArrayForKey:@"AppleLanguages"]; - NSDictionary *fallbackDict = [NSDictionary dictionaryWithContentsOfFile: @"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"]; + NSDictionary<NSString *, id> *fallbackDict = [NSDictionary<NSString *, id> dictionaryWithContentsOfFile:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"]; for (NSString *style in [fallbackDict allKeys]) { - NSArray *list = [fallbackDict valueForKey: style]; + NSArray *list = [fallbackDict valueForKey:style]; QFont::StyleHint fallbackStyleHint = styleHintFromNSString(style); QStringList fallbackList; for (id item in list) { // sort the array based on system language preferences - if ([item isKindOfClass: [NSArray class]]) { - NSArray *langs = [(NSArray *) item sortedArrayUsingFunction: languageMapSort - context: languages]; - for (NSArray *map in langs) - fallbackList.append(familyNameFromPostScriptName([map objectAtIndex: 1])); + if ([item isKindOfClass:[NSArray class]]) { + NSArray *langs = [reinterpret_cast<NSArray *>(item) + sortedArrayUsingFunction:languageMapSort context:languages]; + for (NSArray<NSString *> *map in langs) + fallbackList.append(familyNameFromPostScriptName([map objectAtIndex:1])); } else if ([item isKindOfClass: [NSString class]]) fallbackList.append(familyNameFromPostScriptName(item)); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 341d3bccf2..c3dd49ff3e 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -62,33 +62,29 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time #include <ifaddrs.h> @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject <CWEventDelegate> -{ - NSNotificationCenter *notificationCenter; - CWWiFiClient *client; - QCoreWlanEngine *engine; - NSLock *locker; -} -- (void)powerStateDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName; -- (void)remove; -- (void)setEngine:(QCoreWlanEngine *)coreEngine; -- (QCoreWlanEngine *)engine; -- (void)dealloc; @property (assign) QCoreWlanEngine* engine; @end -@implementation QT_MANGLE_NAMESPACE(QNSListener) +@implementation QT_MANGLE_NAMESPACE(QNSListener) { + NSNotificationCenter *notificationCenter; + CWWiFiClient *client; + QCoreWlanEngine *engine; + NSLock *locker; +} -- (id) init +- (instancetype)init { - [locker lock]; - QMacAutoReleasePool pool; - notificationCenter = [NSNotificationCenter defaultCenter]; - client = [CWWiFiClient sharedWiFiClient]; - client.delegate = self; - [client startMonitoringEventWithType:CWEventTypePowerDidChange error:nil]; - [locker unlock]; + if ((self = [super init])) { + [locker lock]; + QMacAutoReleasePool pool; + notificationCenter = [NSNotificationCenter defaultCenter]; + client = [CWWiFiClient sharedWiFiClient]; + client.delegate = self; + [client startMonitoringEventWithType:CWEventTypePowerDidChange error:nil]; + [locker unlock]; + } return self; } @@ -300,7 +296,7 @@ void QScanThread::getUserConfigurations() if(airportPlist != nil) { NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; - NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"]; + NSArray<NSString *> *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"]; for (NSString *ssidkey in thisSsidarray) { QString thisSsid = QString::fromNSString(ssidkey); if(!userProfiles.contains(thisSsid)) { diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index e456364555..457c158ddc 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -46,6 +46,8 @@ #ifndef QT_NO_ACCESSIBILITY +@class QT_MANGLE_NAMESPACE(QMacAccessibilityElement); + QT_BEGIN_NAMESPACE class QCocoaAccessibility : public QPlatformAccessibility @@ -82,9 +84,8 @@ namespace QCocoaAccessible { NSString *macRole(QAccessibleInterface *interface); NSString *macSubrole(QAccessibleInterface *interface); bool shouldBeIgnored(QAccessibleInterface *interface); -NSArray *unignoredChildren(QAccessibleInterface *interface); +NSArray<QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *> *unignoredChildren(QAccessibleInterface *interface); NSString *getTranslatedAction(const QString &qtAction); -NSMutableArray *createTranslatedActionsList(const QStringList &qtActions); QString translateAction(NSString *nsAction, QAccessibleInterface *interface); bool hasValueAttribute(QAccessibleInterface *interface); id getValueAttribute(QAccessibleInterface *interface); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 8b6dcb35a6..0a773ced29 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -257,12 +257,12 @@ bool shouldBeIgnored(QAccessibleInterface *interface) return false; } -NSArray *unignoredChildren(QAccessibleInterface *interface) +NSArray<QMacAccessibilityElement *> *unignoredChildren(QAccessibleInterface *interface) { int numKids = interface->childCount(); // qDebug() << "Children for: " << axid << iface << " are: " << numKids; - NSMutableArray *kids = [NSMutableArray arrayWithCapacity:numKids]; + NSMutableArray<QMacAccessibilityElement *> *kids = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:numKids]; for (int i = 0; i < numKids; ++i) { QAccessibleInterface *child = interface->child(i); if (!child || !child->isValid() || child->state().invalid || child->state().invisible) @@ -387,7 +387,7 @@ id getValueAttribute(QAccessibleInterface *interface) } if (interface->state().checkable) { - return [NSNumber numberWithInt: (interface->state().checked ? 1 : 0)]; + return interface->state().checked ? @(1) : @(0); } return nil; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h index 07f3f3a99e..914aaa2b1b 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h @@ -52,13 +52,10 @@ @class QT_MANGLE_NAMESPACE(QMacAccessibilityElement); -@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject { - NSString *role; - QAccessible::Id axid; -} +@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject -- (id)initWithId:(QAccessible::Id)anId; -+ (QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *)elementWithId:(QAccessible::Id)anId; +- (instancetype)initWithId:(QAccessible::Id)anId; ++ (instancetype)elementWithId:(QAccessible::Id)anId; @end diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index df2336d08b..ad251a6a44 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -99,9 +99,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of *end = curEnd; } -@implementation QMacAccessibilityElement +@implementation QMacAccessibilityElement { + NSString *role; + QAccessible::Id axid; +} -- (id)initWithId:(QAccessible::Id)anId +- (instancetype)initWithId:(QAccessible::Id)anId { Q_ASSERT((int)anId < 0); self = [super init]; @@ -115,7 +118,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return self; } -+ (id)elementWithId:(QAccessible::Id)anId ++ (instancetype)elementWithId:(QAccessible::Id)anId { Q_ASSERT(anId); if (!anId) @@ -168,22 +171,15 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of { QStringRef textBefore = QStringRef(&text, 0, index); int newlines = textBefore.count(QLatin1Char('\n')); - return [NSNumber numberWithInt: newlines]; + return @(newlines); } - (BOOL) accessibilityNotifiesWhenDestroyed { return YES; } -- (NSArray *)accessibilityAttributeNames { - static NSArray *defaultAttributes = nil; - - QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface || !iface->isValid()) - return defaultAttributes; - - if (defaultAttributes == nil) { - defaultAttributes = [[NSArray alloc] initWithObjects: +- (NSArray<NSString *> *)accessibilityAttributeNames { + static NSArray<NSString *> *defaultAttributes = [@[ NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilitySubroleAttribute, @@ -196,35 +192,36 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of NSAccessibilitySizeAttribute, NSAccessibilityTitleAttribute, NSAccessibilityDescriptionAttribute, - NSAccessibilityEnabledAttribute, - nil]; - } + NSAccessibilityEnabledAttribute + ] retain]; + + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return defaultAttributes; - NSMutableArray *attributes = [[NSMutableArray alloc] initWithCapacity : [defaultAttributes count]]; - [attributes addObjectsFromArray : defaultAttributes]; + NSMutableArray<NSString *> *attributes = [[NSMutableArray<NSString *> alloc] initWithCapacity:defaultAttributes.count]; + [attributes addObjectsFromArray:defaultAttributes]; if (QCocoaAccessible::hasValueAttribute(iface)) { - [attributes addObject : NSAccessibilityValueAttribute]; + [attributes addObject:NSAccessibilityValueAttribute]; } if (iface->textInterface()) { - [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects: + [attributes addObjectsFromArray:@[ NSAccessibilityNumberOfCharactersAttribute, NSAccessibilitySelectedTextAttribute, NSAccessibilitySelectedTextRangeAttribute, NSAccessibilityVisibleCharacterRangeAttribute, - NSAccessibilityInsertionPointLineNumberAttribute, - nil + NSAccessibilityInsertionPointLineNumberAttribute ]]; // TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute, } if (iface->valueInterface()) { - [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects: + [attributes addObjectsFromArray:@[ NSAccessibilityMinValueAttribute, - NSAccessibilityMaxValueAttribute, - nil + NSAccessibilityMaxValueAttribute ]]; } @@ -261,13 +258,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id) minValueAttribute:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) - return [NSNumber numberWithDouble: val->minimumValue().toDouble()]; + return @(val->minimumValue().toDouble()); return nil; } - (id) maxValueAttribute:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) - return [NSNumber numberWithDouble: val->maximumValue().toDouble()]; + return @(val->maximumValue().toDouble()); return nil; } @@ -289,7 +286,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { // Just check if the app thinks we're focused. id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; - return [NSNumber numberWithBool:[focusedElement isEqual:self]]; + return @([focusedElement isEqual:self]); } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { return NSAccessibilityUnignoredAncestor([self parentElement]); } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { @@ -312,7 +309,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { return iface->text(QAccessible::Description).toNSString(); } else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) { - return [NSNumber numberWithBool:!iface->state().disabled]; + return @(!iface->state().disabled); } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { // VoiceOver asks for the value attribute for all elements. Return nil // if we don't want the element to have a value attribute. @@ -323,7 +320,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) - return [NSNumber numberWithInt: text->characterCount()]; + return @(text->characterCount()); return nil; } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { @@ -357,7 +354,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of int position = text->cursorPosition(); convertLineOffset(text, &line, &position); } - return [NSNumber numberWithInt: line]; + return @(line); } return nil; } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { @@ -378,18 +375,17 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } if (iface->textInterface()) { - return [[NSArray alloc] initWithObjects: - NSAccessibilityStringForRangeParameterizedAttribute, - NSAccessibilityLineForIndexParameterizedAttribute, - NSAccessibilityRangeForLineParameterizedAttribute, - NSAccessibilityRangeForPositionParameterizedAttribute, -// NSAccessibilityRangeForIndexParameterizedAttribute, - NSAccessibilityBoundsForRangeParameterizedAttribute, -// NSAccessibilityRTFForRangeParameterizedAttribute, - NSAccessibilityStyleRangeForIndexParameterizedAttribute, - NSAccessibilityAttributedStringForRangeParameterizedAttribute, - nil - ]; + return @[ + NSAccessibilityStringForRangeParameterizedAttribute, + NSAccessibilityLineForIndexParameterizedAttribute, + NSAccessibilityRangeForLineParameterizedAttribute, + NSAccessibilityRangeForPositionParameterizedAttribute, +// NSAccessibilityRangeForIndexParameterizedAttribute, + NSAccessibilityBoundsForRangeParameterizedAttribute, +// NSAccessibilityRTFForRangeParameterizedAttribute, + NSAccessibilityStyleRangeForIndexParameterizedAttribute, + NSAccessibilityAttributedStringForRangeParameterizedAttribute + ]; } return nil; @@ -416,7 +412,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return nil; int line = -1; convertLineOffset(iface->textInterface(), &line, &index); - return [NSNumber numberWithInt:line]; + return @(line); } if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) { int line = [parameter intValue]; diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h index 66a92686bc..15530d8281 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.h +++ b/src/plugins/platforms/cocoa/qcocoaapplication.h @@ -89,8 +89,7 @@ #import <AppKit/AppKit.h> -@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication { -} +@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSApplication); diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h index 59c71017e3..3073cb6b44 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h @@ -92,18 +92,12 @@ @class QT_MANGLE_NAMESPACE(QCocoaMenuLoader); -@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> { - bool startedQuit; - NSMenu *dockMenu; - NSObject <NSApplicationDelegate> *reflectionDelegate; - bool inLaunch; -} -+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate; +@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> ++ (instancetype)sharedDelegate; - (void)setDockMenu:(NSMenu *)newMenu; -- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate; -- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; -- (void) removeAppleEventHandlers; -- (bool) inLaunch; +- (void)setReflectionDelegate:(NSObject<NSApplicationDelegate> *)oldDelegate; +- (void)removeAppleEventHandlers; +- (bool)inLaunch; @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate); diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index a94e0dc517..53407d8b62 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -73,7 +73,6 @@ #import "qcocoaapplicationdelegate.h" -#import "qnswindowdelegate.h" #import "qcocoamenuloader.h" #include "qcocoaintegration.h" #include <qevent.h> @@ -86,7 +85,12 @@ QT_USE_NAMESPACE -@implementation QCocoaApplicationDelegate +@implementation QCocoaApplicationDelegate { + bool startedQuit; + NSMenu *dockMenu; + NSObject <NSApplicationDelegate> *reflectionDelegate; + bool inLaunch; +} + (instancetype)sharedDelegate { @@ -102,7 +106,7 @@ QT_USE_NAMESPACE return shared; } -- (id)init +- (instancetype)init { self = [super init]; if (self) { @@ -151,7 +155,7 @@ QT_USE_NAMESPACE return [[dockMenu retain] autorelease]; } -- (BOOL) canQuit +- (BOOL)canQuit { [[NSApp mainMenu] cancelTracking]; @@ -219,7 +223,7 @@ QT_USE_NAMESPACE return NSTerminateCancel; } -- (void) applicationWillFinishLaunching:(NSNotification *)notification +- (void)applicationWillFinishLaunching:(NSNotification *)notification { Q_UNUSED(notification); @@ -249,14 +253,14 @@ QT_USE_NAMESPACE } // called by QCocoaIntegration's destructor before resetting the application delegate to nil -- (void) removeAppleEventHandlers +- (void)removeAppleEventHandlers { NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager]; [eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication]; [eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL]; } -- (bool) inLaunch +- (bool)inLaunch { return inLaunch; } diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index aa6124507d..0e127902ae 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -50,7 +50,14 @@ QT_USE_NAMESPACE @interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate> -{ +- (void)restoreOriginalContentView; +- (void)updateQtColor; +- (void)finishOffWithCode:(NSInteger)code; +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); + +@implementation QNSColorPanelDelegate { @public NSColorPanel *mColorPanel; QCocoaColorDialogHelper *mHelper; @@ -61,17 +68,9 @@ QT_USE_NAMESPACE BOOL mDialogIsExecuting; BOOL mResultSet; BOOL mClosingDueToKnownButton; -}; -- (void)restoreOriginalContentView; -- (void)updateQtColor; -- (void)finishOffWithCode:(NSInteger)code; -@end - -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - -@implementation QNSColorPanelDelegate +} -- (id)init +- (instancetype)init { self = [super init]; mColorPanel = [NSColorPanel sharedColorPanel]; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 94f2125bad..55c4e51242 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -81,23 +81,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; @interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) : NSObject<NSOpenSavePanelDelegate> -{ - @public - NSOpenPanel *mOpenPanel; - NSSavePanel *mSavePanel; - NSView *mAccessoryView; - NSPopUpButton *mPopUpButton; - NSTextField *mTextField; - QCocoaFileDialogHelper *mHelper; - NSString *mCurrentDir; - - int mReturnCode; - - SharedPointerFileDialogOptions mOptions; - QString *mCurrentSelection; - QStringList *mNameFilterDropDownList; - QStringList *mSelectedNameFilter; -} - (NSString *)strip:(const QString &)label; - (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url; @@ -117,12 +100,27 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); -@implementation QNSOpenSavePanelDelegate +@implementation QNSOpenSavePanelDelegate { + @public + NSOpenPanel *mOpenPanel; + NSSavePanel *mSavePanel; + NSView *mAccessoryView; + NSPopUpButton *mPopUpButton; + NSTextField *mTextField; + QCocoaFileDialogHelper *mHelper; + NSString *mCurrentDir; + + int mReturnCode; + + SharedPointerFileDialogOptions mOptions; + QString *mCurrentSelection; + QStringList *mNameFilterDropDownList; + QStringList *mSelectedNameFilter; +} -- (id)initWithAcceptMode: - (const QString &)selectFile - options:(SharedPointerFileDialogOptions)options - helper:(QCocoaFileDialogHelper *)helper +- (instancetype)initWithAcceptMode:(const QString &)selectFile + options:(SharedPointerFileDialogOptions)options + helper:(QCocoaFileDialogHelper *)helper { self = [super init]; mOptions = options; @@ -406,9 +404,9 @@ static QString strippedText(QString s) { if (mOpenPanel) { QList<QUrl> result; - NSArray* array = [mOpenPanel URLs]; - for (NSUInteger i=0; i<[array count]; ++i) { - QString path = QString::fromNSString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C); + NSArray<NSURL *> *array = [mOpenPanel URLs]; + for (NSURL *url in array) { + QString path = QString::fromNSString(url.path).normalized(QString::NormalizationForm_C); result << QUrl::fromLocalFile(path); } return result; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 9a96895d07..3010aa0870 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -76,7 +76,15 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) @class QT_MANGLE_NAMESPACE(QNSFontPanelDelegate); @interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate> -{ +- (void)restoreOriginalContentView; +- (void)updateQtFont; +- (void)changeFont:(id)sender; +- (void)finishOffWithCode:(NSInteger)code; +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); + +@implementation QNSFontPanelDelegate { @public NSFontPanel *mFontPanel; QCocoaFontDialogHelper *mHelper; @@ -86,33 +94,25 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) NSInteger mResultCode; BOOL mDialogIsExecuting; BOOL mResultSet; -}; -- (void)restoreOriginalContentView; -- (void)updateQtFont; -- (void)changeFont:(id)sender; -- (void)finishOffWithCode:(NSInteger)code; -@end - -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); - -@implementation QNSFontPanelDelegate +} -- (id)init +- (instancetype)init { - self = [super init]; - mFontPanel = [NSFontPanel sharedFontPanel]; - mHelper = 0; - mStolenContentView = 0; - mPanelButtons = 0; - mResultCode = NSModalResponseCancel; - mDialogIsExecuting = false; - mResultSet = false; + if ((self = [super init])) { + mFontPanel = [NSFontPanel sharedFontPanel]; + mHelper = 0; + mStolenContentView = 0; + mPanelButtons = 0; + mResultCode = NSModalResponseCancel; + mDialogIsExecuting = false; + mResultSet = false; - [mFontPanel setRestorable:NO]; - [mFontPanel setDelegate:self]; - [[NSFontManager sharedFontManager] setDelegate:self]; + [mFontPanel setRestorable:NO]; + [mFontPanel setDelegate:self]; + [[NSFontManager sharedFontManager] setDelegate:self]; - [mFontPanel retain]; + [mFontPanel retain]; + } return self; } diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 84632c1487..7fd8715277 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -70,11 +70,8 @@ class QPixmap; class QString; // Conversion functions -QStringList qt_mac_NSArrayToQStringList(void *nsarray); -void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); - -inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) -{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); } +QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *nsarray); +NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list); NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); @@ -170,12 +167,7 @@ QT_END_NAMESPACE - (void)onCancelClicked; @end -@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView { - NSButton *_okButton; - NSButton *_cancelButton; - NSView *_panelContents; - NSEdgeInsets _panelContentsMargins; -} +@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView @property (nonatomic, readonly) NSButton *okButton; @property (nonatomic, readonly) NSButton *cancelButton; @@ -187,6 +179,7 @@ QT_END_NAMESPACE - (NSButton *)createButtonWithTitle:(const char *)title; - (void)layout; + @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index b729c7f4c0..632053b0c4 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -65,21 +65,19 @@ Q_LOGGING_CATEGORY(lcQpaCocoaMouse, "qt.qpa.cocoa.mouse"); // Conversion Functions // -QStringList qt_mac_NSArrayToQStringList(void *nsarray) +QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *array) { QStringList result; - NSArray *array = static_cast<NSArray *>(nsarray); - for (NSUInteger i=0; i<[array count]; ++i) - result << QString::fromNSString([array objectAtIndex:i]); + for (NSString *string in array) + result << QString::fromNSString(string); return result; } -void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) +NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list) { - NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()]; - for (int i=0; i<list.size(); ++i){ - [result addObject:list[i].toNSString()]; - } + NSMutableArray<NSString *> *result = [NSMutableArray<NSString *> arrayWithCapacity:list.size()]; + for (const QString &string : list) + [result addObject:string.toNSString()]; return result; } @@ -93,6 +91,7 @@ struct dndenum_mapper static dndenum_mapper dnd_enums[] = { { NSDragOperationLink, Qt::LinkAction, true }, { NSDragOperationMove, Qt::MoveAction, true }, + { NSDragOperationDelete, Qt::MoveAction, true }, { NSDragOperationCopy, Qt::CopyAction, true }, { NSDragOperationGeneric, Qt::CopyAction, false }, { NSDragOperationEvery, Qt::ActionMask, false }, @@ -288,7 +287,12 @@ QT_END_NAMESPACE the target-action for the OK/Cancel buttons and making sure the layout is consistent. */ -@implementation QNSPanelContentsWrapper +@implementation QNSPanelContentsWrapper { + NSButton *_okButton; + NSButton *_cancelButton; + NSView *_panelContents; + NSEdgeInsets _panelContentsMargins; +} @synthesize okButton = _okButton; @synthesize cancelButton = _cancelButton; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 55b3805df3..60541c32d9 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -196,7 +196,7 @@ QCocoaIntegration::~QCocoaIntegration() QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate]; [delegate removeAppleEventHandlers]; // reset the application delegate - [[NSApplication sharedApplication] setDelegate: 0]; + [[NSApplication sharedApplication] setDelegate:nil]; } #ifndef QT_NO_CLIPBOARD @@ -232,8 +232,8 @@ Q_LOGGING_CATEGORY(lcCocoaScreen, "qt.qpa.cocoa.screens"); */ void QCocoaIntegration::updateScreens() { - NSArray *scrs = [NSScreen screens]; - NSMutableArray *screens = [NSMutableArray arrayWithArray:scrs]; + NSArray<NSScreen *> *scrs = [NSScreen screens]; + NSMutableArray<NSScreen *> *screens = [NSMutableArray<NSScreen *> arrayWithArray:scrs]; if ([screens count] == 0) if ([NSScreen mainScreen]) [screens addObject:[NSScreen mainScreen]]; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index b3c2d5ae90..148dad5d6c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -279,9 +279,7 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) bool previousIsSeparator = true; // setting to true kills all the separators placed at the top. NSMenuItem *previousItem = nil; - NSArray *itemArray = [m_nativeMenu itemArray]; - for (unsigned int i = 0; i < [itemArray count]; ++i) { - NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); + for (NSMenuItem *item in [m_nativeMenu itemArray]) { if ([item isSeparatorItem]) { QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]); if (cocoaItem) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index f8f9648822..59e0150168 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -331,12 +331,9 @@ NSMenuItem *QCocoaMenuItem::sync() NSFont *customMenuFont = [NSFont fontWithName:m_font.family().toNSString() size:m_font.pointSize()]; if (customMenuFont) { - NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil]; - NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil]; - NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; NSAttributedString *str = [[[NSAttributedString alloc] initWithString:finalString.toNSString() - attributes:attributes] autorelease]; - [m_native setAttributedTitle: str]; + attributes:@{NSFontAttributeName: customMenuFont}] autorelease]; + [m_native setAttributedTitle:str]; useAttributedTitle = true; } } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h index 95f347646c..3d040efa84 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.h +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h @@ -55,19 +55,6 @@ #include <QtCore/private/qcore_mac_p.h> @interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder -{ - IBOutlet NSMenu *theMenu; - IBOutlet NSMenu *appMenu; - IBOutlet NSMenuItem *quitItem; - IBOutlet NSMenuItem *preferencesItem; - IBOutlet NSMenuItem *aboutItem; - IBOutlet NSMenuItem *aboutQtItem; - IBOutlet NSMenuItem *hideItem; - NSMenuItem *lastAppSpecificItem; - NSMenuItem *servicesItem; - NSMenuItem *hideAllOthersItem; - NSMenuItem *showAllItem; -} + (instancetype)sharedMenuLoader; - (instancetype)init; - (void)ensureAppMenuInMenu:(NSMenu *)menu; @@ -80,16 +67,16 @@ - (NSMenuItem *)aboutQtMenuItem; - (NSMenuItem *)hideMenuItem; - (NSMenuItem *)appSpecificMenuItem:(NSInteger)tag; -- (IBAction)terminate:(id)sender; -- (IBAction)orderFrontStandardAboutPanel:(id)sender; -- (IBAction)hideOtherApplications:(id)sender; -- (IBAction)unhideAllApplications:(id)sender; -- (IBAction)hide:(id)sender; -- (IBAction)qtDispatcherToQPAMenuItem:(id)sender; +- (void)terminate:(id)sender; +- (void)orderFrontStandardAboutPanel:(id)sender; +- (void)hideOtherApplications:(id)sender; +- (void)unhideAllApplications:(id)sender; +- (void)hide:(id)sender; +- (void)qtDispatcherToQPAMenuItem:(id)sender; - (void)orderFrontCharacterPalette:(id)sender; - (BOOL)validateMenuItem:(NSMenuItem*)menuItem; - (void)qtTranslateApplicationMenu; -- (NSArray *)mergeable; +- (NSArray<NSMenuItem *> *)mergeable; @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader); diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index cd597da71c..d4d7bc1d7a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -50,7 +50,19 @@ #include <QtCore/qcoreapplication.h> #include <QtGui/private/qguiapplication_p.h> -@implementation QCocoaMenuLoader +@implementation QCocoaMenuLoader { + NSMenu *theMenu; + NSMenu *appMenu; + NSMenuItem *quitItem; + NSMenuItem *preferencesItem; + NSMenuItem *aboutItem; + NSMenuItem *aboutQtItem; + NSMenuItem *hideItem; + NSMenuItem *lastAppSpecificItem; + NSMenuItem *servicesItem; + NSMenuItem *hideAllOthersItem; + NSMenuItem *showAllItem; +} + (instancetype)sharedMenuLoader { @@ -323,7 +335,7 @@ #endif } -- (IBAction)qtDispatcherToQPAMenuItem:(id)sender +- (void)qtDispatcherToQPAMenuItem:(id)sender { NSMenuItem *item = static_cast<NSMenuItem *>(sender); if (item == quitItem) { @@ -363,9 +375,10 @@ } } -- (NSArray*) mergeable +- (NSArray<NSMenuItem *> *)mergeable { - // don't include the quitItem here, since we want it always visible and enabled regardless + // Don't include the quitItem here, since we want it always visible and enabled regardless + // Note that lastAppSpecificItem may be nil, so we can't use @[] here. return [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem, lastAppSpecificItem, nil]; } diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index a17a02b629..c963f33270 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -66,7 +66,7 @@ QCocoaScreen::~QCocoaScreen() NSScreen *QCocoaScreen::nativeScreen() const { - NSArray *screens = [NSScreen screens]; + NSArray<NSScreen *> *screens = [NSScreen screens]; // Stale reference, screen configuration has changed if (m_screenIndex < 0 || (NSUInteger)m_screenIndex >= [screens count]) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 5e6913a89a..d3aafa3785 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -95,31 +95,16 @@ QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QNSImageView); @interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate> -{ -@public - QCocoaSystemTrayIcon *systray; - NSStatusItem *item; - QCocoaMenu *menu; - QIcon icon; - QT_MANGLE_NAMESPACE(QNSImageView) *imageCell; -} --(id)initWithSysTray:(QCocoaSystemTrayIcon *)systray; --(void)dealloc; --(NSStatusItem*)item; --(QRectF)geometry; +@property (nonatomic, assign) QCocoaMenu *menu; +@property (nonatomic, assign) QIcon icon; +@property (nonatomic, readonly) NSStatusItem *item; +@property (nonatomic, readonly) QRectF geometry; +- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)systray; - (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton; - (void)doubleClickSelector:(id)sender; -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; @end -@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView { - BOOL down; - QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; -} --(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent; --(void)menuTrackingDone:(NSNotification*)notification; --(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton; +@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem); @@ -178,7 +163,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) if (!m_sys) return; - m_sys->item->icon = icon; + m_sys->item.icon = icon; // The reccomended maximum title bar icon height is 18 points // (device independent pixels). The menu height on past and @@ -249,8 +234,8 @@ void QCocoaSystemTrayIcon::updateMenu(QPlatformMenu *menu) if (!m_sys) return; - m_sys->item->menu = static_cast<QCocoaMenu *>(menu); - if (menu && [m_sys->item->menu->nsMenu() numberOfItems] > 0) { + m_sys->item.menu = static_cast<QCocoaMenu *>(menu); + if (menu && [m_sys->item.menu->nsMenu() numberOfItems] > 0) { [[m_sys->item item] setHighlightMode:YES]; } else { [[m_sys->item item] setHighlightMode:NO]; @@ -289,23 +274,29 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess } QT_END_NAMESPACE -@implementation QNSImageView --(id)initWithParent:(QNSStatusItem*)myParent { +@implementation NSStatusItem (Qt) +@end + +@implementation QNSImageView { + BOOL down; + QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; +} + +- (instancetype)initWithParent:(QNSStatusItem *)myParent { self = [super init]; parent = myParent; down = NO; return self; } --(void)menuTrackingDone:(NSNotification*)notification +- (void)menuTrackingDone:(NSNotification *)__unused notification { - Q_UNUSED(notification); down = NO; [self setNeedsDisplay:YES]; } --(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton +- (void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton { down = YES; int clickCount = [mouseEvent clickCount]; @@ -319,12 +310,12 @@ QT_END_NAMESPACE } } --(void)mouseDown:(NSEvent *)mouseEvent +- (void)mouseDown:(NSEvent *)mouseEvent { [self mousePressed:mouseEvent button:Qt::LeftButton]; } --(void)mouseUp:(NSEvent *)mouseEvent +- (void)mouseUp:(NSEvent *)mouseEvent { Q_UNUSED(mouseEvent); [self menuTrackingDone:nil]; @@ -335,7 +326,7 @@ QT_END_NAMESPACE [self mousePressed:mouseEvent button:Qt::RightButton]; } --(void)rightMouseUp:(NSEvent *)mouseEvent +- (void)rightMouseUp:(NSEvent *)mouseEvent { Q_UNUSED(mouseEvent); [self menuTrackingDone:nil]; @@ -346,21 +337,28 @@ QT_END_NAMESPACE [self mousePressed:mouseEvent button:cocoaButton2QtButton([mouseEvent buttonNumber])]; } --(void)otherMouseUp:(NSEvent *)mouseEvent +- (void)otherMouseUp:(NSEvent *)mouseEvent { Q_UNUSED(mouseEvent); [self menuTrackingDone:nil]; } --(void)drawRect:(NSRect)rect { +- (void)drawRect:(NSRect)rect { [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down]; [super drawRect:rect]; } @end -@implementation QNSStatusItem +@implementation QNSStatusItem { + QCocoaSystemTrayIcon *systray; + NSStatusItem *item; + QT_MANGLE_NAMESPACE(QNSImageView) *imageCell; +} + +@synthesize menu = menu; +@synthesize icon = icon; --(id)initWithSysTray:(QCocoaSystemTrayIcon *)sys +- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)sys { self = [super init]; if (self) { @@ -373,19 +371,19 @@ QT_END_NAMESPACE return self; } --(void)dealloc { +- (void)dealloc { [[NSStatusBar systemStatusBar] removeStatusItem:item]; [[NSNotificationCenter defaultCenter] removeObserver:imageCell]; [imageCell release]; [item release]; [super dealloc]; - } --(NSStatusItem*)item { +- (NSStatusItem *)item { return item; } --(QRectF)geometry { + +- (QRectF)geometry { if (NSWindow *window = [[item view] window]) { if (QCocoaScreen *screen = QCocoaIntegration::instance()->screenForNSScreen([window screen])) return screen->mapFromNative([window frame]); diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 93f0400916..f73db8873b 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -77,26 +77,24 @@ #include <Carbon/Carbon.h> -@interface QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) : NSObject { -QCocoaTheme *mPrivate; -} -- (id)initWithPrivate:(QCocoaTheme *)priv; -- (void)systemColorsDidChange:(NSNotification *)notification; +@interface QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) : NSObject @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeNotificationReceiver); -@implementation QCocoaThemeNotificationReceiver -- (id)initWithPrivate:(QCocoaTheme *)priv +@implementation QCocoaThemeNotificationReceiver { + QCocoaTheme *mPrivate; +} + +- (instancetype)initWithPrivate:(QCocoaTheme *)priv { - self = [super init]; - mPrivate = priv; + if ((self = [self init])) + mPrivate = priv; return self; } -- (void)systemColorsDidChange:(NSNotification *)notification +- (void)systemColorsDidChange:(NSNotification *)__unused notification { - Q_UNUSED(notification); mPrivate->reset(); QWindowSystemInterface::handleThemeChange(nullptr); } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f9c676a5b0..0ece15d1fa 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -117,17 +117,12 @@ static void qRegisterNotificationCallbacks() return; } - if (lcCocoaNotifications().isDebugEnabled()) { - if (cocoaWindows.isEmpty()) { - qCDebug(lcCocoaNotifications) << "Could not find forwarding target for" << - qPrintable(notificationName) << "from" << notification.object; - } else { - QVector<QCocoaWindow *> debugWindows; - for (QCocoaWindow *cocoaWindow : cocoaWindows) - debugWindows += cocoaWindow; - qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) << - "to" << debugWindows; - } + if (lcCocoaNotifications().isDebugEnabled() && !cocoaWindows.isEmpty()) { + QVector<QCocoaWindow *> debugWindows; + for (QCocoaWindow *cocoaWindow : cocoaWindows) + debugWindows += cocoaWindow; + qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) << + "to" << debugWindows; } // FIXME: Could be a foreign window, look up by iterating top level QWindows diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index e2ea862cd5..23c3b6100e 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -42,52 +42,22 @@ #include <AppKit/AppKit.h> -#include <QtCore/QPointer> -#include <QtCore/QSet> -#include <QtGui/QImage> -#include <QtGui/QAccessible> - #include "private/qcore_mac_p.h" QT_BEGIN_NAMESPACE class QCocoaWindow; class QCocoaGLContext; +class QPointF; QT_END_NAMESPACE Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); -@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> { - QPointer<QCocoaWindow> m_platformWindow; - NSTrackingArea *m_trackingArea; - Qt::MouseButtons m_buttons; - Qt::MouseButtons m_acceptedMouseDowns; - Qt::MouseButtons m_frameStrutButtons; - QString m_composingText; - QPointer<QObject> m_composingFocusObject; - bool m_sendKeyEvent; - QStringList *currentCustomDragTypes; - bool m_dontOverrideCtrlLMB; - bool m_sendUpAsRightButton; - Qt::KeyboardModifiers currentWheelModifiers; -#ifndef QT_NO_OPENGL - QCocoaGLContext *m_glContext; - bool m_shouldSetGLContextinDrawRect; -#endif - NSString *m_inputSource; - QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) *m_mouseMoveHelper; - bool m_resendKeyEvent; - bool m_scrolling; - bool m_updatingDrag; - NSEvent *m_currentlyInterpretedKeyEvent; - bool m_isMenuView; - QSet<quint32> m_acceptedKeyDowns; - bool m_updateRequested; -} +@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> @property (nonatomic, retain) NSCursor *cursor; -- (id)init; -- (id)initWithCocoaWindow:(QCocoaWindow *)platformWindow; +- (instancetype)init; +- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow; #ifndef QT_NO_OPENGL - (void)setQCocoaGLContext:(QCocoaGLContext *)context; #endif diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index ec1d126ab9..6a79c76991 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -51,7 +51,11 @@ #include <qpa/qwindowsysteminterface.h> #include <QtGui/QTextFormat> #include <QtCore/QDebug> +#include <QtCore/QPointer> +#include <QtCore/QSet> #include <QtCore/qsysinfo.h> +#include <QtGui/QAccessible> +#include <QtGui/QImage> #include <private/qguiapplication_p.h> #include <private/qcoregraphics_p.h> #include <private/qwindow_p.h> @@ -72,11 +76,8 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") @interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject -{ - QNSView *view; -} -- (id)initWithView:(QNSView *)theView; +- (instancetype)initWithView:(QNSView *)theView; - (void)mouseMoved:(NSEvent *)theEvent; - (void)mouseEntered:(NSEvent *)theEvent; @@ -85,9 +86,11 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") @end -@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) +@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) { + QNSView *view; +} -- (id)initWithView:(QNSView *)theView +- (instancetype)initWithView:(QNSView *)theView { self = [super init]; if (self) { @@ -123,9 +126,35 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") - (BOOL)isTransparentForUserInput; @end -@implementation QT_MANGLE_NAMESPACE(QNSView) +@implementation QT_MANGLE_NAMESPACE(QNSView) { + QPointer<QCocoaWindow> m_platformWindow; + NSTrackingArea *m_trackingArea; + Qt::MouseButtons m_buttons; + Qt::MouseButtons m_acceptedMouseDowns; + Qt::MouseButtons m_frameStrutButtons; + QString m_composingText; + QPointer<QObject> m_composingFocusObject; + bool m_sendKeyEvent; + QStringList *currentCustomDragTypes; + bool m_dontOverrideCtrlLMB; + bool m_sendUpAsRightButton; + Qt::KeyboardModifiers currentWheelModifiers; +#ifndef QT_NO_OPENGL + QCocoaGLContext *m_glContext; + bool m_shouldSetGLContextinDrawRect; +#endif + NSString *m_inputSource; + QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) *m_mouseMoveHelper; + bool m_resendKeyEvent; + bool m_scrolling; + bool m_updatingDrag; + NSEvent *m_currentlyInterpretedKeyEvent; + bool m_isMenuView; + QSet<quint32> m_acceptedKeyDowns; + bool m_updateRequested; +} -- (id) init +- (instancetype)init { if (self = [super initWithFrame:NSZeroRect]) { m_buttons = Qt::NoButton; @@ -168,7 +197,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") [super dealloc]; } -- (id)initWithCocoaWindow:(QCocoaWindow *)platformWindow +- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow { self = [self init]; if (!self) @@ -1432,7 +1461,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) { // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call m_currentlyInterpretedKeyEvent = nsevent; - [self interpretKeyEvents:[NSArray arrayWithObject:nsevent]]; + [self interpretKeyEvents:@[nsevent]]; m_currentlyInterpretedKeyEvent = 0; } } @@ -1790,7 +1819,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) return NSNotFound; } -- (NSArray*)validAttributesForMarkedText +- (NSArray<NSString *> *)validAttributesForMarkedText { if (!m_platformWindow) return nil; @@ -1809,8 +1838,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) return nil; // Support only underline color/style. - return [NSArray arrayWithObjects:NSUnderlineColorAttributeName, - NSUnderlineStyleAttributeName, nil]; + return @[NSUnderlineColorAttributeName, NSUnderlineStyleAttributeName]; } -(void)registerDragTypes @@ -1821,8 +1849,9 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (currentCustomDragTypes == 0) currentCustomDragTypes = new QStringList(); *currentCustomDragTypes = customTypes; - const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName"; - NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType, + NSString * const mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName"; + NSMutableArray<NSString *> *supportedTypes = [NSMutableArray<NSString *> arrayWithArray:@[ + NSColorPboardType, NSFilenamesPboardType, NSStringPboardType, NSFilenamesPboardType, NSPostScriptPboardType, NSTIFFPboardType, NSRTFPboardType, NSTabularTextPboardType, NSFontPboardType, @@ -1830,7 +1859,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) NSRTFDPboardType, NSHTMLPboardType, NSURLPboardType, NSPDFPboardType, NSVCardPboardType, NSFilesPromisePboardType, NSInkTextPboardType, - NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil]; + NSMultipleTextSelectionPboardType, mimeTypeGeneric]]; // Add custom types supported by the application. for (int i = 0; i < customTypes.size(); i++) { [supportedTypes addObject:customTypes[i].toNSString()]; @@ -2034,10 +2063,6 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QCocoaDropData mimeData([sender draggingPasteboard]); response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed); } - if (response.isAccepted()) { - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - nativeDrag->setAcceptedAction(response.acceptedAction()); - } return response.isAccepted(); } @@ -2055,6 +2080,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin if (!target) return; + QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation)); + // keep our state, and QGuiApplication state (buttons member) in-sync, // or future mouse events will be processed incorrectly NSUInteger pmb = [NSEvent pressedMouseButtons]; diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 645a93edf7..ab0036e175 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -53,14 +53,12 @@ @implementation QNSView (QNSViewAccessibility) - (id)childAccessibleElement { - if (m_platformWindow.isNull()) + QCocoaWindow *platformWindow = self.platformWindow; + if (!platformWindow || !platformWindow->window()->accessibleRoot()) return nil; - if (!m_platformWindow->window()->accessibleRoot()) - return nil; - - QAccessible::Id childId = QAccessible::uniqueId(m_platformWindow->window()->accessibleRoot()); - return [QMacAccessibilityElement elementWithId: childId]; + QAccessible::Id childId = QAccessible::uniqueId(platformWindow->window()->accessibleRoot()); + return [QMacAccessibilityElement elementWithId:childId]; } // The QNSView is a container that the user does not interact directly with: diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index cb13b7d184..086a4f8af2 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qnswindow.h" -#include "qnswindowdelegate.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" #include "qcocoaeventdispatcher.h" @@ -72,7 +71,7 @@ static bool isMouseEvent(NSEvent *ev) [center addObserverForName:NSWindowDidEnterFullScreenNotification object:nil queue:nil usingBlock:^(NSNotification *notification) { objc_setAssociatedObject(notification.object, @selector(qt_fullScreen), - [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN); + @(YES), OBJC_ASSOCIATION_RETAIN); } ]; [center addObserverForName:NSWindowDidExitFullScreenNotification object:nil queue:nil @@ -267,14 +266,14 @@ static bool isMouseEvent(NSEvent *ev) if (__builtin_available(macOS 10.12, *)) { // Unfortunately there's no NSWindowListOrderedBackToFront, // so we have to manually reverse the order using an array. - NSMutableArray *windows = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray<NSWindow *> *windows = [NSMutableArray<NSWindow *> new]; [application enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack usingBlock:^(NSWindow *window, BOOL *) { // For some reason AppKit will give us nil-windows, skip those if (!window) return; - [(NSMutableArray*)windows addObject:window]; + [windows addObject:window]; } ]; diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index d2078b5786..e71afcbb2a 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -41,20 +41,16 @@ #define QNSWINDOWDELEGATE_H #include <AppKit/AppKit.h> +#include <QtCore/private/qcore_mac_p.h> -#include "qcocoawindow.h" +QT_BEGIN_NAMESPACE +class QCocoaWindow; +QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(QNSWindowDelegate) : NSObject <NSWindowDelegate> -{ - QCocoaWindow *m_cocoaWindow; -} -- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow; +- (instancetype)initWithQCocoaWindow:(QT_PREPEND_NAMESPACE(QCocoaWindow) *)cocoaWindow; -- (BOOL)windowShouldClose:(NSNotification *)notification; - -- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu; -- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard; @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowDelegate); diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 6e5623d679..1888dc1c90 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -39,20 +39,23 @@ #include "qnswindowdelegate.h" #include "qcocoahelpers.h" +#include "qcocoawindow.h" #include <QDebug> +#include <QtCore/private/qcore_mac_p.h> #include <qpa/qplatformscreen.h> #include <qpa/qwindowsysteminterface.h> static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); -@implementation QNSWindowDelegate +@implementation QNSWindowDelegate { + QCocoaWindow *m_cocoaWindow; +} -- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow +- (instancetype)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow { - if (self = [super init]) + if ((self = [self init])) m_cocoaWindow = cocoaWindow; - return self; } diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h index c52d498cd4..201b277494 100644 --- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h @@ -41,8 +41,6 @@ #include "../../qiosfiledialog.h" -@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> { - QIOSFileDialog *m_fileDialog; -} -- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog; +@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> +- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog; @end diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm index 78e0f00ab4..79d4ecf83f 100644 --- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm @@ -41,15 +41,17 @@ #include "qiosimagepickercontroller.h" -@implementation QIOSImagePickerController +@implementation QIOSImagePickerController { + QIOSFileDialog *m_fileDialog; +} -- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog +- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog { self = [super init]; if (self) { m_fileDialog = fileDialog; - [self setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; - [self setDelegate:self]; + self.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; + self.delegate = self; } return self; } @@ -57,8 +59,8 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { Q_UNUSED(picker); - NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL]; - QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString([url description])); + NSURL *url = info[UIImagePickerControllerReferenceURL]; + QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString(url.description)); m_fileDialog->selectedFilesChanged(QList<QUrl>() << fileUrl); emit m_fileDialog->accept(); } diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm index 9a975eadc9..6bdbf94d3f 100644 --- a/src/plugins/platforms/ios/qiosclipboard.mm +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -46,11 +46,11 @@ #include <QtGui/QGuiApplication> @interface UIPasteboard (QUIPasteboard) - + (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode; ++ (instancetype)pasteboardWithQClipboardMode:(QClipboard::Mode)mode; @end @implementation UIPasteboard (QUIPasteboard) -+ (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode ++ (instancetype)pasteboardWithQClipboardMode:(QClipboard::Mode)mode { NSString *name = (mode == QClipboard::Clipboard) ? UIPasteboardNameGeneral : UIPasteboardNameFind; return [UIPasteboard pasteboardWithName:name create:NO]; @@ -60,17 +60,15 @@ // -------------------------------------------------------------------- @interface QUIClipboard : NSObject -{ -@public +@end + +@implementation QUIClipboard { QIOSClipboard *m_qiosClipboard; NSInteger m_changeCountClipboard; NSInteger m_changeCountFindBuffer; } -@end - -@implementation QUIClipboard -- (id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard +- (instancetype)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard { self = [super init]; if (self) { @@ -149,7 +147,7 @@ QStringList QIOSMimeData::formats() const { QStringList foundMimeTypes; UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode]; - NSArray *pasteboardTypes = [pb pasteboardTypes]; + NSArray<NSString *> *pasteboardTypes = [pb pasteboardTypes]; for (NSUInteger i = 0; i < [pasteboardTypes count]; ++i) { QString uti = QString::fromNSString([pasteboardTypes objectAtIndex:i]); @@ -164,7 +162,7 @@ QStringList QIOSMimeData::formats() const QVariant QIOSMimeData::retrieveData(const QString &mimeType, QVariant::Type) const { UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode]; - NSArray *pasteboardTypes = [pb pasteboardTypes]; + NSArray<NSString *> *pasteboardTypes = [pb pasteboardTypes]; foreach (QMacInternalPasteboardMime *converter, QMacInternalPasteboardMime::all(QMacInternalPasteboardMime::MIME_ALL)) { @@ -213,12 +211,12 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:mode]; if (!mimeData) { - pb.items = [NSArray array]; + pb.items = [NSArray<NSDictionary<NSString *, id> *> array]; return; } mimeData->deleteLater(); - NSMutableDictionary *pbItem = [NSMutableDictionary dictionaryWithCapacity:mimeData->formats().size()]; + NSMutableDictionary<NSString *, id> *pbItem = [NSMutableDictionary<NSString *, id> dictionaryWithCapacity:mimeData->formats().size()]; foreach (const QString &mimeType, mimeData->formats()) { foreach (QMacInternalPasteboardMime *converter, @@ -246,7 +244,7 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) } } - pb.items = [NSArray arrayWithObject:pbItem]; + pb.items = @[pbItem]; } bool QIOSClipboard::supportsMode(QClipboard::Mode mode) const diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index a6f6a7aac9..7a2399efcd 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -245,7 +245,7 @@ extern "C" int main(int argc, char *argv[]); static void __attribute__((noinline, noreturn)) user_main_trampoline() { - NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + NSArray<NSString *> *arguments = [[NSProcessInfo processInfo] arguments]; int argc = arguments.count; char **argv = new char*[argc]; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 050c592aca..3e22634071 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -67,7 +67,7 @@ static QUIView *focusView() @implementation QIOSLocaleListener -- (id)init +- (instancetype)init { if (self = [super init]) { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; @@ -95,16 +95,15 @@ static QUIView *focusView() // ------------------------------------------------------------------------- -@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> { - @private - QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context; -} +@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> @property BOOL hasDeferredScrollToCursor; @end -@implementation QIOSKeyboardListener +@implementation QIOSKeyboardListener { + QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context; +} -- (id)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context +- (instancetype)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context { if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) { @@ -574,7 +573,7 @@ void QIOSInputContext::scroll(int y) // Raise all known windows to above the status-bar if we're scrolling the screen, // while keeping the relative window level between the windows the same. - NSArray *applicationWindows = [[UIApplication sharedApplication] windows]; + NSArray<UIWindow *> *applicationWindows = [[UIApplication sharedApplication] windows]; static QHash<UIWindow *, UIWindowLevel> originalWindowLevels; for (UIWindow *window in applicationWindows) { if (keyboardScrollIsActive && !originalWindowLevels.contains(window)) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 92c1e39d72..5f9f7ad96d 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -97,7 +97,7 @@ QIOSIntegration::QIOSIntegration() QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); UIScreen *mainScreen = [UIScreen mainScreen]; - NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease]; + NSMutableArray<UIScreen *> *screens = [[[UIScreen screens] mutableCopy] autorelease]; if (![screens containsObject:mainScreen]) { // Fallback for iOS 7.1 (QTBUG-42345) [screens insertObject:mainScreen atIndex:0]; diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 6c70676a31..74a77de757 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -60,14 +60,14 @@ QIOSMenu *QIOSMenu::m_currentMenu = 0; static NSString *const kSelectorPrefix = @"_qtMenuItem_"; -@interface QUIMenuController : UIResponder { - QIOSMenuItemList m_visibleMenuItems; -} +@interface QUIMenuController : UIResponder @end -@implementation QUIMenuController +@implementation QUIMenuController { + QIOSMenuItemList m_visibleMenuItems; +} -- (id)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems +- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems { if (self = [super init]) { [self setVisibleMenuItems:visibleMenuItems]; @@ -80,7 +80,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; return self; } --(void)dealloc +- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self @@ -91,7 +91,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; - (void)setVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems { m_visibleMenuItems = visibleMenuItems; - NSMutableArray *menuItemArray = [NSMutableArray arrayWithCapacity:m_visibleMenuItems.size()]; + NSMutableArray<UIMenuItem *> *menuItemArray = [NSMutableArray<UIMenuItem *> arrayWithCapacity:m_visibleMenuItems.size()]; // Create an array of UIMenuItems, one for each visible QIOSMenuItem. Each // UIMenuItem needs a callback assigned, so we assign one of the placeholder methods // added to UIWindow (QIOSMenuActionTargets) below. Each method knows its own index, which @@ -107,7 +107,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; [[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO]; } --(void)menuClosed +- (void)menuClosed { QIOSMenu::currentMenu()->dismiss(); } @@ -141,19 +141,19 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; // ------------------------------------------------------------------------- -@interface QUIPickerView : UIPickerView <UIPickerViewDelegate, UIPickerViewDataSource> { - QIOSMenuItemList m_visibleMenuItems; - QPointer<QObject> m_focusObjectWithPickerView; - NSInteger m_selectedRow; -} +@interface QUIPickerView : UIPickerView <UIPickerViewDelegate, UIPickerViewDataSource> @property(retain) UIToolbar *toolbar; @end -@implementation QUIPickerView +@implementation QUIPickerView { + QIOSMenuItemList m_visibleMenuItems; + QPointer<QObject> m_focusObjectWithPickerView; + NSInteger m_selectedRow; +} -- (id)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem +- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem { if (self = [super init]) { [self setVisibleMenuItems:visibleMenuItems selectItem:selectItem]; @@ -172,7 +172,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(closeMenu)] autorelease]; - [self.toolbar setItems:[NSArray arrayWithObjects:cancelButton, spaceButton, doneButton, nil]]; + [self.toolbar setItems:@[cancelButton, spaceButton, doneButton]]; [self setDelegate:self]; [self setDataSource:self]; diff --git a/src/plugins/platforms/ios/qiosoptionalplugininterface.h b/src/plugins/platforms/ios/qiosoptionalplugininterface.h index 660c74e856..bae9e5a0d8 100644 --- a/src/plugins/platforms/ios/qiosoptionalplugininterface.h +++ b/src/plugins/platforms/ios/qiosoptionalplugininterface.h @@ -44,10 +44,10 @@ #include "qiosfiledialog.h" -QT_BEGIN_NAMESPACE - Q_FORWARD_DECLARE_OBJC_CLASS(UIViewController); +QT_BEGIN_NAMESPACE + #define QIosOptionalPluginInterface_iid "org.qt-project.Qt.QPA.ios.optional" class QIosOptionalPluginInterface diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index c394592d76..91d26c88c2 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -130,16 +130,14 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) // ------------------------------------------------------------------------- -@interface QIOSOrientationListener : NSObject { - @public - QIOSScreen *m_screen; -} -- (id)initWithQIOSScreen:(QIOSScreen *)screen; +@interface QIOSOrientationListener : NSObject @end -@implementation QIOSOrientationListener +@implementation QIOSOrientationListener { + QIOSScreen *m_screen; +} -- (id)initWithQIOSScreen:(QIOSScreen *)screen +- (instancetype)initWithQIOSScreen:(QIOSScreen *)screen { self = [super init]; if (self) { @@ -193,7 +191,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) @implementation QUIWindow -- (id)initWithFrame:(CGRect)frame +- (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) self->_sendingEvent = NO; diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm index fe3c29d037..ff696f5b7f 100644 --- a/src/plugins/platforms/ios/qiostextinputoverlay.mm +++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm @@ -96,7 +96,7 @@ static void executeBlockWithoutAnimation(Block block) @implementation QIOSEditMenu -- (id)init +- (instancetype)init { if (self = [super init]) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; @@ -160,7 +160,13 @@ static void executeBlockWithoutAnimation(Block block) // ------------------------------------------------------------------------- -@interface QIOSLoupeLayer : CALayer { +@interface QIOSLoupeLayer : CALayer +@property (nonatomic, retain) UIView *targetView; +@property (nonatomic, assign) CGPoint focalPoint; +@property (nonatomic, assign) BOOL visible; +@end + +@implementation QIOSLoupeLayer { UIView *_snapshotView; BOOL _pendingSnapshotUpdate; UIView *_loupeImageView; @@ -168,14 +174,8 @@ static void executeBlockWithoutAnimation(Block block) CGFloat _loupeOffset; QTimer _updateTimer; } -@property (nonatomic, retain) UIView *targetView; -@property (nonatomic, assign) CGPoint focalPoint; -@property (nonatomic, assign) BOOL visible; -@end -@implementation QIOSLoupeLayer - -- (id)initWithSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius bottomOffset:(CGFloat)bottomOffset +- (instancetype)initWithSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius bottomOffset:(CGFloat)bottomOffset { if (self = [super init]) { _loupeOffset = bottomOffset + (size.height / 2); @@ -301,26 +301,22 @@ static void executeBlockWithoutAnimation(Block block) // ------------------------------------------------------------------------- -#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0) -@interface QIOSHandleLayer : CALayer <CAAnimationDelegate> { -#else -@interface QIOSHandleLayer : CALayer { -#endif - CALayer *_handleCursorLayer; - CALayer *_handleKnobLayer; - Qt::Edge _selectionEdge; -} +@interface QIOSHandleLayer : CALayer <CAAnimationDelegate> @property (nonatomic, assign) CGRect cursorRectangle; @property (nonatomic, assign) CGFloat handleScale; @property (nonatomic, assign) BOOL visible; @property (nonatomic, copy) Block onAnimationDidStop; @end -@implementation QIOSHandleLayer +@implementation QIOSHandleLayer { + CALayer *_handleCursorLayer; + CALayer *_handleKnobLayer; + Qt::Edge _selectionEdge; +} @dynamic handleScale; -- (id)initWithKnobAtEdge:(Qt::Edge)selectionEdge +- (instancetype)initWithKnobAtEdge:(Qt::Edge)selectionEdge { if (self = [super init]) { CGColorRef bgColor = [UIColor colorWithRed:0.1 green:0.4 blue:0.9 alpha:1].CGColor; @@ -355,16 +351,8 @@ static void executeBlockWithoutAnimation(Block block) // The handle should "bounce" in when becoming visible CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:key]; [animation setDuration:0.5]; - animation.values = [NSArray arrayWithObjects: - [NSNumber numberWithFloat:0], - [NSNumber numberWithFloat:1.3], - [NSNumber numberWithFloat:1.3], - [NSNumber numberWithFloat:1], nil]; - animation.keyTimes = [NSArray arrayWithObjects: - [NSNumber numberWithFloat:0], - [NSNumber numberWithFloat:0.3], - [NSNumber numberWithFloat:0.9], - [NSNumber numberWithFloat:1], nil]; + animation.values = @[@(0.0f), @(1.3f), @(1.3f), @(1.0f)]; + animation.keyTimes = @[@(0.0f), @(0.3f), @(0.9f), @(1.0f)]; return animation; } else { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key]; @@ -436,8 +424,13 @@ static void executeBlockWithoutAnimation(Block block) below will inherit. It takes care of creating and showing a magnifier glass depending on the current gesture state. */ -@interface QIOSLoupeRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate> { -@public +@interface QIOSLoupeRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate> +@property (nonatomic, assign) QPointF focalPoint; +@property (nonatomic, assign) BOOL dragTriggersGesture; +@property (nonatomic, readonly) UIView *focusView; +@end + +@implementation QIOSLoupeRecognizer { QIOSLoupeLayer *_loupeLayer; UIView *_desktopView; CGPoint _firstTouchPoint; @@ -445,14 +438,8 @@ static void executeBlockWithoutAnimation(Block block) QTimer _triggerStateBeganTimer; int _originalCursorFlashTime; } -@property (nonatomic, assign) QPointF focalPoint; -@property (nonatomic, assign) BOOL dragTriggersGesture; -@property (nonatomic, readonly) UIView *focusView; -@end -@implementation QIOSLoupeRecognizer - -- (id)init +- (instancetype)init { if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) { self.enabled = NO; @@ -657,7 +644,10 @@ static void executeBlockWithoutAnimation(Block block) on the sides. If the user starts dragging on a handle (or do a press and hold), it will show a magnifier glass that follows the handle as it moves. */ -@interface QIOSSelectionRecognizer : QIOSLoupeRecognizer { +@interface QIOSSelectionRecognizer : QIOSLoupeRecognizer +@end + +@implementation QIOSSelectionRecognizer { CALayer *_clipRectLayer; QIOSHandleLayer *_cursorLayer; QIOSHandleLayer *_anchorLayer; @@ -669,11 +659,8 @@ static void executeBlockWithoutAnimation(Block block) QMetaObject::Connection _anchorConnection; QMetaObject::Connection _clipRectConnection; } -@end - -@implementation QIOSSelectionRecognizer -- (id)init +- (instancetype)init { if (self = [super init]) { self.delaysTouchesBegan = YES; @@ -889,15 +876,15 @@ static void executeBlockWithoutAnimation(Block block) visibility of the edit menu will be toggled. Otherwise, if there's a selection, a first tap will close the edit menu (if any), and a second tap will remove the selection. */ -@interface QIOSTapRecognizer : UITapGestureRecognizer { +@interface QIOSTapRecognizer : UITapGestureRecognizer +@end + +@implementation QIOSTapRecognizer { int _cursorPosOnPress; UIView *_focusView; } -@end - -@implementation QIOSTapRecognizer -- (id)init +- (instancetype)init { if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) { self.enabled = NO; diff --git a/src/plugins/platforms/ios/qiostextresponder.h b/src/plugins/platforms/ios/qiostextresponder.h index 77be2cf2fe..074598c1c3 100644 --- a/src/plugins/platforms/ios/qiostextresponder.h +++ b/src/plugins/platforms/ios/qiostextresponder.h @@ -49,16 +49,8 @@ class QIOSInputContext; QT_END_NAMESPACE @interface QIOSTextInputResponder : UIResponder <UITextInputTraits, UIKeyInput, UITextInput> -{ - @private - QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext; - QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState; - QString m_markedText; - BOOL m_inSendEventToFocusObject; - BOOL m_inSelectionChange; -} -- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context; +- (instancetype)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context; - (BOOL)needsKeyboardReconfigure:(Qt::InputMethodQueries)updatedProperties; - (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties; diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index b029c49a67..91a088ede1 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -55,13 +55,13 @@ @interface QUITextPosition : UITextPosition @property (nonatomic) NSUInteger index; -+ (QUITextPosition *)positionWithIndex:(NSUInteger)index; ++ (instancetype)positionWithIndex:(NSUInteger)index; @end @implementation QUITextPosition -+ (QUITextPosition *)positionWithIndex:(NSUInteger)index ++ (instancetype)positionWithIndex:(NSUInteger)index { QUITextPosition *pos = [[QUITextPosition alloc] init]; pos.index = index; @@ -75,15 +75,15 @@ @interface QUITextRange : UITextRange @property (nonatomic) NSRange range; -+ (QUITextRange *)rangeWithNSRange:(NSRange)range; ++ (instancetype)rangeWithNSRange:(NSRange)range; @end @implementation QUITextRange -+ (QUITextRange *)rangeWithNSRange:(NSRange)nsrange ++ (instancetype)rangeWithNSRange:(NSRange)nsrange { - QUITextRange *range = [[QUITextRange alloc] init]; + QUITextRange *range = [[self alloc] init]; range.range = nsrange; return [range autorelease]; } @@ -117,7 +117,7 @@ @implementation WrapperView -- (id)initWithView:(UIView *)view +- (instancetype)initWithView:(UIView *)view { if (self = [self init]) { [self addSubview:view]; @@ -132,7 +132,7 @@ - (void)layoutSubviews { - UIView* view = [self.subviews firstObject]; + UIView *view = [self.subviews firstObject]; view.frame = self.bounds; // FIXME: During orientation changes the size and position @@ -161,9 +161,15 @@ // ------------------------------------------------------------------------- -@implementation QIOSTextInputResponder +@implementation QIOSTextInputResponder { + QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext; + QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState; + QString m_markedText; + BOOL m_inSendEventToFocusObject; + BOOL m_inSelectionChange; +} -- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext +- (instancetype)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext { if (!(self = [self init])) return self; @@ -548,7 +554,7 @@ [self sendKeyPressRelease:key modifiers:modifiers]; } -- (void)addKeyCommandsToArray:(NSMutableArray *)array key:(NSString *)key +- (void)addKeyCommandsToArray:(NSMutableArray<UIKeyCommand *> *)array key:(NSString *)key { SEL s = @selector(keyCommandTriggered:); [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:0 action:s]]; @@ -559,19 +565,19 @@ [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand|UIKeyModifierShift action:s]]; } -- (NSArray *)keyCommands +- (NSArray<UIKeyCommand *> *)keyCommands { // Since keyCommands is called for every key // press/release, we cache the result static dispatch_once_t once; - static NSMutableArray *array; + static NSMutableArray<UIKeyCommand *> *array; dispatch_once(&once, ^{ // We let Qt move the cursor around when the arrow keys are being used. This // is normally implemented through UITextInput, but since IM in Qt have poor // support for moving the cursor vertically, and even less support for selecting // text across multiple paragraphs, we do this through key events. - array = [NSMutableArray new]; + array = [NSMutableArray<UIKeyCommand *> new]; [self addKeyCommandsToArray:array key:UIKeyInputUpArrow]; [self addKeyCommandsToArray:array key:UIKeyInputDownArrow]; [self addKeyCommandsToArray:array key:UIKeyInputLeftArrow]; @@ -825,13 +831,13 @@ return startRect.united(endRect).toCGRect(); } -- (NSArray *)selectionRectsForRange:(UITextRange *)range +- (NSArray<UITextSelectionRect *> *)selectionRectsForRange:(UITextRange *)range { Q_UNUSED(range); // This method is supposed to return a rectangle for each line with selection. Since we don't // expose an API in Qt/IM for getting this information, and since we never seems to be getting // a call from UIKit for this, we return an empty array until a need arise. - return [[NSArray new] autorelease]; + return [[NSArray<UITextSelectionRect *> new] autorelease]; } - (CGRect)caretRectForPosition:(UITextPosition *)position @@ -916,7 +922,7 @@ QObject *focusObject = QGuiApplication::focusObject(); if (!focusObject) - return [NSDictionary dictionary]; + return @{}; // Assume position is the same as the cursor for now. QInputMethodQueryEvent with Qt::ImFont // needs to be extended to take an extra position argument before this can be fully correct. @@ -925,8 +931,8 @@ QFont qfont = qvariant_cast<QFont>(e.value(Qt::ImFont)); UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()]; if (!uifont) - return [NSDictionary dictionary]; - return [NSDictionary dictionaryWithObject:uifont forKey:NSFontAttributeName]; + return @{}; + return @{NSFontAttributeName: uifont}; } #endif diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 07d5535e1a..7af4c83b48 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -48,7 +48,7 @@ QT_END_NAMESPACE @interface QIOSViewController : UIViewController -- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen; +- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen; - (void)updateProperties; #ifndef Q_OS_TVOS diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a7663b9e94..787c6b8409 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -56,12 +56,8 @@ // ------------------------------------------------------------------------- -@interface QIOSViewController () { - @public - QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> m_screen; - BOOL m_updatingProperties; - QMetaObject::Connection m_focusWindowChangeConnection; -} +@interface QIOSViewController () +@property (nonatomic, assign) QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> platformScreen; @property (nonatomic, assign) BOOL changingOrientation; @end @@ -72,7 +68,7 @@ @implementation QIOSDesktopManagerView -- (id)init +- (instancetype)init { if (!(self = [super init])) return nil; @@ -125,7 +121,7 @@ { Q_UNUSED(subview); - QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController->m_screen; + QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController.platformScreen; // The 'window' property of our view is not valid until the window // has been shown, so we have to access it through the QIOSScreen. @@ -170,7 +166,7 @@ // here. iOS will still use the latest rendered frame to create the // application switcher thumbnail, but it will be based on the last // active orientation of the application. - QIOSScreen *screen = self.qtViewController->m_screen; + QIOSScreen *screen = self.qtViewController.platformScreen; qCDebug(lcQpaWindow) << "ignoring layout of subviews while suspended," << "likely system snapshot of" << screen->screen()->primaryOrientation(); return; @@ -246,7 +242,10 @@ // ------------------------------------------------------------------------- -@implementation QIOSViewController +@implementation QIOSViewController { + BOOL m_updatingProperties; + QMetaObject::Connection m_focusWindowChangeConnection; +} #ifndef Q_OS_TVOS @synthesize prefersStatusBarHidden; @@ -254,11 +253,10 @@ @synthesize preferredStatusBarStyle; #endif -- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen +- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen { if (self = [self init]) { - m_screen = screen; - + self.platformScreen = screen; self.changingOrientation = NO; #ifndef Q_OS_TVOS @@ -316,7 +314,7 @@ - (BOOL)shouldAutorotate { #ifndef Q_OS_TVOS - return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; + return self.platformScreen && self.platformScreen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; #else return NO; #endif @@ -396,8 +394,8 @@ if (!QCoreApplication::instance()) return; - if (m_screen) - m_screen->updateProperties(); + if (self.platformScreen) + self.platformScreen->updateProperties(); } // ------------------------------------------------------------------------- @@ -407,12 +405,12 @@ if (!isQtApplication()) return; - if (!m_screen || !m_screen->screen()) + if (!self.platformScreen || !self.platformScreen->screen()) return; // For now we only care about the main screen, as both the statusbar // visibility and orientation is only appropriate for the main screen. - if (m_screen->uiScreen() != [UIScreen mainScreen]) + if (self.platformScreen->uiScreen() != [UIScreen mainScreen]) return; // Prevent recursion caused by updating the status bar appearance (position @@ -434,7 +432,7 @@ return; // We only care about changes to focusWindow that involves our screen - if (!focusWindow->screen() || focusWindow->screen()->handle() != m_screen) + if (!focusWindow->screen() || focusWindow->screen()->handle() != self.platformScreen) return; // All decisions are based on the the top level window diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 6ee258e363..cdec57de71 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -96,7 +96,7 @@ QIOSWindow::~QIOSWindow() [m_view touchesCancelled:[NSSet set] withEvent:0]; clearAccessibleCache(); - m_view->m_qioswindow = 0; + m_view.platformWindow = 0; [m_view removeFromSuperview]; [m_view release]; } @@ -139,7 +139,7 @@ void QIOSWindow::setVisible(bool visible) } else if (!visible && [m_view isActiveWindow]) { // Our window was active/focus window but now hidden, so relinquish // focus to the next possible window in the stack. - NSArray *subviews = m_view.viewController.view.subviews; + NSArray<UIView *> *subviews = m_view.viewController.view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = [subviews objectAtIndex:i]; if (view.hidden) @@ -301,7 +301,7 @@ void QIOSWindow::raiseOrLower(bool raise) if (!isQtApplication()) return; - NSArray *subviews = m_view.superview.subviews; + NSArray<UIView *> *subviews = m_view.superview.subviews; if (subviews.count == 1) return; diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h index 03abf5407e..6b8efdcede 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.h +++ b/src/plugins/platforms/ios/quiaccessibilityelement.h @@ -45,13 +45,12 @@ #ifndef QT_NO_ACCESSIBILITY -@interface QMacAccessibilityElement : UIAccessibilityElement -{} +@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : UIAccessibilityElement @property (readonly) QAccessible::Id axid; -- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; -+ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; +- (instancetype)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; ++ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; @end diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index a26ba61b3c..3154536aad 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -42,20 +42,23 @@ #ifndef QT_NO_ACCESSIBILITY #include "private/qaccessiblecache_p.h" +#include "private/qcore_mac_p.h" + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); @implementation QMacAccessibilityElement -- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view +- (instancetype)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view { Q_ASSERT((int)anId < 0); - self = [super initWithAccessibilityContainer: view]; + self = [super initWithAccessibilityContainer:view]; if (self) _axid = anId; return self; } -+ (id)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view ++ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view { Q_ASSERT(anId); if (!anId) @@ -63,10 +66,10 @@ QAccessibleCache *cache = QAccessibleCache::instance(); - QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *element = cache->elementForId(anId); + QMacAccessibilityElement *element = cache->elementForId(anId); if (!element) { Q_ASSERT(QAccessible::accessibleInterface(anId)); - element = [[self alloc] initWithId:anId withAccessibilityContainer: view]; + element = [[self alloc] initWithId:anId withAccessibilityContainer:view]; cache->insertElement(anId, element); } return element; diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index 3e3c579075..e1d5d5af0c 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -53,21 +53,10 @@ QT_END_NAMESPACE @class QIOSViewController; @interface QUIView : UIView -{ - @public - QT_PREPEND_NAMESPACE(QIOSWindow) *m_qioswindow; - @private - QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches; - UITouch *m_activePencilTouch; - int m_nextTouchId; - - @private - NSMutableArray *m_accessibleElements; -}; - -- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window; +- (instancetype)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window; - (void)sendUpdatedExposeEvent; - (BOOL)isActiveWindow; +@property (nonatomic, assign) QT_PREPEND_NAMESPACE(QIOSWindow) *platformWindow; @end @interface QUIView (Accessibility) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 584dfe9b41..53a4485609 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -55,7 +55,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") -@implementation QUIView +@implementation QUIView { + QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches; + UITouch *m_activePencilTouch; + int m_nextTouchId; + NSMutableArray<UIAccessibilityElement *> *m_accessibleElements; +} + (void)load { @@ -82,25 +87,26 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") return [CAEAGLLayer class]; } -- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window +- (instancetype)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window { if (self = [self initWithFrame:window->geometry().toCGRect()]) { - m_qioswindow = window; - m_accessibleElements = [[NSMutableArray alloc] init]; + self.platformWindow = window; + m_accessibleElements = [[NSMutableArray<UIAccessibilityElement *> alloc] init]; } return self; } -- (id)initWithFrame:(CGRect)frame +- (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { // Set up EAGL layer CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer); eaglLayer.opaque = TRUE; - eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + eaglLayer.drawableProperties = @{ + kEAGLDrawablePropertyRetainedBacking: @(YES), + kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8 + }; if (isQtApplication()) self.hidden = YES; @@ -156,7 +162,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") #ifndef QT_NO_DEBUG_STREAM QString platformWindowDescription; QDebug debug(&platformWindowDescription); - debug.nospace() << "; " << m_qioswindow << ">"; + debug.nospace() << "; " << self.platformWindow << ">"; NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; [description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()]; #endif @@ -210,10 +216,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") if (!CGAffineTransformIsIdentity(self.transform)) qWarning() << self << "has a transform set. This is not supported."; - QWindow *window = m_qioswindow->window(); + QWindow *window = self.platformWindow->window(); QRect lastReportedGeometry = qt_window_private(window)->geometry; QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect(); - qCDebug(lcQpaWindow) << m_qioswindow << "new geometry is" << currentGeometry; + qCDebug(lcQpaWindow) << self.platformWindow << "new geometry is" << currentGeometry; QWindowSystemInterface::handleGeometryChange(window, currentGeometry); if (currentGeometry.size() != lastReportedGeometry.size()) { @@ -237,29 +243,29 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") { QRegion region; - if (m_qioswindow->isExposed()) { + if (self.platformWindow->isExposed()) { QSize bounds = QRectF::fromCGRect(self.layer.bounds).toRect().size(); - Q_ASSERT(m_qioswindow->geometry().size() == bounds); - Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + Q_ASSERT(self.platformWindow->geometry().size() == bounds); + Q_ASSERT(self.hidden == !self.platformWindow->window()->isVisible()); region = QRect(QPoint(), bounds); } - qCDebug(lcQpaWindow) << m_qioswindow << region << "isExposed" << m_qioswindow->isExposed(); - QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); + qCDebug(lcQpaWindow) << self.platformWindow << region << "isExposed" << self.platformWindow->isExposed(); + QWindowSystemInterface::handleExposeEvent(self.platformWindow->window(), region); } - (void)safeAreaInsetsDidChange { - QWindowSystemInterface::handleSafeAreaMarginsChanged(m_qioswindow->window()); + QWindowSystemInterface::handleSafeAreaMarginsChanged(self.platformWindow->window()); } // ------------------------------------------------------------------------- - (BOOL)canBecomeFirstResponder { - return !(m_qioswindow->window()->flags() & Qt::WindowDoesNotAcceptFocus); + return !(self.platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus); } - (BOOL)becomeFirstResponder @@ -280,10 +286,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") qImDebug() << self << "became first responder"; } - if (qGuiApp->focusWindow() != m_qioswindow->window()) - QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); + if (qGuiApp->focusWindow() != self.platformWindow->window()) + QWindowSystemInterface::handleWindowActivated(self.platformWindow->window()); else - qImDebug() << m_qioswindow->window() << "already active, not sending window activation"; + qImDebug() << self.platformWindow->window() << "already active, not sending window activation"; return YES; } @@ -361,7 +367,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { - if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput) + if (self.platformWindow->window()->flags() & Qt::WindowTransparentForInput) return NO; return [super pointInside:point withEvent:event]; } @@ -378,7 +384,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") for (UITouch *cTouch in cTouches) { QPointF localViewPosition = QPointF::fromCGPoint([cTouch preciseLocationInView:self]); QPoint localViewPositionI = localViewPosition.toPoint(); - QPointF globalScreenPosition = m_qioswindow->mapToGlobal(localViewPositionI) + + QPointF globalScreenPosition = self.platformWindow->mapToGlobal(localViewPositionI) + (localViewPosition - localViewPositionI); qreal pressure = cTouch.force / cTouch.maximumPossibleForce; // azimuth unit vector: +x to the right, +y going downwards @@ -391,7 +397,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") qCDebug(lcQpaTablet) << i << ":" << timeStamp << localViewPosition << pressure << state << "azimuth" << azimuth.dx << azimuth.dy << "angle" << azimuthAngle << "altitude" << cTouch.altitudeAngle << "xTilt" << qBound(-60.0, altitudeAngle * azimuth.dx, 60.0) << "yTilt" << qBound(-60.0, altitudeAngle * azimuth.dy, 60.0); - QWindowSystemInterface::handleTabletEvent(m_qioswindow->window(), timeStamp, localViewPosition, globalScreenPosition, + QWindowSystemInterface::handleTabletEvent(self.platformWindow->window(), timeStamp, localViewPosition, globalScreenPosition, // device, pointerType, buttons QTabletEvent::RotationStylus, QTabletEvent::Pen, state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton, // pressure, xTilt, yTilt @@ -415,12 +421,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") // just map from the local view position to global coordinates. // tvOS: all touches start at the center of the screen and move from there. QPoint localViewPosition = QPointF::fromCGPoint([uiTouch locationInView:self]).toPoint(); - QPoint globalScreenPosition = m_qioswindow->mapToGlobal(localViewPosition); + QPoint globalScreenPosition = self.platformWindow->mapToGlobal(localViewPosition); touchPoint.area = QRectF(globalScreenPosition, QSize(0, 0)); // FIXME: Do we really need to support QTouchDevice::NormalizedPosition? - QSize screenSize = m_qioswindow->screen()->geometry().size(); + QSize screenSize = self.platformWindow->screen()->geometry().size(); touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(), globalScreenPosition.y() / screenSize.height()); @@ -439,7 +445,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") } if (m_activeTouches.isEmpty()) return; - QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); if (!static_cast<QUIWindow *>(self.window).sendingEvent) { // The event is likely delivered as part of delayed touch delivery, via // _UIGestureEnvironmentSortAndSendDelayedTouches, due to one of the two @@ -450,10 +456,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") // alert dialog, will fail to recognize. To be on the safe side, we deliver // the event asynchronously. QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>( - m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); } else { QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>( - m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); } } @@ -481,8 +487,8 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") #endif } - if (m_qioswindow->shouldAutoActivateWindow() && m_activeTouches.size() == 1) { - QPlatformWindow *topLevel = m_qioswindow; + if (self.platformWindow->shouldAutoActivateWindow() && m_activeTouches.size() == 1) { + QPlatformWindow *topLevel = self.platformWindow; while (QPlatformWindow *p = topLevel->parent()) topLevel = p; if (topLevel->window() != QGuiApplication::focusWindow()) @@ -552,7 +558,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime]; QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration()); - QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::handleTouchCancelEvent(self.platformWindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice()); } - (int)mapPressTypeToKey:(UIPress*)press @@ -580,7 +586,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") int key = [self mapPressTypeToKey:press]; if (key == Qt::Key_unknown) continue; - if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier)) + if (QWindowSystemInterface::handleKeyEvent(self.platformWindow->window(), type, key, Qt::NoModifier)) handled = true; } @@ -634,7 +640,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") - (QWindow *)qwindow { if ([self isKindOfClass:[QUIView class]]) { - if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self)->m_qioswindow) + if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self).platformWindow) return w->window(); } return nil; diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm index 69a4d375bd..a3f4156a59 100644 --- a/src/plugins/platforms/ios/quiview_accessibility.mm +++ b/src/plugins/platforms/ios/quiview_accessibility.mm @@ -49,8 +49,9 @@ if (!iface || iface->state().invisible || (iface->text(QAccessible::Name).isEmpty() && iface->text(QAccessible::Value).isEmpty() && iface->text(QAccessible::Description).isEmpty())) return; QAccessible::Id accessibleId = QAccessible::uniqueId(iface); - UIAccessibilityElement *elem = [[QMacAccessibilityElement alloc] initWithId: accessibleId withAccessibilityContainer: self]; - [m_accessibleElements addObject:[elem autorelease]]; + UIAccessibilityElement *elem = [[QT_MANGLE_NAMESPACE(QMacAccessibilityElement) alloc] initWithId:accessibleId withAccessibilityContainer:self]; + [m_accessibleElements addObject:elem]; + [elem release]; } - (void)createAccessibleContainer:(QAccessibleInterface *)iface @@ -73,7 +74,7 @@ if ([m_accessibleElements count]) return; - QWindow *win = m_qioswindow->window(); + QWindow *win = self.platformWindow->window(); QAccessibleInterface *iface = win->accessibleRoot(); if (iface) [self createAccessibleContainer: iface]; diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 814291c54a..0dd1f40b71 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -178,6 +178,85 @@ Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() return result; } +static QPoint lastMouseMovePos; + +namespace { +struct MouseEvent { + QEvent::Type type; + Qt::MouseButton button; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const MouseEvent &e) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "MouseEvent(" << e.type << ", " << e.button << ')'; + return d; +} +#endif // QT_NO_DEBUG_STREAM +} // namespace + +static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON... +{ + return GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? Qt::BackButton : Qt::ForwardButton; +} + +static inline MouseEvent eventFromMsg(const MSG &msg) +{ + switch (msg.message) { + case WM_MOUSEMOVE: + return {QEvent::MouseMove, Qt::NoButton}; + case WM_LBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::LeftButton}; + case WM_LBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::LeftButton}; + case WM_LBUTTONDBLCLK: + return {QEvent::MouseButtonDblClick, Qt::LeftButton}; + case WM_MBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::MidButton}; + case WM_MBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::MidButton}; + case WM_MBUTTONDBLCLK: + return {QEvent::MouseButtonDblClick, Qt::MidButton}; + case WM_RBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::RightButton}; + case WM_RBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::RightButton}; + case WM_RBUTTONDBLCLK: + return {QEvent::MouseButtonDblClick, Qt::RightButton}; + case WM_XBUTTONDOWN: + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; + case WM_XBUTTONUP: + return {QEvent::MouseButtonRelease, extraButton(msg.wParam)}; + case WM_XBUTTONDBLCLK: + return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)}; + case WM_NCMOUSEMOVE: + return {QEvent::NonClientAreaMouseMove, Qt::NoButton}; + case WM_NCLBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; + case WM_NCLBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton}; + case WM_NCLBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton}; + case WM_NCMBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; + case WM_NCMBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton}; + case WM_NCMBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton}; + case WM_NCRBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; + case WM_NCRBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton}; + case WM_NCRBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton}; + default: // WM_MOUSELEAVE + break; + } + return {QEvent::None, Qt::NoButton}; +} + bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) @@ -192,8 +271,33 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, if (et == QtWindows::MouseWheelEvent) return translateMouseWheelEvent(window, hwnd, msg, result); + const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + QPoint clientPosition; + QPoint globalPosition; + if (et & QtWindows::NonClientEventFlag) { + globalPosition = winEventPosition; + clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition); + } else { + clientPosition = winEventPosition; + globalPosition = QWindowsGeometryHint::mapToGlobal(hwnd, winEventPosition); + } + + // Windows sends a mouse move with no buttons pressed to signal "Enter" + // when a window is shown over the cursor. Discard the event and only use + // it for generating QEvent::Enter to be consistent with other platforms - + // X11 and macOS. + bool discardEvent = false; + if (msg.message == WM_MOUSEMOVE) { + const bool samePosition = globalPosition == lastMouseMovePos; + lastMouseMovePos = globalPosition; + if (msg.wParam == 0 && (m_windowUnderMouse.isNull() || samePosition)) + discardEvent = true; + } + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; + const MouseEvent mouseEvent = eventFromMsg(msg); + // Check for events synthesized from touch. Lower byte is touch index, 0 means pen. static const bool passSynthesizedMouseEvents = !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch); @@ -210,13 +314,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, } } - const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); - if (et & QtWindows::NonClientEventFlag) { - const QPoint globalPosition = winEventPosition; - const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition); + if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) { const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons(); QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, globalPosition, buttons, + mouseEvent.button, mouseEvent.type, QWindowsKeyMapper::queryKeyboardModifiers(), source); return false; // Allow further event processing (dragging of windows). @@ -224,7 +326,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, *result = 0; if (msg.message == WM_MOUSELEAVE) { - qCDebug(lcQpaEvents) << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow; + qCDebug(lcQpaEvents) << mouseEvent << "for" << window << "previous window under mouse=" + << m_windowUnderMouse << "tracked window=" << m_trackedWindow; // When moving out of a window, WM_MOUSEMOVE within the moved-to window is received first, // so if m_trackedWindow is not the window here, it means the cursor has left the @@ -269,7 +372,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, } } - const QPoint globalPosition = QWindowsGeometryHint::mapToGlobal(hwnd, winEventPosition); // In this context, neither an invisible nor a transparent window (transparent regarding mouse // events, "click-through") can be considered as the window under mouse. QWindow *currentWindowUnderMouse = platformWindow->hasMouseCapture() ? @@ -290,10 +392,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, // Qt expects the platform plugin to capture the mouse on // any button press until release. if (!platformWindow->hasMouseCapture() - && (msg.message == WM_LBUTTONDOWN || msg.message == WM_MBUTTONDOWN - || msg.message == WM_RBUTTONDOWN || msg.message == WM_XBUTTONDOWN - || msg.message == WM_LBUTTONDBLCLK || msg.message == WM_MBUTTONDBLCLK - || msg.message == WM_RBUTTONDBLCLK || msg.message == WM_XBUTTONDBLCLK)) { + && (mouseEvent.type == QEvent::MouseButtonPress || mouseEvent.type == QEvent::MouseButtonDblClick)) { platformWindow->setMouseGrabEnabled(true); platformWindow->setFlag(QWindowsWindow::AutoMouseCapture); qCDebug(lcQpaEvents) << "Automatic mouse capture " << window; @@ -302,8 +401,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, window->requestActivate(); } else if (platformWindow->hasMouseCapture() && platformWindow->testFlag(QWindowsWindow::AutoMouseCapture) - && (msg.message == WM_LBUTTONUP || msg.message == WM_MBUTTONUP - || msg.message == WM_RBUTTONUP || msg.message == WM_XBUTTONUP) + && mouseEvent.type == QEvent::MouseButtonRelease && !buttons) { platformWindow->setMouseGrabEnabled(false); qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window; @@ -369,9 +467,12 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, m_windowUnderMouse = currentWindowUnderMouse; } - QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons, - QWindowsKeyMapper::queryKeyboardModifiers(), - source); + if (!discardEvent && mouseEvent.type != QEvent::None) { + QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons, + mouseEvent.button, mouseEvent.type, + QWindowsKeyMapper::queryKeyboardModifiers(), + source); + } m_previousCaptureWindow = hasCapture ? window : 0; // QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND // is sent for unhandled WM_XBUTTONDOWN. @@ -397,9 +498,10 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del { // If a window is blocked by modality, it can't get the event. if (isValidWheelReceiver(window)) { + const QPoint point = (orientation == Qt::Vertical) ? QPoint(0, delta) : QPoint(delta, 0); QWindowSystemInterface::handleWheelEvent(window, QWindowsGeometryHint::mapFromGlobal(window, globalPos), - globalPos, delta, orientation, mods); + globalPos, QPoint(), point, mods); } } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2431f99ab8..7d213320a4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -2032,10 +2032,7 @@ void QXcbConnection::initializeAllAtoms() { ++ptr; } - Q_ASSERT(i == QXcbAtom::NPredefinedAtoms); - - const QByteArray settings_atom_name = "_QT_SETTINGS_TIMESTAMP_" + m_displayName; - names[i++] = settings_atom_name; + Q_ASSERT(i == QXcbAtom::NAtoms); xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms]; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index ced5208c81..4a9958f334 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -303,9 +303,6 @@ namespace QXcbAtom { _COMPIZ_TOOLKIT_ACTION, _GTK_LOAD_ICONTHEMES, - NPredefinedAtoms, - - _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms, NAtoms }; } diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index bd0d641e79..725ee0d58b 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -132,6 +132,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const case PPK_CupsOptions: ret = d->cupsOptions; break; + case PPK_Duplex: + ret = d->duplex; + break; default: ret = QPdfPrintEngine::property(key); break; @@ -140,7 +143,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const } -QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) : QPdfPrintEnginePrivate(m) +QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) + : QPdfPrintEnginePrivate(m) + , duplex(QPrint::DuplexNone) { } diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index d5363bb8cc..2a1a83b9d7 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -99,6 +99,7 @@ private: QPrintDevice m_printDevice; QStringList cupsOptions; QString cupsTempFile; + QPrint::DuplexMode duplex; }; QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/configure.json b/src/plugins/sqldrivers/configure.json index 234f880579..4802d3b04d 100644 --- a/src/plugins/sqldrivers/configure.json +++ b/src/plugins/sqldrivers/configure.json @@ -229,7 +229,7 @@ Oracle driver, as the current build will most likely fail." "summary": [ { - "section": "Qt Sql", + "section": "Qt Sql Drivers", "entries": [ "sql-db2", "sql-ibase", "sql-mysql", "sql-oci", "sql-odbc", "sql-psql", "sql-sqlite2", "sql-sqlite", "system-sqlite", "sql-tds" diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 9e8af78a8e..cdddf227ac 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -145,22 +145,12 @@ static QWindow *qt_getWindow(const QWidget *widget) return widget ? widget->window()->windowHandle() : 0; } -@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject { -QMacStylePrivate *mPrivate; -} -- (id)initWithPrivate:(QMacStylePrivate *)priv; -- (void)scrollBarStyleDidChange:(NSNotification *)notification; +@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject @end QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver); @implementation NotificationReceiver -- (id)initWithPrivate:(QMacStylePrivate *)priv -{ - self = [super init]; - mPrivate = priv; - return self; -} - (void)scrollBarStyleDidChange:(NSNotification *)notification { @@ -2285,7 +2275,7 @@ QMacStyle::QMacStyle() Q_D(QMacStyle); QMacAutoReleasePool pool; - d->receiver = [[NotificationReceiver alloc] initWithPrivate:d]; + d->receiver = [[NotificationReceiver alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:d->receiver selector:@selector(scrollBarStyleDidChange:) name:NSPreferredScrollerStyleDidChangeNotification @@ -4513,7 +4503,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw)); sv.frame = opt->rect.toCGRect(); - d->drawNSViewInRect(cw, sv, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) { + d->drawNSViewInRect(cw, sv, opt->rect, p, w != nullptr, ^(CGContextRef __unused ctx, const CGRect &rect) { [sv drawDividerInRect:rect]; }); } else { @@ -6209,7 +6199,7 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, switch (ct) { #if QT_CONFIG(spinbox) case CT_SpinBox: - if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { const int buttonWidth = 20; // FIXME Use subControlRect() sz += QSize(buttonWidth, -3); } diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm index 1e398452f7..a3511fe7b6 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm +++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm @@ -52,16 +52,13 @@ QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate); @interface QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) : NSObject -{ +@end + +@implementation QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) { NSPrintInfo *printInfo; } -- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo; -- (void)pageLayoutDidEnd:(NSPageLayout *)pageLayout - returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end -@implementation QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) -- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo +- (instancetype)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo { self = [super init]; if (self) { diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index 854779977c..ed2d0908c4 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -77,22 +77,20 @@ QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate); @interface QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) : NSObject -{ +@end + +@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) { NSPrintInfo *printInfo; } -- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo; -- (void)printPanelDidEnd:(NSPrintPanel *)printPanel - returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end -@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) -- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo +- (instancetype)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo { - if (self = [super init]) { + if ((self = [self init])) { printInfo = nsPrintInfo; } return self; } + - (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo { @@ -102,8 +100,8 @@ QT_USE_NAMESPACE QPrinter *printer = dialog->printer(); if (returnCode == NSModalResponseOK) { - PMPrintSession session = static_cast<PMPrintSession>([printInfo PMPrintSession]); - PMPrintSettings settings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]); + PMPrintSession session = static_cast<PMPrintSession>(printInfo.PMPrintSession); + PMPrintSettings settings = static_cast<PMPrintSettings>(printInfo.PMPrintSettings); UInt32 frompage, topage; PMGetFirstPage(settings, &frompage); @@ -192,6 +190,7 @@ QT_USE_NAMESPACE dialog->done((returnCode == NSModalResponseOK) ? QDialog::Accepted : QDialog::Rejected); } + @end QT_BEGIN_NAMESPACE diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index 8dba402a6e..46ce24eded 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -247,6 +247,10 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QSizeF &size, QPageSize: QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize) const { + // If it's a known page size, just return itself + if (m_pageSizes.contains(pageSize)) + return pageSize; + // Try to find a supported page size based on point size for (const QPageSize &ps : m_pageSizes) { if (ps.sizePoints() == pageSize.sizePoints()) diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp index 0230ebddc8..3c24e5ac69 100644 --- a/src/printsupport/kernel/qprintengine_pdf.cpp +++ b/src/printsupport/kernel/qprintengine_pdf.cpp @@ -132,6 +132,8 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va // The following keys are settings that are unsupported by the PDF PrintEngine case PPK_CustomBase: break; + case PPK_Duplex: + break; // The following keys are properties and settings that are supported by the PDF PrintEngine case PPK_CollateCopies: @@ -203,9 +205,6 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va case PPK_FontEmbedding: d->embedFonts = value.toBool(); break; - case PPK_Duplex: - d->duplex = static_cast<QPrint::DuplexMode>(value.toInt()); - break; case PPK_CustomPaperSize: d->m_pageLayout.setPageSize(QPageSize(value.toSizeF(), QPageSize::Point)); break; @@ -249,6 +248,7 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const // The following keys are settings that are unsupported by the PDF PrintEngine // Return sensible default values to ensure consistent behavior across platforms case PPK_CustomBase: + case PPK_Duplex: // Special case, leave null break; @@ -322,9 +322,6 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const case PPK_FontEmbedding: ret = d->embedFonts; break; - case PPK_Duplex: - ret = d->duplex; - break; case PPK_CustomPaperSize: ret = d->m_pageLayout.fullRectPoints().size(); break; @@ -389,7 +386,6 @@ void QPdfPrintEnginePrivate::closePrintDevice() QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m) : QPdfEnginePrivate(), - duplex(QPrint::DuplexNone), collate(true), copies(1), pageOrder(QPrinter::FirstPageFirst), diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h index bb01a2e9e1..e7ae21f260 100644 --- a/src/printsupport/kernel/qprintengine_pdf_p.h +++ b/src/printsupport/kernel/qprintengine_pdf_p.h @@ -130,7 +130,6 @@ private: QString printProgram; QString selectionOption; - QPrint::DuplexMode duplex; bool collate; int copies; QPrinter::PageOrder pageOrder; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 8a2cdcb34f..ed4292ff3d 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -224,8 +224,8 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons class QPrinterPagedPaintDevicePrivate : public QPagedPaintDevicePrivate { public: - QPrinterPagedPaintDevicePrivate(QPrinterPrivate *d) - : QPagedPaintDevicePrivate(), pd(d) + QPrinterPagedPaintDevicePrivate(QPrinter *p) + : QPagedPaintDevicePrivate(), m_printer(p) {} virtual ~QPrinterPagedPaintDevicePrivate() @@ -233,6 +233,8 @@ public: bool setPageLayout(const QPageLayout &newPageLayout) override { + QPrinterPrivate *pd = QPrinterPrivate::get(m_printer); + if (pd->paintEngine->type() != QPaintEngine::Pdf && pd->printEngine->printerState() == QPrinter::Active) { qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active"); @@ -242,14 +244,13 @@ public: // Try to set the print engine page layout pd->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newPageLayout)); - // Set QPagedPaintDevice layout to match the current print engine value - m_pageLayout = pageLayout(); - return pageLayout().isEquivalentTo(newPageLayout); } bool setPageSize(const QPageSize &pageSize) override { + QPrinterPrivate *pd = QPrinterPrivate::get(m_printer); + if (pd->paintEngine->type() != QPaintEngine::Pdf && pd->printEngine->printerState() == QPrinter::Active) { qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active"); @@ -260,46 +261,38 @@ public: // Try to set the print engine page size pd->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize)); - // Set QPagedPaintDevice layout to match the current print engine value - m_pageLayout = pageLayout(); - return pageLayout().pageSize().isEquivalentTo(pageSize); } bool setPageOrientation(QPageLayout::Orientation orientation) override { + QPrinterPrivate *pd = QPrinterPrivate::get(m_printer); + // Set the print engine value pd->setProperty(QPrintEngine::PPK_Orientation, orientation); - // Set QPagedPaintDevice layout to match the current print engine value - m_pageLayout = pageLayout(); - return pageLayout().orientation() == orientation; } - bool setPageMargins(const QMarginsF &margins) override - { - return setPageMargins(margins, pageLayout().units()); - } - bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override { + QPrinterPrivate *pd = QPrinterPrivate::get(m_printer); + // Try to set print engine margins QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(margins, units); pd->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair)); - // Set QPagedPaintDevice layout to match the current print engine value - m_pageLayout = pageLayout(); - return pageLayout().margins() == margins && pageLayout().units() == units; } QPageLayout pageLayout() const override { + QPrinterPrivate *pd = QPrinterPrivate::get(m_printer); + return pd->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>(); } - QPrinterPrivate *pd; + QPrinter *m_printer; }; @@ -554,11 +547,9 @@ public: Creates a new printer object with the given \a mode. */ QPrinter::QPrinter(PrinterMode mode) - : QPagedPaintDevice(), + : QPagedPaintDevice(new QPrinterPagedPaintDevicePrivate(this)), d_ptr(new QPrinterPrivate(this)) { - delete d; - d = new QPrinterPagedPaintDevicePrivate(d_func()); d_ptr->init(QPrinterInfo(), mode); } @@ -568,11 +559,9 @@ QPrinter::QPrinter(PrinterMode mode) Creates a new printer object with the given \a printer and \a mode. */ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode) - : QPagedPaintDevice(), + : QPagedPaintDevice(new QPrinterPagedPaintDevicePrivate(this)), d_ptr(new QPrinterPrivate(this)) { - delete d; - d = new QPrinterPagedPaintDevicePrivate(d_func()); d_ptr->init(printer, mode); } @@ -1469,8 +1458,6 @@ void QPrinter::setFullPage(bool fp) Q_D(QPrinter); // Set the print engine d->setProperty(QPrintEngine::PPK_FullPage, fp); - // Set QPagedPaintDevice layout to match the current print engine value - devicePageLayout() = pageLayout(); } diff --git a/src/printsupport/kernel/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h index 6ced466236..37c9702c17 100644 --- a/src/printsupport/kernel/qprinter_p.h +++ b/src/printsupport/kernel/qprinter_p.h @@ -94,6 +94,10 @@ public: } + static QPrinterPrivate *get(QPrinter *printer) { + return printer->d_ptr.get(); + } + void init(const QPrinterInfo &printer, QPrinter::PrinterMode mode); QPrinterInfo findValidPrinter(const QPrinterInfo &printer = QPrinterInfo()); diff --git a/src/sql/configure.json b/src/sql/configure.json new file mode 100644 index 0000000000..8fdc27e3a2 --- /dev/null +++ b/src/sql/configure.json @@ -0,0 +1,22 @@ +{ + "module": "sql", + "depends": [ + "core" + ], + + "features": { + "sqlmodel": { + "label": "SQL item models", + "purpose": "Provides item model classes backed by SQL databases.", + "condition": "features.itemmodel", + "output": [ "publicFeature" ] + } + }, + + "summary": [ + { + "section": "Qt Sql", + "entries": [ "sqlmodel" ] + } + ] +} diff --git a/src/sql/kernel/qtsqlglobal.h b/src/sql/kernel/qtsqlglobal.h index d421adc84b..ec79e8da1e 100644 --- a/src/sql/kernel/qtsqlglobal.h +++ b/src/sql/kernel/qtsqlglobal.h @@ -41,6 +41,7 @@ #define QTSQLGLOBAL_H #include <QtCore/qglobal.h> +#include <QtSql/qtsql-config.h> QT_BEGIN_NAMESPACE diff --git a/src/sql/kernel/qtsqlglobal_p.h b/src/sql/kernel/qtsqlglobal_p.h index ab45f6cd38..78a2461257 100644 --- a/src/sql/kernel/qtsqlglobal_p.h +++ b/src/sql/kernel/qtsqlglobal_p.h @@ -53,5 +53,6 @@ #include <QtSql/qtsqlglobal.h> #include <QtCore/private/qglobal_p.h> +#include <QtSql/private/qtsql-config_p.h> #endif // QTSQLGLOBAL_P_H diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h index 869a5f030c..427b369ae2 100644 --- a/src/sql/models/qsqlquerymodel.h +++ b/src/sql/models/qsqlquerymodel.h @@ -44,8 +44,9 @@ #include <QtCore/qabstractitemmodel.h> #include <QtSql/qsqldatabase.h> -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(sqlmodel); +QT_BEGIN_NAMESPACE class QSqlQueryModelPrivate; class QSqlError; diff --git a/src/sql/models/qsqlquerymodel_p.h b/src/sql/models/qsqlquerymodel_p.h index ffc34b9f95..76aaf00c88 100644 --- a/src/sql/models/qsqlquerymodel_p.h +++ b/src/sql/models/qsqlquerymodel_p.h @@ -60,6 +60,8 @@ #include "QtCore/qvarlengtharray.h" #include "QtCore/qvector.h" +QT_REQUIRE_CONFIG(sqlmodel); + QT_BEGIN_NAMESPACE class QSqlQueryModelPrivate: public QAbstractItemModelPrivate diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h index 53f43a4acb..0af87f64ae 100644 --- a/src/sql/models/qsqlrelationaldelegate.h +++ b/src/sql/models/qsqlrelationaldelegate.h @@ -42,6 +42,8 @@ #include <QtSql/qtsqlglobal.h> +QT_REQUIRE_CONFIG(sqlmodel); + #ifdef QT_WIDGETS_LIB #include <QtWidgets/qitemdelegate.h> diff --git a/src/sql/models/qsqlrelationaltablemodel.h b/src/sql/models/qsqlrelationaltablemodel.h index 90b7a6481f..555755009c 100644 --- a/src/sql/models/qsqlrelationaltablemodel.h +++ b/src/sql/models/qsqlrelationaltablemodel.h @@ -45,6 +45,8 @@ #include <QtCore/qtypeinfo.h> +QT_REQUIRE_CONFIG(sqlmodel); + QT_BEGIN_NAMESPACE diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h index 77b0517c74..7acc7dc94d 100644 --- a/src/sql/models/qsqltablemodel.h +++ b/src/sql/models/qsqltablemodel.h @@ -44,6 +44,8 @@ #include <QtSql/qsqldatabase.h> #include <QtSql/qsqlquerymodel.h> +QT_REQUIRE_CONFIG(sqlmodel); + QT_BEGIN_NAMESPACE diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index 490bb48a24..faa1b30803 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -56,6 +56,8 @@ #include "QtSql/qsqlindex.h" #include "QtCore/qmap.h" +QT_REQUIRE_CONFIG(sqlmodel); + QT_BEGIN_NAMESPACE class Q_AUTOTEST_EXPORT QSqlTableModelPrivate: public QSqlQueryModelPrivate diff --git a/src/sql/sql.pro b/src/sql/sql.pro index 821ae1c9b9..1cd2a05250 100644 --- a/src/sql/sql.pro +++ b/src/sql/sql.pro @@ -11,7 +11,7 @@ PRECOMPILED_HEADER = ../corelib/global/qt_pch.h SQL_P = sql include(kernel/kernel.pri) -include(models/models.pri) +qtConfig(sqlmodel): include(models/models.pri) MODULE_PLUGIN_TYPES = \ sqldrivers diff --git a/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp b/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp index 0dc45bef76..de301b8df9 100644 --- a/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp +++ b/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp @@ -48,19 +48,41 @@ ** ****************************************************************************/ +#include <QtTest> + //! [0] class MyFirstTest: public QObject { Q_OBJECT + +private: + bool myCondition() + { + return true; + } + private slots: void initTestCase() - { qDebug("called before everything else"); } + { + qDebug("Called before everything else."); + } + void myFirstTest() - { QVERIFY(1 == 1); } + { + QVERIFY(true); // check that a condition is satisfied + QCOMPARE(1, 1); // compare two values + } + void mySecondTest() - { QVERIFY(1 != 2); } + { + QVERIFY(myCondition()); + QVERIFY(1 != 2); + } + void cleanupTestCase() - { qDebug("called after myFirstTest and mySecondTest"); } + { + qDebug("Called after myFirstTest and mySecondTest."); + } }; //! [0] diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 9bd210d71f..2e2af8d67f 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -69,8 +69,8 @@ \li Qt Test supports benchmarking and provides several measurement back-ends. \row \li \b {IDE friendly} - \li Qt Test outputs messages that can be interpreted by Visual - Studio and KDevelop. + \li Qt Test outputs messages that can be interpreted by Qt Creator, Visual + Studio, and KDevelop. \row \li \b Thread-safety \li The error reporting is thread safe and atomic. diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index f38f7ed4df..2e50f4f44f 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -253,6 +253,22 @@ namespace QTest return nullptr; } + template<typename F> // Output QFlags of registered enumerations + inline typename std::enable_if<QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f) + { + const QMetaEnum me = QMetaEnum::fromType<F>(); + return qstrdup(me.valueToKeys(int(f)).constData()); + } + + template <typename F> // Fallback: Output hex value + inline typename std::enable_if<!QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f) + { + const size_t space = 3 + 2 * sizeof(unsigned); // 2 for 0x, two hex digits per byte, 1 for '\0' + char *msg = new char[space]; + qsnprintf(msg, space, "0x%x", unsigned(f)); + return msg; + } + } // namespace Internal template<typename T> diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h index 046fe1a3e7..a6cea26884 100644 --- a/src/testlib/qtestsystem.h +++ b/src/testlib/qtestsystem.h @@ -74,10 +74,8 @@ namespace QTest QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); remaining = deadline.remainingTime(); - if (remaining > 0) { + if (remaining > 0) QTest::qSleep(qMin(10, remaining)); - remaining = deadline.remainingTime(); - } if (predicate()) return true; diff --git a/src/testlib/qxctestlogger.mm b/src/testlib/qxctestlogger.mm index 62fd73070f..9fa9da2fdd 100644 --- a/src/testlib/qxctestlogger.mm +++ b/src/testlib/qxctestlogger.mm @@ -200,7 +200,7 @@ private: [autoreleasepool release]; } -+ (id)defaultTestSuite ++ (QTestLibTests *)defaultTestSuite { return [[QtTestLibTests alloc] initWithName:@"QtTestLib"]; } @@ -255,7 +255,7 @@ static XCTestSuiteRun *s_qtTestSuiteRun = 0; @implementation QtTestLibTest -- (id)initWithInvocation:(NSInvocation *)invocation +- (instancetype)initWithInvocation:(NSInvocation *)invocation { if (self = [super initWithInvocation:invocation]) { // The test object name and function name are used by XCTest after QtTestLib has @@ -322,7 +322,7 @@ QXcodeTestLogger *QXcodeTestLogger::s_currentTestLogger = 0; QXcodeTestLogger::QXcodeTestLogger() : QAbstractTestLogger(0) - , m_testRuns([[NSMutableArray arrayWithCapacity:2] retain]) + , m_testRuns([[NSMutableArray<XCTestRun *> arrayWithCapacity:2] retain]) { Q_ASSERT(!s_currentTestLogger); @@ -383,11 +383,11 @@ static bool isTestFunctionInActiveScope(const char *function) Q_ASSERT(activeScope == Selected); - static NSArray *forcedTests = [@[ @"initTestCase", @"initTestCase_data", @"cleanupTestCase" ] retain]; + static NSArray<NSString *> *forcedTests = [@[ @"initTestCase", @"initTestCase_data", @"cleanupTestCase" ] retain]; if ([forcedTests containsObject:[NSString stringWithUTF8String:function]]) return true; - static NSArray *testsInScope = [[testScope componentsSeparatedByString:@","] retain]; + static NSArray<NSString *> *testsInScope = [[testScope componentsSeparatedByString:@","] retain]; bool inScope = [testsInScope containsObject:[NSString stringWithFormat:@"%s/%s", QTestResult::currentTestObjectName(), function]]; diff --git a/src/testlib/qxctestlogger_p.h b/src/testlib/qxctestlogger_p.h index 1b641f18af..8baa5aa27f 100644 --- a/src/testlib/qxctestlogger_p.h +++ b/src/testlib/qxctestlogger_p.h @@ -90,7 +90,7 @@ private: void pushTestRunForTest(XCTest *test, bool start); XCTestRun *popTestRun(); - NSMutableArray *m_testRuns; + NSMutableArray<XCTestRun *> *m_testRuns; static QXcodeTestLogger *s_currentTestLogger; }; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 3d91bdef34..ef369349b2 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -517,7 +517,7 @@ void QFileDialog::changeEvent(QEvent *e) QFileDialogPrivate::QFileDialogPrivate() : -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) proxyModel(0), #endif model(0), @@ -663,7 +663,7 @@ void QFileDialogPrivate::retranslateStrings() QList<QAction*> actions = qFileDialogUi->treeView->header()->actions(); QAbstractItemModel *abstractModel = model; -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) if (proxyModel) abstractModel = proxyModel; #endif @@ -2796,7 +2796,7 @@ bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPo QList<QAction*> actions = headerView->actions(); QAbstractItemModel *abstractModel = model; -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) if (proxyModel) abstractModel = proxyModel; #endif @@ -2965,7 +2965,7 @@ void QFileDialogPrivate::createWidgets() q, SLOT(_q_showHeader(QAction*)));; QAbstractItemModel *abstractModel = model; -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) if (proxyModel) abstractModel = proxyModel; #endif @@ -3046,7 +3046,7 @@ void QFileDialogPrivate::_q_showHeader(QAction *action) qFileDialogUi->treeView->header()->setSectionHidden(actionGroup->actions().indexOf(action) + 1, !action->isChecked()); } -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) /*! \since 4.3 @@ -3124,7 +3124,7 @@ QAbstractProxyModel *QFileDialog::proxyModel() const Q_D(const QFileDialog); return d->proxyModel; } -#endif // QT_NO_PROXYMODEL +#endif // QT_CONFIG(proxymodel) /*! \internal diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 1cbd690f24..8646894750 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -178,7 +178,7 @@ public: void setSupportedSchemes(const QStringList &schemes); QStringList supportedSchemes() const; -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) void setProxyModel(QAbstractProxyModel *model); QAbstractProxyModel *proxyModel() const; #endif diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 17290381d3..3a93a53911 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -227,7 +227,7 @@ public: void _q_fileRenamed(const QString &path, const QString &oldName, const QString &newName); // layout -#ifndef QT_NO_PROXYMODEL +#if QT_CONFIG(proxymodel) QAbstractProxyModel *proxyModel; #endif @@ -346,17 +346,17 @@ private: }; QModelIndex QFileDialogPrivate::mapToSource(const QModelIndex &index) const { -#ifdef QT_NO_PROXYMODEL - return index; -#else +#if QT_CONFIG(proxymodel) return proxyModel ? proxyModel->mapToSource(index) : index; +#else + return index; #endif } QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) const { -#ifdef QT_NO_PROXYMODEL - return index; -#else +#if QT_CONFIG(proxymodel) return proxyModel ? proxyModel->mapFromSource(index) : index; +#else + return index; #endif } diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp index f7f09486e9..398ef1aaf5 100644 --- a/src/widgets/graphicsview/qgraphicssceneevent.cpp +++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp @@ -259,8 +259,9 @@ #include "qgraphicssceneevent.h" -#ifndef QT_NO_DEBUG +#ifndef QT_NO_DEBUG_STREAM #include <QtCore/qdebug.h> +#include <private/qdebug_p.h> #endif #include <QtCore/qmap.h> #include <QtCore/qpoint.h> @@ -1730,4 +1731,99 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos) d->newPos = pos; } +#ifndef QT_NO_DEBUG_STREAM +template <class Event> +static inline void formatPositions(QDebug &debug, const Event *event) +{ + debug << ", pos="; + QtDebugUtils::formatQPoint(debug, event->pos()); + debug << ", scenePos="; + QtDebugUtils::formatQPoint(debug, event->scenePos()); + debug << ", screenPos="; + QtDebugUtils::formatQPoint(debug, event->screenPos()); +} + +QDebug operator<<(QDebug debug, const QGraphicsSceneEvent *event) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + if (!event) { + debug << "QGraphicsSceneEvent(0)"; + return debug; + } + + const QEvent::Type type = event->type(); + switch (type) { + case QEvent::GraphicsSceneMouseMove: + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMouseDoubleClick: { + const QGraphicsSceneMouseEvent *me = static_cast<const QGraphicsSceneMouseEvent *>(event); + const Qt::MouseButton button = me->button(); + const Qt::MouseButtons buttons = me->buttons(); + debug << "QGraphicsSceneMouseEvent("; + QtDebugUtils::formatQEnum(debug, type); + if (type != QEvent::GraphicsSceneMouseMove) { + debug << ", "; + QtDebugUtils::formatQEnum(debug, button); + } + if (buttons && button != buttons) { + debug << ", buttons="; + QtDebugUtils::formatQFlags(debug, buttons); + } + QtDebugUtils::formatNonNullQFlags(debug, ", ", me->modifiers()); + formatPositions(debug, me); + QtDebugUtils::formatNonNullQEnum(debug, ", ", me->source()); + QtDebugUtils::formatNonNullQFlags(debug, ", flags=", me->flags()); + debug << ')'; + } + break; + case QEvent::GraphicsSceneContextMenu: { + const QGraphicsSceneContextMenuEvent *ce = static_cast<const QGraphicsSceneContextMenuEvent *>(event); + debug << "QGraphicsSceneContextMenuEvent(reason=" << ce->reason(); + QtDebugUtils::formatNonNullQFlags(debug, ", ", ce->modifiers()); + formatPositions(debug, ce); + debug << ')'; + } + break; + case QEvent::GraphicsSceneHoverEnter: + case QEvent::GraphicsSceneHoverMove: + case QEvent::GraphicsSceneHoverLeave: + debug << "QGraphicsSceneHoverEvent("; + formatPositions(debug, static_cast<const QGraphicsSceneHoverEvent *>(event)); + debug << ')'; + break; + case QEvent::GraphicsSceneHelp: + break; + case QEvent::GraphicsSceneDragEnter: + case QEvent::GraphicsSceneDragMove: + case QEvent::GraphicsSceneDragLeave: + case QEvent::GraphicsSceneDrop: { + const QGraphicsSceneDragDropEvent *de = static_cast<const QGraphicsSceneDragDropEvent *>(event); + debug << "QGraphicsSceneDragDropEvent(proposedAction="; + QtDebugUtils::formatQEnum(debug, de->proposedAction()); + debug << ", possibleActions="; + QtDebugUtils::formatQFlags(debug, de->possibleActions()); + debug << ", source=" << de->source(); + QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", de->buttons()); + QtDebugUtils::formatNonNullQFlags(debug, ", ", de->modifiers()); + formatPositions(debug, de); + } + break; + case QEvent::GraphicsSceneWheel: { + const QGraphicsSceneWheelEvent *we = static_cast<const QGraphicsSceneWheelEvent *>(event); + debug << "QGraphicsSceneWheelEvent("; + QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", we->buttons()); + QtDebugUtils::formatNonNullQFlags(debug, ", ", we->modifiers()); + formatPositions(debug, we); + debug << ')'; + } + break; + default: + break; + } + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + QT_END_NAMESPACE diff --git a/src/widgets/graphicsview/qgraphicssceneevent.h b/src/widgets/graphicsview/qgraphicssceneevent.h index 77b53e401d..9d940be2c0 100644 --- a/src/widgets/graphicsview/qgraphicssceneevent.h +++ b/src/widgets/graphicsview/qgraphicssceneevent.h @@ -320,6 +320,10 @@ public: void setNewPos(const QPointF &pos); }; +#ifndef QT_NO_DEBUG_STREAM +Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QGraphicsSceneEvent *); +#endif + QT_END_NAMESPACE #endif diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 1fedad80aa..9aa14db368 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -48,9 +48,6 @@ QT_BEGIN_NAMESPACE -// workaround for VC++ 6.0 linker bug (?) -typedef bool(*LessThan)(const QPair<QListWidgetItem*,int>&,const QPair<QListWidgetItem*,int>&); - class QListWidgetMimeData : public QMimeData { Q_OBJECT @@ -301,7 +298,7 @@ void QListModel::sort(int column, Qt::SortOrder order) sorting[i].second = i; } - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::sort(sorting.begin(), sorting.end(), compare); QModelIndexList fromIndexes; QModelIndexList toIndexes; @@ -338,7 +335,7 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en sorting[i].second = start + i; } - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::sort(sorting.begin(), sorting.end(), compare); QModelIndexList oldPersistentIndexes = persistentIndexList(); diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 1cb88cbeeb..0c746d2e02 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -506,7 +506,7 @@ void QTableModel::sort(int column, Qt::SortOrder order) unsortable.append(row); } - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::stable_sort(sortable.begin(), sortable.end(), compare); QVector<QTableWidgetItem*> sorted_table(tableItems.count()); @@ -558,7 +558,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order, sorting.append(QPair<QTableWidgetItem*,int>(itm, row)); } - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::stable_sort(sorting.begin(), sorting.end(), compare); QModelIndexList oldPersistentIndexes, newPersistentIndexes; QVector<QTableWidgetItem*> newTable = tableItems; diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h index 6412477be0..74b1f226c1 100644 --- a/src/widgets/itemviews/qtablewidget_p.h +++ b/src/widgets/itemviews/qtablewidget_p.h @@ -62,9 +62,6 @@ QT_REQUIRE_CONFIG(tablewidget); QT_BEGIN_NAMESPACE -// workaround for VC++ 6.0 linker bug -typedef bool(*LessThan)(const QPair<QTableWidgetItem*,int>&,const QPair<QTableWidgetItem*,int>&); - class QTableWidgetMimeData : public QMimeData { Q_OBJECT diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index ebeefad682..4a02f30822 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2495,7 +2495,6 @@ void QTreeView::scrollContentsBy(int dx, int dy) int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy) int currentViewIndex = currentScrollbarValue; // the first visible item int previousViewIndex = previousScrollbarValue; - const QVector<QTreeViewItem> viewItems = d->viewItems; dy = 0; if (previousViewIndex < currentViewIndex) { // scrolling down for (int i = previousViewIndex; i < currentViewIndex; ++i) { diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index de7f7c0b77..07907711d7 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -52,9 +52,6 @@ QT_BEGIN_NAMESPACE -// workaround for VC++ 6.0 linker bug (?) -typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&); - class QTreeModelLessThan { public: @@ -610,7 +607,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order, sorting[i].second = start + i; } - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::stable_sort(sorting.begin(), sorting.end(), compare); QModelIndexList oldPersistentIndexes; @@ -777,7 +774,7 @@ bool QTreeModel::isChanging() const if column is -1 then all columns have changed */ -void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column) +void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles) { if (signalsBlocked()) return; @@ -800,7 +797,7 @@ void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column) topLeft = index(item, column); bottomRight = topLeft; } - emit dataChanged(topLeft, bottomRight); + emit dataChanged(topLeft, bottomRight, roles); } void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count) @@ -850,7 +847,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO } // do the sorting - LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); + const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan); std::stable_sort(sorting.begin(), sorting.end(), compare); QModelIndexList fromList; @@ -1766,11 +1763,14 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value) } if (model) { - model->emitDataChanged(this, column); + const QVector<int> roles((role == Qt::DisplayRole || role == Qt::EditRole) ? + QVector<int>({Qt::DisplayRole, Qt::EditRole}) : + QVector<int>({role})); + model->emitDataChanged(this, column, roles); if (role == Qt::CheckStateRole) { QTreeWidgetItem *p; for (p = par; p && (p->itemFlags & Qt::ItemIsAutoTristate); p = p->par) - model->emitDataChanged(p, column); + model->emitDataChanged(p, column, roles); } } } diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index a31af0428a..24919c411d 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -339,6 +339,7 @@ Q_SIGNALS: void itemDoubleClicked(QTreeWidgetItem *item, int column); void itemActivated(QTreeWidgetItem *item, int column); void itemEntered(QTreeWidgetItem *item, int column); + // ### Qt 6: add changed roles void itemChanged(QTreeWidgetItem *item, int column); void itemExpanded(QTreeWidgetItem *item); void itemCollapsed(QTreeWidgetItem *item); diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h index f4625842ef..7bc8af8fbd 100644 --- a/src/widgets/itemviews/qtreewidget_p.h +++ b/src/widgets/itemviews/qtreewidget_p.h @@ -139,7 +139,7 @@ public: protected: QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = 0); - void emitDataChanged(QTreeWidgetItem *item, int column); + void emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles); void beginInsertItems(QTreeWidgetItem *parent, int row, int count); void endInsertItems(); void beginRemoveItems(QTreeWidgetItem *parent, int row, int count); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b855e32f2d..4cf52f994a 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1020,17 +1020,17 @@ QString QApplication::styleSheet() const void QApplication::setStyleSheet(const QString& styleSheet) { QApplicationPrivate::styleSheet = styleSheet; - QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style); + QStyleSheetStyle *styleSheetStyle = qt_styleSheet(QApplicationPrivate::app_style); if (styleSheet.isEmpty()) { // application style sheet removed - if (!proxy) + if (!styleSheetStyle) return; // there was no stylesheet before - setStyle(proxy->base); - } else if (proxy) { // style sheet update, just repolish - proxy->repolish(qApp); + setStyle(styleSheetStyle->base); + } else if (styleSheetStyle) { // style sheet update, just repolish + styleSheetStyle->repolish(qApp); } else { // stylesheet set the first time - QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style); - QApplicationPrivate::app_style->setParent(newProxy); - setStyle(newProxy); + QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(QApplicationPrivate::app_style); + QApplicationPrivate::app_style->setParent(newStyleSheetStyle); + setStyle(newStyleSheetStyle); } } @@ -1140,11 +1140,11 @@ void QApplication::setStyle(QStyle *style) QStyle *old = QApplicationPrivate::app_style; // save #ifndef QT_NO_STYLE_STYLESHEET - if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) { + if (!QApplicationPrivate::styleSheet.isEmpty() && !qt_styleSheet(style)) { // we have a stylesheet already and a new style is being set - QStyleSheetStyle *newProxy = new QStyleSheetStyle(style); - style->setParent(newProxy); - QApplicationPrivate::app_style = newProxy; + QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(style); + style->setParent(newStyleSheetStyle); + QApplicationPrivate::app_style = newStyleSheetStyle; } else #endif // QT_NO_STYLE_STYLESHEET QApplicationPrivate::app_style = style; @@ -1194,8 +1194,8 @@ void QApplication::setStyle(QStyle *style) } #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) { - oldProxy->deref(); + if (QStyleSheetStyle *oldStyleSheetStyle = qt_styleSheet(old)) { + oldStyleSheetStyle->deref(); } else #endif if (old && old->parent() == qApp) { @@ -3272,6 +3272,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), phase, wheel->source(), wheel->inverted()); + we.setTimestamp(wheel->timestamp()); bool eventAccepted; do { we.spont = spontaneous && w == receiver; @@ -3308,6 +3309,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos()); QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), wheel->phase(), wheel->source()); + we.setTimestamp(wheel->timestamp()); we.spont = true; we.ignore(); d->notify_helper(QApplicationPrivate::wheel_widget, &we); diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index f3db4f4e2d..64acd8d229 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1244,6 +1244,26 @@ int QLayout::indexOf(QWidget *widget) const } /*! + \since 5.12 + Searches for layout item \a layoutItem in this layout (not including child + layouts). + + Returns the index of \a layoutItem, or -1 if \a layoutItem is not found. +*/ +int QLayout::indexOf(QLayoutItem *layoutItem) const +{ + int i = 0; + QLayoutItem *item = itemAt(i); + while (item) { + if (item == layoutItem) + return i; + ++i; + item = itemAt(i); + } + return -1; +} + +/*! \enum QLayout::SizeConstraint The possible values are: diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index bcc33a0811..616f4e7164 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -122,6 +122,7 @@ public: virtual QLayoutItem *itemAt(int index) const = 0; virtual QLayoutItem *takeAt(int index) = 0; virtual int indexOf(QWidget *) const; + QT6_VIRTUAL int indexOf(QLayoutItem *) const; virtual int count() const = 0; bool isEmpty() const override; QSizePolicy::ControlTypes controlTypes() const override; diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index baf717d715..b10ccdd9fe 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -383,7 +383,7 @@ int QTipLabel::getTipScreen(const QPoint &pos, QWidget *w) void QTipLabel::placeTip(const QPoint &pos, QWidget *w) { #ifndef QT_NO_STYLE_STYLESHEET - if (testAttribute(Qt::WA_StyleSheet) || (w && qobject_cast<QStyleSheetStyle *>(w->style()))) { + if (testAttribute(Qt::WA_StyleSheet) || (w && qt_styleSheet(w->style()))) { //the stylesheet need to know the real parent QTipLabel::instance->setProperty("_q_stylesheet_parent", QVariant::fromValue(w)); //we force the style to be the QStyleSheetStyle, and force to clear the cache as well. diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 74f2dc0c41..138733476f 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1847,7 +1847,7 @@ void QWidgetPrivate::deleteExtra() deleteSysExtra(); #ifndef QT_NO_STYLE_STYLESHEET // dereference the stylesheet style - if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style)) + if (QStyleSheetStyle *proxy = qt_styleSheet(extra->style)) proxy->deref(); #endif if (extra->topextra) { @@ -2657,7 +2657,7 @@ void QWidget::setStyleSheet(const QString& styleSheet) return; d->createExtra(); - QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style); + QStyleSheetStyle *proxy = qt_styleSheet(d->extra->style); d->extra->styleSheet = styleSheet; if (styleSheet.isEmpty()) { // stylesheet removed if (!proxy) @@ -2722,12 +2722,12 @@ void QWidget::setStyle(QStyle *style) setAttribute(Qt::WA_SetStyle, style != 0); d->createExtra(); #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) { + if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) { //if for some reason someone try to set a QStyleSheetStyle, ref it //(this may happen for exemple in QButtonDialogBox which propagates its style) - proxy->ref(); + styleSheetStyle->ref(); d->setStyle_helper(style, false); - } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) { + } else if (qt_styleSheet(d->extra->style) || !qApp->styleSheet().isEmpty()) { // if we have an application stylesheet or have a proxy already, propagate d->setStyle_helper(new QStyleSheetStyle(style), true); } else @@ -2735,48 +2735,22 @@ void QWidget::setStyle(QStyle *style) d->setStyle_helper(style, false); } -void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool -#if 0 // Used to be included in Qt4 for Q_WS_MAC - metalHack -#endif - ) +void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate) { Q_Q(QWidget); - QStyle *oldStyle = q->style(); -#ifndef QT_NO_STYLE_STYLESHEET - QPointer<QStyle> origStyle; -#endif + QStyle *oldStyle = q->style(); -#if 0 // Used to be included in Qt4 for Q_WS_MAC - // the metalhack boolean allows Qt/Mac to do a proper re-polish depending - // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever - // set when changing that attribute and passes the widget's CURRENT style. - // therefore no need to do a reassignment. - if (!metalHack) -#endif - { - createExtra(); + createExtra(); #ifndef QT_NO_STYLE_STYLESHEET - origStyle = extra->style.data(); + QPointer<QStyle> origStyle = extra->style; #endif - extra->style = newStyle; - } + extra->style = newStyle; // repolish - if (q->windowType() != Qt::Desktop) { - if (polished) { - oldStyle->unpolish(q); -#if 0 // Used to be included in Qt4 for Q_WS_MAC - if (metalHack) - macUpdateMetalAttribute(); -#endif - q->style()->polish(q); -#if 0 // Used to be included in Qt4 for Q_WS_MAC - } else if (metalHack) { - macUpdateMetalAttribute(); -#endif - } + if (polished && q->windowType() != Qt::Desktop) { + oldStyle->unpolish(q); + q->style()->polish(q); } if (propagate) { @@ -2790,8 +2764,8 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool } #ifndef QT_NO_STYLE_STYLESHEET - if (!qobject_cast<QStyleSheetStyle*>(newStyle)) { - if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) { + if (!qt_styleSheet(newStyle)) { + if (const QStyleSheetStyle* cssStyle = qt_styleSheet(origStyle)) { cssStyle->clearWidgetFont(q); } } @@ -2802,7 +2776,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool #ifndef QT_NO_STYLE_STYLESHEET // dereference the old stylesheet style - if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data())) + if (QStyleSheetStyle *proxy = qt_styleSheet(origStyle)) proxy->deref(); #endif } @@ -2813,7 +2787,9 @@ void QWidgetPrivate::inheritStyle() #ifndef QT_NO_STYLE_STYLESHEET Q_Q(QWidget); - QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0; + QStyle *extraStyle = extra ? (QStyle*)extra->style : nullptr; + + QStyleSheetStyle *proxy = qt_styleSheet(extraStyle); if (!q->styleSheet().isEmpty()) { Q_ASSERT(proxy); @@ -2821,16 +2797,16 @@ void QWidgetPrivate::inheritStyle() return; } - QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0); + QStyle *origStyle = proxy ? proxy->base : extraStyle; QWidget *parent = q->parentWidget(); QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0; // If we have stylesheet on app or parent has stylesheet style, we need // to be running a proxy - if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) { + if (!qApp->styleSheet().isEmpty() || qt_styleSheet(parentStyle)) { QStyle *newStyle = parentStyle; if (q->testAttribute(Qt::WA_SetStyle)) newStyle = new QStyleSheetStyle(origStyle); - else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle)) + else if (QStyleSheetStyle *newProxy = qt_styleSheet(parentStyle)) newProxy->ref(); setStyle_helper(newStyle, true); @@ -2839,7 +2815,7 @@ void QWidgetPrivate::inheritStyle() // So, we have no stylesheet on parent/app and we have an empty stylesheet // we just need our original style back - if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different? + if (origStyle == extraStyle) // is it any different? return; // We could have inherited the proxy from our parent (which has a custom style) @@ -4688,9 +4664,8 @@ void QWidget::setFont(const QFont &font) #ifndef QT_NO_STYLE_STYLESHEET const QStyleSheetStyle* style; - if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) { + if (d->extra && (style = qt_styleSheet(d->extra->style))) style->saveWidgetFont(this, font); - } #endif setAttribute(Qt::WA_SetFont, font.resolve() != 0); @@ -4786,7 +4761,7 @@ void QWidgetPrivate::updateFont(const QFont &font) Q_Q(QWidget); #ifndef QT_NO_STYLE_STYLESHEET const QStyleSheetStyle* cssStyle; - cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0; + cssStyle = extra ? qt_styleSheet(extra->style) : 0; const bool useStyleSheetPropagationInWidgetStyles = QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); #endif diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index a9c73c6a26..c39333161b 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -395,7 +395,7 @@ public: void setLocale_helper(const QLocale &l, bool forceUpdate = false); void resolveLocale(); - void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false); + void setStyle_helper(QStyle *newStyle, bool propagate); void inheritStyle(); void setUpdatesEnabled_helper(bool ); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 1078652234..e33a891d74 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -840,6 +840,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event) QPoint mapped = widget->mapFrom(rootWidget, pos); QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); + translated.setTimestamp(event->timestamp()); QGuiApplication::forwardEvent(widget, &translated, event); } diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 557277b9e0..06590afe72 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -931,11 +931,10 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt viewItemTextLayout(textLayout, textRect.width()); - QString elidedText; qreal height = 0; qreal width = 0; - int elidedIndex = -1; const int lineCount = textLayout.lineCount(); + QHash<int, QString> elidedTexts; for (int j = 0; j < lineCount; ++j) { const QTextLine line = textLayout.lineAt(j); if (j + 1 <= lineCount - 1) { @@ -944,22 +943,20 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt int start = line.textStart(); int length = line.textLength() + nextLine.textLength(); const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); + elidedTexts.insert(j, engine.elidedText(option->textElideMode, textRect.width())); height += line.height(); width = textRect.width(); - elidedIndex = j; - break; + continue; } } if (line.naturalTextWidth() > textRect.width()) { int start = line.textStart(); int length = line.textLength(); const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); + elidedTexts.insert(j, engine.elidedText(option->textElideMode, textRect.width())); height += line.height(); width = textRect.width(); - elidedIndex = j; - break; + continue; } width = qMax<qreal>(width, line.width()); height += line.height(); @@ -970,14 +967,16 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt const QPointF position = layoutRect.topLeft(); for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); - if (i == elidedIndex) { + auto it = elidedTexts.constFind(i); + if (it != elidedTexts.constEnd()) { + const QString &elidedText = it.value(); qreal x = position.x() + line.x(); qreal y = position.y() + line.y() + line.ascent(); p->save(); p->setFont(option->font); p->drawText(QPointF(x, y), elidedText); p->restore(); - break; + continue; } line.draw(p, position); } diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index e12aeb900b..295f47c310 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -1039,7 +1039,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject if (const QWidget *widget = qobject_cast<const QWidget *>(object)) { QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle); if (!style) - style = qobject_cast<QStyleSheetStyle *>(widget->style()); + style = qt_styleSheet(widget->style()); if (style) fixupBorder(style->nativeFrameWidth(widget)); } @@ -1500,7 +1500,7 @@ public: return className; } else if (name == QLatin1String("style")) { QWidget *w = qobject_cast<QWidget *>(obj); - QStyleSheetStyle *proxy = w ? qobject_cast<QStyleSheetStyle *>(w->style()) : 0; + QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : 0; if (proxy) { QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className()); cache[name] = styleName; @@ -2732,7 +2732,7 @@ QStyle *QStyleSheetStyle::baseStyle() const { if (base) return base; - if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style())) + if (QStyleSheetStyle *me = qt_styleSheet(QApplication::style())) return me->base; return QApplication::style(); } diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h index 042abf5c22..d1647fb107 100644 --- a/src/widgets/styles/qstylesheetstyle_p.h +++ b/src/widgets/styles/qstylesheetstyle_p.h @@ -215,6 +215,13 @@ template <typename T> class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>> : QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {}; + +// Returns a QStyleSheet from the given style. +inline QStyleSheetStyle* qt_styleSheet(QStyle *style) +{ + return qobject_cast<QStyleSheetStyle *>(style); +} + QT_END_NAMESPACE #endif // QT_NO_STYLE_STYLESHEET #endif // QSTYLESHEETSTYLE_P_H diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index d444fe6053..60421a56b7 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -999,7 +999,7 @@ QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent) d->init(model); } -#ifndef QT_NO_STRINGLISTMODEL +#if QT_CONFIG(stringlistmodel) /*! Constructs a QCompleter object with the given \a parent that uses the specified \a list as a source of possible completions. @@ -1010,7 +1010,7 @@ QCompleter::QCompleter(const QStringList& list, QObject *parent) Q_D(QCompleter); d->init(new QStringListModel(list, this)); } -#endif // QT_NO_STRINGLISTMODEL +#endif // QT_CONFIG(stringlistmodel) /*! Destroys the completer object. diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h index de79302e15..fd1191d123 100644 --- a/src/widgets/util/qcompleter.h +++ b/src/widgets/util/qcompleter.h @@ -84,7 +84,7 @@ public: QCompleter(QObject *parent = nullptr); QCompleter(QAbstractItemModel *model, QObject *parent = nullptr); -#ifndef QT_NO_STRINGLISTMODEL +#if QT_CONFIG(stringlistmodel) QCompleter(const QStringList& completions, QObject *parent = nullptr); #endif ~QCompleter(); diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index ee4825d3e5..511db1a72c 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -1019,9 +1019,8 @@ void QLabel::paintEvent(QPaintEvent *) QStyleOption opt; opt.initFrom(this); #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) { + if (QStyleSheetStyle* cssStyle = qt_styleSheet(style)) cssStyle->styleSheetPalette(this, &opt, &opt.palette); - } #endif if (d->control) { #ifndef QT_NO_SHORTCUT diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index bdeef7cdf7..d7c9d7a44c 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -2000,7 +2000,7 @@ void QLineEdit::paintEvent(QPaintEvent *) // draw text, selections and cursors #ifndef QT_NO_STYLE_STYLESHEET - if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) { + if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) { cssStyle->styleSheetPalette(this, &panel, &pal); } #endif diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 623ca5b0a1..ff00e26683 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -711,7 +711,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid); if (m_validInput) { if (m_text != textCopy) { - internalSetText(textCopy, cursorCopy, false); + internalSetText(textCopy, cursorCopy, edited); return true; } m_cursor = cursorCopy; |