diff options
author | Jerome Pasion <jerome.pasion@digia.com> | 2012-11-02 14:41:27 +0100 |
---|---|---|
committer | Jerome Pasion <jerome.pasion@digia.com> | 2012-11-02 14:41:27 +0100 |
commit | c808dd27459e030fde0577feb8ba06e3bd465526 (patch) | |
tree | 4bf898dc4a88e2b03c9716f940638a2e01c6c0ce /src/corelib | |
parent | d9d8845d507a6bdbc9c9f24c0d9d86dca513461d (diff) | |
parent | 300534fc214f2547a63594ce0891e9a54c8f33ca (diff) |
Merge branch 'master' of ssh://codereview.qt-project.org/qt/qtbase into newdocs
Change-Id: I7e6cee190a341901dfbf8effb54ebccb91bf7a17
Diffstat (limited to 'src/corelib')
51 files changed, 692 insertions, 532 deletions
diff --git a/src/corelib/Qt5CTestMacros.cmake b/src/corelib/Qt5CTestMacros.cmake index 3d1b3b3191..715ad9356e 100644 --- a/src/corelib/Qt5CTestMacros.cmake +++ b/src/corelib/Qt5CTestMacros.cmake @@ -59,3 +59,83 @@ macro(expect_fail _dir) --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST} ) endmacro() + +function(test_module_includes) + + set(all_args ${ARGN}) + set(packages_string "") + set(libraries_string "") + + foreach(_package ${Qt5_MODULE_TEST_DEPENDS}) + set(packages_string + " + ${packages_string} + find_package(Qt5${_package} REQUIRED) + " + ) + endforeach() + + while(all_args) + list(GET all_args 0 qtmodule) + list(REMOVE_AT all_args 0 1) + set(packages_string + "${packages_string} + find_package(Qt5${qtmodule} REQUIRED) + include_directories(\${Qt5${qtmodule}_INCLUDE_DIRS}) + add_definitions(\${Qt5${qtmodule}_DEFINITIONS})\n" + ) + set(libraries_string "${libraries_string} Qt5::${qtmodule}") + endwhile() + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/module_includes/CMakeLists.txt" + " + cmake_minimum_required(VERSION 2.8) + project(module_includes) + + ${packages_string} + + set(CMAKE_CXX_FLAGS \"\${CMAKE_CXX_FLAGS} \${Qt5Core_EXECUTABLE_COMPILE_FLAGS}\") + + add_executable(module_includes_exe \"\${CMAKE_CURRENT_SOURCE_DIR}/main.cpp\") + target_link_libraries(module_includes_exe ${libraries_string})\n" + ) + + set(all_args ${ARGN}) + set(includes_string "") + set(instances_string "") + while(all_args) + list(GET all_args 0 qtmodule) + list(GET all_args 1 qtinclude) + list(REMOVE_AT all_args 0 1) + set(includes_string + "${includes_string} + #include <${qtinclude}> + #include <Qt${qtmodule}/${qtinclude}> + #include <Qt${qtmodule}> + #include <Qt${qtmodule}/Qt${qtmodule}>" + ) + set(instances_string + "${instances_string} + ${qtinclude} local${qtinclude}; + ") + endwhile() + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/module_includes/main.cpp" + " + + ${includes_string} + + int main(int, char **) { ${instances_string} return 0; }\n" + ) + + add_test(module_includes ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMAKE_CURRENT_BINARY_DIR}/module_includes/" + "${CMAKE_CURRENT_BINARY_DIR}/module_includes/build" + --build-config "${CMAKE_BUILD_TYPE}" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-project module_includes + --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST} + ) +endfunction() diff --git a/src/corelib/codecs/codecs.qdoc b/src/corelib/codecs/codecs.qdoc index b982302355..3a9f5c8f79 100644 --- a/src/corelib/codecs/codecs.qdoc +++ b/src/corelib/codecs/codecs.qdoc @@ -31,10 +31,10 @@ \ingroup groups \brief Codec support in Qt. - These codecs provide facilities for conversion between Unicode and - specific text encodings. + These \l{Qt Core} codecs classes provide facilities for conversion between + Unicode and specific text encodings. - \generatelist{related} + \annotatedlist codecs */ /*! diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp index 6538c7178d..f1479a8ed7 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp @@ -38,17 +38,28 @@ ** ****************************************************************************/ +#include <QString> +#include <QStringList> +#include <QRegularExpression> +#include <QRegularExpressionMatch> +#include <QRegularExpressionMatchIterator> + +int main() { + +{ //! [0] QRegularExpression re("a pattern"); //! [0] +} - +{ //! [1] QRegularExpression re; re.setPattern("another pattern"); //! [1] +} - +{ //! [2] // matches two digits followed by a space and a word QRegularExpression re("\\d\\d \\w+"); @@ -56,27 +67,31 @@ QRegularExpression re("\\d\\d \\w+"); // matches a backslash QRegularExpression re2("\\\\"); //! [2] +} - +{ //! [3] QRegularExpression re("a third pattern"); QString pattern = re.pattern(); // pattern == "a third pattern" //! [3] +} - +{ //! [4] // matches "Qt rocks", but also "QT rocks", "QT ROCKS", "qT rOcKs", etc. QRegularExpression re("Qt rocks", QRegularExpression::CaseInsensitiveOption); //! [4] +} - +{ //! [5] QRegularExpression re("^\\d+$"); re.setPatternOptions(QRegularExpression::MultilineOption); // re matches any line in the subject string that contains only digits (but at least one) //! [5] +} - +{ //! [6] QRegularExpression re = QRegularExpression("^two.*words$", QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption); @@ -84,16 +99,18 @@ QRegularExpression re = QRegularExpression("^two.*words$", QRegularExpression::M QRegularExpression::PatternOptions options = re.patternOptions(); // options == QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption //! [6] +} - +{ //! [7] // match two digits followed by a space and a word QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("abc123 def"); bool hasMatch = match.hasMatch(); // true //! [7] +} - +{ //! [8] QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("abc123 def"); @@ -102,8 +119,9 @@ if (match.hasMatch()) { // ... } //! [8] +} - +{ //! [9] QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("12 abc 45 def", 1); @@ -112,31 +130,34 @@ if (match.hasMatch()) { // ... } //! [9] +} - +{ //! [10] QRegularExpression re("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$"); QRegularExpressionMatch match = re.match("08/12/1985"); if (match.hasMatch()) { - QString day = re.captured(1); // day == "08" - QString month = re.captured(2); // month == "12" - QString year = re.captured(3); // year == "1985" + QString day = match.captured(1); // day == "08" + QString month = match.captured(2); // month == "12" + QString year = match.captured(3); // year == "1985" // ... } //! [10] +} - +{ //! [11] QRegularExpression re("abc(\\d+)def"); QRegularExpressionMatch match = re.match("XYZabc123defXYZ"); if (match.hasMatch()) { - int startOffset = re.capturedStart(1); // startOffset == 6 - int endOffset = re.capturedEnd(1); // endOffset == 9 + int startOffset = match.capturedStart(1); // startOffset == 6 + int endOffset = match.capturedEnd(1); // endOffset == 9 // ... } //! [11] +} - +{ //! [12] QRegularExpression re("^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$"); QRegularExpressionMatch match = re.match("08/12/1985"); @@ -146,14 +167,14 @@ if (match.hasMatch()) { QString year = match.captured("year"); // year == 1985 } //! [12] +} - +{ //! [13] QRegularExpression re("(\\w+)"); QRegularExpressionMatchIterator i = re.globalMatch("the quick fox"); //! [13] - //! [14] QStringList words; while (i.hasNext()) { @@ -163,72 +184,86 @@ while (i.hasNext()) { } // words contains "the", "quick", "fox" //! [14] +} - +{ //! [15] QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$"); QRegularExpression re(pattern); QString input("Jan 21,"); -QRegularExpressionMatch match = re.match(input, 0, QRegularExpressionMatch::PartialPreferCompleteMatch); +QRegularExpressionMatch match = re.match(input, 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [15] +} - +{ +QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$"); +QRegularExpression re(pattern); //! [16] QString input("Dec 8, 1985"); -QRegularExpressionMatch match = re.match(input, 0, QRegularExpressionMatch::PartialPreferCompleteMatch); +QRegularExpressionMatch match = re.match(input, 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // true bool hasPartialMatch = match.hasPartialMatch(); // false //! [16] +} - +{ //! [17] QRegularExpression re("abc\\w+X|def"); -QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpressionMatch::PartialPreferCompleteMatch); +QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // true bool hasPartialMatch = match.hasPartialMatch(); // false QString captured = match.captured(0); // captured == "def" //! [17] +} - +{ //! [18] QRegularExpression re("abc\\w+X|defY"); -QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpressionMatch::PartialPreferCompleteMatch); +QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true QString captured = match.captured(0); // captured == "abcdef" //! [18] +} - +{ //! [19] QRegularExpression re("abc|ab"); -QRegularExpressionMatch match = re.match("ab", 0, QRegularExpressionMatch::PartialPreferFirstMatch); +QRegularExpressionMatch match = re.match("ab", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [19] +} - +{ //! [20] QRegularExpression re("abc(def)?"); -QRegularExpressionMatch match = re.match("abc", 0, QRegularExpressionMatch::PartialPreferFirstMatch); +QRegularExpressionMatch match = re.match("abc", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [20] +} +{ //! [21] QRegularExpression re("(abc)*"); -QRegularExpressionMatch match = re.match("abc", 0, QRegularExpressionMatch::PartialPreferFirstMatch); +QRegularExpressionMatch match = re.match("abc", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [21] +} +{ //! [22] QRegularExpression invalidRe("(unmatched|parenthesis"); bool isValid = invalidRe.isValid(); // false //! [22] +} +{ //! [23] QRegularExpression invalidRe("(unmatched|parenthesis"); if (!invalidRe.isValid()) { @@ -237,44 +272,62 @@ if (!invalidRe.isValid()) { // ... } //! [23] +} +{ //! [24] QRegularExpression re("^this pattern must match exactly$"); //! [24] +} +{ //! [25] QString p("a .*|pattern"); QRegularExpression re("\\A(?:" + p + ")\\z"); // re matches exactly the pattern string p //! [25] +} +{ //! [26] QString escaped = QRegularExpression::escape("a(x) = f(x) + g(x)"); // escaped == "a\\(x\\)\\ \\=\\ f\\(x\\)\\ \\+\\ g\\(x\\)" //! [26] +} +{ +QString name; +QString nickname; //! [27] QString pattern = "(" + QRegularExpression::escape(name) + "|" + QRegularExpression::escape(nickname) + ")"; QRegularExpression re(pattern); //! [27] +} +{ +QString string; +QRegularExpression re; //! [28] -QRegularExpressionMatch match = re.match(...); +QRegularExpressionMatch match = re.match(string); for (int i = 0; i <= match.lastCapturedIndex(); ++i) { QString captured = match.captured(i); // ... } //! [28] +} +{ //! [29] -QRegularExpression("(\\d\\d) (?<name>\\w+)"); +QRegularExpression re("(\\d\\d) (?<name>\\w+)"); QRegularExpressionMatch match = re.match("23 Jordan"); if (match.hasMatch()) { QString number = match.captured(1); // first == "23" QString name = match.captured("name"); // name == "Jordan" } //! [29] +} +{ //! [30] // extracts the words QRegularExpression re("(\\w+)"); @@ -285,5 +338,6 @@ while (i.hasNext()) { // ... } //! [30] +} - +} diff --git a/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp b/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp index e7c1c36e9d..8181cb04dd 100644 --- a/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp +++ b/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) //! [2] QStringList arguments; - arguments << "-style" << "motif"; + arguments << "-style" << "fusion"; QProcess *myProcess = new QProcess(parent); myProcess->start(program, arguments); diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc index c76845c93c..7724d533d6 100644 --- a/src/corelib/doc/src/animation.qdoc +++ b/src/corelib/doc/src/animation.qdoc @@ -28,6 +28,11 @@ /*! \group animation \title Animation Framework + + This page lists classes belonging to \l{Qt Core}'s + \l{The Animation Framework}{animation framework}. + + \annotatedlist animation */ /*! @@ -102,7 +107,7 @@ the framework, please look up their class descriptions. \section1 Classes in the Animation Framework - + These classes provide a framework for creating both simple and complex animations. @@ -361,4 +366,3 @@ framework for animations, see the states example (it lives in the \c{examples/animation/states} directory). */ - diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index 24c5629ae2..262add419c 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -26,22 +26,6 @@ ****************************************************************************/ /*! - \group tools - \title Non-GUI Classes - \ingroup groups - - \brief Collection classes such as list, queue, stack and string, along - with other classes that can be used without needing QApplication. - - The non-GUI classes are general-purpose collection and string classes - that may be used independently of the GUI classes. - - In particular, these classes do not depend on QApplication at all, - and so can be used in non-GUI programs. - -*/ - -/*! \page containers.html \title Container Classes \ingroup technology-apis @@ -394,13 +378,13 @@ QMapIterator, which is somewhat different because it iterates on (key, value) pairs. - Like QListIterator, QMapIterator provides - \l{QMapIterator::toFront()}{toFront()}, - \l{QMapIterator::toBack()}{toBack()}, - \l{QMapIterator::hasNext()}{hasNext()}, - \l{QMapIterator::next()}{next()}, - \l{QMapIterator::peekNext()}{peekNext()}, - \l{QMapIterator::hasPrevious()}{hasPrevious()}, + Like QListIterator, QMapIterator provides + \l{QMapIterator::toFront()}{toFront()}, + \l{QMapIterator::toBack()}{toBack()}, + \l{QMapIterator::hasNext()}{hasNext()}, + \l{QMapIterator::next()}{next()}, + \l{QMapIterator::peekNext()}{peekNext()}, + \l{QMapIterator::hasPrevious()}{hasPrevious()}, \l{QMapIterator::previous()}{previous()}, and \l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and value components are extracted by calling key() and value() on diff --git a/src/corelib/doc/src/datastreamformat.qdoc b/src/corelib/doc/src/datastreamformat.qdoc index 8c3b592276..e2c3f9bae1 100644 --- a/src/corelib/doc/src/datastreamformat.qdoc +++ b/src/corelib/doc/src/datastreamformat.qdoc @@ -33,7 +33,7 @@ The \l QDataStream allows you to serialize some of the Qt data types. The table below lists the data types that QDataStream can serialize and how they are represented. The format described below is - \l{QDataStream::setVersion()}{version 12}. + \l{QDataStream::setVersion()}{version 13}. It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing. This ensures that @@ -129,7 +129,7 @@ \li \list \li Date (QDate) \li Time (QTime) - \li 0 for Qt::LocalTime, 1 for Qt::UTC (quint8) + \li The \l{Qt::TimeSpec}{time spec} (quint8) \endlist \row \li QEasingCurve \li \list diff --git a/src/corelib/doc/src/eventsandfilters.qdoc b/src/corelib/doc/src/eventsandfilters.qdoc index 5fe444538d..e4605afb0b 100644 --- a/src/corelib/doc/src/eventsandfilters.qdoc +++ b/src/corelib/doc/src/eventsandfilters.qdoc @@ -32,10 +32,11 @@ \brief Classes used to create and handle events. - These classes are used to create and handle events. + These \l{Qt Core} classes are used to create and handle events. - For more information see the \link object.html Object model\endlink - and \link signalsandslots.html Signals and Slots\endlink. + For more information see the \l{The Event System}{Event System} page. + + \annotatedlist events */ /*! diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc index 7b29998951..2038d43230 100644 --- a/src/corelib/doc/src/implicit-sharing.qdoc +++ b/src/corelib/doc/src/implicit-sharing.qdoc @@ -31,6 +31,12 @@ /*! \group shared \title Implicitly Shared Classes + + These \l{Qt Core} classes provides a safe and efficient way of sharing and + manipulating data by \l{Implicit Sharing}{implicitly sharing} data. + + \annotatedlist shared + */ /*! diff --git a/src/corelib/doc/src/io.qdoc b/src/corelib/doc/src/io.qdoc index cd967844c0..7aff227931 100644 --- a/src/corelib/doc/src/io.qdoc +++ b/src/corelib/doc/src/io.qdoc @@ -33,7 +33,9 @@ \brief Classes providing file input and output along with directory and network handling. - These classes are used to handle input and output to and from external - devices, processes, files etc. as well as manipulating files and directories. -*/ + These \l{Qt Core} classes are used to handle input and output to and from + external devices, processes, files etc. as well as manipulating files and + directories. + \annotatedlist io +*/ diff --git a/src/corelib/doc/src/json.qdoc b/src/corelib/doc/src/json.qdoc index 25496dd759..9e6e190dcb 100644 --- a/src/corelib/doc/src/json.qdoc +++ b/src/corelib/doc/src/json.qdoc @@ -108,5 +108,6 @@ \annotatedlist json - All JSON classes are value based, implicitly shared classes. + All JSON classes are value based, + \l{Implicit Sharing}{implicitly shared classes}. */ diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc index f0031ee26b..bc387aeed9 100644 --- a/src/corelib/doc/src/plugins-howto.qdoc +++ b/src/corelib/doc/src/plugins-howto.qdoc @@ -32,12 +32,14 @@ \brief Plugin related classes. - These classes deal with shared libraries, (e.g. .so and DLL files), - and with Qt plugins. + These \l{Qt Core} classes deal with shared libraries, (e.g. .so and DLL + files), and with Qt plugins. - See the \link plugins-howto.html plugins documentation\endlink. + See the \l{How to Create Qt Plugins} page for more information.. See also the \l{ActiveQt framework} for Windows. + + \annotatedlist plugins */ /*! diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc new file mode 100644 index 0000000000..f876a362c7 --- /dev/null +++ b/src/corelib/doc/src/qtcore-index.qdoc @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtcore-index.html + \title Qt Core + + \brief The Qt Core module is part of Qt's essential modules. + + \section1 Getting Started + All other Qt modules rely on this module. To include the + definitions of the module's classes, use the following directive: + + \snippet code/doc_src_qtcore.cpp 0 + + \section1 Core Functionalities + + Qt adds these features to C++: + + \list + \li a very powerful mechanism for seamless object communication called + signals and slots + \li queryable and designable object properties + \li hierarchical and queryable object trees that organize + \li object ownership in a natural way with guarded pointers (QPointer) + \li a dynamic cast that works across library boundaries + \endlist + + The following pages provide more information about Qt's core features: + \list + \li \l{The Meta-Object System} + \li \l{The Property System} + \li \l{Object Model} + \li \l{Object Trees & Ownership} + \li \l{Signals & Slots} + \endlist + + \section1 Threading and Concurrent Programming + + Qt provides thread support in the form of platform-independent \l{Threading + Classes}{threading classes}, a thread-safe way of posting events, and + signal-slot connections across threads. Multithreaded programming is also a + useful paradigm for performing time-consuming operations without freezing + the user interface of an application. + + The \l{Thread Support in Qt} page contains information on implementing + threads in applications. Additional concurrent classes are provided by the + \l{Qt Concurrent} module. + + \section1 Input/Output, Resources, and Containers + + Qt provides a resource system for organizing application files and assets, + a set of containers, and classes for receiving input and printing output. + \list + \li \l{Container Classes} + \li \l{Serializing Qt Data Types} + \li \l{Implicit Sharing} + \endlist + + In addition, Qt Core provides a platform-independent mechanism for storing + binary files in the application's executable. + + \list + \li \l{The Qt Resource System} + \endlist + + \section1 Additional Frameworks + Qt Core also provides some of Qt's key frameworks. + + \list + \li \l{The Animation Framework} + \li \l{JSON Support in Qt} + \li \l{The State Machine Framework} + \li \l{How to Create Qt Plugins} + \li \l{The Event System} + \endlist + + \section1 Related Information + \section1 Reference + These are links to the API reference materials. + \list + \li \l{Qt Core C++ Classes}{C++ classes} + \list + \li \l{Animation Framework}{Animation Classes} + \li \l{Threading Classes} + \li \l{Container Classes} + \li \l{Plugin Classes} + \li \l{Implicitly Shared Classes} + \li \l{State Machine Classes} + \li \l{Input/Output and Networking}{Input/Output Classes} + \li \l{Event Classes} + \endlist + \endlist + +*/ diff --git a/src/corelib/doc/src/qtcore.qdoc b/src/corelib/doc/src/qtcore.qdoc index 0d06bb7998..4b4814d5b7 100644 --- a/src/corelib/doc/src/qtcore.qdoc +++ b/src/corelib/doc/src/qtcore.qdoc @@ -27,16 +27,13 @@ /*! \module QtCore - \title QtCore Module + \title Qt Core C++ Classes \ingroup modules - \keyword QtCore - - \brief The QtCore module contains core non-GUI functionality. + \brief Provides core non-GUI functionality. All other Qt modules rely on this module. To include the definitions of the module's classes, use the following directive: \snippet code/doc_src_qtcore.cpp 0 */ - diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index dd4f992288..1a5c216e04 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -28,6 +28,11 @@ /*! \group statemachine \title State Machine Classes + + These \l{Qt Core} classes are part of the \l{The State Machine Framework}{ + State Machine Framework}. + + \annotatedlist statemachine */ /*! @@ -69,7 +74,7 @@ \section1 Classes in the State Machine Framework These classes are provided by qt for creating event-driven state machines. - + \annotatedlist statemachine \section1 A Simple State Machine diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 0f752bc726..64d33e3b34 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -28,6 +28,10 @@ /*! \group thread \title Threading Classes + + These \l{Qt Core} classes provide threading support to applications. + The \l{Thread Support in Qt} page covers how to use these classes. + \annotatedlist thread */ /*! @@ -111,13 +115,13 @@ /*! \page threads-starting.html \title Starting Threads with QThread - + \contentspage Thread Support in Qt \nextpage Synchronizing Threads A QThread instance represents a thread and provides the means to \l{QThread::start()}{start()} a thread, which will then execute the - reimplementation of QThread::run(). The \c run() implementation is for a + reimplementation of QThread::run(). The \c run() implementation is for a thread what the \c main() entry point is for the application. All code executed in a call stack that starts in the \c run() function is executed by the new thread, and the thread finishes when the function returns. @@ -141,12 +145,12 @@ Then, create an instance of the thread object and call QThread::start(). Note that you must create the QApplication (or QCoreApplication) object before you can create a QThread. - - The function will return immediately and the + + The function will return immediately and the main thread will continue. The code that appears in the \l{QThread::run()}{run()} reimplementation will then be executed in a separate thread. - + Creating threads is explained in more detail in the QThread documentation. @@ -160,7 +164,7 @@ /*! \page threads-synchronizing.html \title Synchronizing Threads - + \previouspage Starting Threads with QThread \contentspage Thread Support in Qt \nextpage Reentrancy and Thread-Safety @@ -227,7 +231,7 @@ \list \li A \e thread-safe function can be called simultaneously from - multiple threads, even when the invocations use shared data, + multiple threads, even when the invocations use shared data, because all references to the shared data are serialized. \li A \e reentrant function can also be called simultaneously from multiple threads, but only if each invocation uses its own data. @@ -577,8 +581,8 @@ \endlist - Qt Concurrent supports several STL-compatible container and iterator types, - but works best with Qt containers that have random-access iterators, such as + Qt Concurrent supports several STL-compatible container and iterator types, + but works best with Qt containers that have random-access iterators, such as QList or QVector. The map and filter functions accept both containers and begin/end iterators. STL Iterator support overview: @@ -609,14 +613,14 @@ \li QList, QVector, std::vector \li Supported and Recommended \endtable - + Random access iterators can be faster in cases where Qt Concurrent is iterating over a large number of lightweight items, since they allow skipping to any point in the container. In addition, using random access iterators allows Qt Concurrent to provide progress information trough QFuture::progressValue() and QFutureWatcher:: progressValueChanged(). - The non in-place modifying functions such as mapped() and filtered() makes a + The non in-place modifying functions such as mapped() and filtered() makes a copy of the container when called. If you are using STL containers this copy operation might take some time, in this case we recommend specifying the begin and end iterators for the container instead. @@ -643,7 +647,7 @@ QPainter can be used in a thread to paint onto QImage, QPrinter, and QPicture paint devices. Painting onto QPixmaps and QWidgets is \e not - supported. On Mac OS X the automatic progress dialog will not be + supported. On Mac OS X the automatic progress dialog will not be displayed if you are printing from outside the GUI thread. Any number of threads can paint at any given time, however only diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index b4b73a9aaa..b4194c18f8 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -326,11 +326,6 @@ #define QT_NO_SOCKS5 #endif -// QSoftKeyManager -#if !defined(QT_NO_SOFTKEYMANAGER) && (defined(QT_NO_ACTION)) -#define QT_NO_SOFTKEYMANAGER -#endif - // QSplitter #if !defined(QT_NO_SPLITTER) && (defined(QT_NO_RUBBERBAND)) #define QT_NO_SPLITTER diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 7f31259c16..0f3a5c9a1d 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -63,13 +63,6 @@ Requires: Name: QAction SeeAlso: ??? -Feature: SOFTKEYMANAGER -Description: Supports softkeys. -Section: Gui -Requires: ACTION -Name: QSoftKeyManager -SeeAlso: ??? - Feature: CURSOR Description: Supports mouse cursors. Section: Kernel diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index ccf071826a..ffdf8d0fd3 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -276,6 +276,8 @@ static const struct { { "HostPrefix", "" }, { "HostBinaries", "bin" }, { "HostData", "." }, + { "TargetSpec", "" }, + { "HostSpec", "" }, #endif }; @@ -378,6 +380,12 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) #endif // QT_NO_SETTINGS } +#ifdef QT_BOOTSTRAPPED + // The specs need to be returned verbatim. + if (loc == TargetSpecPath || loc == HostSpecPath) + return ret; +#endif + if (!ret.isEmpty() && QDir::isRelativePath(ret)) { QString baseDir; #ifdef QT_BOOTSTRAPPED diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h index 1d9b809207..93b0c81562 100644 --- a/src/corelib/global/qlibraryinfo.h +++ b/src/corelib/global/qlibraryinfo.h @@ -81,7 +81,9 @@ public: HostPrefixPath, HostBinariesPath, HostDataPath, - LastHostPath = HostDataPath, + TargetSpecPath, + HostSpecPath, + LastHostPath = HostSpecPath, #endif SettingsPath = 100 }; diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index e7953b47dd..6430c85936 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -311,8 +311,6 @@ public: BypassGraphicsProxyWidget = 0x20000000, WindowOkButtonHint = 0x00080000, WindowCancelButtonHint = 0x00100000, - WindowSoftkeysVisibleHint = 0x40000000, - WindowSoftkeysRespondHint = 0x80000000, NoDropShadowWindowHint = 0x40000000 }; @@ -470,9 +468,6 @@ public: WA_WState_AcceptedTouchBeginEvent = 122, WA_TouchPadAcceptSingleTouchEvents = 123, - WA_MergeSoftkeys = 124, - WA_MergeSoftkeysRecursively = 125, - WA_X11DoNotAcceptFocus = 126, WA_MacNoShadow = 127, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 50578d78c5..66442a83c7 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1160,17 +1160,6 @@ \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single touch events to be sent to the widget. - \value WA_MergeSoftkeys Allows widget to merge softkeys with parent widget, - i.e. widget can set only one softkeys and request softkey implementation - to take rest of the softkeys from the parent. Note parents are traversed until - WA_MergeSoftkeys is not set. See also Qt::WA_MergeSoftkeysRecursively - This attribute currently has effect only on Symbian platforms - - \value WA_MergeSoftkeysRecursively Allows widget to merge softkeys recursively - with all parents. If this attribute is set, the widget parents are traversed until - window boundary (widget without parent or dialog) is found. - This attribute currently has effect only on Symbian platforms - \value WA_X11DoNotAcceptFocus Asks the window manager to not give focus to this top level window. This attribute has no effect on non-X11 platforms. @@ -2031,14 +2020,6 @@ \value WindowCancelButtonHint Adds a Cancel button to the window decoration of a dialog. Only supported for Windows CE. - \value WindowSoftkeysVisibleHint Makes softkeys visible when widget is fullscreen. - Only supported for Symbian. - - \value WindowSoftkeysRespondHint Makes softkeys to receive key events even - when invisible. With this hint the softkey actions are triggered - even the softkeys are invisible i.e. the window is displayed with - \c showFullscreen(). Only supported for Symbian. - \value WindowTransparentForInput Informs the window system that this window is used only for output (displaying something) and does not take input. Therefore input events should pass through as if it wasn't there. diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index 4bd8d60754..00a511a96f 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -46,17 +46,17 @@ // Borland's windows.h does not set these correctly, resulting in // unusable WinSDK standard dialogs #ifndef WINVER -#define WINVER 0x400 +# define WINVER 0x0501 #endif #ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x400 +# define _WIN32_WINNT 0x0501 #endif #endif #if defined(Q_CC_MINGW) // mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation #ifndef WINVER -#define WINVER 0x500 +# define WINVER 0x501 #endif #endif @@ -65,6 +65,13 @@ #endif #include <windows.h> +#if defined(_WIN32_IE) && _WIN32_IE < 0x0501 +# undef _WIN32_IE +#endif +#if !defined(_WIN32_IE) +# define _WIN32_IE 0x0501 +#endif + #ifdef _WIN32_WCE #include <ceconfig.h> #endif diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 9e89f9fdc0..f57dcebe33 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -118,15 +118,13 @@ win32 { } else { SOURCES += io/qstandardpaths_unix.cpp } - } else:standardpathsjson { - SOURCES += io/qstandardpaths_json.cpp } else:blackberry { SOURCES += io/qstandardpaths_blackberry.cpp } else { SOURCES += io/qstandardpaths_unix.cpp } - linux-* { + linux-*|if(qnx:contains(QT_CONFIG, inotify)) { SOURCES += io/qfilesystemwatcher_inotify.cpp HEADERS += io/qfilesystemwatcher_inotify_p.h } diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index fe06210fb9..8707aec0b8 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -300,6 +300,13 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) const struct dirent_extra_stat * const extra_stat = reinterpret_cast<struct dirent_extra_stat *>(extra); + // Remember whether this was a link or not, this saves an lstat() call later. + if (extra->d_type == _DTYPE_LSTAT) { + knownFlagsMask |= QFileSystemMetaData::LinkType; + if (S_ISLNK(extra_stat->d_stat.st_mode)) + entryFlags |= QFileSystemMetaData::LinkType; + } + // For symlinks, the extra type _DTYPE_LSTAT doesn't work for filling out the meta data, // as we need the stat() information there, not the lstat() information. // In this case, don't use the extra information. diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 77a5959f8f..449be9b7b5 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -51,11 +51,14 @@ #include <qset.h> #include <qtimer.h> +#if defined(Q_OS_LINUX) || (defined(Q_OS_QNX) && !defined(QT_NO_INOTIFY)) +#define USE_INOTIFY +#endif #include "qfilesystemwatcher_polling_p.h" #if defined(Q_OS_WIN) # include "qfilesystemwatcher_win_p.h" -#elif defined(Q_OS_LINUX) +#elif defined(USE_INOTIFY) # include "qfilesystemwatcher_inotify_p.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) # include "qfilesystemwatcher_kqueue_p.h" @@ -67,7 +70,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject { #if defined(Q_OS_WIN) return new QWindowsFileSystemWatcherEngine(parent); -#elif defined(Q_OS_LINUX) +#elif defined(USE_INOTIFY) // there is a chance that inotify may fail on Linux pre-2.6.13 (August // 2005), so we can't just new inotify directly. return QInotifyFileSystemWatcherEngine::create(parent); diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 390a280ff2..11ac0e5b5d 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -52,12 +52,20 @@ #include <qsocketnotifier.h> #include <qvarlengtharray.h> +#if defined(Q_OS_LINUX) #include <sys/syscall.h> #include <sys/ioctl.h> #include <unistd.h> #include <fcntl.h> +#endif #if defined(QT_NO_INOTIFY) + +#if defined(Q_OS_QNX) +// These files should only be compiled on QNX if the inotify headers are found +#error "Should not get here." +#endif + #include <linux/types.h> #if defined(__i386__) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 395effaff9..c52053000d 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -458,8 +458,8 @@ void QProcessPrivate::Channel::clear() are supplied as individual strings in a QStringList. For example, the following code snippet runs the analog clock - example in the Motif style on X11 platforms by passing strings - containing "-style" and "motif" as two items in the list of + example in the Fusion style on X11 platforms by passing strings + containing "-style" and "fusion" as two items in the list of arguments: \snippet qprocess/qprocess-simpleexecution.cpp 0 diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index 91e343b021..4d7e359117 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -272,7 +272,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr searchPaths.reserve(rawPaths.size()); foreach (const QString &rawPath, rawPaths) { QString cleanPath = QDir::cleanPath(rawPath); - if (cleanPath.size() > 1 && cleanPath.endsWith('/')) + if (cleanPath.size() > 1 && cleanPath.endsWith(QLatin1Char('/'))) cleanPath.truncate(cleanPath.size() - 1); searchPaths.push_back(cleanPath); } diff --git a/src/corelib/io/qstandardpaths_json.cpp b/src/corelib/io/qstandardpaths_json.cpp deleted file mode 100644 index 839cd9e873..0000000000 --- a/src/corelib/io/qstandardpaths_json.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "qstandardpaths.h" - -#include <QString> -#include <QJsonDocument> -#include <QJsonObject> -#include <QJsonValue> -#include <QJsonArray> -#include <QFile> -#include <QDir> -#include <QAtomicPointer> -#include <QCoreApplication> -#include <QRegularExpression> -#include <QRegularExpressionMatchIterator> -#include <QRegularExpressionMatch> - -#ifndef QT_NO_STANDARDPATHS - -QT_BEGIN_NAMESPACE - -class QStandardPathsPrivate { -public: - QStandardPathsPrivate() : object(0){} - ~QStandardPathsPrivate() { delete object.load(); } - QAtomicPointer<QJsonObject> object; -}; - -Q_GLOBAL_STATIC(QStandardPathsPrivate, configCache); - -/*! - \internal - Substitute environment variables in the form ${name} - - The JSON QStandardPaths implementation can be configured on a per user - (or per application) basis through the use of environment variables, - which are evaluated each time a location is queried. This function - performs that evaluation on \a value. No substitution is performed - for undefined variables. - - This slightly underselects according to the 2009-09-20 version of - the GNU setenv(3) manual page: It disallows '}' within the variable - name. ${var}} will look for a variable named "var", not "var}". - */ -static QString substituteEnvVars(const QJsonValue & value) -{ - QString str = value.toString(); - if (str.isEmpty() || !str.contains(QLatin1String("${"))) - return str; - - // optimize for a common case - str.replace(QLatin1String("${HOME}"), QDir::homePath()); - - // Do ${} format environment variable substitution if necessary - // repeat this test because ${HOME} might expand to the empty string - if (!str.isEmpty() && str.contains(QLatin1String("${"))) { - QRegularExpression varRegExp(QLatin1String("\\$\\{([^\\}=]*)\\}")); - QRegularExpressionMatchIterator matchIterator = - varRegExp.globalMatch(str); - while (matchIterator.hasNext()) { - QRegularExpressionMatch match = matchIterator.next(); - QByteArray envValue = - qgetenv(match.captured(1).toLatin1().data()); - if (!envValue.isNull()) { - QString replacement = - QFile::decodeName(envValue); - str.replace(match.captured(0), replacement); - } - } - } - return str; -} - -static void appendOrganizationAndApp(QString &path) -{ - const QString org = QCoreApplication::organizationName(); - if (!org.isEmpty()) - path += QLatin1Char('/') + org; - const QString appName = QCoreApplication::applicationName(); - if (!appName.isEmpty()) - path += QLatin1Char('/') + appName; -} - -QString QStandardPaths::writableLocation(StandardLocation type) -{ - QStringList locations = QStandardPaths::standardLocations(type); - if (locations.isEmpty()) - return QString(); - return locations.first(); -} - -QStringList QStandardPaths::standardLocations(StandardLocation type) -{ - switch (type) { - case HomeLocation: - return QStringList(QDir::homePath()); // set $HOME - case TempLocation: - return QStringList(QDir::tempPath()); // set $TMPDIR - default: - break; - } - - if (isTestModeEnabled()) { - const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest"); - QString path; - switch (type) { - case GenericDataLocation: - case DataLocation: - path = qttestDir + QLatin1String("/share"); - if (type == DataLocation) - appendOrganizationAndApp(path); - return QStringList(path); - case GenericCacheLocation: - case CacheLocation: - path = qttestDir + QLatin1String("/cache"); - if (type == CacheLocation) - appendOrganizationAndApp(path); - return QStringList(path); - case ConfigLocation: - return QStringList(qttestDir + QLatin1String("/config")); - default: - break; - } - } - - - QJsonObject * localConfigObject = configCache()->object.loadAcquire(); - if (localConfigObject == 0) { - QString configHome = QFile::decodeName(qgetenv("PATH_CONFIG_HOME")); - if (configHome.isEmpty()) - configHome = QLatin1String("/etc/user-dirs.json"); - QFile file(configHome); - if (file.open(QIODevice::ReadOnly)) { - QJsonDocument configDoc = QJsonDocument::fromJson(file.readAll()); - if (configDoc.isNull()) - return QStringList(); - - QJsonObject myConfigObject = configDoc.object(); - localConfigObject = new QJsonObject(myConfigObject); - if (!configCache()->object.testAndSetRelease(0, localConfigObject)) { - delete localConfigObject; - localConfigObject = configCache()->object.loadAcquire(); - } - } else { - return QStringList(); - } - } - - QLatin1String key(""); - - switch (type) { - case DocumentsLocation: - key = QLatin1String("DOCUMENTS"); - break; - case PicturesLocation: - key = QLatin1String("PICTURES"); - break; - case MusicLocation: - key = QLatin1String("MUSIC"); - break; - case MoviesLocation: - key = QLatin1String("VIDEOS"); - break; - case DownloadLocation: - key = QLatin1String("DOWNLOAD"); - break; - case ApplicationsLocation: - key = QLatin1String("APPLICATIONS"); - break; - case CacheLocation: - key = QLatin1String("CACHE"); - break; - case GenericCacheLocation: - key = QLatin1String("GENERIC_CACHE"); - break; - case DataLocation: - key = QLatin1String("DATA"); - break; - case GenericDataLocation: - key = QLatin1String("GENERIC_DATA"); - break; - case ConfigLocation: - key = QLatin1String("CONFIG"); - break; - case RuntimeLocation: - key = QLatin1String("RUNTIME"); - break; - case DesktopLocation: - key = QLatin1String("DESKTOP"); - break; - case FontsLocation: - key = QLatin1String("FONTS"); - break; - - default: - return QStringList(); - } - - QJsonObject::const_iterator iter = localConfigObject->constFind(key); - if (iter == localConfigObject->constEnd()) - return QStringList(); - - switch (iter.value().type()) { - case QJsonValue::Array: { - QStringList resultList; - foreach (const QJsonValue &item, iter.value().toArray()) - resultList.append(substituteEnvVars(item)); - return resultList; - } - case QJsonValue::String: - return QStringList(substituteEnvVars(iter.value())); - default: - break; - } - return QStringList(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_STANDARDPATHS diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index cca6e80810..bef6097043 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -213,7 +213,8 @@ void QWindowsPipeReader::startAsyncRead() // We get notified by the QWinOverlappedIoNotifier - even in the synchronous case. return; } else { - switch (GetLastError()) { + const DWORD dwError = GetLastError(); + switch (dwError) { case ERROR_IO_PENDING: // This is not an error. We're getting notified, when data arrives. return; @@ -223,16 +224,19 @@ void QWindowsPipeReader::startAsyncRead() // didn't fit into the pipe's system buffer. // We're getting notified by the QWinOverlappedIoNotifier. break; + case ERROR_BROKEN_PIPE: case ERROR_PIPE_NOT_CONNECTED: { // It may happen, that the other side closes the connection directly // after writing data. Then we must set the appropriate socket state. + readSequenceStarted = false; pipeBroken = true; emit pipeClosed(); return; } default: - emit winError(GetLastError(), QLatin1String("QWindowsPipeReader::startAsyncRead")); + readSequenceStarted = false; + emit winError(dwError, QLatin1String("QWindowsPipeReader::startAsyncRead")); return; } } diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index c672888992..e44931a16b 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -95,7 +95,7 @@ public: void itemsAboutToBeMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation); void itemsMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation); bool allowMove(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation); - + inline QModelIndex createIndex(int row, int column, void *data = 0) const { return q_func()->createIndex(row, column, data); } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 8ff4aa7c54..590d127094 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -577,8 +577,12 @@ void QCoreApplication::flush() \a argc must be greater than zero and \a argv must contain at least one valid character string. */ -QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal) -: QObject(*new QCoreApplicationPrivate(argc, argv, _internal)) +QCoreApplication::QCoreApplication(int &argc, char **argv +#ifndef Q_QDOC + , int _internal +#endif + ) + : QObject(*new QCoreApplicationPrivate(argc, argv, _internal)) { init(); QCoreApplicationPrivate::eventDispatcher->startingUp(); @@ -698,7 +702,17 @@ bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute) return QCoreApplicationPrivate::testAttribute(attribute); } -/*!/ + +/*! + \property QCoreApplication::quitLockEnabled + + Returns true if the use of the QEventLoopLocker feature can cause the + application to quit, otherwise returns false. + + \sa QEventLoopLocker +*/ + +/*! Returns true if the use of the QEventLoopLocker feature can cause the application to quit, otherwise returns false. @@ -2220,7 +2234,7 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt } /*! - Removes an event filter object \a obj from this object. The + Removes an event \a filterObject from this object. The request is ignored if such an event filter has not been installed. All event filters for this object are automatically removed when @@ -2232,12 +2246,12 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt \sa installNativeEventFilter() \since 5.0 */ -void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObj) +void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject) { QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); - if (!filterObj || !eventDispatcher) + if (!filterObject || !eventDispatcher) return; - eventDispatcher->removeNativeEventFilter(filterObj); + eventDispatcher->removeNativeEventFilter(filterObject); } /*! diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 46eab4e740..b65f0cd314 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -85,7 +85,11 @@ public: GuiServer // # deprecated }; - QCoreApplication(int &argc, char **argv, int = ApplicationFlags); + QCoreApplication(int &argc, char **argv +#ifndef Q_QDOC + , int = ApplicationFlags +#endif + ); ~QCoreApplication(); diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 71690ba90b..c0292ee984 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -270,7 +270,6 @@ QT_BEGIN_NAMESPACE \omitvalue MacGLClearDrawable \omitvalue NetworkReplyUpdated \omitvalue FutureCallOut - \omitvalue UpdateSoftKeys \omitvalue NativeGesture */ diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index d30f93f9f3..6cce838649 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -256,8 +256,6 @@ public: RequestSoftwareInputPanel = 199, CloseSoftwareInputPanel = 200, - UpdateSoftKeys = 201, // Internal for compressing soft key updates - WinIdChange = 203, #ifndef QT_NO_GESTURES Gesture = 198, diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp index b2ec574c89..4be1d73b7a 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp +++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp @@ -67,7 +67,7 @@ struct bpsIOHandlerData { fd_set *exceptfds; }; -static int bpsIOReadyDomain = -1; +static int bpsUnblockDomain = -1; static int bpsIOHandler(int fd, int io_events, void *data) { @@ -103,13 +103,13 @@ static int bpsIOHandler(int fd, int io_events, void *data) qEventDispatcherDebug << "Sending bpsIOReadyDomain event"; // create IO ready event bps_event_t *event; - int result = bps_event_create(&event, bpsIOReadyDomain, 0, NULL, NULL); + int result = bps_event_create(&event, bpsUnblockDomain, 0, NULL, NULL); if (result != BPS_SUCCESS) { qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_event_create() failed"); return BPS_FAILURE; } - // post IO ready event to our thread + // post unblock event to our thread result = bps_push_event(event); if (result != BPS_SUCCESS) { qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_push_event() failed"); @@ -129,31 +129,33 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate() if (result != BPS_SUCCESS) qFatal("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_initialize() failed"); - // get domain for IO ready events - ignoring race condition here for now - if (bpsIOReadyDomain == -1) { - bpsIOReadyDomain = bps_register_domain(); - if (bpsIOReadyDomain == -1) + bps_channel = bps_channel_get_active(); + + // get domain for IO ready and wake up events - ignoring race condition here for now + if (bpsUnblockDomain == -1) { + bpsUnblockDomain = bps_register_domain(); + if (bpsUnblockDomain == -1) qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_register_domain() failed"); } - - // Register thread_pipe[0] with bps - int io_events = BPS_IO_INPUT; - result = bps_add_fd(thread_pipe[0], io_events, &bpsIOHandler, ioData.data()); - if (result != BPS_SUCCESS) - qWarning() << Q_FUNC_INFO << "bps_add_fd() failed"; } QEventDispatcherBlackberryPrivate::~QEventDispatcherBlackberryPrivate() { - // Unregister thread_pipe[0] from bps - const int result = bps_remove_fd(thread_pipe[0]); - if (result != BPS_SUCCESS) - qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed"; - // we're done using BPS bps_shutdown(); } +int QEventDispatcherBlackberryPrivate::initThreadWakeUp() +{ + return -1; // no fd's used +} + +int QEventDispatcherBlackberryPrivate::processThreadWakeUp(int nsel) +{ + Q_UNUSED(nsel); + return wakeUps.fetchAndStoreRelaxed(0); +} + ///////////////////////////////////////////////////////////////////////////// QEventDispatcherBlackberry::QEventDispatcherBlackberry(QObject *parent) @@ -317,7 +319,7 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef if (!event) // In case of !event, we break out of the loop to let Qt process the timers break; // (since timeout has expired) and socket notifiers that are now ready. - if (bps_event_get_domain(event) == bpsIOReadyDomain) { + if (bps_event_get_domain(event) == bpsUnblockDomain) { timeoutTotal = 0; // in order to immediately drain the event queue of native events event = 0; // (especially touch move events) we don't break out here } @@ -339,6 +341,21 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef return d->ioData->count; } +void QEventDispatcherBlackberry::wakeUp() +{ + Q_D(QEventDispatcherBlackberry); + if (d->wakeUps.testAndSetAcquire(0, 1)) { + bps_event_t *event; + if (bps_event_create(&event, bpsUnblockDomain, 0, 0, 0) == BPS_SUCCESS) { + if (bps_channel_push_event(d->bps_channel, event) == BPS_SUCCESS) + return; + else + bps_event_destroy(event); + } + qWarning("QEventDispatcherBlackberryPrivate::wakeUp failed"); + } +} + int QEventDispatcherBlackberry::ioEvents(int fd) { int io_events = 0; diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h index 84cdf9e2dd..79ed21dbf2 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h +++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h @@ -71,6 +71,8 @@ public: void registerSocketNotifier(QSocketNotifier *notifier); void unregisterSocketNotifier(QSocketNotifier *notifier); + void wakeUp(); + protected: QEventDispatcherBlackberry(QEventDispatcherBlackberryPrivate &dd, QObject *parent = 0); @@ -89,6 +91,10 @@ public: QEventDispatcherBlackberryPrivate(); ~QEventDispatcherBlackberryPrivate(); + int initThreadWakeUp(); + int processThreadWakeUp(int nsel); + + int bps_channel; QScopedPointer<bpsIOHandlerData> ioData; }; diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 44715b0553..6c2a610a56 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -110,7 +110,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() bool pipefail = false; // initialize the common parts of the event loop -#if defined(Q_OS_NACL) +#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY) // do nothing. #elif defined(Q_OS_INTEGRITY) // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead @@ -157,7 +157,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() { -#if defined(Q_OS_NACL) +#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY) // do nothing. #elif defined(Q_OS_VXWORKS) close(thread_pipe[0]); @@ -211,8 +211,8 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, FD_ZERO(&sn_vec[2].select_fds); } - FD_SET(thread_pipe[0], &sn_vec[0].select_fds); - highest = qMax(highest, thread_pipe[0]); + int wakeUpFd = initThreadWakeUp(); + highest = qMax(highest, wakeUpFd); nsel = q->select(highest + 1, &sn_vec[0].select_fds, @@ -271,25 +271,7 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, } } - // some other thread woke us up... consume the data on the thread pipe so that - // select doesn't immediately return next time - int nevents = 0; - if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { -#if defined(Q_OS_VXWORKS) - char c[16]; - ::read(thread_pipe[0], c, sizeof(c)); - ::ioctl(thread_pipe[0], FIOFLUSH, 0); -#else - char c[16]; - while (::read(thread_pipe[0], c, sizeof(c)) > 0) - ; -#endif - if (!wakeUps.testAndSetRelease(1, 0)) { - // hopefully, this is dead code - qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!"); - } - ++nevents; - } + int nevents = processThreadWakeUp(nsel); // activate socket notifiers if (! (flags & QEventLoop::ExcludeSocketNotifiers) && nsel > 0 && sn_highest >= 0) { @@ -307,6 +289,35 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, return (nevents + q->activateSocketNotifiers()); } +int QEventDispatcherUNIXPrivate::initThreadWakeUp() +{ + FD_SET(thread_pipe[0], &sn_vec[0].select_fds); + return thread_pipe[0]; +} + +int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) +{ + if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { + // some other thread woke us up... consume the data on the thread pipe so that + // select doesn't immediately return next time +#if defined(Q_OS_VXWORKS) + char c[16]; + ::read(thread_pipe[0], c, sizeof(c)); + ::ioctl(thread_pipe[0], FIOFLUSH, 0); +#else + char c[16]; + while (::read(thread_pipe[0], c, sizeof(c)) > 0) + ; +#endif + if (!wakeUps.testAndSetRelease(1, 0)) { + // hopefully, this is dead code + qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!"); + } + return 1; + } + return 0; +} + QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent) { } diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 0c5d06ddd1..98ea19ced8 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -144,6 +144,8 @@ public: ~QEventDispatcherUNIXPrivate(); int doSelect(QEventLoop::ProcessEventsFlags flags, timeval *timeout); + virtual int initThreadWakeUp(); + virtual int processThreadWakeUp(int nsel); bool mainThread; int thread_pipe[2]; diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index e76c2da57c..c5aa90e519 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -192,10 +192,58 @@ inline qreal qPow(qreal x, qreal y) return pow(x, y); } +#ifndef M_E +#define M_E (2.7182818284590452354) +#endif + +#ifndef M_LOG2E +#define M_LOG2E (1.4426950408889634074) +#endif + +#ifndef M_LOG10E +#define M_LOG10E (0.43429448190325182765) +#endif + +#ifndef M_LN2 +#define M_LN2 (0.69314718055994530942) +#endif + +#ifndef M_LN10 +#define M_LN10 (2.30258509299404568402) +#endif + #ifndef M_PI #define M_PI (3.14159265358979323846) #endif +#ifndef M_PI_2 +#define M_PI_2 (1.57079632679489661923) +#endif + +#ifndef M_PI_4 +#define M_PI_4 (0.78539816339744830962) +#endif + +#ifndef M_1_PI +#define M_1_PI (0.31830988618379067154) +#endif + +#ifndef M_2_PI +#define M_2_PI (0.63661977236758134308) +#endif + +#ifndef M_2_SQRTPI +#define M_2_SQRTPI (1.12837916709551257390) +#endif + +#ifndef M_SQRT2 +#define M_SQRT2 (1.41421356237309504880) +#endif + +#ifndef M_SQRT1_2 +#define M_SQRT1_2 (0.70710678118654752440) +#endif + inline qreal qFastSin(qreal x) { int si = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); // Would be more accurate with qRound, but slower. diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index f48d1c7576..bbc9577b8c 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -192,13 +192,10 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty case QVariant::ByteArray: case QVariant::Color: return data.toByteArray(); - break; case QVariant::String: return data.toString().toUtf8(); - break; case QVariant::Url: return data.toUrl().toEncoded(); - break; case QVariant::List: { // has to be list of URLs QByteArray result; diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index ce9eb143d7..e85f632fdf 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -419,6 +419,16 @@ bool QFutureInterfaceBase::referenceCountIsOne() const return d->refCount.load() == 1; } +bool QFutureInterfaceBase::refT() const +{ + return d->refCount.refT(); +} + +bool QFutureInterfaceBase::derefT() const +{ + return d->refCount.derefT(); +} + QFutureInterfaceBasePrivate::QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState) : refCount(1), m_progressValue(0), m_progressMinimum(0), m_progressMaximum(0), state(initialState), pendingResults(0), diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index b7bf779412..3cbb9506ec 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -130,6 +130,8 @@ public: protected: bool referenceCountIsOne() const; + bool refT() const; + bool derefT() const; public: #ifndef QFUTURE_TEST @@ -148,13 +150,17 @@ class QFutureInterface : public QFutureInterfaceBase public: QFutureInterface(State initialState = NoState) : QFutureInterfaceBase(initialState) - { } + { + refT(); + } QFutureInterface(const QFutureInterface &other) : QFutureInterfaceBase(other) - { } + { + refT(); + } ~QFutureInterface() { - if (referenceCountIsOne()) + if (!derefT()) resultStore().clear(); } @@ -163,7 +169,8 @@ public: QFutureInterface &operator=(const QFutureInterface &other) { - if (referenceCountIsOne()) + other.refT(); + if (!derefT()) resultStore().clear(); QFutureInterfaceBase::operator=(other); return *this; diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index a9081d4c89..ece5e56768 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -129,7 +129,31 @@ class QFutureInterfaceBasePrivate public: QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState); - QAtomicInt refCount; + // When the last QFuture<T> reference is removed, we need to make + // sure that data stored in the ResultStore is cleaned out. + // Since QFutureInterfaceBasePrivate can be shared between QFuture<T> + // and QFuture<void> objects, we use a separate ref. counter + // to keep track of QFuture<T> objects. + class RefCount + { + public: + inline RefCount(int r = 0, int rt = 0) + : m_refCount(r), m_refCountT(rt) {} + // Default ref counter for QFIBP + inline bool ref() { return m_refCount.ref(); } + inline bool deref() { return m_refCount.deref(); } + inline int load() const { return m_refCount.load(); } + // Ref counter for type T + inline bool refT() { return m_refCountT.ref(); } + inline bool derefT() { return m_refCountT.deref(); } + inline int loadT() const { return m_refCountT.load(); } + + private: + QAtomicInt m_refCount; + QAtomicInt m_refCountT; + }; + + RefCount refCount; mutable QMutex m_mutex; QWaitCondition waitCondition; QList<QFutureCallOutInterface *> outputConnections; diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 7d18e93dce..56dc0fade9 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -93,47 +93,67 @@ static inline QDate fixedDate(int y, int m, int d) return result; } -static inline qint64 julianDayFromDate(qint64 year, int month, int day) +static inline qint64 floordiv(qint64 a, qint64 b) { - // Gregorian calendar - // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern + return (a - (a < 0 ? b-1 : 0)) / b; +} +static inline qint64 floordiv(qint64 a, int b) +{ + return (a - (a < 0 ? b-1 : 0)) / b; +} + +static inline int floordiv(int a, int b) +{ + return (a - (a < 0 ? b-1 : 0)) / b; +} + +static inline qint64 julianDayFromDate(int year, int month, int day) +{ + // Adjust for no year 0 if (year < 0) ++year; - 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; +/* + * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php + * This formula is correct for all julian days, when using mathematical integer + * division (round to negative infinity), not c++11 integer division (round to zero) + */ + int a = floordiv(14 - month, 12); + qint64 y = (qint64)year + 4800 - a; + int m = month + 12 * a - 3; + return day + floordiv(153 * m + 2, 5) + 365 * y + floordiv(y, 4) - floordiv(y, 100) + floordiv(y, 400) - 32045; } -static void getDateFromJulianDay(qint64 julianDay, int *year, int *month, int *day) +static void getDateFromJulianDay(qint64 julianDay, int *yearp, int *monthp, int *dayp) { - int y, m, d; +/* + * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php + * This formula is correct for all julian days, when using mathematical integer + * division (round to negative infinity), not c++11 integer division (round to zero) + */ + qint64 a = julianDay + 32044; + qint64 b = floordiv(4 * a + 3, 146097); + int c = a - floordiv(146097 * b, 4); - // Gregorian calendar - // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern - qint64 ell, n, i, j; //TODO These will need to be bigger to prevent overflow!!! - ell = julianDay + 68569; - n = (4 * ell) / 146097; - ell = ell - (146097 * n + 3) / 4; - i = (4000 * (ell + 1)) / 1461001; - ell = ell - (1461 * i) / 4 + 31; - j = (80 * ell) / 2447; - d = ell - (2447 * j) / 80; - ell = j / 11; - m = j + 2 - (12 * ell); - y = 100 * (n - 49) + i + ell; + int d = floordiv(4 * c + 3, 1461); + int e = c - floordiv(1461 * d, 4); + int m = floordiv(5 * e + 2, 153); - if (y<= 0) - --y; + int day = e - floordiv(153 * m + 2, 5) + 1; + int month = m + 3 - 12 * floordiv(m, 10); + int year = 100 * b + d - 4800 + floordiv(m, 10); - if (year) - *year = y; - if (month) - *month = m; - if (day) - *day = d; + // Adjust for no year 0 + if (year <= 0) + --year ; + + if (yearp) + *yearp = year; + if (monthp) + *monthp = month; + if (dayp) + *dayp = day; } @@ -225,14 +245,8 @@ static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* d QDate::toJulianDay() and can be set using QDate::fromJulianDay(). The range of dates able to be stored by QDate as a Julian Day number is - limited for convenience from std::numeric_limits<qint64>::min() / 2 to - std::numeric_limits<qint64>::max() / 2, which on most platforms means - from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively - covering the full range of astronomical time. The range of Julian Days - able to be accurately converted to and from valid YMD form Dates is - restricted to 1 January 4800 BCE to 31 December 1400000 CE due to - shortcomings in the available conversion formulas. Conversions outside this - range are not guaranteed to be correct. This may change in the future. + for technical reasons limited to between -784350574879 and 784354017364, + which means from before 2 billion BCE to after 2 billion CE. \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget */ @@ -859,9 +873,6 @@ QString QDate::toString(const QString& format) const If the specified date is invalid, the QDate object is set to be invalid. - Note that any date before 4800 BCE or after about 1.4 million CE - may not be accurately stored. - \sa isValid() */ bool QDate::setDate(int year, int month, int day) @@ -882,9 +893,6 @@ bool QDate::setDate(int year, int month, int day) Returns 0 if the date is invalid. - Note that any date before 4800 BCE or after about 1.4 million CE - may not be accurately stored. - \sa year(), month(), day(), isValid() */ void QDate::getDate(int *year, int *month, int *day) @@ -2100,14 +2108,8 @@ int QTime::elapsed() const QDate::toJulianDay() and can be set using QDate::fromJulianDay(). The range of dates able to be stored by QDate as a Julian Day number is - limited for convenience from std::numeric_limits<qint64>::min() / 2 to - std::numeric_limits<qint64>::max() / 2, which on most platforms means - from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively - covering the full range of astronomical time. The range of Julian Days - able to be accurately converted to and from valid YMD form Dates is - restricted to 1 January 4800 BCE to 31 December 1400000 CE due to - shortcomings in the available conversion formulas. Conversions outside this - range are not guaranteed to be correct. This may change in the future. + for technical reasons limited to between -784350574879 and 784354017364, + which means from before 2 billion BCE to after 2 billion CE. \section2 Use of System Timezone @@ -2418,7 +2420,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) QDateTimePrivate::Spec oldSpec = d->spec; - int ddays = msecs / MSECS_PER_DAY; + qint64 ddays = msecs / MSECS_PER_DAY; msecs %= MSECS_PER_DAY; if (msecs < 0) { // negative @@ -3391,10 +3393,11 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) int year; QStringList timeParts = parts.at(3).split(QLatin1Char(':')); if ((timeParts.count() == 3) || (timeParts.count() == 2)) { + // Year is after time, e.g. "Sun Dec 1 13:02:00 1974" year = parts.at(4).toInt(&ok); if (!ok) return QDateTime(); - } else { + } else { // Year is before time, e.g. "Sun Dec 1 1974 13:02:00" timeParts = parts.at(4).split(QLatin1Char(':')); if ((timeParts.count() != 3) && (timeParts.count() != 2)) return QDateTime(); @@ -3743,7 +3746,8 @@ static bool hasUnquotedAP(const QString &f) for (int i=0; i<max; ++i) { if (f.at(i) == quote) { inquote = !inquote; - } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) { + } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A') + && i + 1 < max && f.at(i + 1).toUpper() == QLatin1Char('P')) { return true; } } diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index ed7d8adb5f..22db5a4830 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -121,8 +121,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d) private: static inline qint64 nullJd() { return std::numeric_limits<qint64>::min(); } - static inline qint64 minJd() { return std::numeric_limits<qint64>::min() / 2; } - static inline qint64 maxJd() { return (std::numeric_limits<qint64>::max()) / 2; } + static inline qint64 minJd() { return Q_INT64_C(-784350574879); } + static inline qint64 maxJd() { return Q_INT64_C( 784354017364); } qint64 jd; diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index dea87c6b63..7c33d60750 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE -const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 } }; +const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 }, 0 }; const QMapNodeBase *QMapNodeBase::nextNode() const { @@ -177,6 +177,12 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z) QMapNodeBase *x_parent; if (y->left == 0) { x = y->right; + if (y == mostLeftNode) { + if (x) + mostLeftNode = x; // It cannot have (left) children due the red black invariant. + else + mostLeftNode = y->parent(); + } } else { if (y->right == 0) { x = y->left; @@ -290,6 +296,13 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z) --size; } +void QMapDataBase::recalcMostLeftNode() +{ + mostLeftNode = &header; + while (mostLeftNode->left) + mostLeftNode = mostLeftNode->left; +} + static inline int qMapAlignmentThreshold() { // malloc on 32-bit platforms should return pointers that are 8-byte @@ -324,6 +337,8 @@ QMapNodeBase *QMapDataBase::createNode(int alloc, int alignment, QMapNodeBase *p if (parent) { if (left) { parent->left = node; + if (parent == mostLeftNode) + mostLeftNode = node; } else { parent->right = node; } @@ -352,6 +367,7 @@ QMapDataBase *QMapDataBase::createData() d->header.p = 0; d->header.left = 0; d->header.right = 0; + d->mostLeftNode = &(d->header); return d; } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 642cf82f08..d44a79473d 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -173,11 +173,13 @@ struct Q_CORE_EXPORT QMapDataBase QtPrivate::RefCount ref; int size; QMapNodeBase header; + QMapNodeBase *mostLeftNode; void rotateLeft(QMapNodeBase *x); void rotateRight(QMapNodeBase *x); void rebalance(QMapNodeBase *x); void freeNodeAndRebalance(QMapNodeBase *z); + void recalcMostLeftNode(); QMapNodeBase *createNode(int size, int alignment, QMapNodeBase *parent, bool left); void freeTree(QMapNodeBase *root, int alignment); @@ -197,8 +199,8 @@ struct QMapData : public QMapDataBase const Node *end() const { return static_cast<const Node *>(&header); } Node *end() { return static_cast<Node *>(&header); } - const Node *begin() const { if (root()) return root()->minimumNode(); return end(); } - Node *begin() { if (root()) return root()->minimumNode(); return end(); } + const Node *begin() const { if (root()) return static_cast<const Node*>(mostLeftNode); return end(); } + Node *begin() { if (root()) return static_cast<Node*>(mostLeftNode); return end(); } void deleteNode(Node *z); Node *findNode(const Key &akey) const; @@ -555,6 +557,7 @@ inline QMap<Key, T>::QMap(const QMap<Key, T> &other) if (other.d->header.left) { d->header.left = static_cast<Node *>(other.d->header.left)->copy(d); d->header.left->setParent(&d->header); + d->recalcMostLeftNode(); } } } @@ -780,6 +783,7 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper() if (!d->ref.deref()) d->destroy(); d = x; + d->recalcMostLeftNode(); } template <class Key, class T> @@ -935,7 +939,7 @@ Q_OUTOFLINE_TEMPLATE QMap<Key, T>::QMap(const std::map<Key, T> &other) typename std::map<Key,T>::const_iterator it = other.end(); while (it != other.begin()) { --it; - insert((*it).first, (*it).second); + d->createNode((*it).first, (*it).second, d->begin(), true); // insert on most left node. } } @@ -946,7 +950,7 @@ Q_OUTOFLINE_TEMPLATE std::map<Key, T> QMap<Key, T>::toStdMap() const const_iterator it = end(); while (it != begin()) { --it; - map.insert(std::pair<Key, T>(it.key(), it.value())); + map.insert(map.begin(), std::pair<Key, T>(it.key(), it.value())); } return map; } diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index e87e5efc1f..7aea083788 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -1324,14 +1324,11 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &pattern, QRegExp::Pat #ifndef QT_NO_REGEXP_WILDCARD case QRegExp::Wildcard: return wc2rx(pattern, false); - break; case QRegExp::WildcardUnix: return wc2rx(pattern, true); - break; #endif case QRegExp::FixedString: return QRegExp::escape(pattern); - break; case QRegExp::W3CXmlSchema11: default: return pattern; diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 94733f77da..2c688db507 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -252,7 +252,7 @@ void QVector<T>::defaultConstruct(T *from, T *to) new (from++) T(); } } else { - ::memset(from, 0, (to - from) * sizeof(T)); + ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T)); } } @@ -267,7 +267,7 @@ void QVector<T>::copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom) while (srcFrom != srcTo) new (dstFrom++) T(*srcFrom++); } else { - ::memcpy(dstFrom, srcFrom, (srcTo - srcFrom) * sizeof(T)); + ::memcpy(static_cast<void *>(dstFrom), static_cast<const void *>(srcFrom), (srcTo - srcFrom) * sizeof(T)); } } @@ -467,7 +467,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo new (dst++) T(*srcBegin++); } } else { - ::memcpy(static_cast<void *>(dst), srcBegin, (srcEnd - srcBegin) * sizeof(T)); + ::memcpy(static_cast<void *>(dst), static_cast<void *>(srcBegin), (srcEnd - srcBegin) * sizeof(T)); dst += srcEnd - srcBegin; // destruct unused / not moved data |