diff options
32 files changed, 478 insertions, 239 deletions
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 8ddfc38c63..6368c8e394 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -24,8 +24,23 @@ win32:count(MOC_INCLUDEPATH, 40, >) { write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONT)|error("Aborting.") } +# QNX's compiler sets "gcc" config, but does not support the -dM option; +# iOS builds are multi-arch, so this feature cannot possibly work. +if(gcc|intel_icl|msvc):!rim_qcc:!ios { + moc_predefs.CONFIG = no_link + gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + else:msvc { + moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_path($$[QT_INSTALL_BINS/get]/qmake) $$QMAKE_CXXFLAGS -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} + } else: error("Oops, I messed up") + moc_predefs.output = $$MOC_DIR/moc_predefs.h + moc_predefs.input = MOC_PREDEF_FILE + silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\n\t)@$$moc_predefs.commands + QMAKE_EXTRA_COMPILERS += moc_predefs + MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp +} + defineReplace(mocCmdBase) { - RET = !isEmpty(WIN_INCLUDETEMP) { incvar = @$$WIN_INCLUDETEMP } else { @@ -34,7 +49,14 @@ defineReplace(mocCmdBase) { incvar += -I$$shell_quote($$inc) incvar += $$QMAKE_FRAMEWORKPATH_FLAGS } - RET += $$QMAKE_MOC $(DEFINES) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$incvar $$QMAKE_MOC_OPTIONS + + RET = $$QMAKE_MOC $(DEFINES) + msvc: RET += --compiler-flavor=msvc + + isEmpty(MOC_PREDEF_FILE): RET += $$join(QMAKE_COMPILER_DEFINES, " -D", -D) + else: RET += --include $$moc_predefs.output + + RET += $$incvar $$QMAKE_MOC_OPTIONS return($$RET) } @@ -46,7 +68,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK moc_header.input = HEADERS moc_header.variable_out = SOURCES moc_header.name = MOC ${QMAKE_FILE_IN} -moc_header.depends += $$WIN_INCLUDETEMP +moc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands QMAKE_EXTRA_COMPILERS += moc_header INCREDIBUILD_XGE += moc_header @@ -58,7 +80,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_ moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} moc_source.input = SOURCES OBJECTIVE_SOURCES moc_source.name = MOC ${QMAKE_FILE_IN} -moc_source.depends += $$WIN_INCLUDETEMP +moc_source.depends += $$WIN_INCLUDETEMP $$moc_predefs.output silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands QMAKE_EXTRA_COMPILERS += moc_source INCREDIBUILD_XGE += moc_source diff --git a/qmake/main.cpp b/qmake/main.cpp index 8410e83cbf..6d7e023b41 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the qmake application of the Qt Toolkit. @@ -42,6 +43,10 @@ #include <sys/types.h> #include <sys/stat.h> +#ifdef Q_OS_WIN +# include <qt_windows.h> +#endif + QT_BEGIN_NAMESPACE #ifdef Q_OS_WIN @@ -241,6 +246,30 @@ static int doInstall(int argc, char **argv) return 3; } +static int dumpMacros(const wchar_t *cmdline) +{ + // from http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros + int argc; + wchar_t **argv = CommandLineToArgvW(cmdline, &argc); + if (!argv) + return 2; + for (int i = 0; i < argc; ++i) { + if (argv[i][0] != L'-' || argv[i][1] != 'D') + continue; + + wchar_t *value = wcschr(argv[i], L'='); + if (value) { + *value = 0; + ++value; + } else { + // point to the NUL at the end, so we don't print anything + value = argv[i] + wcslen(argv[i]); + } + wprintf(L"#define %Ls %Ls\n", argv[i] + 2, value); + } + return 0; +} + #endif // Q_OS_WIN /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function @@ -275,6 +304,15 @@ int runQMake(int argc, char **argv) // Workaround for inferior/missing command line tools on Windows: make our own! if (argc >= 2 && !strcmp(argv[1], "-install")) return doInstall(argc - 2, argv + 2); + + { + // Support running as Visual C++'s compiler + const wchar_t *cmdline = _wgetenv(L"MSC_CMD_FLAGS"); + if (!cmdline || !*cmdline) + cmdline = _wgetenv(L"MSC_IDE_FLAGS"); + if (cmdline && *cmdline) + return dumpMacros(cmdline); + } #endif QMakeVfs vfs; diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 9235641544..23909c9f3f 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -90,6 +90,9 @@ macro(QT5_GET_MOC_FLAGS _moc_flags) if(WIN32) set(${_moc_flags} ${${_moc_flags}} -DWIN32) endif() + if (MSVC) + set(${_moc_flags} --compiler-flavor=msvc) + endif() endmacro() diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 1bf59847c4..c5d891cc28 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -539,24 +539,46 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max # define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref #endif -#ifdef Q_OS_MAC -# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) \ - ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios)) - -# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) \ - ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \ - (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios)) - +#ifdef Q_OS_DARWIN +# define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) \ + ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= macos) || \ + (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios) || \ + (defined(__TV_OS_VERSION_MAX_ALLOWED) && tvos != __TVOS_NA && __TV_OS_VERSION_MAX_ALLOWED >= tvos) || \ + (defined(__WATCH_OS_VERSION_MAX_ALLOWED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MAX_ALLOWED >= watchos)) + +# define QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, tvos, watchos) \ + ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < macos) || \ + (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios) || \ + (defined(__TV_OS_VERSION_MIN_REQUIRED) && tvos != __TVOS_NA && __TV_OS_VERSION_MIN_REQUIRED < tvos) || \ + (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MIN_REQUIRED < watchos)) + +# define QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios) \ + QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, __TVOS_NA, __WATCHOS_NA) +# define QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos) \ + QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA) # define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \ - QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios) -# define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) \ - QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, __IPHONE_NA) - + QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA) +# define QT_TVOS_PLATFORM_SDK_EQUAL_OR_ABOVE(tvos) \ + QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA) +# define QT_WATCHOS_PLATFORM_SDK_EQUAL_OR_ABOVE(watchos) \ + QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos) + +# define QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(macos, ios) \ + QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, __TVOS_NA, __WATCHOS_NA) +# define QT_MACOS_DEPLOYMENT_TARGET_BELOW(macos) \ + QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA) # define QT_IOS_DEPLOYMENT_TARGET_BELOW(ios) \ - QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios) -# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \ - QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA) + QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA) +# define QT_TVOS_DEPLOYMENT_TARGET_BELOW(tvos) \ + QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA) +# define QT_WATCHOS_DEPLOYMENT_TARGET_BELOW(watchos) \ + QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos) + +# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) +# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(osx, ios) + +# define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) +# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) QT_MACOS_DEPLOYMENT_TARGET_BELOW(osx) // Implemented in qcore_mac_objc.mm class Q_CORE_EXPORT QMacAutoReleasePool @@ -569,7 +591,7 @@ private: void *pool; }; -#endif // Q_OS_MAC +#endif // Q_OS_DARWIN /* Data stream functions are provided by many classes (defined in qdatastream.h) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index febfdbb9d4..6424012a9a 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -227,14 +227,27 @@ static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &st { statBuf64->st_mode = statBuf32.st_mode; statBuf64->st_size = statBuf32.st_size; +#if _POSIX_VERSION >= 200809L + statBuf64->st_ctim = statBuf32.st_ctim; + statBuf64->st_mtim = statBuf32.st_mtim; + statBuf64->st_atim = statBuf32.st_atim; +#else statBuf64->st_ctime = statBuf32.st_ctime; statBuf64->st_mtime = statBuf32.st_mtime; statBuf64->st_atime = statBuf32.st_atime; +#endif statBuf64->st_uid = statBuf32.st_uid; statBuf64->st_gid = statBuf32.st_gid; } #endif +#if _POSIX_VERSION >= 200809L +static qint64 timespecToMSecs(const timespec &spec) +{ + return (qint64(spec.tv_sec) * 1000) + (spec.tv_nsec / 1000000); +} +#endif + void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) { // Permissions @@ -278,9 +291,17 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) #endif // Times - creationTime_ = statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime; - modificationTime_ = statBuffer.st_mtime; - accessTime_ = statBuffer.st_atime; +#if _POSIX_VERSION >= 200809L + modificationTime_ = timespecToMSecs(statBuffer.st_mtim); + creationTime_ = timespecToMSecs(statBuffer.st_ctim); + if (!creationTime_) + creationTime_ = modificationTime_; + accessTime_ = timespecToMSecs(statBuffer.st_atim); +#else + creationTime_ = qint64(statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime) * 1000; + modificationTime_ = qint64(statBuffer.st_mtime) * 1000; + accessTime_ = qint64(statBuffer.st_atime) * 1000; +#endif userId_ = statBuffer.st_uid; groupId_ = statBuffer.st_gid; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 9507a101a8..091552f86e 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -237,9 +237,10 @@ private: FILETIME lastAccessTime_; FILETIME lastWriteTime_; #else - time_t creationTime_; - time_t modificationTime_; - time_t accessTime_; + // msec precision + qint64 creationTime_; + qint64 modificationTime_; + qint64 accessTime_; uint userId_; uint groupId_; @@ -276,9 +277,9 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim #endif #if defined(Q_OS_UNIX) -inline QDateTime QFileSystemMetaData::creationTime() const { return QDateTime::fromSecsSinceEpoch(creationTime_); } -inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromSecsSinceEpoch(modificationTime_); } -inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromSecsSinceEpoch(accessTime_); } +inline QDateTime QFileSystemMetaData::creationTime() const { return QDateTime::fromMSecsSinceEpoch(creationTime_); } +inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromMSecsSinceEpoch(modificationTime_); } +inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromMSecsSinceEpoch(accessTime_); } inline uint QFileSystemMetaData::userId() const { return userId_; } inline uint QFileSystemMetaData::groupId() const { return groupId_; } diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 4aac24f454..7118ad5c9b 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -403,7 +403,7 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent) Note that deleting a QThread object will not stop the execution of the thread it manages. Deleting a running QThread (i.e. - isFinished() returns \c false) will probably result in a program + isFinished() returns \c false) will result in a program crash. Wait for the finished() signal before deleting the QThread. */ @@ -418,7 +418,7 @@ QThread::~QThread() locker.relock(); } if (d->running && !d->finished && !d->data->isAdopted) - qWarning("QThread: Destroyed while thread is still running"); + qFatal("QThread: Destroyed while thread is still running"); d->data->thread = 0; } diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 3490e786a8..5bf0df67db 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -402,6 +402,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const return true; case ItemViewActivateItemOnSingleClick: return QPlatformTheme::defaultThemeHint(QPlatformTheme::ItemViewActivateItemOnSingleClick); + case UiEffects: + return QPlatformTheme::defaultThemeHint(QPlatformTheme::UiEffects); } return 0; diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index 8754ff555f..22a834f0e1 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -156,7 +156,8 @@ public: MousePressAndHoldInterval, TabFocusBehavior, ReplayMousePressOutsidePopup, - ItemViewActivateItemOnSingleClick + ItemViewActivateItemOnSingleClick, + UiEffects }; virtual QVariant styleHint(StyleHint hint) const; diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 7f74959a60..32ad057452 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -444,6 +444,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MousePressAndHoldInterval); case QPlatformTheme::ItemViewActivateItemOnSingleClick: return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ItemViewActivateItemOnSingleClick); + case QPlatformTheme::UiEffects: + return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::UiEffects); default: return QPlatformTheme::defaultThemeHint(hint); } diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h index a5bd8b24ba..b16fdd7939 100644 --- a/src/gui/kernel/qplatformtheme.h +++ b/src/gui/kernel/qplatformtheme.h @@ -270,7 +270,8 @@ public: AnimateComboUiEffect = 0x8, AnimateTooltipUiEffect = 0x10, FadeTooltipUiEffect = 0x20, - AnimateToolBoxUiEffect = 0x40 + AnimateToolBoxUiEffect = 0x40, + HoverEffect = 0x80 }; enum IconOption { diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index ecc2886a04..7ccf1d86b0 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -77,6 +77,7 @@ public: , m_keyboardInputInterval(-1) , m_cursorFlashTime(-1) , m_tabFocusBehavior(-1) + , m_uiEffects(-1) {} int m_mouseDoubleClickInterval; @@ -86,6 +87,7 @@ public: int m_keyboardInputInterval; int m_cursorFlashTime; int m_tabFocusBehavior; + int m_uiEffects; }; /*! @@ -451,4 +453,34 @@ bool QStyleHints::singleClickActivation() const return themeableHint(QPlatformTheme::ItemViewActivateItemOnSingleClick, QPlatformIntegration::ItemViewActivateItemOnSingleClick).toBool(); } +/*! + \property QStyleHints::useHoverEffects + \brief \c true if UI elements should use hover effects. This is the + standard behavior on desktop platforms with a mouse pointer, whereas + on touch platforms the overhead of hover event delivery can be avoided. + + \since 5.8 +*/ +bool QStyleHints::useHoverEffects() const +{ + Q_D(const QStyleHints); + return (d->m_uiEffects >= 0 ? + d->m_uiEffects : + themeableHint(QPlatformTheme::UiEffects, QPlatformIntegration::UiEffects).toInt()) & QPlatformTheme::HoverEffect; +} + +void QStyleHints::setUseHoverEffects(bool useHoverEffects) +{ + Q_D(QStyleHints); + if (d->m_uiEffects >= 0 && useHoverEffects == bool(d->m_uiEffects & QPlatformTheme::HoverEffect)) + return; + if (d->m_uiEffects == -1) + d->m_uiEffects = 0; + if (useHoverEffects) + d->m_uiEffects |= QPlatformTheme::HoverEffect; + else + d->m_uiEffects &= ~QPlatformTheme::HoverEffect; + emit useHoverEffectsChanged(useHoverEffects); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index 7be8b3a33a..fb55cc7ed6 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -70,6 +70,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject Q_PROPERTY(bool useRtlExtensions READ useRtlExtensions STORED false CONSTANT FINAL) Q_PROPERTY(Qt::TabFocusBehavior tabFocusBehavior READ tabFocusBehavior NOTIFY tabFocusBehaviorChanged FINAL) Q_PROPERTY(bool singleClickActivation READ singleClickActivation STORED false CONSTANT FINAL) + Q_PROPERTY(bool useHoverEffects READ useHoverEffects WRITE setUseHoverEffects NOTIFY useHoverEffectsChanged FINAL) public: void setMouseDoubleClickInterval(int mouseDoubleClickInterval); @@ -96,6 +97,8 @@ public: Qt::TabFocusBehavior tabFocusBehavior() const; void setTabFocusBehavior(Qt::TabFocusBehavior tabFocusBehavior); bool singleClickActivation() const; + bool useHoverEffects() const; + void setUseHoverEffects(bool useHoverEffects); Q_SIGNALS: void cursorFlashTimeChanged(int cursorFlashTime); @@ -105,6 +108,7 @@ Q_SIGNALS: void startDragDistanceChanged(int startDragDistance); void startDragTimeChanged(int startDragTime); void tabFocusBehaviorChanged(Qt::TabFocusBehavior tabFocusBehavior); + void useHoverEffectsChanged(bool useHoverEffects); private: friend class QGuiApplication; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index cdfcdec80c..594d791e9c 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2221,10 +2221,18 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem) sample += QChar(0x05D3); break; case Arabic: + sample += QChar(0x0623); sample += QChar(0x0628); + sample += QChar(0x062C); + sample += QChar(0x062F); + sample += QChar(0x064A); + sample += QChar(0x0629); + sample += QChar(0x0020); + sample += QChar(0x0639); + sample += QChar(0x0631); + sample += QChar(0x0628); + sample += QChar(0x064A); sample += QChar(0x0629); - sample += QChar(0x062A); - sample += QChar(0x063A); break; case Syriac: sample += QChar(0x0715); diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index 2d80f38bec..2e3e26d37d 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -39,6 +39,10 @@ unix: { unix:HEADERS += \ socket/qnet_unix_p.h +# Suppress deprecation warnings with moc because MS headers have +# invalid C/C++ code otherwise. +msvc: QMAKE_MOC_OPTIONS += -D_WINSOCK_DEPRECATED_NO_WARNINGS + win32:!winrt:SOURCES += socket/qnativesocketengine_win.cpp \ socket/qlocalsocket_win.cpp \ socket/qlocalserver_win.cpp diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 9abcd04063..118b4988a5 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -666,6 +666,8 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const return QVariant(int(GnomeKeyboardScheme)); case QPlatformTheme::PasswordMaskCharacter: return QVariant(QChar(0x2022)); + case QPlatformTheme::UiEffects: + return QVariant(int(HoverEffect)); default: break; } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f02dad675e..21a2ba3611 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -332,7 +332,6 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) // Load the application menu. This menu contains Preferences, Hide, Quit. QCocoaMenuLoader *qtMenuLoader = [[QCocoaMenuLoader alloc] init]; - qt_mac_loadMenuNib(qtMenuLoader); [cocoaApplication setMenu:[qtMenuLoader menu]]; [newDelegate setMenuLoader:qtMenuLoader]; } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h index 6f58b2f24c..d1f47b18f0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.h +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h @@ -68,6 +68,7 @@ NSMenuItem *hideAllOthersItem; NSMenuItem *showAllItem; } +- (instancetype)init; - (void)ensureAppMenuInMenu:(NSMenu *)menu; - (void)removeActionsFromAppMenu; - (NSMenu *)applicationMenu; @@ -92,10 +93,4 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader); -QT_BEGIN_NAMESPACE - -void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader); - -QT_END_NAMESPACE - #endif // QCOCOAMENULOADER_P_H diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index e440a9080c..9b16999d48 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -55,86 +55,117 @@ QT_FORWARD_DECLARE_CLASS(QCFString) QT_FORWARD_DECLARE_CLASS(QString) +@implementation QCocoaMenuLoader -QT_BEGIN_NAMESPACE - -/* - Loads and instantiates the main app menu from the menu nib file(s). - - The main app menu contains the Quit, Hide About, Preferences entries, and - The reason for having the nib file is that those can not be created - programmatically. To ease deployment the nib files are stored in Qt resources - and written to QDir::temp() before loading. (Earlier Qt versions used - to require having the nib file in the Qt GUI framework.) -*/ -void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader) +- (instancetype)init { - // Create qt_menu.nib dir in temp. - QDir temp = QDir::temp(); - temp.mkdir("qt_menu.nib"); - QString nibDir = temp.canonicalPath() + QLatin1String("/") + QLatin1String("qt_menu.nib/"); - if (!QDir(nibDir).exists()) { - qWarning("qt_mac_loadMenuNib: could not create nib directory in temp"); - return; - } - - // Copy nib files from resources to temp. - QDir nibResource(":/qt-project.org/mac/qt_menu.nib/"); - if (!nibResource.exists()) { - qWarning("qt_mac_loadMenuNib: could not load nib from resources"); - return; - } - foreach (const QFileInfo &file, nibResource.entryInfoList()) { - QFileInfo destinationFile(nibDir + QLatin1String("/") + file.fileName()); - if (destinationFile.exists() && destinationFile.size() != file.size()) - QFile::remove(destinationFile.absoluteFilePath()); - - QFile::copy(file.absoluteFilePath(), destinationFile.absoluteFilePath()); + if ((self = [super init])) { + NSString *appName = qt_mac_applicationName().toNSString(); + + // Menubar as menu. Title as set in the NIB file + theMenu = [[NSMenu alloc] initWithTitle:@"Main Menu"]; + + // Application menu. Since 10.6, the first menu + // is always identified as the application menu. + NSMenuItem *appItem = [[[NSMenuItem alloc] init] autorelease]; + appItem.title = appName; + [theMenu addItem:appItem]; + appMenu = [[NSMenu alloc] initWithTitle:appName]; + appItem.submenu = appMenu; + + // About Application + aboutItem = [[NSMenuItem alloc] initWithTitle:[@"About " stringByAppendingString:appName] + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + aboutItem.target = self; + // Disable until a QAction is associated + aboutItem.enabled = NO; + aboutItem.hidden = YES; + [appMenu addItem:aboutItem]; + + // About Qt (shameless self-promotion) + aboutQtItem = [[NSMenuItem alloc] init]; + aboutQtItem.title = @"About Qt"; + // Disable until a QAction is associated + aboutQtItem.enabled = NO; + aboutQtItem.hidden = YES; + [appMenu addItem:aboutQtItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Preferences + preferencesItem = [[NSMenuItem alloc] initWithTitle:@"Preferences…" + action:@selector(qtDispatcherToQPAMenuItem:) + keyEquivalent:@","]; + preferencesItem.target = self; + // Disable until a QAction is associated + preferencesItem.enabled = NO; + preferencesItem.hidden = YES; + [appMenu addItem:preferencesItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Services item and menu + servicesItem = [[NSMenuItem alloc] init]; + servicesItem.title = @"Services"; + NSApplication *app = [NSApplication sharedApplication]; + app.servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease]; + servicesItem.submenu = app.servicesMenu; + [appMenu addItem:servicesItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Hide Application + hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName] + action:@selector(hide:) + keyEquivalent:@"h"]; + hideItem.target = self; + [appMenu addItem:hideItem]; + + // Hide Others + hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"]; + hideAllOthersItem.target = self; + hideAllOthersItem.keyEquivalentModifierMask = NSCommandKeyMask | NSAlternateKeyMask; + [appMenu addItem:hideAllOthersItem]; + + // Show All + showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + showAllItem.target = self; + [appMenu addItem:showAllItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Quit Application + quitItem = [[NSMenuItem alloc] initWithTitle:[@"Quit " stringByAppendingString:appName] + action:@selector(terminate:) + keyEquivalent:@"q"]; + quitItem.target = self; + [appMenu addItem:quitItem]; } - // Load and instantiate nib file from temp - NSURL *nibUrl = [NSURL fileURLWithPath : QCFString::toNSString(nibDir)]; - NSNib *nib = [[NSNib alloc] initWithContentsOfURL : nibUrl]; - [nib autorelease]; - if(!nib) { - qWarning("qt_mac_loadMenuNib: could not load nib from temp"); - return; - } - bool ok = [nib instantiateNibWithOwner : qtMenuLoader topLevelObjects : nil]; - if (!ok) { - qWarning("qt_mac_loadMenuNib: could not instantiate nib"); - } + return self; } -QT_END_NAMESPACE +- (void)dealloc +{ + [theMenu release]; + [appMenu release]; + [aboutItem release]; + [aboutQtItem release]; + [preferencesItem release]; + [servicesItem release]; + [hideItem release]; + [hideAllOthersItem release]; + [showAllItem release]; + [quitItem release]; -@implementation QCocoaMenuLoader + [lastAppSpecificItem release]; -- (void)awakeFromNib -{ - servicesItem = [[appMenu itemWithTitle:@"Services"] retain]; - hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain]; - showAllItem = [[appMenu itemWithTitle:@"Show All"] retain]; - - // Get the names in the nib to match the app name set by Qt. - const NSString *appName = qt_mac_applicationName().toNSString(); - [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - // Disable the items that don't do anything. If someone associates a QAction with them - // They should get synced back in. - [preferencesItem setEnabled:NO]; - [preferencesItem setHidden:YES]; - - // should set this in the NIB - [preferencesItem setTarget: self]; - [preferencesItem setAction: @selector(qtDispatcherToQPAMenuItem:)]; - - [aboutItem setEnabled:NO]; - [aboutItem setHidden:YES]; + [super dealloc]; } - (void)ensureAppMenuInMenu:(NSMenu *)menu @@ -179,18 +210,6 @@ QT_END_NAMESPACE [item setTag:0]; } -- (void)dealloc -{ - [servicesItem release]; - [hideAllOthersItem release]; - [showAllItem release]; - - [lastAppSpecificItem release]; - [theMenu release]; - [appMenu release]; - [super dealloc]; -} - - (NSMenu *)menu { return [[theMenu retain] autorelease]; diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc index 9e0640db7d..4255bfba9d 100644 --- a/src/plugins/platforms/cocoa/qcocoaresources.qrc +++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc @@ -9,9 +9,4 @@ <qresource prefix="/qt-project.org/mac/style"> <file>images/leopard-unified-toolbar-on.png</file> </qresource> -<qresource prefix="/qt-project.org/mac/"> -<file>qt_menu.nib/classes.nib</file> -<file>qt_menu.nib/info.nib</file> -<file>qt_menu.nib/keyedobjects.nib</file> -</qresource> </RCC> diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 831f1cfcf4..01b654af68 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -309,6 +309,8 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const } case QPlatformTheme::PasswordMaskCharacter: return QVariant(QChar(kBulletUnicode)); + case QPlatformTheme::UiEffects: + return QVariant(int(HoverEffect)); default: break; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 86df38c583..19a04b2f4b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1023,9 +1023,7 @@ void QCocoaWindow::raise() } static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); if (raiseProcess) { - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); + [NSApp activateIgnoringOtherApps:YES]; } } } diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib deleted file mode 100644 index 78941153c2..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBClasses</key> - <array> - <dict> - <key>ACTIONS</key> - <dict> - <key>hide</key> - <string>id</string> - <key>hideOtherApplications</key> - <string>id</string> - <key>orderFrontStandardAboutPanel</key> - <string>id</string> - <key>qtDispatcherToQPAMenuItem</key> - <string>id</string> - <key>terminate</key> - <string>id</string> - <key>unhideAllApplications</key> - <string>id</string> - </dict> - <key>CLASS</key> - <string>QCocoaMenuLoader</string> - <key>LANGUAGE</key> - <string>ObjC</string> - <key>OUTLETS</key> - <dict> - <key>aboutItem</key> - <string>NSMenuItem</string> - <key>aboutQtItem</key> - <string>NSMenuItem</string> - <key>appMenu</key> - <string>NSMenu</string> - <key>hideItem</key> - <string>NSMenuItem</string> - <key>preferencesItem</key> - <string>NSMenuItem</string> - <key>quitItem</key> - <string>NSMenuItem</string> - <key>theMenu</key> - <string>NSMenu</string> - </dict> - <key>SUPERCLASS</key> - <string>NSResponder</string> - </dict> - <dict> - <key>CLASS</key> - <string>FirstResponder</string> - <key>LANGUAGE</key> - <string>ObjC</string> - <key>SUPERCLASS</key> - <string>NSObject</string> - </dict> - </array> - <key>IBVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/info.nib b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib deleted file mode 100644 index 02e5cca562..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBFramework Version</key> - <string>672</string> - <key>IBOldestOS</key> - <integer>5</integer> - <key>IBOpenObjects</key> - <array> - <integer>57</integer> - </array> - <key>IBSystem Version</key> - <string>9L31a</string> - <key>targetFramework</key> - <string>IBCocoaFramework</string> -</dict> -</plist> diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib Binary files differdeleted file mode 100644 index 67207ca628..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib +++ /dev/null diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index ff556caeaf..e84033f5e4 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -348,7 +348,7 @@ static inline QStringList styleNames() static inline int uiEffects() { - int result = 0; + int result = QPlatformTheme::HoverEffect; if (booleanSystemParametersInfo(SPI_GETUIEFFECTS, false)) result |= QPlatformTheme::GeneralUiEffect; if (booleanSystemParametersInfo(SPI_GETMENUANIMATION, false)) diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 0c327a641f..0a10aef989 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -242,6 +243,11 @@ int runMoc(int argc, char **argv) metadataOption.setFlags(QCommandLineOption::ShortOptionStyle); parser.addOption(metadataOption); + QCommandLineOption compilerFlavorOption(QStringLiteral("compiler-flavor")); + compilerFlavorOption.setDescription(QStringLiteral("Set the compiler flavor: either \"msvc\" or \"unix\".")); + compilerFlavorOption.setValueName(QStringLiteral("flavor")); + parser.addOption(compilerFlavorOption); + QCommandLineOption noIncludeOption(QStringLiteral("i")); noIncludeOption.setDescription(QStringLiteral("Do not generate an #include statement.")); parser.addOption(noIncludeOption); @@ -263,6 +269,11 @@ int runMoc(int argc, char **argv) prependIncludeOption.setValueName(QStringLiteral("file")); parser.addOption(prependIncludeOption); + QCommandLineOption includeOption(QStringLiteral("include")); + includeOption.setDescription(QStringLiteral("Parse <file> as an #include before the main source(s).")); + includeOption.setValueName(QStringLiteral("file")); + parser.addOption(includeOption); + QCommandLineOption noNotesWarningsCompatOption(QStringLiteral("n")); noNotesWarningsCompatOption.setDescription(QStringLiteral("Do not display notes (-nn) or warnings (-nw). Compatibility option.")); noNotesWarningsCompatOption.setValueName(QStringLiteral("which")); @@ -323,9 +334,32 @@ int runMoc(int argc, char **argv) if (parser.isSet(pathPrefixOption)) moc.includePath = QFile::encodeName(parser.value(pathPrefixOption)); } + const auto includePaths = parser.values(includePathOption); for (const QString &path : includePaths) pp.includes += Preprocessor::IncludePath(QFile::encodeName(path)); + QString compilerFlavor = parser.value(compilerFlavorOption); + if (compilerFlavor.isEmpty() || compilerFlavor == QLatin1String("unix")) { + // traditional Unix compilers use both CPATH and CPLUS_INCLUDE_PATH + // $CPATH feeds to #include <...> and #include "...", whereas + // CPLUS_INCLUDE_PATH is equivalent to GCC's -isystem, so we parse later + const auto cpath = qgetenv("CPATH").split(QDir::listSeparator().toLatin1()); + for (const QByteArray &p : cpath) + pp.includes += Preprocessor::IncludePath(p); + const auto cplus_include_path = qgetenv("CPLUS_INCLUDE_PATH").split(QDir::listSeparator().toLatin1()); + for (const QByteArray &p : cplus_include_path) + pp.includes += Preprocessor::IncludePath(p); + } else if (compilerFlavor == QLatin1String("msvc")) { + // MSVC uses one environment variable: INCLUDE + const auto include = qgetenv("INCLUDE").split(QDir::listSeparator().toLatin1()); + for (const QByteArray &p : include) + pp.includes += Preprocessor::IncludePath(p); + } else { + error(qPrintable(QLatin1String("Unknown compiler flavor '") + compilerFlavor + + QLatin1String("'; valid values are: msvc, unix."))); + parser.showHelp(1); + } + const auto macFrameworks = parser.values(macFrameworkOption); for (const QString &path : macFrameworks) { // minimalistic framework support for the mac @@ -420,7 +454,17 @@ int runMoc(int argc, char **argv) moc.includes = pp.includes; // 1. preprocess - moc.symbols = pp.preprocessed(moc.filename, &in); + const auto includeFiles = parser.values(includeOption); + for (const QString &includeName : includeFiles) { + QByteArray rawName = pp.resolveInclude(QFile::encodeName(includeName), moc.filename); + QFile f(QFile::decodeName(rawName)); + if (f.open(QIODevice::ReadOnly)) { + moc.symbols += Symbol(0, MOC_INCLUDE_BEGIN, rawName); + moc.symbols += pp.preprocessed(rawName, &f); + moc.symbols += Symbol(0, MOC_INCLUDE_END, rawName); + } + } + moc.symbols += pp.preprocessed(moc.filename, &in); // We obviously do not support MS extensions pp.macros.remove("_MSC_EXTENSIONS"); diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index befc280f4e..415003e6b1 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -1005,6 +1005,36 @@ static void mergeStringLiterals(Symbols *_symbols) } } +QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo) +{ + // #### stringery + QFileInfo fi; + if (!relativeTo.isEmpty()) + fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo.constData())).dir(), QString::fromLocal8Bit(include.constData())); + for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { + const IncludePath &p = Preprocessor::includes.at(j); + if (p.isFrameworkPath) { + const int slashPos = include.indexOf('/'); + if (slashPos == -1) + continue; + fi.setFile(QString::fromLocal8Bit(p.path + '/' + include.left(slashPos) + ".framework/Headers/"), + QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); + } else { + fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); + } + // try again, maybe there's a file later in the include paths with the same name + // (186067) + if (fi.isDir()) { + fi = QFileInfo(); + continue; + } + } + + if (!fi.exists() || fi.isDir()) + return QByteArray(); + return fi.canonicalFilePath().toLocal8Bit(); +} + void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); @@ -1025,32 +1055,9 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) continue; until(PP_NEWLINE); - // #### stringery - QFileInfo fi; - if (local) - fi.setFile(QFileInfo(QString::fromLocal8Bit(filename.constData())).dir(), QString::fromLocal8Bit(include.constData())); - for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { - const IncludePath &p = Preprocessor::includes.at(j); - if (p.isFrameworkPath) { - const int slashPos = include.indexOf('/'); - if (slashPos == -1) - continue; - fi.setFile(QString::fromLocal8Bit(p.path + '/' + include.left(slashPos) + ".framework/Headers/"), - QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); - } else { - fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); - } - // try again, maybe there's a file later in the include paths with the same name - // (186067) - if (fi.isDir()) { - fi = QFileInfo(); - continue; - } - } - - if (!fi.exists() || fi.isDir()) + include = resolveInclude(include, local ? filename : QByteArray()); + if (include.isNull()) continue; - include = fi.canonicalFilePath().toLocal8Bit(); if (Preprocessor::preprocessedIncludes.contains(include)) continue; @@ -1205,6 +1212,7 @@ Symbols Preprocessor::preprocessed(const QByteArray &filename, QFile *file) input = cleaned(input); // phase 2: tokenize for the preprocessor + index = 0; symbols = tokenize(input); #if 0 diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index 9a49751eb0..a7eb1a19e1 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -62,6 +62,7 @@ public: QList<QByteArray> frameworks; QSet<QByteArray> preprocessedIncludes; Macros macros; + QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo); Symbols preprocessed(const QByteArray &filename, QFile *device); void parseDefineArguments(Macro *m); diff --git a/tests/auto/tools/moc/subdir/extradefines.h b/tests/auto/tools/moc/subdir/extradefines.h new file mode 100644 index 0000000000..e7888ce80d --- /dev/null +++ b/tests/auto/tools/moc/subdir/extradefines.h @@ -0,0 +1 @@ +#define FOO 1 diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index d5d8a2ecaa..8f1fde4f35 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -575,6 +575,10 @@ private slots: void frameworkSearchPath(); void cstyleEnums(); void defineMacroViaCmdline(); + void defineMacroViaForcedInclude(); + void defineMacroViaForcedIncludeRelative(); + void environmentIncludePaths_data(); + void environmentIncludePaths(); void specifyMetaTagsFromCmdline(); void invokable(); void singleFunctionKeywordSignalAndSlot(); @@ -1253,6 +1257,92 @@ void tst_Moc::defineMacroViaCmdline() #endif } +void tst_Moc::defineMacroViaForcedInclude() +{ +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QProcess proc; + + QStringList args; + args << "--include" << m_sourceDirectory + QLatin1String("/subdir/extradefines.h"); + args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); + + proc.start(m_moc, args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + QCOMPARE(proc.readAllStandardError(), QByteArray()); + QByteArray mocOut = proc.readAllStandardOutput(); + QVERIFY(!mocOut.isEmpty()); +#else + QSKIP("Only tested on linux/gcc"); +#endif +} + +void tst_Moc::defineMacroViaForcedIncludeRelative() +{ +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QProcess proc; + + QStringList args; + args << "--include" << QStringLiteral("extradefines.h") << "-I" + m_sourceDirectory + "/subdir"; + args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); + + proc.start(m_moc, args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + QCOMPARE(proc.readAllStandardError(), QByteArray()); + QByteArray mocOut = proc.readAllStandardOutput(); + QVERIFY(!mocOut.isEmpty()); +#else + QSKIP("Only tested on linux/gcc"); +#endif +} + + +void tst_Moc::environmentIncludePaths_data() +{ +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QTest::addColumn<QString>("cmdline"); + QTest::addColumn<QString>("varname"); + + QTest::newRow("INCLUDE") << "--compiler-flavor=msvc" << "INCLUDE"; + QTest::newRow("CPATH1") << QString() << "CPATH"; + QTest::newRow("CPATH2") << "--compiler-flavor=unix" << "CPATH"; + QTest::newRow("CPLUS_INCLUDE_PATH1") << QString() << "CPLUS_INCLUDE_PATH"; + QTest::newRow("CPLUS_INCLUDE_PATH2") << "--compiler-flavor=unix" << "CPLUS_INCLUDE_PATH"; +#endif +} + +void tst_Moc::environmentIncludePaths() +{ +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QFETCH(QString, cmdline); + QFETCH(QString, varname); + + QStringList args; + if (!cmdline.isEmpty()) + args << cmdline; + args << "--include" << QStringLiteral("extradefines.h") + << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); + + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.remove("INCLUDE"); + env.remove("CPATH"); + env.remove("CPLUS_INCLUDE_PATH"); + env.insert(varname, m_sourceDirectory + "/subdir"); + + QProcess proc; + proc.setProcessEnvironment(env); + proc.start(m_moc, args); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + QCOMPARE(proc.readAllStandardError(), QByteArray()); + QByteArray mocOut = proc.readAllStandardOutput(); + QVERIFY(!mocOut.isEmpty()); +#else + QSKIP("Only tested on linux/gcc"); +#endif +} + // tst_Moc::specifyMetaTagsFromCmdline() // plugin_metadata.h contains a plugin which we register here. Since we're not building this // application as a plugin, we need top copy some of the initializer code found in qplugin.h: diff --git a/util/lexgen/configfile.h b/util/lexgen/configfile.h index 1bba26e980..da891ea836 100644 --- a/util/lexgen/configfile.h +++ b/util/lexgen/configfile.h @@ -31,6 +31,7 @@ #include <QStringList> #include <QMap> #include <QVector> +#include <QIODevice> struct ConfigFile { |