summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/Qt5CTestMacros.cmake29
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in6
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/io/qdatastream.cpp1
-rw-r--r--src/corelib/io/qlockfile.h4
-rw-r--r--src/corelib/io/qsavefile.cpp101
-rw-r--r--src/corelib/io/qsavefile.h3
-rw-r--r--src/corelib/io/qsavefile_p.h3
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp7
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp3
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
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