diff options
80 files changed, 2289 insertions, 523 deletions
diff --git a/doc/src/snippets/qelapsedtimer/main.cpp b/doc/src/snippets/qelapsedtimer/main.cpp new file mode 100644 index 0000000..9d0421f --- /dev/null +++ b/doc/src/snippets/qelapsedtimer/main.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore> + +void slowOperation1() +{ + static char buf[256]; + for (int i = 0; i < (1<<20); ++i) + buf[i % sizeof buf] = i; +} + +void slowOperation2(int) { slowOperation1(); } + +void startExample() +{ +//![0] + QElapsedTimer timer; + timer.start(); + + slowOperation1(); + + qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds"; +//![0] +} + +//![1] +void executeSlowOperations(int timeout) +{ + QElapsedTimer timer; + timer.start(); + slowOperation1(); + + int remainingTime = timeout - timer.elapsed(); + if (remainingTime > 0) + slowOperation2(remainingTime); +} +//![1] + +//![2] +void executeOperationsForTime(int ms) +{ + QElapsedTimer timer; + timer.start(); + + while (!timer.hasExpired(ms)) + slowOperation1(); +} +//![2] + +int restartExample() +{ +//![3] + QElapsedTimer timer; + + int count = 1; + timer.start(); + do { + count *= 2; + slowOperation2(count); + } while (timer.restart() < 250); + + return count; +//![3] +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + startExample(); + restartExample(); + executeSlowOperations(5); + executeOperationsForTime(5); +} diff --git a/doc/src/snippets/qelapsedtimer/qelapsedtimer.pro b/doc/src/snippets/qelapsedtimer/qelapsedtimer.pro new file mode 100644 index 0000000..b0a8f66 --- /dev/null +++ b/doc/src/snippets/qelapsedtimer/qelapsedtimer.pro @@ -0,0 +1,2 @@ +SOURCES = main.cpp +QT -= gui diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 16b9a28..239b998 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -74,8 +74,8 @@ QMAKE_LINK_OBJECT_MAX = QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl -QMAKE_LIBS_CORE = $$QMAKE_LIBS -llibpthread -lefsrv -QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository +QMAKE_LIBS_CORE = $$QMAKE_LIBS -llibpthread -lefsrv -lhal +QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index b9d2445..29a2422 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1245,7 +1245,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs, bool n } if(!dirstr.endsWith(Option::dir_sep)) dirstr += Option::dir_sep; - if(exists(wild)) { //real file + bool is_target = (wild == fileFixify(var("TARGET"), FileFixifyAbsolute)); + if(is_target || exists(wild)) { //real file or target QString file = wild; QFileInfo fi(fileInfo(wild)); if(!target.isEmpty()) @@ -1259,7 +1260,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs, bool n QString cmd; if (fi.isDir()) cmd = "-$(INSTALL_DIR)"; - else if (fi.isExecutable()) + else if (is_target || fi.isExecutable()) cmd = "-$(INSTALL_PROGRAM)"; else cmd = "-$(INSTALL_FILE)"; diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f834a80..82b3003 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -170,6 +170,7 @@ QUnifiedTimer::QUnifiedTimer() : currentAnimationIdx(0), consistentTiming(false), slowMode(false), isPauseTimerActive(false), runningLeafAnimations(0) { + time.invalidate(); } QUnifiedTimer *QUnifiedTimer::instance() diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 8bc3224..2282cdb 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -56,6 +56,7 @@ #include <QtCore/qbasictimer.h> #include <QtCore/qdatetime.h> #include <QtCore/qtimer.h> +#include <QtCore/qelapsedtimer.h> #include <private/qobject_p.h> #ifdef Q_OS_WIN @@ -113,61 +114,7 @@ private: Q_DECLARE_PUBLIC(QAbstractAnimation) }; -class ElapsedTimer -{ -public: - ElapsedTimer() { - invalidate(); - } - - void invalidate() { - m_started = -1; - } - - bool isValid() const { - return m_started >= 0; - } - - void start() { - m_started = getTickCount_sys(); - } - - qint64 elapsed() const { - qint64 current = getTickCount_sys(); - qint64 delta = current - m_started; - if (delta < 0) - delta += getPeriod_sys(); //we wrapped around - return delta; - } - -private: - enum { - MSECS_PER_HOUR = 3600000, - MSECS_PER_MIN = 60000 - }; - - qint64 m_started; - - quint64 getPeriod_sys() const { -#ifdef Q_OS_WIN - return Q_UINT64_C(0x100000000); -#else - // fallback - return 86400 * 1000; -#endif - } - - qint64 getTickCount_sys() const { -#ifdef Q_OS_WIN - return ::GetTickCount(); -#else - // fallback - const QTime t = QTime::currentTime(); - return MSECS_PER_HOUR * t.hour() + MSECS_PER_MIN * t.minute() + 1000 * t.second() + t.msec(); -#endif - } -}; - +typedef QElapsedTimer ElapsedTimer; class QUnifiedTimer : public QObject { diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 12a992a..63c2ab8 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -88,7 +88,7 @@ QT_END_NAMESPACE #include "qprocess_p.h" #include <qbytearray.h> -#include <qdatetime.h> +#include <qelapsedtimer.h> #include <qcoreapplication.h> #include <qsocketnotifier.h> #include <qtimer.h> @@ -1639,7 +1639,7 @@ bool QProcess::waitForBytesWritten(int msecs) if (d->processState == QProcess::NotRunning) return false; if (d->processState == QProcess::Starting) { - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); bool started = waitForStarted(msecs); if (!started) @@ -1676,7 +1676,7 @@ bool QProcess::waitForFinished(int msecs) if (d->processState == QProcess::NotRunning) return false; if (d->processState == QProcess::Starting) { - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); bool started = waitForStarted(msecs); if (!started) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 5119ec0..216c382 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -92,7 +92,6 @@ QT_END_NAMESPACE #include <private/qcoreapplication_p.h> #include <private/qthread_p.h> -#include <qdatetime.h> #include <qfile.h> #include <qfileinfo.h> #include <qlist.h> @@ -101,6 +100,7 @@ QT_END_NAMESPACE #include <qsemaphore.h> #include <qsocketnotifier.h> #include <qthread.h> +#include <qelapsedtimer.h> #include <errno.h> #include <stdlib.h> @@ -933,7 +933,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs); #endif - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); forever { @@ -1005,7 +1005,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs); #endif - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); while (!writeBuffer.isEmpty()) { @@ -1072,7 +1072,7 @@ bool QProcessPrivate::waitForFinished(int msecs) qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); forever { diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 0fd965b..e0d92c0 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qcore_unix_p.h" +#include "qelapsedtimer.h" #ifndef Q_OS_VXWORKS # if !defined(Q_OS_HPUX) || defined(__ia64) @@ -56,74 +57,12 @@ #include <mach/mach_time.h> #endif -#if !defined(QT_NO_CLOCK_MONOTONIC) -# if defined(QT_BOOTSTRAPPED) -# define QT_NO_CLOCK_MONOTONIC -# endif -#endif - QT_BEGIN_NAMESPACE -bool qt_gettime_is_monotonic() -{ -#if (_POSIX_MONOTONIC_CLOCK-0 > 0) || defined(Q_OS_MAC) - return true; -#else - static int returnValue = 0; - - if (returnValue == 0) { -# if (_POSIX_MONOTONIC_CLOCK-0 < 0) - returnValue = -1; -# elif (_POSIX_MONOTONIC_CLOCK == 0) - // detect if the system support monotonic timers - long x = sysconf(_SC_MONOTONIC_CLOCK); - returnValue = (x >= 200112L) ? 1 : -1; -# endif - } - - return returnValue != -1; -#endif -} - -timeval qt_gettime() -{ - timeval tv; -#if defined(Q_OS_MAC) - static mach_timebase_info_data_t info = {0,0}; - if (info.denom == 0) - mach_timebase_info(&info); - - uint64_t cpu_time = mach_absolute_time(); - uint64_t nsecs = cpu_time * (info.numer / info.denom); - tv.tv_sec = nsecs / 1000000000ull; - tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000); - return tv; -#elif (_POSIX_MONOTONIC_CLOCK-0 > 0) - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - tv.tv_sec = ts.tv_sec; - tv.tv_usec = ts.tv_nsec / 1000; - return tv; -#else -# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) - if (qt_gettime_is_monotonic()) { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - tv.tv_sec = ts.tv_sec; - tv.tv_usec = ts.tv_nsec / 1000; - return tv; - } -# endif - // use gettimeofday - ::gettimeofday(&tv, 0); - return tv; -#endif -} - static inline bool time_update(struct timeval *tv, const struct timeval &start, const struct timeval &timeout) { - if (!qt_gettime_is_monotonic()) { + if (!QElapsedTimer::isMonotonic()) { // we cannot recalculate the timeout without a monotonic clock as the time may have changed return false; } diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 297b25d..439ca5a 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -314,8 +314,8 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) # define _POSIX_MONOTONIC_CLOCK -1 #endif -bool qt_gettime_is_monotonic(); -timeval qt_gettime(); +timeval qt_gettime(); // in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp + Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, const struct timeval *tv); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 2da5a7d..8fc3fb8 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -47,7 +47,6 @@ #include "qeventloop.h" #include "qcorecmdlineargs_p.h" #include <qdatastream.h> -#include <qdatetime.h> #include <qdebug.h> #include <qdir.h> #include <qfile.h> @@ -59,6 +58,7 @@ #include <qthreadpool.h> #include <qthreadstorage.h> #include <private/qthread_p.h> +#include <qelapsedtimer.h> #include <qlibraryinfo.h> #include <qvarlengtharray.h> #include <private/qfactoryloader_p.h> @@ -917,7 +917,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m QThreadData *data = QThreadData::current(); if (!data->eventDispatcher) return; - QTime start; + QElapsedTimer start; start.start(); if (flags & QEventLoop::DeferredDeletion) QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index a141887..f7d45ac 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -45,6 +45,7 @@ #include "qpair.h" #include "qsocketnotifier.h" #include "qthread.h" +#include "qelapsedtimer.h" #include "qeventdispatcher_unix_p.h" #include <private/qthread_p.h> @@ -311,12 +312,10 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, QTimerInfoList::QTimerInfoList() { - currentTime = qt_gettime(); - #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) - if (!qt_gettime_is_monotonic()) { + if (!QElapsedTimer::isMonotonic()) { // not using monotonic timers, initialize the timeChanged() machinery - previousTime = currentTime; + previousTime = qt_gettime(); tms unused; previousTicks = times(&unused); @@ -393,7 +392,7 @@ bool QTimerInfoList::timeChanged(timeval *delta) void QTimerInfoList::repairTimersIfNeeded() { - if (qt_gettime_is_monotonic()) + if (QElapsedTimer::isMonotonic()) return; timeval delta; if (timeChanged(&delta)) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index dd0c257..cb84538 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -617,7 +617,9 @@ QThread::Priority QThread::priority() const { Q_D(const QThread); QMutexLocker locker(&d->mutex); - return d->priority; + + // mask off the high bits that are used for flags + return Priority(d->priority & 0xffff); } /*! diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index cda35a4..5a50646 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -92,10 +92,17 @@ # endif #endif +#if defined(Q_OS_LINUX) && !defined(SCHED_IDLE) +// from linux/sched.h +# define SCHED_IDLE 5 +#endif + QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD +enum { ThreadPriorityResetFlag = 0x80000000 }; + static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT; static pthread_key_t current_thread_data_key; @@ -221,6 +228,11 @@ void *QThreadPrivate::start(void *arg) QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); + // do we need to reset the thread priority? + if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) { + thr->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); + } + #ifdef Q_OS_SYMBIAN // Because Symbian Open C does not provide a way to convert between // RThread and pthread_t, we must delay initialization of the RThread @@ -436,6 +448,37 @@ void QThread::usleep(unsigned long usecs) thread_sleep(&ti); } +// Does some magic and calculate the Unix scheduler priorities +// sched_policy is IN/OUT: it must be set to a valid policy before calling this function +// sched_priority is OUT only +static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority) +{ +#ifdef SCHED_IDLE + if (priority == QThread::IdlePriority) { + *sched_policy = SCHED_IDLE; + *sched_priority = 0; + return true; + } + const int lowestPriority = QThread::LowestPriority; +#else + const int lowestPriority = QThread::IdlePriority; +#endif + const int highestPriority = QThread::TimeCriticalPriority; + + int prio_min = sched_get_priority_min(*sched_policy); + int prio_max = sched_get_priority_max(*sched_policy); + if (prio_min == -1 || prio_max == -1) + return false; + + int prio; + // crudely scale our priority enum values to the prio_min/prio_max + prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min; + prio = qMax(prio_min, qMin(prio_max, prio)); + + *sched_priority = prio; + return true; +} + void QThread::start(Priority priority) { Q_D(QThread); @@ -472,32 +515,14 @@ void QThread::start(Priority priority) break; } - int prio_min = sched_get_priority_min(sched_policy); - int prio_max = sched_get_priority_max(sched_policy); - if (prio_min == -1 || prio_max == -1) { + int prio; + if (!calculateUnixPriority(priority, &sched_policy, &prio)) { // failed to get the scheduling parameters, don't // bother setting the priority qWarning("QThread::start: Cannot determine scheduler priority range"); break; } - int prio; - switch (priority) { - case IdlePriority: - prio = prio_min; - break; - - case TimeCriticalPriority: - prio = prio_max; - break; - - default: - // crudely scale our priority enum values to the prio_min/prio_max - prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min; - prio = qMax(prio_min, qMin(prio_max, prio)); - break; - } - sched_param sp; sp.sched_priority = prio; @@ -505,7 +530,9 @@ void QThread::start(Priority priority) || pthread_attr_setschedpolicy(&attr, sched_policy) != 0 || pthread_attr_setschedparam(&attr, &sp) != 0) { // could not set scheduling hints, fallback to inheriting them + // we'll try again from inside the thread pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + d->priority = Priority(priority | ThreadPriorityResetFlag); } break; } @@ -672,38 +699,28 @@ void QThread::setPriority(Priority priority) return; } - int prio_min = sched_get_priority_min(sched_policy); - int prio_max = sched_get_priority_max(sched_policy); - if (prio_min == -1 || prio_max == -1) { + int prio; + if (!calculateUnixPriority(priority, &sched_policy, &prio)) { // failed to get the scheduling parameters, don't // bother setting the priority qWarning("QThread::setPriority: Cannot determine scheduler priority range"); return; } - int prio; - switch (priority) { - case InheritPriority: - qWarning("QThread::setPriority: Argument cannot be InheritPriority"); - return; - - case IdlePriority: - prio = prio_min; - break; - - case TimeCriticalPriority: - prio = prio_max; - break; - - default: - // crudely scale our priority enum values to the prio_min/prio_max - prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min; - prio = qMax(prio_min, qMin(prio_max, prio)); - break; - } - param.sched_priority = prio; - pthread_setschedparam(d->thread_id, sched_policy, ¶m); + int status = pthread_setschedparam(d->thread_id, sched_policy, ¶m); + +# ifdef SCHED_IDLE + // were we trying to set to idle priority and failed? + if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { + // reset to lowest priority possible + pthread_getschedparam(d->thread_id, &sched_policy, ¶m); + param.sched_priority = sched_get_priority_min(sched_policy); + pthread_setschedparam(d->thread_id, sched_policy, ¶m); + } +# else + Q_UNUSED(status); +# endif // SCHED_IDLE #endif } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index c1027ed..54a4205 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -98,18 +98,23 @@ static inline QDate fixedDate(int y, int m, int d) return result; } +static inline uint julianDayFromGregorianDate(int year, int month, int day) +{ + // Gregorian calendar starting from October 15, 1582 + // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern + return (1461 * (year + 4800 + (month - 14) / 12)) / 4 + + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12 + - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4 + + day - 32075; +} + static uint julianDayFromDate(int year, int month, int day) { if (year < 0) ++year; if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) { - // Gregorian calendar starting from October 15, 1582 - // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern - return (1461 * (year + 4800 + (month - 14) / 12)) / 4 - + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12 - - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4 - + day - 32075; + return julianDayFromGregorianDate(year, month, day); } else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) { // Julian calendar until October 4, 1582 // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering @@ -1118,46 +1123,12 @@ int QDate::daysTo(const QDate &d) const */ /*! - \overload + \fn QDate::currentDate() Returns the current date, as reported by the system clock. \sa QTime::currentTime(), QDateTime::currentDateTime() */ -QDate QDate::currentDate() -{ - QDate d; -#if defined(Q_OS_WIN) - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - GetLocalTime(&st); - d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay); -#elif defined(Q_OS_SYMBIAN) - TTime localTime; - localTime.HomeTime(); - TDateTime localDateTime = localTime.DateTime(); - // months and days are zero indexed - d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 ); -#else - // posix compliant system - time_t ltime; - time(<ime); - tm *t = 0; - -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) - // use the reentrant version of localtime() where available - tzset(); - tm res; - t = localtime_r(<ime, &res); -#else - t = localtime(<ime); -#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS - - d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday); -#endif - return d; -} - #ifndef QT_NO_DATESTRING /*! \fn QDate QDate::fromString(const QString &string, Qt::DateFormat format) @@ -1812,7 +1783,7 @@ int QTime::msecsTo(const QTime &t) const */ /*! - \overload + \fn QTime::currentTime() Returns the current time as reported by the system clock. @@ -1820,53 +1791,6 @@ int QTime::msecsTo(const QTime &t) const operating system; not all systems provide 1-millisecond accuracy. */ -QTime QTime::currentTime() -{ - QTime ct; - -#if defined(Q_OS_WIN) - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - GetLocalTime(&st); - ct.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond - + st.wMilliseconds; -#if defined(Q_OS_WINCE) - ct.startTick = GetTickCount() % MSECS_PER_DAY; -#endif -#elif defined(Q_OS_SYMBIAN) - TTime localTime; - localTime.HomeTime(); - TDateTime localDateTime = localTime.DateTime(); - ct.mds = MSECS_PER_HOUR * localDateTime.Hour() + MSECS_PER_MIN * localDateTime.Minute() - + 1000 * localDateTime.Second() + (localDateTime.MicroSecond() / 1000); -#elif defined(Q_OS_UNIX) - // posix compliant system - struct timeval tv; - gettimeofday(&tv, 0); - time_t ltime = tv.tv_sec; - tm *t = 0; - -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) - // use the reentrant version of localtime() where available - tzset(); - tm res; - t = localtime_r(<ime, &res); -#else - t = localtime(<ime); -#endif - Q_CHECK_PTR(t); - - ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec - + tv.tv_usec / 1000; -#else - time_t ltime; // no millisecond resolution - ::time(<ime); - const tm *const t = localtime(<ime); - ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec; -#endif - return ct; -} - #ifndef QT_NO_DATESTRING /*! \fn QTime QTime::fromString(const QString &string, Qt::DateFormat format) @@ -2872,63 +2796,280 @@ bool QDateTime::operator<(const QDateTime &other) const */ /*! + \fn QDateTime QDateTime::currentDateTime() Returns the current datetime, as reported by the system clock, in the local time zone. - \sa QDate::currentDate(), QTime::currentTime(), toTimeSpec() + \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec() */ -QDateTime QDateTime::currentDateTime() +/*! + \fn QDateTime QDateTime::currentDateTimeUtc() + \since 4.7 + Returns the current datetime, as reported by the system clock, in + UTC. + + \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec() +*/ + +/*! + \fn qint64 QDateTime::currentMsecsSinceEpoch() + \since 4.7 + + Returns the number of milliseconds since 1970-01-01T00:00:00 Universal + Coordinated Time. This number is like the POSIX time_t variable, but + expressed in milliseconds instead. + + \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec() +*/ + +static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0) { + return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec; +} + #if defined(Q_OS_WIN) +QDate QDate::currentDate() +{ + QDate d; + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + GetLocalTime(&st); + d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay); + return d; +} + +QTime QTime::currentTime() +{ + QTime ct; + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + GetLocalTime(&st); + ct.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); +#if defined(Q_OS_WINCE) + ct.startTick = GetTickCount() % MSECS_PER_DAY; +#endif + return ct; +} + +QDateTime QDateTime::currentDateTime() +{ QDate d; QTime t; SYSTEMTIME st; memset(&st, 0, sizeof(SYSTEMTIME)); GetLocalTime(&st); d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay); - t.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond - + st.wMilliseconds; + t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); return QDateTime(d, t); +} + +QDateTime QDateTime::currentDateTimeUtc() +{ + QDate d; + QTime t; + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + GetSystemTime(&st); + d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay); + t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + return QDateTime(d, t, Qt::UTC); +} + +qint64 QDateTime::currentMsecsSinceEpoch() +{ + QDate d; + QTime t; + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + GetSystemTime(&st); + + return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) + + qint64(julianDayFromGregorianDate(st.wYear, st.wMonth, st.wDay) + - julianDayFromGregorianDate(1970, 1, 1)) * Q_INT64_C(86400000); +} + #elif defined(Q_OS_SYMBIAN) - return QDateTime(QDate::currentDate(), QTime::currentTime()); +QDate QDate::currentDate() +{ + QDate d; + TTime localTime; + localTime.HomeTime(); + TDateTime localDateTime = localTime.DateTime(); + // months and days are zero indexed + d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 ); + return d; +} + +QTime QTime::currentTime() +{ + QTime ct; + TTime localTime; + localTime.HomeTime(); + TDateTime localDateTime = localTime.DateTime(); + ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(), + localDateTime.Second(), localDateTime.MicroSecond() / 1000); + return ct; +} + +QDateTime QDateTime::currentDateTime() +{ + QDate d; + QTime ct; + TTime localTime; + localTime.HomeTime(); + TDateTime localDateTime = localTime.DateTime(); + // months and days are zero indexed + d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1); + ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(), + localDateTime.Second(), localDateTime.MicroSecond() / 1000); + return QDateTime(d, ct); +} + +QDateTime QDateTime::currentDateTimeUtc() +{ + QDate d; + QTime ct; + TTime gmTime; + gmTime.UniversalTime(); + TDateTime gmtDateTime = gmTime.DateTime(); + // months and days are zero indexed + d.jd = julianDayFromDate(gmtDateTime.Year(), gmtDateTime.Month() + 1, gmtDateTime.Day() + 1); + ct.mds = msecsFromDecomposed(gmtDateTime.Hour(), gmtDateTime.Minute(), + gmtDateTime.Second(), gmtDateTime.MicroSecond() / 1000); + return QDateTime(d, ct, Qt::UTC); +} + +qint64 QDateTime::currentMsecsSinceEpoch() +{ + QDate d; + QTime ct; + TTime gmTime; + gmTime.UniversalTime(); + TDateTime gmtDateTime = gmTime.DateTime(); + + // according to the documentation, the value is: + // "a date and time as a number of microseconds since midnight, January 1st, 0 AD nominal Gregorian" + qint64 value = gmTime.Int64(); + + // whereas 1970-01-01T00:00:00 is (in the same representation): + // ((1970 * 365) + (1970 / 4) - (1970 / 100) + (1970 / 400) - 13) * 86400 * 1000000 + static const qint64 unixEpoch = Q_INT64_C(0xdcddb30f2f8000); + + return (value - unixEpoch) / 1000; +} + +#elif defined(Q_OS_UNIX) +QDate QDate::currentDate() +{ + QDate d; + // posix compliant system + time_t ltime; + time(<ime); + struct tm *t = 0; + +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant version of localtime() where available + tzset(); + struct tm res; + t = localtime_r(<ime, &res); #else -#if defined(Q_OS_UNIX) + t = localtime(<ime); +#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS + + d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday); + return d; +} + +QTime QTime::currentTime() +{ + QTime ct; + // posix compliant system + struct timeval tv; + gettimeofday(&tv, 0); + time_t ltime = tv.tv_sec; + struct tm *t = 0; + +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant version of localtime() where available + tzset(); + struct tm res; + t = localtime_r(<ime, &res); +#else + t = localtime(<ime); +#endif + Q_CHECK_PTR(t); + + ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000); + return ct; +} + +QDateTime QDateTime::currentDateTime() +{ // posix compliant system // we have milliseconds struct timeval tv; gettimeofday(&tv, 0); time_t ltime = tv.tv_sec; - tm *t = 0; + struct tm *t = 0; #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available tzset(); - tm res; + struct tm res; t = localtime_r(<ime, &res); #else t = localtime(<ime); #endif QDateTime dt; - dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec - + tv.tv_usec / 1000; -#else - time_t ltime; // no millisecond resolution - ::time(<ime); - tm *t = 0; - localtime(<ime); - dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec; -#endif // Q_OS_UNIX + dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000); dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday); dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST : t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard : QDateTimePrivate::LocalUnknown; return dt; +} + +QDateTime QDateTime::currentDateTimeUtc() +{ + // posix compliant system + // we have milliseconds + struct timeval tv; + gettimeofday(&tv, 0); + time_t ltime = tv.tv_sec; + struct tm *t = 0; + +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant version of localtime() where available + struct tm res; + t = gmtime_r(<ime, &res); +#else + t = gmtime(<ime); #endif + + QDateTime dt; + dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000); + + dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday); + dt.d->spec = QDateTimePrivate::UTC; + return dt; } +qint64 QDateTime::currentMsecsSinceEpoch() +{ + // posix compliant system + // we have milliseconds + struct timeval tv; + gettimeofday(&tv, 0); + return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000; +} + +#else +#error "What system is this?" +#endif + /*! \since 4.2 diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 6fdc855..ef5968e 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -261,11 +261,13 @@ public: int utcOffset() const; static QDateTime currentDateTime(); + static QDateTime currentDateTimeUtc(); #ifndef QT_NO_DATESTRING static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate); static QDateTime fromString(const QString &s, const QString &format); #endif static QDateTime fromTime_t(uint secsSince1Jan1970UTC); + static qint64 currentMsecsSinceEpoch(); #ifdef QT3_SUPPORT inline QT3_SUPPORT void setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec) { diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp new file mode 100644 index 0000000..28dfc23 --- /dev/null +++ b/src/corelib/tools/qelapsedtimer.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QElapsedTimer + \brief The QElapsedTimer class provides a fast way to calculate elapsed times. + \since 4.7 + + \reentrant + \ingroup tools + \inmodule QtCore + + The QElapsedTimer class is usually used to quickly calculate how much + time has elapsed between two events. Its API is similar to that of QTime, + so code that was using that can be ported quickly to the new class. + + However, unlike QTime, QElapsedTimer tries to use monotonic clocks if + possible. This means it's not possible to convert QElapsedTimer objects + to a human-readable time. + + The typical use-case for the class is to determine how much time was + spent in a slow operation. The simplest example of such a case is for + debugging purposes, as in the following example: + + \snippet doc/src/snippets/qelapsedtimer/main.cpp 0 + + In this example, the timer is started by a call to start() and the + elapsed timer is calculated by the elapsed() function. + + The time elapsed can also be used to recalculate the time available for + another operation, after the first one is complete. This is useful when + the execution must complete within a certain time period, but several + steps are needed. The \tt{waitFor}-type functions in QIODevice and its + subclasses are good examples of such need. In that case, the code could + be as follows: + + \snippet doc/src/snippets/qelapsedtimer/main.cpp 1 + + Another use-case is to execute a certain operation for a specific + timeslice. For this, QElapsedTimer provides the hasExpired() convenience + function, which can be used to determine if a certain number of + milliseconds has already elapsed: + + \snippet doc/src/snippets/qelapsedtimer/main.cpp 1 + + \section1 Reference clocks + + QElapsedTimer will use the platform's monotonic reference clock in all + platforms that support it (see QElapsedTimer::isMonotonic()). This has + the added benefit that QElapsedTimer is immune to time adjustments, such + as the user correcting the time. Also unlike QTime, QElapsedTimer is + immune to changes in the timezone settings, such as daylight savings + periods. + + On the other hand, this means QElapsedTimer values can only be compared + with other values that use the same reference. This is especially true if + the time since the reference is extracted from the QElapsedTimer object + (QElapsedTimer::msecsSinceReference()) and serialised. These values + should never be exchanged across the network or saved to disk, since + there's no telling whether the computer node receiving the data is the + same as the one originating it or if it has rebooted since. + + It is, however, possible to exchange the value with other processes + running on the same machine, provided that they also use the same + reference clock. QElapsedTimer will always use the same clock, so it's + safe to compare with the value coming from another process in the same + machine. If comparing to values produced by other APIs, you should check + that the clock used is the same as QElapsedTimer (see + QElapsedTimer::clockType()). + + \section2 32-bit overflows + + Some of the clocks that QElapsedTimer have a limited range and may + overflow after hitting the upper limit (usually 32-bit). QElapsedTimer + deals with this overflow issue and presents a consistent timing. However, + when extracting the time since reference from QElapsedTimer, two + different processes in the same machine may have different understanding + of how much time has actually elapsed. + + The information on which clocks types may overflow and how to remedy that + issue is documented along with the clock types. + + \sa QTime, QTimer +*/ + +/*! + \enum QElapsedTimer::ClockType + + This enum contains the different clock types that QElapsedTimer may use. + + QElapsedTimer will always use the same clock type in a particular + machine, so this value will not change during the lifetime of a program. + It is provided so that QElapsedTimer can be used with other non-Qt + implementations, to guarantee that the same reference clock is being + used. + + \value SystemTime The human-readable system time. This clock is not monotonic. + \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is not monotonic and does not overflow. + \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow. + \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow. + + \section2 SystemTime + + The system time clock is purely the real time, expressed in milliseconds + since Jan 1, 1970 at 0:00 UTC. It's equivalent to the value returned by + the C and POSIX \tt{time} function, with the milliseconds added. This + clock type is currently only used on Unix systems that do not support + monotonic clocks (see below). + + This is the only non-monotonic clock that QElapsedTimer may use. + + \section2 MonotonicClock + + This is the system's monotonic clock, expressed in milliseconds since an + arbitrary point in the past. This clock type is used on Unix systems + which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}). + + This clock does not overflow. + + \section2 TickCounter + + The tick counter clock type is based on the system's or the processor's + tick counter, multiplied by the duration of a tick. This clock type is + used on Windows and Symbian platforms. + + The TickCounter clock type is the only clock type that may overflow. + Windows Vista and Windows Server 2008 support the extended 64-bit tick + counter, which allows avoiding the overflow. + + On Windows systems, the clock overflows after 2^32 milliseconds, which + corresponds to roughly 49.7 days. This means two processes's reckoning of + the time since the reference may be different by multiples of 2^32 + milliseconds. When comparing such values, it's recommended that the high + 32 bits of the millisecond count be masked off. + + On Symbian systems, the overflow happens after 2^32 ticks, the duration + of which can be obtained from the platform HAL using the constant + HAL::ENanoTickPeriod. When comparing values between processes, it's + necessary to divide the value by the tick duration and mask off the high + 32 bits. + + \section2 MachAbsoluteTime + + This clock type is based on the absolute time presented by Mach kernels, + such as that found on Mac OS X. This clock type is presented separately + from MonotonicClock since Mac OS X is also a Unix system and may support + a POSIX monotonic clock with values differing from the Mach absolute + time. + + This clock is monotonic and does not overflow. + + \sa clockType(), isMonotonic() +*/ + +/*! + \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const + + Returns true if this object and \a other contain the same time. +*/ + +/*! + \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const + + Returns true if this object and \a other contain different times. +*/ + +static const qint64 invalidData = Q_INT64_C(0x8000000000000000); + +/*! + Marks this QElapsedTimer object as invalid. + + An invalid object can be checked with isValid(). Calculations of timer + elapsed since invalid data are undefined and will likely produce bizarre + results. + + \sa isValid(), start(), restart() +*/ +void QElapsedTimer::invalidate() +{ + t1 = t2 = invalidData; +} + +/*! + Returns true if this object was invalidated by a call to invalidate() and + has not been restarted since. + + \sa invalidate(), start(), restart() +*/ +bool QElapsedTimer::isValid() const +{ + return t1 != invalidData && t2 != invalidData; +} + +/*! + Returns true if this QElapsedTimer has already expired by \a timeout + milliseconds (that is, more than \a timeout milliseconds have elapsed). + The value of \a timeout can be -1 to indicate that this timer does not + expire, in which case this function will always return false. + + \sa elapsed() +*/ +bool QElapsedTimer::hasExpired(qint64 timeout) const +{ + // if timeout is -1, quint64(timeout) is LLINT_MAX, so this will be + // considered as never expired + return quint64(elapsed()) > quint64(timeout); +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h new file mode 100644 index 0000000..0d6f0be --- /dev/null +++ b/src/corelib/tools/qelapsedtimer.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTIMESTAMP_H +#define QTIMESTAMP_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class Q_CORE_EXPORT QElapsedTimer +{ +public: + enum ClockType { + SystemTime, + MonotonicClock, + TickCounter, + MachAbsoluteTime + }; + static ClockType clockType(); + static bool isMonotonic(); + + void start(); + qint64 restart(); + void invalidate(); + bool isValid() const; + + qint64 elapsed() const; + bool hasExpired(qint64 timeout) const; + + qint64 msecsSinceReference() const; + qint64 msecsTo(const QElapsedTimer &other) const; + qint64 secsTo(const QElapsedTimer &other) const; + + bool operator==(const QElapsedTimer &other) const + { return t1 == other.t1 && t2 == other.t2; } + bool operator!=(const QElapsedTimer &other) const + { return !(*this == other); } + + friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2); + +private: + qint64 t1; + qint64 t2; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QTIMESTAMP_H diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp new file mode 100644 index 0000000..9b589c1 --- /dev/null +++ b/src/corelib/tools/qelapsedtimer_generic.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include "qdatetime.h" + +QT_BEGIN_NAMESPACE + +/*! + Returns the clock type that this QElapsedTimer implementation uses. + + \sa isMonotonic() +*/ +QElapsedTimer::ClockType QElapsedTimer::clockType() +{ + return SystemTime; +} + +/*! + Returns true if this is a monotonic clock, false otherwise. See the + information on the different clock types to understand which ones are + monotonic. + + \sa clockType(), QElapsedTimer::ClockType +*/ +bool QElapsedTimer::isMonotonic() +{ + return false; +} + +/*! + Starts this timer. Once started, a timer value can be checked with elapsed() or msecsSinceReference(). + + Normally, a timer is started just before a lengthy operation, such as: + \snippet doc/src/snippets/qelapsedtimer/main.cpp 0 + + Also, starting a timer makes it valid again. + + \sa restart(), invalidate(), elapsed() +*/ +void QElapsedTimer::start() +{ + restart(); +} + +/*! + Restarts the timer and returns the time elapsed since the previous start. + This function is equivalent to obtaining the elapsed time with elapsed() + and then starting the timer again with restart(), but it does so in one + single operation, avoiding the need to obtain the clock value twice. + + The following example illustrates how to use this function to calibrate a + parameter to a slow operation (for example, an iteration count) so that + this operation takes at least 250 milliseconds: + + \snippet doc/src/snippets/qelapsedtimer/main.cpp 3 + + \sa start(), invalidate(), elapsed() +*/ +qint64 QElapsedTimer::restart() +{ + qint64 old = t1; + t1 = QDateTime::currentMsecsSinceEpoch(); + t2 = 0; + return t1 - old; +} + +/*! + Returns the number of milliseconds since this QElapsedTimer was last + started. Calling this function in a QElapsedTimer that was invalidated + will result in undefined results. + + \sa start(), restart(), hasExpired(), invalidate() +*/ +qint64 QElapsedTimer::elapsed() const +{ + return QDateTime::currentMsecsSinceEpoch() - t1; +} + +/*! + Returns the number of milliseconds between last time this QElapsedTimer + object was started and its reference clock's start. + + This number is usually arbitrary for all clocks except the + QElapsedTimer::SystemTime clock. For that clock type, this number is the + number of milliseconds since January 1st, 1970 at 0:00 UTC (that is, it + is the Unix time expressed in milliseconds). + + \sa clockType(), elapsed() +*/ +qint64 QElapsedTimer::msecsSinceReference() const +{ + return t1; +} + +/*! + Returns the number of milliseconds between this QElapsedTimer and \a + other. If \a other was started before this object, the returned value + will be positive. If it was started later, the returned value will be + negative. + + The return value is undefined if this object or \a other were invalidated. + + \sa secsTo(), elapsed() +*/ +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const +{ + qint64 diff = other.t1 - t1; + return diff; +} + +/*! + Returns the number of seconds between this QElapsedTimer and \a other. If + \a other was started before this object, the returned value will be + positive. If it was started later, the returned value will be negative. + + The return value is undefined if this object or \a other were invalidated. + + \sa msecsTo(), elapsed() +*/ +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const +{ + return msecsTo(other) / 1000; +} + +/*! + \relates QElapsedTimer + + Returns true if \a v1 was started before \a v2, false otherwise. + + The returned value is undefined if one of the two parameters is invalid + and the other isn't. However, two invalid timers are equal and thus this + function will return false. +*/ +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_mac.cpp b/src/corelib/tools/qelapsedtimer_mac.cpp new file mode 100644 index 0000000..8fceb49 --- /dev/null +++ b/src/corelib/tools/qelapsedtimer_mac.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include <sys/time.h> +#include <unistd.h> + +#include <mach/mach_time.h> + +QT_BEGIN_NAMESPACE + +QElapsedTimer::ClockType QElapsedTimer::clockType() +{ + return MachAbsoluteTime; +} + +bool QElapsedTimer::isMonotonic() +{ + return true; +} + +static mach_timebase_info_data_t info = {0,0}; +static qint64 absoluteToNSecs(qint64 cpuTime) +{ + if (info.denom == 0) + mach_timebase_info(&info); + qint64 nsecs = cpuTime * info.numer / info.denom; + return nsecs; +} + +static qint64 absoluteToMSecs(qint64 cpuTime) +{ + return absoluteToNSecs(cpuTime) / 1000000; +} + +timeval qt_gettime() +{ + timeval tv; + + uint64_t cpu_time = mach_absolute_time(); + uint64_t nsecs = absoluteToNSecs(cpu_time); + tv.tv_sec = nsecs / 1000000000ull; + tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000); + return tv; +} + +void QElapsedTimer::start() +{ + t1 = mach_absolute_time(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() +{ + qint64 old = t1; + t1 = mach_absolute_time(); + t2 = 0; + + return absoluteToMSecs(t1 - old); +} + +qint64 QElapsedTimer::elapsed() const +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToMSecs(cpu_time - t1); +} + +qint64 QElapsedTimer::msecsSinceReference() const +{ + return absoluteToMSecs(t1); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const +{ + return absoluteToMSecs(other.t1 - t1); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_symbian.cpp b/src/corelib/tools/qelapsedtimer_symbian.cpp new file mode 100644 index 0000000..038b102 --- /dev/null +++ b/src/corelib/tools/qelapsedtimer_symbian.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include "qpair.h" +#include <e32std.h> +#include <sys/time.h> +#include <hal.h> + +QT_BEGIN_NAMESPACE + +// return quint64 to avoid sign-extension +static quint64 getMicrosecondFromTick() +{ + static TInt nanokernel_tick_period; + if (!nanokernel_tick_period) + HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period); + + static quint32 highdword = 0; + static quint32 lastval = 0; + quint32 val = User::NTickCount(); + if (val < lastval) + ++highdword; + lastval = val; + + return nanokernel_tick_period * (val | (quint64(highdword) << 32)); +} + +static quint64 getMillisecondFromTick() +{ + return getMicrosecondFromTick() / 1000; +} + +timeval qt_gettime() +{ + timeval tv; + quint64 now = getMicrosecondFromTick(); + tv.tv_sec = now / 1000000; + tv.tv_usec = now % 1000000; + + return tv; +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() +{ + return TickCounter; +} + +bool QElapsedTimer::isMonotonic() +{ + return true; +} + +void QElapsedTimer::start() +{ + t1 = getMillisecondFromTick(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() +{ + qint64 oldt1 = t1; + t1 = getMillisecondFromTick(); + t2 = 0; + return t1 - oldt1; +} + +qint64 QElapsedTimer::elapsed() const +{ + return getMillisecondFromTick() - t1; +} + +qint64 QElapsedTimer::msecsSinceReference() const +{ + return t1; +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const +{ + return other.t1 - t1; +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) +{ + return (v1.t1 - v2.t1) < 0; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp new file mode 100644 index 0000000..85d7fa8 --- /dev/null +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include "qpair.h" +#include <sys/time.h> +#include <time.h> +#include <unistd.h> + +#if !defined(QT_NO_CLOCK_MONOTONIC) +# if defined(QT_BOOTSTRAPPED) +# define QT_NO_CLOCK_MONOTONIC +# endif +#endif + +QT_BEGIN_NAMESPACE + +static qint64 fractionAdjustment() +{ + if (QElapsedTimer::isMonotonic()) { + // the monotonic timer is measured in nanoseconds + // 1 ms = 1000000 ns + return 1000*1000ull; + } else { + // gettimeofday is measured in microseconds + // 1 ms = 1000 us + return 1000; + } +} + +bool QElapsedTimer::isMonotonic() +{ +#if (_POSIX_MONOTONIC_CLOCK-0 > 0) + return true; +#else + static int returnValue = 0; + + if (returnValue == 0) { +# if (_POSIX_MONOTONIC_CLOCK-0 < 0) + returnValue = -1; +# elif (_POSIX_MONOTONIC_CLOCK == 0) + // detect if the system support monotonic timers + long x = sysconf(_SC_MONOTONIC_CLOCK); + returnValue = (x >= 200112L) ? 1 : -1; +# endif + } + + return returnValue != -1; +#endif +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() +{ + return isMonotonic() ? MonotonicClock : SystemTime; +} + +static inline QPair<long, long> do_gettime() +{ +#if (_POSIX_MONOTONIC_CLOCK-0 > 0) + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return qMakePair(ts.tv_sec, ts.tv_nsec); +#else +# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) + if (QElapsedTimer::isMonotonic()) { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return qMakePair(ts.tv_sec, ts.tv_nsec); + } +# endif + // use gettimeofday + timeval tv; + ::gettimeofday(&tv, 0); + return qMakePair(tv.tv_sec, tv.tv_usec); +#endif +} + +// used in qcore_unix.cpp and qeventdispatcher_unix.cpp +timeval qt_gettime() +{ + QPair<long, long> r = do_gettime(); + + timeval tv; + tv.tv_sec = r.first; + tv.tv_usec = r.second; + if (QElapsedTimer::isMonotonic()) + tv.tv_usec /= 1000; + + return tv; +} + +void QElapsedTimer::start() +{ + QPair<long, long> r = do_gettime(); + t1 = r.first; + t2 = r.second; +} + +qint64 QElapsedTimer::restart() +{ + QPair<long, long> r = do_gettime(); + qint64 oldt1 = t1; + qint64 oldt2 = t2; + t1 = r.first; + t2 = r.second; + + r.first -= oldt1; + r.second -= oldt2; + return r.first * Q_INT64_C(1000) + r.second / fractionAdjustment(); +} + +qint64 QElapsedTimer::elapsed() const +{ + QElapsedTimer now; + now.start(); + return msecsTo(now); +} + +qint64 QElapsedTimer::msecsSinceReference() const +{ + return t1 * Q_INT64_C(1000) + t2 / fractionAdjustment(); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const +{ + qint64 secs = other.t1 - t1; + qint64 fraction = other.t2 - t2; + return secs * Q_INT64_C(1000) + fraction / fractionAdjustment(); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const +{ + return other.t1 - t1; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) +{ + return v1.t1 < v2.t1 || (v1.t1 == v2.t1 && v1.t2 < v2.t2); +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp new file mode 100644 index 0000000..135196a --- /dev/null +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include <windows.h> + +typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void); +static PtrGetTickCount64 ptrGetTickCount64 = 0; + +QT_BEGIN_NAMESPACE + +static void resolveLibs() +{ + static bool done = false; + if (done) + return; + + // try to get GetTickCount64 from the system + HMODULE kernel32 = GetModuleHandleW(L"kernel32"); + if (!kernel32) + return; + +#if defined(Q_OS_WINCE) + // does this function exist on WinCE, or will ever exist? + ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, L"GetTickCount64"); +#else + ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64"); +#endif + + done = true; +} + +static quint64 getTickCount() +{ + resolveLibs(); + if (ptrGetTickCount64) + return ptrGetTickCount64(); + + static quint32 highdword = 0; + static quint32 lastval = 0; + quint32 val = GetTickCount(); + if (val < lastval) + ++highdword; + lastval = val; + return val | (quint64(highdword) << 32); +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() +{ + return TickCounter; +} + +bool QElapsedTimer::isMonotonic() +{ + return true; +} + +void QElapsedTimer::start() +{ + t1 = getTickCount(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() +{ + qint64 oldt1 = t1; + t1 = getTickCount(); + t2 = 0; + return t1 - oldt1; +} + +qint64 QElapsedTimer::elapsed() const +{ + return getTickCount() - t1; +} + +qint64 QElapsedTimer::msecsSinceReference() const +{ + return t1; +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const +{ + return other.t1 - t1; +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) +{ + return (v1.t1 - v2.t1) < 0; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 1966a79..e36497c 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1274,11 +1274,25 @@ QLocale QSystemLocale::fallbackLocale() const */ QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const { - if (type == MeasurementSystem) { + switch (type) { + case MeasurementSystem: return QVariant(unixGetSystemMeasurementSystem()); - } else { - return QVariant(); + case LanguageId: + case CountryId: { + QString locale = QLatin1String(envVarLocale()); + QLocale::Language lang; + QLocale::Country cntry; + getLangAndCountry(locale, lang, cntry); + if (type == LanguageId) + return lang; + if (cntry == QLocale::AnyCountry) + return fallbackLocale().country(); + return cntry; + } + default: + break; } + return QVariant(); } #elif !defined(Q_OS_SYMBIAN) @@ -1310,12 +1324,10 @@ QVariant QSystemLocale::query(QueryType /* type */, QVariant /* in */) const #endif -#ifndef QT_NO_SYSTEMLOCALE static QSystemLocale *_systemLocale = 0; Q_GLOBAL_STATIC_WITH_ARGS(QSystemLocale, QSystemLocale_globalSystemLocale, (true)) static QLocalePrivate *system_lp = 0; Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate) -#endif /****************************************************************************** ** Default system locale behavior @@ -1388,7 +1400,8 @@ QSystemLocale::QSystemLocale() /*! \internal */ QSystemLocale::QSystemLocale(bool) -{ } +{ +} /*! Deletes the object. @@ -1410,16 +1423,42 @@ static const QSystemLocale *systemLocale() return QSystemLocale_globalSystemLocale(); } +static const QLocalePrivate *maybeSystemPrivate(); +bool QLocalePrivate::isUninitializedSystemLocale() const +{ + return this == maybeSystemPrivate() && m_language_id == 0; +} + +QVariant QLocalePrivate::querySystemLocale(int type, const QVariant &in) const +{ + QVariant res = systemLocale()->query(QSystemLocale::QueryType(type), in); + if (res.isNull() && isUninitializedSystemLocale()) { + // if we were not able to get data from the system, initialize the + // system locale private data (which is essentially equals to this) + // with a fallback locale. + QLocalePrivate *system_private = globalLocalePrivate(); + *system_private = *systemLocale()->fallbackLocale().d(); + // internal cache is not initialized with values from the system, mark + // it as not fully initialized system locale. + system_private->m_language_id = 0; + } + return res; +} + +// retrieves data from the system locale and caches them locally. void QLocalePrivate::updateSystemPrivate() { const QSystemLocale *sys_locale = systemLocale(); if (!system_lp) - system_lp = globalLocalePrivate(); + return; + + // copy over the information from the fallback locale and modify *system_lp = *sys_locale->fallbackLocale().d(); QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant()); if (!res.isNull()) system_lp->m_language_id = res.toInt(); + res = sys_locale->query(QSystemLocale::CountryId, QVariant()); if (!res.isNull()) system_lp->m_country_id = res.toInt(); @@ -1446,19 +1485,29 @@ void QLocalePrivate::updateSystemPrivate() } #endif +// returns the private data for the system locale. Cached data will not be +// initialized until the updateSystemPrivate is called. static const QLocalePrivate *systemPrivate() { #ifndef QT_NO_SYSTEMLOCALE - // copy over the information from the fallback locale and modify - if (!system_lp || system_lp->m_language_id == 0) - QLocalePrivate::updateSystemPrivate(); - + if (!system_lp) { + system_lp = globalLocalePrivate(); + // mark the locale as uninitialized system locale + system_lp->m_language_id = 0; + } return system_lp; #else return locale_data; #endif } +#ifndef QT_NO_SYSTEMLOCALE +static const QLocalePrivate *maybeSystemPrivate() +{ + return system_lp; +} +#endif + static const QLocalePrivate *defaultPrivate() { if (!default_lp) @@ -2283,7 +2332,12 @@ void QLocale::setDefault(const QLocale &locale) */ QLocale::Language QLocale::language() const { - return Language(d()->languageId()); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return Language(dd->languageId()); } /*! @@ -2293,7 +2347,12 @@ QLocale::Language QLocale::language() const */ QLocale::Country QLocale::country() const { - return Country(d()->countryId()); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return Country(dd->countryId()); } /*! @@ -2631,8 +2690,8 @@ QString QLocale::toString(const QDate &date, FormatType format) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort, date); if (!res.isNull()) @@ -2726,8 +2785,8 @@ QString QLocale::toString(const QDateTime &dateTime, FormatType format) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::DateTimeToStringLong : QSystemLocale::DateTimeToStringShort, dateTime); @@ -2752,8 +2811,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort, time); if (!res.isNull()) @@ -2779,8 +2838,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const QString QLocale::dateFormat(FormatType format) const { #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort, QVariant()); if (!res.isNull()) @@ -2816,8 +2875,8 @@ QString QLocale::dateFormat(FormatType format) const QString QLocale::timeFormat(FormatType format) const { #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort, QVariant()); if (!res.isNull()) @@ -2853,8 +2912,8 @@ QString QLocale::timeFormat(FormatType format) const QString QLocale::dateTimeFormat(FormatType format) const { #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(format == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(format == LongFormat ? QSystemLocale::DateTimeFormatLong : QSystemLocale::DateTimeFormatShort, QVariant()); @@ -3021,7 +3080,12 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons */ QChar QLocale::decimalPoint() const { - return d()->decimal(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->decimal(); } /*! @@ -3031,7 +3095,12 @@ QChar QLocale::decimalPoint() const */ QChar QLocale::groupSeparator() const { - return d()->group(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->group(); } /*! @@ -3041,7 +3110,12 @@ QChar QLocale::groupSeparator() const */ QChar QLocale::percent() const { - return d()->percent(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->percent(); } /*! @@ -3051,7 +3125,12 @@ QChar QLocale::percent() const */ QChar QLocale::zeroDigit() const { - return d()->zero(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->zero(); } /*! @@ -3061,7 +3140,12 @@ QChar QLocale::zeroDigit() const */ QChar QLocale::negativeSign() const { - return d()->minus(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->minus(); } /*! @@ -3071,7 +3155,12 @@ QChar QLocale::negativeSign() const */ QChar QLocale::positiveSign() const { - return d()->plus(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->plus(); } /*! @@ -3081,7 +3170,12 @@ QChar QLocale::positiveSign() const */ QChar QLocale::exponential() const { - return d()->exponential(); + const QLocalePrivate *dd = d(); +#ifndef QT_NO_SYSTEMLOCALE + if (dd->isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif + return dd->exponential(); } static bool qIsUpper(char c) @@ -3200,8 +3294,8 @@ QString QLocale::monthName(int month, FormatType type) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(type == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(type == LongFormat ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort, month); if (!res.isNull()) @@ -3246,8 +3340,8 @@ QString QLocale::standaloneMonthName(int month, FormatType type) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(type == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(type == LongFormat ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort, month); if (!res.isNull()) @@ -3293,8 +3387,8 @@ QString QLocale::dayName(int day, FormatType type) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(type == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(type == LongFormat ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort, day); if (!res.isNull()) @@ -3342,8 +3436,8 @@ QString QLocale::standaloneDayName(int day, FormatType type) const return QString(); #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(type == LongFormat + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(type == LongFormat ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort, day); if (!res.isNull()) @@ -3387,8 +3481,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const bool found = false; #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant()); + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(QSystemLocale::MeasurementSystem, QVariant()); if (!res.isNull()) { meas = MeasurementSystem(res.toInt()); found = true; @@ -3415,8 +3509,8 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const QString QLocale::amText() const { #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant()); + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(QSystemLocale::AMText, QVariant()); if (!res.isNull()) return res.toString(); } @@ -3435,8 +3529,8 @@ QString QLocale::amText() const QString QLocale::pmText() const { #ifndef QT_NO_SYSTEMLOCALE - if (d() == systemPrivate()) { - QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant()); + if (d() == maybeSystemPrivate()) { + QVariant res = d()->querySystemLocale(QSystemLocale::PMText, QVariant()); if (!res.isNull()) return res.toString(); } @@ -3851,6 +3945,10 @@ QString QLocalePrivate::doubleToString(double d, int width, unsigned flags) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif if (precision == -1) precision = 6; if (width == -1) @@ -4001,6 +4099,10 @@ QString QLocalePrivate::longLongToString(qlonglong l, int precision, int base, int width, unsigned flags) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif bool precision_not_specified = false; if (precision == -1) { precision_not_specified = true; @@ -4086,6 +4188,10 @@ QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision, int base, int width, unsigned flags) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif bool precision_not_specified = false; if (precision == -1) { precision_not_specified = true; @@ -4288,6 +4394,10 @@ bool QLocalePrivate::numberToCLocale(const QString &num, bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif buff->clear(); buff->reserve(str.length()); @@ -4381,6 +4491,10 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte double QLocalePrivate::stringToDouble(const QString &number, bool *ok, GroupSeparatorMode group_sep_mode) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif CharBuff buff; if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number, group_sep_mode, &buff)) { @@ -4394,6 +4508,10 @@ double QLocalePrivate::stringToDouble(const QString &number, bool *ok, qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base, bool *ok, GroupSeparatorMode group_sep_mode) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif CharBuff buff; if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number, group_sep_mode, &buff)) { @@ -4408,6 +4526,10 @@ qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base, qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base, bool *ok, GroupSeparatorMode group_sep_mode) const { +#ifndef QT_NO_SYSTEMLOCALE + if (isUninitializedSystemLocale()) + QLocalePrivate::updateSystemPrivate(); +#endif CharBuff buff; if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number, group_sep_mode, &buff)) { diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index e854c84..9b7b214 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -638,6 +638,7 @@ public: ; private: friend struct QLocalePrivate; + // ### We now use this field to pack an index into locale_data and NumberOptions. // ### Qt 5: change to a QLocaleData *d; uint numberOptions. union { diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index ecf79e9..003ae8c 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -63,14 +63,14 @@ QT_BEGIN_NAMESPACE struct Q_CORE_EXPORT QLocalePrivate { public: - QChar decimal() const { return QChar(m_decimal); } - QChar group() const { return QChar(m_group); } - QChar list() const { return QChar(m_list); } - QChar percent() const { return QChar(m_percent); } - QChar zero() const { return QChar(m_zero); } - QChar plus() const { return QChar(m_plus); } - QChar minus() const { return QChar(m_minus); } - QChar exponential() const { return QChar(m_exponential); } + QChar decimal() const { Q_ASSERT(m_decimal); return QChar(m_decimal); } + QChar group() const { Q_ASSERT(m_group); return QChar(m_group); } + QChar list() const { Q_ASSERT(m_list); return QChar(m_list); } + QChar percent() const { Q_ASSERT(m_percent); return QChar(m_percent); } + QChar zero() const { Q_ASSERT(m_zero); return QChar(m_zero); } + QChar plus() const { Q_ASSERT(m_plus); return QChar(m_plus); } + QChar minus() const { Q_ASSERT(m_minus); return QChar(m_minus); } + QChar exponential() const { Q_ASSERT(m_exponential); return QChar(m_exponential); } quint32 languageId() const { return m_language_id; } quint32 countryId() const { return m_country_id; } @@ -132,6 +132,8 @@ public: CharBuff *result) const; inline char digitToCLocale(const QChar &c) const; + inline bool isUninitializedSystemLocale() const; + QVariant querySystemLocale(int type, const QVariant &in) const; static void updateSystemPrivate(); enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode }; diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index 877a77a..f413223 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -42,9 +42,9 @@ #include "qtimeline.h" #include <private/qobject_p.h> -#include <QtCore/qdatetime.h> #include <QtCore/qcoreevent.h> #include <QtCore/qmath.h> +#include <QtCore/qelapsedtimer.h> QT_BEGIN_NAMESPACE @@ -70,7 +70,7 @@ public: int currentTime; int timerId; - QTime timer; + QElapsedTimer timer; QTimeLine::Direction direction; QEasingCurve easingCurve; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 6d64915..4e0ebbc 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -42,6 +42,7 @@ HEADERS += \ tools/qstringmatcher.h \ tools/qtextboundaryfinder.h \ tools/qtimeline.h \ + tools/qelapsedtimer.h \ tools/qunicodetables_p.h \ tools/qvarlengtharray.h \ tools/qvector.h \ @@ -56,6 +57,7 @@ SOURCES += \ tools/qcryptographichash.cpp \ tools/qdatetime.cpp \ tools/qeasingcurve.cpp \ + tools/qelapsedtimer.cpp \ tools/qhash.cpp \ tools/qline.cpp \ tools/qlinkedlist.cpp \ @@ -81,6 +83,12 @@ SOURCES += \ symbian:SOURCES+=tools/qlocale_symbian.cpp +mac:SOURCES += tools/qelapsedtimer_mac.cpp +else:symbian:SOURCES += tools/qelapsedtimer_symbian.cpp +else:unix:SOURCES += tools/qelapsedtimer_unix.cpp +else:win32:SOURCES += tools/qelapsedtimer_win.cpp +else:SOURCES += tools/qelapsedtimer_generic.cpp + #zlib support contains(QT_CONFIG, zlib) { wince*: DEFINES += NO_ERRNO_H diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp index 3b08bf6..3b279ae 100644 --- a/src/gui/dialogs/qfileinfogatherer.cpp +++ b/src/gui/dialogs/qfileinfogatherer.cpp @@ -297,7 +297,8 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil return; } - QTime base = QTime::currentTime(); + QElapsedTimer base; + base.start(); QFileInfo fileInfo; bool firstTime = true; QList<QPair<QString, QFileInfo> > updatedFiles; @@ -326,9 +327,10 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil emit directoryLoaded(path); } -void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QTime &base, bool &firstTime, QList<QPair<QString, QFileInfo> > &updatedFiles, const QString &path) { +void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bool &firstTime, QList<QPair<QString, QFileInfo> > &updatedFiles, const QString &path) { updatedFiles.append(QPair<QString, QFileInfo>(fileInfo.fileName(), fileInfo)); - QTime current = QTime::currentTime(); + QElapsedTimer current; + current.start(); if ((firstTime && updatedFiles.count() > 100) || base.msecsTo(current) > 1000) { emit updates(path, updatedFiles); updatedFiles.clear(); diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/gui/dialogs/qfileinfogatherer_p.h index eff6b3c..5abcd94 100644 --- a/src/gui/dialogs/qfileinfogatherer_p.h +++ b/src/gui/dialogs/qfileinfogatherer_p.h @@ -60,9 +60,10 @@ #include <qfileiconprovider.h> #include <qfsfileengine.h> #include <qpair.h> -#include <qdatetime.h> #include <qstack.h> +#include <qdatetime.h> #include <qdir.h> +#include <qelapsedtimer.h> QT_BEGIN_NAMESPACE @@ -174,7 +175,7 @@ protected: void getFileInfos(const QString &path, const QStringList &files); private: - void fetch(const QFileInfo &info, QTime &base, bool &firstTime, QList<QPair<QString, QFileInfo> > &updatedFiles, const QString &path); + void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime, QList<QPair<QString, QFileInfo> > &updatedFiles, const QString &path); QString translateDriveName(const QFileInfo &drive) const; QMutex mutex; diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp index 4fffdba..a2d7b23 100644 --- a/src/gui/dialogs/qprogressdialog.cpp +++ b/src/gui/dialogs/qprogressdialog.cpp @@ -46,7 +46,6 @@ #include "qshortcut.h" #include "qpainter.h" #include "qdrawutil.h" -#include "qdatetime.h" #include "qlabel.h" #include "qprogressbar.h" #include "qapplication.h" @@ -54,6 +53,7 @@ #include "qpushbutton.h" #include "qcursor.h" #include "qtimer.h" +#include "qelapsedtimer.h" #include <private/qdialog_p.h> #include <limits.h> @@ -103,7 +103,7 @@ public: QTimer *forceTimer; bool shown_once; bool cancellation_flag; - QTime starttime; + QElapsedTimer starttime; #ifndef QT_NO_CURSOR QCursor parentCursor; #endif diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index dd9a7e6..fc53ea3 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -104,7 +104,8 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() horizontalScrollMode(QAbstractItemView::ScrollPerItem), currentIndexSet(false), wrapItemText(false), - delayedPendingLayout(false) + delayedPendingLayout(false), + moveCursorUpdatedView(false) { } @@ -2210,6 +2211,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) #endif QPersistentModelIndex newCurrent; + d->moveCursorUpdatedView = false; switch (event->key()) { case Qt::Key_Down: newCurrent = moveCursor(MoveDown, event->modifiers()); @@ -2266,6 +2268,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) QRect rect(d->pressedPosition - d->offset(), QSize(1, 1)); setSelection(rect, command); } + event->accept(); return; } } @@ -2363,6 +2366,8 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } break; } } + if (d->moveCursorUpdatedView) + event->accept(); } /*! @@ -2839,7 +2844,8 @@ void QAbstractItemView::keyboardSearch(const QString &search) QModelIndex start = currentIndex().isValid() ? currentIndex() : d->model->index(0, 0, d->root); - QTime now(QTime::currentTime()); + QElapsedTimer now; + now.start(); bool skipRow = false; if (search.isEmpty() || (d->keyboardInputTime.msecsTo(now) > QApplication::keyboardInputInterval())) { diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 82fd1a6..fce74f3 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -56,7 +56,6 @@ #include "private/qabstractscrollarea_p.h" #include "private/qabstractitemmodel_p.h" #include "QtGui/qapplication.h" -#include "QtCore/qdatetime.h" #include "QtGui/qevent.h" #include "QtGui/qmime.h" #include "QtGui/qpainter.h" @@ -65,6 +64,7 @@ #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" #include "QtCore/qbasictimer.h" +#include "QtCore/qelapsedtimer.h" #ifndef QT_NO_ITEMVIEWS @@ -390,7 +390,7 @@ public: #endif QString keyboardInput; - QTime keyboardInputTime; + QElapsedTimer keyboardInputTime; bool autoScroll; QBasicTimer autoScrollTimer; @@ -419,6 +419,7 @@ public: bool wrapItemText; mutable bool delayedPendingLayout; + bool moveCursorUpdatedView; private: mutable QBasicTimer delayedLayout; diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 4135ba0..95ba67c 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -958,7 +958,8 @@ void QTreeView::keyboardSearch(const QString &search) else start = d->model->index(0, 0, d->root); - QTime now(QTime::currentTime()); + QElapsedTimer now; + now.start(); bool skipRow = false; if (search.isEmpty() || (d->keyboardInputTime.msecsTo(now) > QApplication::keyboardInputInterval())) { @@ -2138,9 +2139,10 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie return d->modelIndex(d->above(vi), current.column()); case MoveLeft: { QScrollBar *sb = horizontalScrollBar(); - if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) + if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) { d->collapse(vi, true); - else { + d->moveCursorUpdatedView = true; + } else { bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, 0, this); if (descend) { QModelIndex par = current.parent(); @@ -2160,7 +2162,10 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie return next; } + int oldValue = sb->value(); sb->setValue(sb->value() - sb->singleStep()); + if (oldValue != sb->value()) + d->moveCursorUpdatedView = true; } } @@ -2172,6 +2177,7 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie if (vi < d->viewItems.count() && !d->viewItems.at(vi).expanded && d->itemsExpandable && d->hasVisibleChildren(d->viewItems.at(vi).index)) { d->expand(vi, true); + d->moveCursorUpdatedView = true; } else { bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, 0, this); if (descend) { @@ -2194,7 +2200,10 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie //last restort: we change the scrollbar value QScrollBar *sb = horizontalScrollBar(); + int oldValue = sb->value(); sb->setValue(sb->value() + sb->singleStep()); + if (oldValue != sb->value()) + d->moveCursorUpdatedView = true; } } updateGeometries(); diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index 047bd09..3bdc971 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -65,7 +65,6 @@ #include "qapplication.h" #include "qdesktopwidget.h" #include "qbitmap.h" -#include "qdatetime.h" #include "qiodevice.h" #include "qbuffer.h" #include "qtextcodec.h" @@ -76,6 +75,7 @@ #include "qt_x11_p.h" #include "qx11info_x11.h" #include "qimagewriter.h" +#include "qelapsedtimer.h" #include "qvariant.h" #include "qdnd_p.h" #include <private/qwidget_p.h> @@ -516,8 +516,9 @@ static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer) bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout) { - QTime started = QTime::currentTime(); - QTime now = started; + QElapsedTimer started; + started.start(); + QElapsedTimer now = started; if (QAbstractEventDispatcher::instance()->inherits("QtMotif") || QApplication::clipboard()->property("useEventLoopWhenWaiting").toBool()) { @@ -545,9 +546,7 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti XSync(X11->display, false); usleep(50000); - now = QTime::currentTime(); - if (started > now) // crossed midnight - started = now; + now.start(); QEventLoop::ProcessEventsFlags flags(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers @@ -576,9 +575,7 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0)) qApp->x11ProcessEvent(&e); - now = QTime::currentTime(); - if ( started > now ) // crossed midnight - started = now; + now.start(); XFlush(X11->display); diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 9fe5ae0..129e0a5 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -132,26 +132,6 @@ QT_END_NAMESPACE [super toggleToolbarShown:sender]; } -/* - The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever - get hit. We automatically say we can be first responder if we are a window. - So, the handling should get handled by the view. This is here more as a - last resort (i.e., this is code that can potentially be removed). - */ -- (void)keyDown:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyDown:theEvent]; -} - -- (void)keyUp:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyUp:theEvent]; -} - - (void)flagsChanged:(NSEvent *)theEvent { qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 4f71681..0bc57e0 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -241,7 +241,8 @@ static int qCocoaViewCount = 0; QRegion mask = qt_widget_private(cursorWidget)->extra->mask; NSCursor *nscursor = static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursorWidget->cursor())); - if (mask.isEmpty()) { + // The mask could have the WA_MouseNoMask attribute set and that means that we have to ignore the mask. + if (mask.isEmpty() || cursorWidget->testAttribute(Qt::WA_MouseNoMask)) { [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor]; } else { const QVector<QRect> &rects = mask.rects(); @@ -1029,11 +1030,16 @@ static int qCocoaViewCount = 0; { if (!qwidget) return NO; + // disabled widget shouldn't get focus even if it's a window. + // hence disabled windows will not get any key or mouse events. + if (!qwidget->isEnabled()) + return NO; // Before accepting the focus for a window, we check that // the focusWidget (if any) is not contained in the same window. - if (qwidget->isWindow() && (!qApp->focusWidget() - || qApp->focusWidget()->window() != qwidget)) + if (qwidget->isWindow() && !qt_widget_private(qwidget)->topData()->embedded + && (!qApp->focusWidget() || qApp->focusWidget()->window() != qwidget)) { return YES; // Always do it, so that windows can accept key press events. + } return qwidget->focusPolicy() != Qt::NoFocus; } @@ -1044,7 +1050,16 @@ static int qCocoaViewCount = 0; // Seems like the following test only triggers if this // view is inside a QMacNativeWidget: if (qwidget == QApplication::focusWidget()) - QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason); + qwidget->clearFocus(); + return YES; +} + +- (BOOL)becomeFirstResponder +{ + // see the comment in the acceptsFirstResponder - if the window "stole" focus + // let it become the responder, but don't tell Qt + if (!QApplication::focusWidget() && qwidget->focusPolicy() != Qt::NoFocus) + qwidget->setFocus(Qt::OtherFocusReason); return YES; } @@ -1118,8 +1133,15 @@ static int qCocoaViewCount = 0; } if (sendKeyEvents && !composing) { bool keyOK = qt_dispatchKeyEvent(theEvent, widgetToGetKey); - if (!keyOK && !sendToPopup) - [super keyDown:theEvent]; + if (!keyOK && !sendToPopup) { + // find the first responder that is not created by Qt and forward + // the event to it (for example if Qt widget is embedded into native). + QWidget *toplevel = qwidget->window(); + if (toplevel && qt_widget_private(toplevel)->topData()->embedded) { + if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview]) + [w keyDown:theEvent]; + } + } } } @@ -1128,8 +1150,13 @@ static int qCocoaViewCount = 0; { if (sendKeyEvents) { bool keyOK = qt_dispatchKeyEvent(theEvent, qwidget); - if (!keyOK) - [super keyUp:theEvent]; + if (!keyOK) { + QWidget *toplevel = qwidget->window(); + if (toplevel && qt_widget_private(toplevel)->topData()->embedded) { + if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview]) + [w keyUp:theEvent]; + } + } } } diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index 9591b9a..0a05d8e 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -51,10 +51,10 @@ #include "qbitmap.h" #include "qdesktopwidget.h" #include "qevent.h" -#include "qdatetime.h" #include "qiodevice.h" #include "qpointer.h" #include "qcursor.h" +#include "qelapsedtimer.h" #include "qvariant.h" #include "qvector.h" #include "qurl.h" @@ -1911,23 +1911,19 @@ Qt::DropAction QDragManager::drag(QDrag * o) // then we could still have problems, but this is highly unlikely QApplication::flush(); - QTime started = QTime::currentTime(); - QTime now = started; + QElapsedTimer timer; + timer.start(); do { XEvent event; if (XCheckTypedEvent(X11->display, ClientMessage, &event)) qApp->x11ProcessEvent(&event); - now = QTime::currentTime(); - if (started > now) // crossed midnight - started = now; - // sleep 50 ms, so we don't use up CPU cycles all the time. struct timeval usleep_tv; usleep_tv.tv_sec = 0; usleep_tv.tv_usec = 50000; select(0, 0, 0, 0, &usleep_tv); - } while (object && started.msecsTo(now) < 1000); + } while (object && timer.hasExpired(1000)); } object = o; diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 649a310..bf60f97 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -55,8 +55,8 @@ #include "qrect.h" #include "qpoint.h" -#include "qdatetime.h" #include "qgesture.h" +#include "qelapsedtimer.h" #include "private/qobject_p.h" QT_BEGIN_NAMESPACE @@ -148,7 +148,7 @@ public: QPoint lastPositions[3]; bool started; qreal speed; - QTime time; + QElapsedTimer time; }; class QTapGesturePrivate : public QGesturePrivate diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 86bf1b2e..a575717 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -301,7 +301,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state, switch (event->type()) { case QEvent::TouchBegin: { d->speed = 1; - d->time = QTime::currentTime(); + d->time.start(); d->started = true; result = QGestureRecognizer::MayBeGesture; break; @@ -338,11 +338,10 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state, p3.screenPos().y() - d->lastPositions[2].y()) / 3; const int distance = xDistance >= yDistance ? xDistance : yDistance; - int elapsedTime = d->time.msecsTo(QTime::currentTime()); + int elapsedTime = d->time.restart(); if (!elapsedTime) elapsedTime = 1; d->speed = 0.9 * d->speed + distance / elapsedTime; - d->time = QTime::currentTime(); d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle(); static const int MoveThreshold = 50; @@ -405,7 +404,7 @@ void QSwipeGestureRecognizer::reset(QGesture *state) d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint(); d->started = false; d->speed = 0; - d->time = QTime(); + d->time.invalidate(); QGestureRecognizer::reset(state); } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 24fe5f7..b1e4c94 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -652,8 +652,7 @@ bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widge UInt32 macScanCode = 1; QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength), macScanCode, [event keyCode], [event modifierFlags]); - qt_sendSpontaneousEvent(widgetToGetEvent, &ke); - return ke.isAccepted(); + return qt_sendSpontaneousEvent(widgetToGetEvent, &ke) && ke.isAccepted(); } #endif @@ -703,8 +702,8 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve if (mustUseCocoaKeyEvent()) return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent); bool isAccepted; - qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true); - return isAccepted; + bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true); + return consumed && isAccepted; #endif } diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 10fb009..ece4be4 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -49,7 +49,7 @@ #include "qbitmap.h" #include "qlayout.h" #include "qtextcodec.h" -#include "qdatetime.h" +#include "qelapsedtimer.h" #include "qcursor.h" #include "qstack.h" #include "qcolormap.h" @@ -352,7 +352,7 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) return; QApplication::flush(); XEvent ev; - QTime t; + QElapsedTimer t; t.start(); static const int maximumWaitTime = 2000; if (!w->testAttribute(Qt::WA_WState_Created)) @@ -369,7 +369,7 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) // ConfigureNotify ... MapNotify ... Expose enum State { - Initial, Reparented, Mapped + Initial, Mapped } state = Initial; do { @@ -377,33 +377,15 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) XNextEvent(X11->display, &ev); qApp->x11ProcessEvent(&ev); - if (w->windowFlags() & Qt::X11BypassWindowManagerHint) { - switch (state) { - case Initial: - case Reparented: - if (ev.type == MapNotify && ev.xany.window == winid) - state = Mapped; - break; - case Mapped: - if (ev.type == Expose && ev.xany.window == winid) - return; - break; - } - } else { - switch (state) { - case Initial: - if (ev.type == ReparentNotify && ev.xany.window == winid) - state = Reparented; - break; - case Reparented: - if (ev.type == MapNotify && ev.xany.window == winid) - state = Mapped; - break; - case Mapped: - if (ev.type == Expose && ev.xany.window == winid) - return; - break; - } + switch (state) { + case Initial: + if (ev.type == MapNotify && ev.xany.window == winid) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose && ev.xany.window == winid) + return; + break; } } else { if (!XEventsQueued(X11->display, QueuedAfterFlush)) diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index 35850db..b527e72 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -47,7 +47,7 @@ #include <qlayout.h> #include <qstyle.h> #include <qstyleoption.h> -#include <qdatetime.h> +#include <qelapsedtimer.h> #include <qpointer.h> #include <qdebug.h> #include <qx11info_x11.h> @@ -1231,7 +1231,7 @@ void QX11EmbedContainer::embedClient(WId id) For safety, we will not wait more than 500 ms, so that we can preemptively workaround buggy window managers. */ - QTime t; + QElapsedTimer t; t.start(); functorData data; diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 9f69fd8..4ae9f79 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -56,7 +56,6 @@ static const int blueFrameWidth = 2; // with of line edit focus frame #include <qabstractitemview.h> #include <qcheckbox.h> #include <qcombobox.h> -#include <qdatetime.h> #include <qdebug.h> #include <qdialogbuttonbox.h> #include <qformlayout.h> @@ -81,6 +80,7 @@ static const int blueFrameWidth = 2; // with of line edit focus frame #include <qsplitter.h> #include <qstyleoption.h> #include <qtextedit.h> +#include <qelapsedtimer.h> #include <qtoolbar.h> #include <qtoolbox.h> #include <qtoolbutton.h> @@ -980,7 +980,7 @@ public: #ifndef QT_NO_PROGRESSBAR QList<QProgressBar *> bars; int progressBarAnimateTimer; - QTime timer; + QElapsedTimer timer; #endif }; diff --git a/src/gui/styles/qwindowsstyle_p.h b/src/gui/styles/qwindowsstyle_p.h index 808abe1..2a89b84 100644 --- a/src/gui/styles/qwindowsstyle_p.h +++ b/src/gui/styles/qwindowsstyle_p.h @@ -58,8 +58,8 @@ #ifndef QT_NO_STYLE_WINDOWS #include <qlist.h> -#include <qdatetime.h> #include <qhash.h> +#include <qelapsedtimer.h> QT_BEGIN_NAMESPACE @@ -80,7 +80,7 @@ public: QList<QProgressBar *> bars; int animationFps; int animateTimer; - QTime startTime; + QElapsedTimer startTime; int animateStep; QColor inactiveCaptionText; QColor activeCaptionColor; diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h index 673568d..ab941a1 100644 --- a/src/gui/styles/qwindowsvistastyle_p.h +++ b/src/gui/styles/qwindowsvistastyle_p.h @@ -86,6 +86,7 @@ #include <qlistview.h> #include <qtableview.h> #include <qbasictimer.h> +#include <qdatetime.h> #include <qcommandlinkbutton.h> QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index bb1e60d..b1ab478 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -41,9 +41,9 @@ #include <qplatformdefs.h> -#include <qdatetime.h> #include <qdebug.h> #include <qpaintdevice.h> +#include <qelapsedtimer.h> #include <private/qt_x11_p.h> #include "qx11info_x11.h" @@ -1218,7 +1218,7 @@ static void load(const QString &family = QString(), int script = -1, bool forceX } #ifdef QFONTDATABASE_DEBUG - QTime t; + QElapsedTimer t; t.start(); #endif @@ -1301,7 +1301,7 @@ static void initializeDb() if (!db || db->count) return; - QTime t; + QElapsedTimer t; t.start(); #ifndef QT_NO_FONTCONFIG @@ -1314,7 +1314,7 @@ static void initializeDb() } loadFontConfig(); - FD_DEBUG("QFontDatabase: loaded FontConfig: %d ms", t.elapsed()); + FD_DEBUG("QFontDatabase: loaded FontConfig: %d ms", int(t.elapsed())); #endif t.start(); diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 522d472..6a01d68 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -764,12 +764,12 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) SliderAction action = SliderNoAction; #ifdef QT_KEYPAD_NAVIGATION if (ev->isAutoRepeat()) { - if (d->firstRepeat.isNull()) - d->firstRepeat = QTime::currentTime(); + if (!d->firstRepeat.isValid()) + d->firstRepeat.start(); else if (1 == d->repeatMultiplier) { // This is the interval in milli seconds which one key repetition // takes. - const int repeatMSecs = d->firstRepeat.msecsTo(QTime::currentTime()); + const int repeatMSecs = d->firstRepeat.elapsed(); /** * The time it takes to currently navigate the whole slider. @@ -787,8 +787,8 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) } } - else if (!d->firstRepeat.isNull()) { - d->firstRepeat = QTime(); + else if (!d->firstRepeat.isValid()) { + d->firstRepeat.invalidate(); d->repeatMultiplier = 1; } diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h index 6e6ff6e..19d1fca 100644 --- a/src/gui/widgets/qabstractslider_p.h +++ b/src/gui/widgets/qabstractslider_p.h @@ -54,6 +54,7 @@ // #include "QtCore/qbasictimer.h" +#include "QtCore/qelapsedtimer.h" #include "private/qwidget_p.h" #include "qstyle.h" @@ -103,7 +104,7 @@ public: /** * The time of when the first auto repeating key press event occurs. */ - QTime firstRepeat; + QElapsedTimer firstRepeat; #endif diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index dd7fc48..a56d093 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -41,7 +41,6 @@ #include "qapplication.h" #ifndef QT_NO_EFFECTS -#include "qdatetime.h" #include "qdesktopwidget.h" #include "qeffects_p.h" #include "qevent.h" @@ -50,6 +49,7 @@ #include "qpixmap.h" #include "qpointer.h" #include "qtimer.h" +#include "qelapsedtimer.h" #include "qdebug.h" QT_BEGIN_NAMESPACE @@ -103,7 +103,7 @@ private: int elapsed; bool showWidget; QTimer anim; - QTime checkTime; + QElapsedTimer checkTime; double windowOpacity; }; @@ -384,7 +384,7 @@ private: int orientation; QTimer anim; - QTime checkTime; + QElapsedTimer checkTime; QPixmap pm; }; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 8e715a9..42df800 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1767,7 +1767,6 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } break; #endif - default: if (!handled) unknown = true; diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 43722a1..627043d 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -2060,6 +2060,22 @@ bool QMenuBarPrivate::macUpdateMenuBarImmediatly() QWidget *w = findWindowThatShouldDisplayMenubar(); QMenuBar *mb = findMenubarForWindow(w); + // We need to see if we are in full screen mode, if so we need to + // switch the full screen mode to be able to show or hide the menubar. + if(w && mb) { + // This case means we are creating a menubar, check if full screen + if(w->isFullScreen()) { + // Ok, switch to showing the menubar when hovering over it. + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + } + } else if(w) { + // Removing a menubar + if(w->isFullScreen()) { + // Ok, switch to not showing the menubar when hovering on it + SetSystemUIMode(kUIModeAllHidden, 0); + } + } + if (mb && mb->isNativeMenuBar()) { bool modal = QApplicationPrivate::modalState(); #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index c0eeb2f..4ee9f27 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -47,7 +47,7 @@ #include "qstyle.h" #include "qstyleoption.h" #include "qmenu.h" -#include <QtCore/qdatetime.h> +#include <QtCore/qelapsedtimer.h> #ifndef QT_NO_SCROLLBAR @@ -613,7 +613,7 @@ void QScrollBar::mousePressEvent(QMouseEvent *e) } const int initialDelay = 500; // default threshold d->activateControl(d->pressedControl, initialDelay); - QTime time; + QElapsedTimer time; time.start(); repaint(style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this)); if (time.elapsed() >= initialDelay && d->repeatActionTimer.isActive()) { diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index 2a6a7da..7180c4d 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -44,7 +44,6 @@ #include "qapplication.h" #include "qbitmap.h" #include "qcursor.h" -#include "qdatetime.h" #include "qdesktopwidget.h" #include "qevent.h" #include "qhash.h" @@ -59,6 +58,7 @@ #include "qscrollbar.h" #include "qstyle.h" #include "qstyleoption.h" +#include "qelapsedtimer.h" #include "qtooltip.h" #include "qdebug.h" #include <private/qwidget_p.h> @@ -450,10 +450,10 @@ void QWorkspaceTitleBar::mousePressEvent(QMouseEvent *e) case QStyle::SC_TitleBarSysMenu: if (d->flags & Qt::WindowSystemMenuHint) { d->buttonDown = QStyle::SC_None; - static QTime *t = 0; + static QElapsedTimer *t = 0; static QWorkspaceTitleBar *tc = 0; if (!t) - t = new QTime; + t = new QElapsedTimer; if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) { emit showOperationMenu(); t->start(); @@ -1839,7 +1839,7 @@ bool QWorkspace::event(QEvent *e) bool QWorkspace::eventFilter(QObject *o, QEvent * e) { Q_D(QWorkspace); - static QTime* t = 0; + static QElapsedTimer* t = 0; static QWorkspace* tc = 0; if (o == d->maxtools) { switch (e->type()) { @@ -1847,7 +1847,7 @@ bool QWorkspace::eventFilter(QObject *o, QEvent * e) { QMenuBar* b = (QMenuBar*)o->parent(); if (!t) - t = new QTime; + t = new QElapsedTimer; if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) { if (isRightToLeft()) { QPoint p = b->mapToGlobal(QPoint(b->x() + b->width(), b->y() + b->height())); diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h index 92cef83..c907019 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.h +++ b/src/multimedia/audio/qaudioinput_alsa_p.h @@ -61,6 +61,7 @@ #include <QtCore/qtimer.h> #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> +#include <QtCore/qelapsedtimer.h> #include <QtCore/qdatetime.h> #include <QtMultimedia/qaudio.h> @@ -116,8 +117,8 @@ private: void drain(); QTimer* timer; - QTime timeStamp; - QTime clockStamp; + QElapsedTimer timeStamp; + QElapsedTimer clockStamp; qint64 elapsedTimeOffset; int intervalTime; char* audioBuffer; diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.h b/src/multimedia/audio/qaudiooutput_alsa_p.h index 802bc27..e6ac231 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.h +++ b/src/multimedia/audio/qaudiooutput_alsa_p.h @@ -60,6 +60,7 @@ #include <QtCore/qtimer.h> #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> +#include <QtCore/qelapsedtimer.h> #include <QtCore/qdatetime.h> #include <QtMultimedia/qaudio.h> @@ -133,8 +134,8 @@ private: QTimer* timer; QByteArray m_device; int bytesAvailable; - QTime timeStamp; - QTime clockStamp; + QElapsedTimer timeStamp; + QElapsedTimer clockStamp; qint64 elapsedTimeOffset; char* audioBuffer; snd_pcm_t* handle; diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 6908277..07b472e 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -72,7 +72,7 @@ public: { } - ~QNetworkConfigurationPrivate() + virtual ~QNetworkConfigurationPrivate() { //release pointers to member configurations serviceNetworkMembers.clear(); diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 95721ee..21cd0fd 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -365,12 +365,12 @@ #include "private/qhostinfo_p.h" #include <qabstracteventdispatcher.h> -#include <qdatetime.h> #include <qhostaddress.h> #include <qhostinfo.h> #include <qmetaobject.h> #include <qpointer.h> #include <qtimer.h> +#include <qelapsedtimer.h> #ifndef QT_NO_OPENSSL #include <QtNetwork/qsslsocket.h> @@ -1738,7 +1738,7 @@ bool QAbstractSocket::waitForConnected(int msecs) bool wasPendingClose = d->pendingClose; d->pendingClose = false; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); if (d->state == HostLookupState) { @@ -1819,7 +1819,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) return false; } - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // handle a socket in connecting state @@ -1878,7 +1878,7 @@ bool QAbstractSocket::waitForBytesWritten(int msecs) if (d->writeBuffer.isEmpty()) return false; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // handle a socket in connecting state @@ -1960,7 +1960,7 @@ bool QAbstractSocket::waitForDisconnected(int msecs) return false; } - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // handle a socket in connecting state diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 3293ff5..dfda257 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -42,9 +42,9 @@ #include "qhttpsocketengine_p.h" #include "qtcpsocket.h" #include "qhostaddress.h" -#include "qdatetime.h" #include "qurl.h" #include "qhttp.h" +#include "qelapsedtimer.h" #if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP) #include <qdebug.h> @@ -319,7 +319,7 @@ bool QHttpSocketEngine::waitForRead(int msecs, bool *timedOut) if (!d->socket || d->socket->state() == QAbstractSocket::UnconnectedState) return false; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // Wait for more data if nothing is available. @@ -366,7 +366,7 @@ bool QHttpSocketEngine::waitForWrite(int msecs, bool *timedOut) return true; } - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // If we're not connected yet, wait until we are, and until bytes have diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 1ca11d8..f14decc 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -52,9 +52,9 @@ #include <fcntl.h> #include <errno.h> -#include <qdatetime.h> #include <qdir.h> #include <qdebug.h> +#include <qelapsedtimer.h> #ifdef Q_OS_VXWORKS # include <selectLib.h> @@ -534,7 +534,7 @@ bool QLocalSocket::waitForConnected(int msec) int result = -1; // on Linux timeout will be updated by select, but _not_ on other systems. - QTime timer; + QElapsedTimer timer; timer.start(); while (state() == ConnectingState && (-1 == msec || timer.elapsed() < msec)) { diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 9a2c349..6c800fe 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -44,8 +44,8 @@ #include "private/qnet_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" +#include "qelapsedtimer.h" #include "qvarlengtharray.h" -#include "qdatetime.h" #include <time.h> #include <errno.h> #include <fcntl.h> @@ -1003,7 +1003,7 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c #ifndef Q_OS_SYMBIAN ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); #else - QTime timer; + QElapsedTimer timer; timer.start(); do { diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 924530e..f68edfe 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -49,7 +49,7 @@ #include "qdebug.h" #include "qhash.h" #include "qqueue.h" -#include "qdatetime.h" +#include "qelapsedtimer.h" #include "qmutex.h" #include "qthread.h" #include "qcoreapplication.h" @@ -308,7 +308,7 @@ struct QSocks5BindData : public QSocks5Data quint16 localPort; QHostAddress peerAddress; quint16 peerPort; - QDateTime timeStamp; + QElapsedTimer timeStamp; }; struct QSocks5RevivedDatagram @@ -369,7 +369,7 @@ void QSocks5BindStore::add(int socketDescriptor, QSocks5BindData *bindData) if (store.contains(socketDescriptor)) { // qDebug() << "delete it"; } - bindData->timeStamp = QDateTime::currentDateTime(); + bindData->timeStamp.start(); store.insert(socketDescriptor, bindData); // start sweep timer if not started if (sweepTimerId == -1) @@ -412,7 +412,7 @@ void QSocks5BindStore::timerEvent(QTimerEvent * event) QMutableHashIterator<int, QSocks5BindData *> it(store); while (it.hasNext()) { it.next(); - if (it.value()->timeStamp.secsTo(QDateTime::currentDateTime()) > 350) { + if (it.value()->timeStamp.hasExpired(350000)) { QSOCKS5_DEBUG << "QSocks5BindStore removing JJJJ"; it.remove(); } @@ -1355,7 +1355,7 @@ bool QSocks5SocketEngine::bind(const QHostAddress &address, quint16 port) } int msecs = SOCKS5_BLOCKING_BIND_TIMEOUT; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port()); if (!d->waitForConnected(msecs, 0) || @@ -1455,7 +1455,7 @@ void QSocks5SocketEngine::close() if (d->data && d->data->controlSocket) { if (d->data->controlSocket->state() == QAbstractSocket::ConnectedState) { int msecs = 100; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); while (!d->data->controlSocket->bytesToWrite()) { if (!d->data->controlSocket->waitForBytesWritten(qt_timeout_value(msecs, stopWatch.elapsed()))) @@ -1674,7 +1674,7 @@ bool QSocks5SocketEnginePrivate::waitForConnected(int msecs, bool *timedOut) mode == BindMode ? BindSuccess : UdpAssociateSuccess; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); while (socks5State != wantedState) { @@ -1699,7 +1699,7 @@ bool QSocks5SocketEngine::waitForRead(int msecs, bool *timedOut) d->readNotificationActivated = false; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // are we connected yet? @@ -1749,7 +1749,7 @@ bool QSocks5SocketEngine::waitForWrite(int msecs, bool *timedOut) Q_D(QSocks5SocketEngine); QSOCKS5_DEBUG << "waitForWrite" << msecs; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); // are we connected yet? diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 9623570..86b11b9 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -286,8 +286,8 @@ #include <QtCore/qdebug.h> #include <QtCore/qdir.h> -#include <QtCore/qdatetime.h> #include <QtCore/qmutex.h> +#include <QtCore/qelapsedtimer.h> #include <QtNetwork/qhostaddress.h> #include <QtNetwork/qhostinfo.h> @@ -1393,7 +1393,7 @@ bool QSslSocket::waitForEncrypted(int msecs) if (d->mode == UnencryptedMode && !d->autoStartHandshake) return false; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); if (d->plainSocket->state() != QAbstractSocket::ConnectedState) { @@ -1433,7 +1433,7 @@ bool QSslSocket::waitForReadyRead(int msecs) bool *previousReadyReadEmittedPointer = d->readyReadEmittedPointer; d->readyReadEmittedPointer = &readyReadEmitted; - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); if (!d->connectionEncrypted) { @@ -1470,7 +1470,7 @@ bool QSslSocket::waitForBytesWritten(int msecs) if (d->mode == UnencryptedMode) return d->plainSocket->waitForBytesWritten(msecs); - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); if (!d->connectionEncrypted) { @@ -1508,7 +1508,7 @@ bool QSslSocket::waitForDisconnected(int msecs) if (d->mode == UnencryptedMode) return d->plainSocket->waitForDisconnected(msecs); - QTime stopWatch; + QElapsedTimer stopWatch; stopWatch.start(); if (!d->connectionEncrypted) { diff --git a/src/testlib/qtestcoreelement.h b/src/testlib/qtestcoreelement.h index 4738f7d..e1ad44a 100644 --- a/src/testlib/qtestcoreelement.h +++ b/src/testlib/qtestcoreelement.h @@ -45,8 +45,6 @@ #include <QtTest/qtestcorelist.h> #include <QtTest/qtestelementattribute.h> -#include <cstdlib> - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -95,9 +93,6 @@ void QTestCoreElement<ElementType>::addAttribute(const QTest::AttributeIndex att if (attribute(attributeIndex)) return; - // if (attributeIndex == QTest::AI_Metric) - // abort(); - QTestElementAttribute *testAttribute = new QTestElementAttribute; testAttribute->setPair(attributeIndex, value); testAttribute->addToList(&listOfAttributes); diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h index 3c11cdd..82d69d6 100644 --- a/src/testlib/qtestsystem.h +++ b/src/testlib/qtestsystem.h @@ -44,7 +44,7 @@ #include <QtTest/qtestcase.h> #include <QtCore/qcoreapplication.h> -#include <QtCore/qdatetime.h> +#include <QtCore/qelapsedtimer.h> QT_BEGIN_HEADER @@ -63,7 +63,7 @@ namespace QTest { Q_ASSERT(QCoreApplication::instance()); - QTime timer; + QElapsedTimer timer; timer.start(); do { QCoreApplication::processEvents(QEventLoop::AllEvents, ms); diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri index b3ee948..6442526 100644 --- a/src/tools/bootstrap/bootstrap.pri +++ b/src/tools/bootstrap/bootstrap.pri @@ -51,7 +51,7 @@ hpux-acc*|hpuxi-acc* { } LIBS += -lbootstrap } -!contains(QT_CONFIG, zlib):!contains(QT_CONFIG, no-zlib) { +!contains(QT_CONFIG, zlib):!contains(QT_CONFIG, no-zlib):!cross_compile { unix:LIBS += -lz # win32:LIBS += libz.lib } diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 0dbb90f..7e91333 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -95,7 +95,7 @@ macx: { LIBS += -framework CoreServices } -contains(QT_CONFIG, zlib) { +contains(QT_CONFIG, zlib)|cross_compile { INCLUDEPATH += ../../3rdparty/zlib SOURCES+= \ ../3rdparty/zlib/adler32.c \ diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index 86a4c80..a6b9a5f 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -106,6 +106,8 @@ private slots: void secsTo(); void operator_eqeq(); void currentDateTime(); + void currentDateTimeUtc(); + void currentDateTimeUtc2(); void fromStringTextDate_data(); void fromStringTextDate(); @@ -880,6 +882,79 @@ void tst_QDateTime::currentDateTime() QVERIFY(dt3.timeSpec() == Qt::UTC); } +void tst_QDateTime::currentDateTimeUtc() +{ +#if defined(Q_OS_WINCE) + __time64_t buf1, buf2; + ::_time64(&buf1); +#else + time_t buf1, buf2; + ::time(&buf1); +#endif + QDateTime lowerBound; + lowerBound.setTime_t(buf1); + + QDateTime dt1 = QDateTime::currentDateTimeUtc(); + QDateTime dt2 = QDateTime::currentDateTimeUtc().toLocalTime(); + QDateTime dt3 = QDateTime::currentDateTimeUtc().toUTC(); + +#if defined(Q_OS_WINCE) + ::_time64(&buf2); +#else + ::time(&buf2); +#endif + QDateTime upperBound; + upperBound.setTime_t(buf2); + upperBound = upperBound.addSecs(1); + + QVERIFY(lowerBound < upperBound); + + QVERIFY(lowerBound <= dt1); + QVERIFY(dt1 < upperBound); + QVERIFY(lowerBound <= dt2); + QVERIFY(dt2 < upperBound); + QVERIFY(lowerBound <= dt3); + QVERIFY(dt3 < upperBound); + + QVERIFY(dt1.timeSpec() == Qt::UTC); + QVERIFY(dt2.timeSpec() == Qt::LocalTime); + QVERIFY(dt3.timeSpec() == Qt::UTC); +} + +void tst_QDateTime::currentDateTimeUtc2() +{ + QDateTime local, utc; + qint64 msec; + + // check that we got all down to the same milliseconds + int i = 2; + bool ok = false; + do { + local = QDateTime::currentDateTime(); + utc = QDateTime::currentDateTimeUtc(); + msec = QDateTime::currentMsecsSinceEpoch(); + ok = local.time().msec() == utc.time().msec() + && utc.time().msec() == (msec % 1000); + } while (--i && !ok); + + if (!i) + QSKIP("Failed to get the dates within 1 ms of each other", SkipAll); + + // seconds and milliseconds should be the same: + QCOMPARE(utc.time().second(), local.time().second()); + QCOMPARE(utc.time().msec(), local.time().msec()); + QCOMPARE(msec % 1000, qint64(local.time().msec())); + QCOMPARE(msec / 1000 % 60, qint64(local.time().second())); + + // the two dates should be equal, actually + QCOMPARE(local.toUTC(), utc); + QCOMPARE(utc.toLocalTime(), local); + + // and finally, the time_t should equal our number + QCOMPARE(qint64(utc.toTime_t()), msec / 1000); + QCOMPARE(qint64(local.toTime_t()), msec / 1000); +} + void tst_QDateTime::toTime_t_data() { QTest::addColumn<QString>("dateTimeStr"); diff --git a/tests/auto/qelapsedtimer/qelapsedtimer.pro b/tests/auto/qelapsedtimer/qelapsedtimer.pro new file mode 100644 index 0000000..ed75228 --- /dev/null +++ b/tests/auto/qelapsedtimer/qelapsedtimer.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +QT -= gui + +SOURCES += tst_qelapsedtimer.cpp +wince* { + DEFINES += SRCDIR=\\\"\\\" +} else:symbian { + # do not define SRCDIR at all + TARGET.EPOCHEAPSIZE = 0x100000 0x3000000 +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} + diff --git a/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp new file mode 100644 index 0000000..5c3d4f8 --- /dev/null +++ b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp @@ -0,0 +1,111 @@ +#include <QtCore/QString> +#include <QtCore/QTime> +#include <QtCore/QElapsedTimer> +#include <QtTest/QtTest> + +static const int minResolution = 50; // the minimum resolution for the tests + +class tst_QElapsedTimer : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void statics(); + void validity(); + void basics(); + void elapsed(); +}; + +void tst_QElapsedTimer::statics() +{ + qDebug() << "Clock type is" << QElapsedTimer::clockType(); + qDebug() << "Said clock is" << (QElapsedTimer::isMonotonic() ? "monotonic" : "not monotonic"); + QElapsedTimer t; + t.start(); + qDebug() << "Current time is" << t.msecsSinceReference(); +} + +void tst_QElapsedTimer::validity() +{ + QElapsedTimer t; + + t.invalidate(); + QVERIFY(!t.isValid()); + + t.start(); + QVERIFY(t.isValid()); + + t.invalidate(); + QVERIFY(!t.isValid()); +} + +void tst_QElapsedTimer::basics() +{ + QElapsedTimer t1; + t1.start(); + + QVERIFY(t1.msecsSinceReference() != 0); + + QCOMPARE(t1, t1); + QVERIFY(!(t1 != t1)); + QVERIFY(!(t1 < t1)); + QCOMPARE(t1.msecsTo(t1), qint64(0)); + QCOMPARE(t1.secsTo(t1), qint64(0)); +// QCOMPARE(t1 + 0, t1); +// QCOMPARE(t1 - 0, t1); + +#if 0 + QElapsedTimer t2 = t1; + t2 += 1000; // so we can use secsTo + + QVERIFY(t1 != t2); + QVERIFY(!(t1 == t2)); + QVERIFY(t1 < t2); + QVERIFY(!(t2 < t1)); + QCOMPARE(t1.msecsTo(t2), qint64(1000)); + QCOMPARE(t1.secsTo(t2), qint64(1)); +// QCOMPARE(t2 - t1, qint64(1000)); +// QCOMPARE(t1 - t2, qint64(-1000)); +#endif + + quint64 value1 = t1.msecsSinceReference(); + qint64 elapsed = t1.restart(); + quint64 value2 = t1.msecsSinceReference(); + QCOMPARE(elapsed, qint64(value2 - value1)); + QVERIFY(elapsed < minResolution); +} + +void tst_QElapsedTimer::elapsed() +{ + QElapsedTimer t1; + t1.start(); + + QTest::qSleep(4*minResolution); + QElapsedTimer t2; + t2.start(); + + QVERIFY(t1 != t2); + QVERIFY(!(t1 == t2)); + QVERIFY(t1 < t2); + QVERIFY(t1.msecsTo(t2) > 0); + // don't check: t1.secsTo(t2) +// QVERIFY(t1 - t2 < 0); + + QVERIFY(t1.elapsed() > 0); + QVERIFY(t1.hasExpired(minResolution)); + QVERIFY(!t1.hasExpired(8*minResolution)); + QVERIFY(!t2.hasExpired(minResolution)); + + QVERIFY(!t1.hasExpired(-1)); + QVERIFY(!t2.hasExpired(-1)); + + qint64 elapsed = t1.restart(); + QVERIFY(elapsed > 3*minResolution); + QVERIFY(elapsed < 5*minResolution); + qint64 diff = t2.msecsTo(t1); + QVERIFY(diff < minResolution); +} + +QTEST_MAIN(tst_QElapsedTimer); + +#include "tst_qelapsedtimer.moc" diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index 5a87154..9363e4e 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -158,9 +158,15 @@ void tst_QLocale::ctor() QCoreApplication app(argc, (char**)&argv); #endif QLocale default_locale = QLocale::system(); + + QVERIFY(!default_locale.monthName(1, QLocale::LongFormat).isEmpty()); + QVERIFY(!default_locale.monthName(1, QLocale::ShortFormat).isEmpty()); + QVERIFY(default_locale.language() != 0); + QLocale::Language default_lang = default_locale.language(); QLocale::Country default_country = default_locale.country(); + qDebug("Default: %s/%s", QLocale::languageToString(default_lang).toLatin1().constData(), QLocale::countryToString(default_country).toLatin1().constData()); diff --git a/tests/manual/qtbug-8933/README b/tests/manual/qtbug-8933/README new file mode 100644 index 0000000..b3ce407 --- /dev/null +++ b/tests/manual/qtbug-8933/README @@ -0,0 +1,7 @@ +The purpose of this test is to check if the full screen mode in OSX is working properly or not. +This test creates a widget and 5 seconds later enters full screen mode. If you hover over the area +where the menubar should be you will get no menubar. After 5 more seconds (i.e. 10 seconds since +start) a menubar is created. At that point, if you hover over the menubar area you will get the +menubar. 5 seconds later the menubar is destroyed and if you hover over there will be no menubar. +After 5 more seconds the widget goes back to normal mode and the test is finished. + diff --git a/tests/manual/qtbug-8933/main.cpp b/tests/manual/qtbug-8933/main.cpp new file mode 100644 index 0000000..841b7c3 --- /dev/null +++ b/tests/manual/qtbug-8933/main.cpp @@ -0,0 +1,10 @@ +#include <QtGui/QApplication> +#include "widget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + return a.exec(); +} diff --git a/tests/manual/qtbug-8933/qtbug-8933.pro b/tests/manual/qtbug-8933/qtbug-8933.pro new file mode 100644 index 0000000..8b87c83 --- /dev/null +++ b/tests/manual/qtbug-8933/qtbug-8933.pro @@ -0,0 +1,16 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-03-16T14:40:16 +# +#------------------------------------------------- + +TARGET = qtbug-8933 +TEMPLATE = app + + +SOURCES += main.cpp\ + widget.cpp + +HEADERS += widget.h + +FORMS += widget.ui diff --git a/tests/manual/qtbug-8933/widget.cpp b/tests/manual/qtbug-8933/widget.cpp new file mode 100644 index 0000000..47a440b --- /dev/null +++ b/tests/manual/qtbug-8933/widget.cpp @@ -0,0 +1,58 @@ +#include "widget.h" +#include "ui_widget.h" + +#include <QTimer> +#include <QDebug> + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + QTimer::singleShot(5000, this, SLOT(switchToFullScreen())); + QTimer::singleShot(10000, this, SLOT(addMenuBar())); + QTimer::singleShot(15000, this, SLOT(removeMenuBar())); + QTimer::singleShot(20000, this, SLOT(switchToNormalScreen())); +} + +Widget::~Widget() +{ + delete ui; +} + +void Widget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void Widget::switchToFullScreen() +{ + ui->label->setText("entering full screen"); + showFullScreen(); +} + +void Widget::switchToNormalScreen() +{ + ui->label->setText("leaving full screen"); + showNormal(); +} + +void Widget::addMenuBar() +{ + ui->label->setText("adding menu bar"); + menuBar = new QMenuBar(this); + menuBar->setVisible(true); +} + +void Widget::removeMenuBar() +{ + ui->label->setText("removing menu bar"); + delete menuBar; +} diff --git a/tests/manual/qtbug-8933/widget.h b/tests/manual/qtbug-8933/widget.h new file mode 100644 index 0000000..f6afa8f --- /dev/null +++ b/tests/manual/qtbug-8933/widget.h @@ -0,0 +1,32 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include <QWidget> +#include <QMenuBar> +#include <QMenu> + +namespace Ui { + class Widget; +} + +class Widget : public QWidget { + Q_OBJECT +public: + Widget(QWidget *parent = 0); + ~Widget(); + +public slots: + void switchToFullScreen(); + void switchToNormalScreen(); + void addMenuBar(); + void removeMenuBar(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::Widget *ui; + QMenuBar *menuBar; +}; + +#endif // WIDGET_H diff --git a/tests/manual/qtbug-8933/widget.ui b/tests/manual/qtbug-8933/widget.ui new file mode 100644 index 0000000..e0ded3f --- /dev/null +++ b/tests/manual/qtbug-8933/widget.ui @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="QWidget" name="Widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>400</height> + </rect> + </property> + <property name="windowTitle"> + <string>Widget</string> + </property> + <widget class="QLabel" name="label"> + <property name="geometry"> + <rect> + <x>110</x> + <y>60</y> + <width>311</width> + <height>16</height> + </rect> + </property> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/tools/designer/src/components/widgetbox/widgetbox.cpp b/tools/designer/src/components/widgetbox/widgetbox.cpp index 512d6ba..091135a 100644 --- a/tools/designer/src/components/widgetbox/widgetbox.cpp +++ b/tools/designer/src/components/widgetbox/widgetbox.cpp @@ -74,7 +74,10 @@ WidgetBox::WidgetBox(QDesignerFormEditorInterface *core, QWidget *parent, Qt::Wi FilterWidget *filterWidget = new FilterWidget(0, FilterWidget::LayoutAlignNone); filterWidget->setRefuseFocus(true); connect(filterWidget, SIGNAL(filterChanged(QString)), m_view, SLOT(filter(QString))); - l->addWidget(filterWidget); + + QToolBar *toolBar = new QToolBar(this); + toolBar->addWidget(filterWidget); + l->addWidget(toolBar); // View connect(m_view, SIGNAL(pressed(QString,QString,QPoint)), diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 0c6497b..62f191b 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -1194,14 +1194,14 @@ void Generator::appendSortedQmlNames(Text& text, QMap<QString,Text> classMap; int index = 0; -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES qDebug() << "Generator::appendSortedQmlNames():" << base->name() << "is inherited by..."; -#endif +#endif for (int i = 0; i < subs.size(); ++i) { Text t; -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES qDebug() << " " << subs[i]->name(); -#endif +#endif appendFullName(t, subs[i], base, marker); classMap[t.toString().toLower()] = t; } diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index d60ff73..bd37443 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -1297,9 +1297,9 @@ QmlClassNode::QmlClassNode(InnerNode *parent, */ QmlClassNode::~QmlClassNode() { -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES qDebug() << "Deleting QmlClassNode:" << name(); -#endif +#endif } /*! @@ -1334,9 +1334,9 @@ QString QmlClassNode::fileBase() const void QmlClassNode::addInheritedBy(const QString& base, Node* sub) { inheritedBy.insert(base,sub); -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE-QDOCCONF_FILES qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size(); -#endif +#endif } /*! @@ -1347,10 +1347,10 @@ void QmlClassNode::subclasses(const QString& base, NodeList& subs) subs.clear(); if (inheritedBy.count(base) > 0) { subs = inheritedBy.values(base); -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES qDebug() << "QmlClassNode::subclasses():" << inheritedBy.count(base) << base << "subs:" << subs.size() << "total size:" << inheritedBy.size(); -#endif +#endif } } |