diff options
author | Sergio Ahumada <sergio.ahumada@digia.com> | 2013-04-10 15:41:47 +0200 |
---|---|---|
committer | Sergio Ahumada <sergio.ahumada@digia.com> | 2013-04-10 15:42:22 +0200 |
commit | 90297a64f203959f90041887ea31f4bd04bc059a (patch) | |
tree | 86f8ad6a5af26fd618cdb2e20601e6df89ac94d6 /src/corelib | |
parent | 537a4bc4011d32de193dc31caf09a44c1810ab33 (diff) | |
parent | f273d6fbc02055ff3999adc0df76360ca0670435 (diff) |
Merge branch 'stable' into dev
Change-Id: Icff019d74ae04c628a80f66aa478e4db40fae464
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/Qt5CTestMacros.cmake | 29 | ||||
-rw-r--r-- | src/corelib/Qt5CoreConfigExtras.cmake.in | 6 | ||||
-rw-r--r-- | src/corelib/doc/src/objectmodel/properties.qdoc | 2 | ||||
-rw-r--r-- | src/corelib/global/qlibraryinfo.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qdatastream.cpp | 1 | ||||
-rw-r--r-- | src/corelib/io/qlockfile.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qsavefile.cpp | 101 | ||||
-rw-r--r-- | src/corelib/io/qsavefile.h | 3 | ||||
-rw-r--r-- | src/corelib/io/qsavefile_p.h | 3 | ||||
-rw-r--r-- | src/corelib/itemmodels/qabstractproxymodel.cpp | 7 | ||||
-rw-r--r-- | src/corelib/itemmodels/qsortfilterproxymodel.cpp | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 2 |
13 files changed, 134 insertions, 33 deletions
diff --git a/src/corelib/Qt5CTestMacros.cmake b/src/corelib/Qt5CTestMacros.cmake index 32af44a79d..e507c8009e 100644 --- a/src/corelib/Qt5CTestMacros.cmake +++ b/src/corelib/Qt5CTestMacros.cmake @@ -26,6 +26,14 @@ if (NO_DBUS) list(APPEND BUILD_OPTIONS_LIST "-DNO_DBUS=True") endif() +foreach(module ${CMAKE_MODULES_UNDER_TEST}) + list(APPEND BUILD_OPTIONS_LIST + "-DCMAKE_${module}_MODULE_MAJOR_VERSION=${CMAKE_${module}_MODULE_MAJOR_VERSION}" + "-DCMAKE_${module}_MODULE_MINOR_VERSION=${CMAKE_${module}_MODULE_MINOR_VERSION}" + "-DCMAKE_${module}_MODULE_PATCH_VERSION=${CMAKE_${module}_MODULE_PATCH_VERSION}" + ) +endforeach() + macro(expect_pass _dir) string(REPLACE "(" "_" testname "${_dir}") string(REPLACE ")" "_" testname "${testname}") @@ -95,11 +103,30 @@ function(test_module_includes) while(all_args) list(GET all_args 0 qtmodule) list(REMOVE_AT all_args 0 1) + + set(CMAKE_MODULE_VERSION ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION}.${CMAKE_${qtmodule}_MODULE_MINOR_VERSION}.${CMAKE_${qtmodule}_MODULE_PATCH_VERSION} ) + set(packages_string "${packages_string} find_package(Qt5${qtmodule} 5.0.0 REQUIRED) include_directories(\${Qt5${qtmodule}_INCLUDE_DIRS}) - add_definitions(\${Qt5${qtmodule}_DEFINITIONS})\n" + add_definitions(\${Qt5${qtmodule}_DEFINITIONS}) + + if(NOT \"\${Qt5${qtmodule}_VERSION}\" VERSION_EQUAL ${CMAKE_MODULE_VERSION}) + message(SEND_ERROR \"Qt5${qtmodule}_VERSION variable was not ${CMAKE_MODULE_VERSION}. Got \${Qt5${qtmodule}_VERSION} instead.\") + endif() + if(NOT \"\${Qt5${qtmodule}_VERSION_MAJOR}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION}) + message(SEND_ERROR \"Qt5${qtmodule}_VERSION_MAJOR variable was not ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION}. Got \${Qt5${qtmodule}_VERSION_MAJOR} instead.\") + endif() + if(NOT \"\${Qt5${qtmodule}_VERSION_MINOR}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_MINOR_VERSION}) + message(SEND_ERROR \"Qt5${qtmodule}_VERSION_MINOR variable was not ${CMAKE_${qtmodule}_MODULE_MINOR_VERSION}. Got \${Qt5${qtmodule}_VERSION_MINOR} instead.\") + endif() + if(NOT \"\${Qt5${qtmodule}_VERSION_PATCH}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_PATCH_VERSION}) + message(SEND_ERROR \"Qt5${qtmodule}_VERSION_PATCH variable was not ${CMAKE_${qtmodule}_MODULE_PATCH_VERSION}. Got \${Qt5${qtmodule}_VERSION_PATCH} instead.\") + endif() + if(NOT \"\${Qt5${qtmodule}_VERSION_STRING}\" VERSION_EQUAL ${CMAKE_MODULE_VERSION}) + message(SEND_ERROR \"Qt5${qtmodule}_VERSION_STRING variable was not ${CMAKE_MODULE_VERSION}. Got \${Qt5${qtmodule}_VERSION_STRING} instead.\") + endif()\n" ) set(libraries_string "${libraries_string} Qt5::${qtmodule}") endwhile() diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index bdafc85796..379fb5d10e 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -46,10 +46,10 @@ set_property(TARGET Qt5::Core APPEND PROPERTY COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION ) -!!IF isEmpty(CMAKE_ARCHDATA_DIR_IS_ABSOLUTE) -set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_ARCHDATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\") +!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE) +set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\") !!ELSE -set(_qt5_corelib_extra_includes \"$${CMAKE_ARCHDATA_DIR}mkspecs/$${CMAKE_MKSPEC}\") +set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\") !!ENDIF list(APPEND Qt5Core_INCLUDE_DIRS ${_qt5_corelib_extra_includes}) diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc index 65e23d9dc7..d1690c5908 100644 --- a/src/corelib/doc/src/objectmodel/properties.qdoc +++ b/src/corelib/doc/src/objectmodel/properties.qdoc @@ -195,7 +195,7 @@ Suppose we have a class MyClass, which is derived from QObject and which uses the Q_OBJECT macro in its private section. We want to - declare a property in MyClass to keep track of a priorty + declare a property in MyClass to keep track of a priority value. The name of the property will be \e priority, and its type will be an enumeration type named \e Priority, which is defined in MyClass. diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 747fd87207..5fb9640b19 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -273,7 +273,11 @@ static const struct { { "Documentation", "doc" }, // should be ${Data}/doc { "Headers", "include" }, { "Libraries", "lib" }, +#ifdef Q_OS_WIN + { "LibraryExecutables", "bin" }, +#else { "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec +#endif { "Binaries", "bin" }, { "Plugins", "plugins" }, // should be ${ArchData}/plugins { "Imports", "imports" }, // should be ${ArchData}/imports diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 42b263be77..484dcbf22e 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -572,6 +572,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \table \header \li Qt Version \li QDataStream Version + \row \li Qt 5.0 \li 13 \row \li Qt 4.6 \li 12 \row \li Qt 4.5 \li 11 \row \li Qt 4.4 \li 10 diff --git a/src/corelib/io/qlockfile.h b/src/corelib/io/qlockfile.h index 4c8b6bf31a..d46f07ab7b 100644 --- a/src/corelib/io/qlockfile.h +++ b/src/corelib/io/qlockfile.h @@ -45,8 +45,6 @@ #include <QtCore/qstring.h> #include <QtCore/qscopedpointer.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QLockFilePrivate; @@ -86,6 +84,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QLOCKFILE_H diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index fee6a4c4d8..f8b5ebcabd 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -48,11 +48,16 @@ #include "qtemporaryfile.h" #include "private/qiodevice_p.h" #include "private/qtemporaryfile_p.h" +#ifdef Q_OS_UNIX +#include <errno.h> +#endif QT_BEGIN_NAMESPACE QSaveFilePrivate::QSaveFilePrivate() - : writeError(QFileDevice::NoError) + : writeError(QFileDevice::NoError), + useTemporaryFile(true), + directWriteFallback(false) { } @@ -201,6 +206,18 @@ bool QSaveFile::open(OpenMode mode) // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); +#ifdef Q_OS_UNIX + if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) { + delete d->fileEngine; + d->fileEngine = QAbstractFileEngine::create(d->fileName); + if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { + d->useTemporaryFile = false; + QFileDevice::open(mode); + return true; + } + err = d->fileEngine->error(); + } +#endif if (err == QFileDevice::UnspecifiedError) err = QFileDevice::OpenError; d->setError(err, d->fileEngine->errorString()); @@ -209,6 +226,7 @@ bool QSaveFile::open(OpenMode mode) return false; } + d->useTemporaryFile = true; QFileDevice::open(mode); if (existingFile.exists()) setPermissions(existingFile.permissions()); @@ -253,22 +271,24 @@ bool QSaveFile::commit() // Sync to disk if possible. Ignore errors (e.g. not supported). d->fileEngine->syncToDisk(); - if (d->writeError != QFileDevice::NoError) { - d->fileEngine->remove(); - d->writeError = QFileDevice::NoError; - delete d->fileEngine; - d->fileEngine = 0; - return false; - } - // atomically replace old file with new file - // Can't use QFile::rename for that, must use the file engine directly - Q_ASSERT(d->fileEngine); - if (!d->fileEngine->renameOverwrite(d->fileName)) { - d->setError(d->fileEngine->error(), d->fileEngine->errorString()); - d->fileEngine->remove(); - delete d->fileEngine; - d->fileEngine = 0; - return false; + if (d->useTemporaryFile) { + if (d->writeError != QFileDevice::NoError) { + d->fileEngine->remove(); + d->writeError = QFileDevice::NoError; + delete d->fileEngine; + d->fileEngine = 0; + return false; + } + // atomically replace old file with new file + // Can't use QFile::rename for that, must use the file engine directly + Q_ASSERT(d->fileEngine); + if (!d->fileEngine->renameOverwrite(d->fileName)) { + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); + d->fileEngine->remove(); + delete d->fileEngine; + d->fileEngine = 0; + return false; + } } delete d->fileEngine; d->fileEngine = 0; @@ -286,6 +306,11 @@ bool QSaveFile::commit() Further write operations are possible after calling this method, but none of it will have any effect, the written file will be discarded. + This method has no effect when direct write fallback is used. This is the case + when saving over an existing file in a readonly directory: no temporary file can + be created, so the existing file is overwritten no matter what, and cancelWriting() + cannot do anything about that, the contents of the existing file will be lost. + \sa commit() */ void QSaveFile::cancelWriting() @@ -313,4 +338,46 @@ qint64 QSaveFile::writeData(const char *data, qint64 len) return ret; } +/*! + Allows writing over the existing file if necessary. + + QSaveFile creates a temporary file in the same directory as the final + file and atomically renames it. However this is not possible if the + directory permissions do not allow creating new files. + In order to preserve atomicity guarantees, open() fails when it + cannot create the temporary file. + + In order to allow users to edit files with write permissions in a + directory with restricted permissions, call setDirectWriteFallback() with + \a enabled set to true, and the following calls to open() will fallback to + opening the existing file directly and writing into it, without the use of + a temporary file. + This does not have atomicity guarantees, i.e. an application crash or + for instance a power failure could lead to a partially-written file on disk. + It also means cancelWriting() has no effect, in such a case. + + Typically, to save documents edited by the user, call setDirectWriteFallback(true), + and to save application internal files (configuration files, data files, ...), keep + the default setting which ensures atomicity. + + \sa directWriteFallback() +*/ +void QSaveFile::setDirectWriteFallback(bool enabled) +{ + Q_D(QSaveFile); + d->directWriteFallback = enabled; +} + +/*! + Returns true if the fallback solution for saving files in read-only + directories is enabled. + + \sa setDirectWriteFallback() +*/ +bool QSaveFile::directWriteFallback() const +{ + Q_D(const QSaveFile); + return d->directWriteFallback; +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h index 32af4a708e..6d81f58d42 100644 --- a/src/corelib/io/qsavefile.h +++ b/src/corelib/io/qsavefile.h @@ -75,6 +75,9 @@ public: void cancelWriting(); + void setDirectWriteFallback(bool enabled); + bool directWriteFallback() const; + protected: qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE; diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h index 27e687835b..53a8b5eb34 100644 --- a/src/corelib/io/qsavefile_p.h +++ b/src/corelib/io/qsavefile_p.h @@ -68,6 +68,9 @@ protected: QString fileName; QFileDevice::FileError writeError; + + bool useTemporaryFile; + bool directWriteFallback; }; QT_END_NAMESPACE diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index d5887a52d5..d435c4bcf5 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -91,6 +91,7 @@ QT_BEGIN_NAMESPACE //detects the deletion of the source model void QAbstractProxyModelPrivate::_q_sourceModelDestroyed() { + invalidatePersistentIndexes(); model = QAbstractItemModelPrivate::staticEmptyModel(); } @@ -271,8 +272,7 @@ QVariant QAbstractProxyModel::headerData(int section, Qt::Orientation orientatio */ QMap<int, QVariant> QAbstractProxyModel::itemData(const QModelIndex &proxyIndex) const { - Q_D(const QAbstractProxyModel); - return d->model->itemData(mapToSource(proxyIndex)); + return QAbstractItemModel::itemData(proxyIndex); } /*! @@ -298,8 +298,7 @@ bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &valu */ bool QAbstractProxyModel::setItemData(const QModelIndex &index, const QMap< int, QVariant >& roles) { - Q_D(QAbstractProxyModel); - return d->model->setItemData(mapToSource(index), roles); + return QAbstractItemModel::setItemData(index, roles); } /*! diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index e5bdd83dc3..67b0d98402 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -295,7 +295,8 @@ typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap; void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed() { QAbstractProxyModelPrivate::_q_sourceModelDestroyed(); - _q_clearMapping(); + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); } void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 189116ddc1..4add02f805 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -689,7 +689,7 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true> return id; const char * const cName = T::staticMetaObject.className(); QByteArray typeName; - typeName.reserve(strlen(cName) + 1); + typeName.reserve(int(strlen(cName)) + 1); typeName.append(cName).append('*'); const int newId = qRegisterNormalizedMetaType<T*>( typeName, diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 7b80e5c1da..bae4a837a0 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -971,7 +971,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names QVariant to convert between types given suitable data; it is still possible to supply data which cannot actually be converted. - For example, canConvert(int) would return true when called on a variant + For example, canConvert(Int) would return true when called on a variant containing a string because, in principle, QVariant is able to convert strings of numbers to integers. However, if the string contains non-numeric characters, it cannot be |