summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/moc.prf30
-rw-r--r--qmake/main.cpp38
-rw-r--r--src/corelib/Qt5CoreMacros.cmake3
-rw-r--r--src/corelib/global/qglobal.h56
-rw-r--r--src/corelib/io/qfilesystemengine.cpp27
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h13
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/gui/kernel/qplatformintegration.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.h3
-rw-r--r--src/gui/kernel/qplatformtheme.cpp2
-rw-r--r--src/gui/kernel/qplatformtheme.h3
-rw-r--r--src/gui/kernel/qstylehints.cpp32
-rw-r--r--src/gui/kernel/qstylehints.h4
-rw-r--r--src/gui/text/qfontdatabase.cpp12
-rw-r--r--src/network/socket/socket.pri4
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h7
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm187
-rw-r--r--src/plugins/platforms/cocoa/qcocoaresources.qrc5
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm4
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/classes.nib59
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/info.nib18
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nibbin5560 -> 0 bytes
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp2
-rw-r--r--src/tools/moc/main.cpp46
-rw-r--r--src/tools/moc/preprocessor.cpp58
-rw-r--r--src/tools/moc/preprocessor.h1
-rw-r--r--tests/auto/tools/moc/subdir/extradefines.h1
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp90
-rw-r--r--util/lexgen/configfile.h1
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 &paramList)
// 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
deleted file mode 100644
index 67207ca628..0000000000
--- a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
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
{