summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm2
-rw-r--r--src/corelib/kernel/qmetatype.h88
-rw-r--r--src/corelib/kernel/qmimedata.cpp53
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp115
-rw-r--r--src/corelib/kernel/qsignalmapper.h10
-rw-r--r--src/corelib/kernel/qtranslator.cpp42
-rw-r--r--src/corelib/kernel/qtranslator.h3
-rw-r--r--src/corelib/kernel/qvariant.cpp4
8 files changed, 256 insertions, 61 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index b1f3b74cd4..a042361686 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -247,7 +247,7 @@ AppleApplication *qt_apple_sharedApplication()
qWarning() << "accessing the shared" << [AppleApplication class]
<< "is not allowed in application extensions";
- // In practice the application is actually available, but the the App
+ // In practice the application is actually available, but the App
// review process will likely catch uses of it, so we return nil just
// in case, unless we don't care about being App Store compliant.
#if QT_CONFIG(appstore_compliant)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 927bfb7667..b5a62d1aa0 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -988,6 +988,30 @@ enum IteratorCapability
RandomAccessCapability = 4
};
+enum ContainerCapability
+{
+ ContainerIsAppendable = 1
+};
+
+template<typename Container, typename T = void>
+struct ContainerCapabilitiesImpl
+{
+ enum {ContainerCapabilities = 0};
+ using appendFunction = void(*)(const void *container, const void *newElement);
+ static constexpr const appendFunction appendImpl = nullptr;
+};
+
+template<typename Container>
+struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().push_back(std::declval<typename Container::value_type>()))>
+{
+ enum {ContainerCapabilities = ContainerIsAppendable};
+
+ // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
+ // pointed to a const object to begin with
+ static void appendImpl(const void *container, const void *value)
+ { static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); }
+};
+
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
struct CapabilitiesImpl;
@@ -1019,6 +1043,12 @@ template<typename T>
struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
{ static int size(const std::list<T> *t) { return int(t->size()); } };
+/*
+ revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set
+ revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce
+ _revision, _containerCapabilities and _unused. The latter contains 21 bits that are
+ not used yet
+*/
class QSequentialIterableImpl
{
public:
@@ -1027,19 +1057,37 @@ public:
int _metaType_id;
uint _metaType_flags;
uint _iteratorCapabilities;
+ // Iterator capabilities looks actually like
+ // uint _iteratorCapabilities:4;
+ // uint _revision:3;
+ // uint _containerCapabilities:4;
+ // uint _unused:21;*/
typedef int(*sizeFunc)(const void *p);
typedef const void * (*atFunc)(const void *p, int);
typedef void (*moveIteratorFunc)(const void *p, void **);
+ enum Position { ToBegin, ToEnd };
+ typedef void (*moveIteratorFunc2)(const void *p, void **, Position position);
typedef void (*advanceFunc)(void **p, int);
typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
typedef void (*copyIterFunc)(void **, void * const *);
+ typedef void(*appendFunction)(const void *container, const void *newElement);
+
+ IteratorCapability iteratorCapabilities() {return static_cast<IteratorCapability>(_iteratorCapabilities & 0xF);}
+ uint revision() {return _iteratorCapabilities >> 4 & 0x7;}
+ uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;}
sizeFunc _size;
atFunc _at;
- moveIteratorFunc _moveToBegin;
- moveIteratorFunc _moveToEnd;
+ union {
+ moveIteratorFunc _moveToBegin;
+ moveIteratorFunc2 _moveTo;
+ };
+ union {
+ moveIteratorFunc _moveToEnd;
+ appendFunction _append;
+ };
advanceFunc _advance;
getFunc _get;
destroyIterFunc _destroyIter;
@@ -1066,6 +1114,15 @@ public:
static void moveToEndImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+ template<class Container>
+ static void moveToImpl(const void *container, void **iterator, Position position)
+ {
+ if (position == ToBegin)
+ moveToBeginImpl<Container>(container, iterator);
+ else
+ moveToEndImpl<Container>(container, iterator);
+ }
+
template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
@@ -1076,11 +1133,11 @@ public:
, _iterator(nullptr)
, _metaType_id(qMetaTypeId<typename T::value_type>())
, _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
- , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
+ , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl<T>::ContainerCapabilities << (4+3)))
, _size(sizeImpl<T>)
, _at(atImpl<T>)
- , _moveToBegin(moveToBeginImpl<T>)
- , _moveToEnd(moveToEndImpl<T>)
+ , _moveTo(moveToImpl<T>)
+ , _append(ContainerCapabilitiesImpl<T>::appendImpl)
, _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>)
, _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
@@ -1094,7 +1151,7 @@ public:
, _iterator(nullptr)
, _metaType_id(QMetaType::UnknownType)
, _metaType_flags(0)
- , _iteratorCapabilities(0)
+ , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1
, _size(nullptr)
, _at(nullptr)
, _moveToBegin(nullptr)
@@ -1107,8 +1164,18 @@ public:
{
}
- inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
- inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
+ inline void moveToBegin() {
+ if (revision() == 0)
+ _moveToBegin(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToBegin);
+ }
+ inline void moveToEnd() {
+ if (revision() == 0)
+ _moveToEnd(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToEnd);
+ }
inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
inline QSequentialIterableImpl &advance(int i) {
Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
@@ -1116,6 +1183,11 @@ public:
return *this;
}
+ inline void append(const void *newElement) {
+ if (containerCapabilities() & ContainerIsAppendable)
+ _append(_iterable, newElement);
+ }
+
inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
VariantData at(int idx) const
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index fca258c9e3..c38dab3e3f 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -72,40 +72,44 @@ public:
QVariant retrieveTypedData(const QString &format, QMetaType::Type type) const;
- QVector<QMimeDataStruct> dataList;
+ std::vector<QMimeDataStruct>::iterator find(const QString &format) noexcept {
+ const auto formatEquals = [](const QString &format) {
+ return [&format](const QMimeDataStruct &s) { return s.format == format; };
+ };
+ return std::find_if(dataList.begin(), dataList.end(), formatEquals(format));
+ }
+
+ std::vector<QMimeDataStruct>::const_iterator find(const QString &format) const noexcept {
+ return const_cast<QMimeDataPrivate*>(this)->find(format);
+ }
+
+ std::vector<QMimeDataStruct> dataList;
};
void QMimeDataPrivate::removeData(const QString &format)
{
- for (int i=0; i<dataList.size(); i++) {
- if (dataList.at(i).format == format) {
- dataList.removeAt(i);
- return;
- }
- }
+ const auto it = find(format);
+ if (it != dataList.end())
+ dataList.erase(it);
}
void QMimeDataPrivate::setData(const QString &format, const QVariant &data)
{
- // remove it first if the format is already here.
- removeData(format);
- QMimeDataStruct mimeData;
- mimeData.format = format;
- mimeData.data = data;
- dataList += mimeData;
+ const auto it = find(format);
+ if (it == dataList.end())
+ dataList.push_back({format, data});
+ else
+ it->data = data;
}
QVariant QMimeDataPrivate::getData(const QString &format) const
{
- QVariant data;
- for (int i=0; i<dataList.size(); i++) {
- if (dataList.at(i).format == format) {
- data = dataList.at(i).data;
- break;
- }
- }
- return data;
+ const auto it = find(format);
+ if (it == dataList.cend())
+ return {};
+ else
+ return it->data;
}
QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::Type type) const
@@ -635,10 +639,9 @@ QStringList QMimeData::formats() const
{
Q_D(const QMimeData);
QStringList list;
- const int size = d->dataList.size();
- list.reserve(size);
- for (int i = 0; i < size; ++i)
- list += d->dataList.at(i).format;
+ list.reserve(static_cast<int>(d->dataList.size()));
+ for (auto &e : d->dataList)
+ list += e.format;
return list;
}
diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp
index 24b174972f..dc0dfe8f40 100644
--- a/src/corelib/kernel/qsignalmapper.cpp
+++ b/src/corelib/kernel/qsignalmapper.cpp
@@ -53,11 +53,36 @@ public:
Q_Q(QSignalMapper);
q->removeMappings(q->sender());
}
+
+ template <class Signal, class Container>
+ void emitMappedValue(QObject *sender, Signal signal, const Container &mappedValues)
+ {
+ Q_Q(QSignalMapper);
+
+ auto it = mappedValues.find(sender);
+ if (it != mappedValues.end()) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ Q_EMIT q->mapped(*it);
+QT_WARNING_POP
+#endif
+ Q_EMIT (q->*signal)(*it);
+ }
+ }
+
+ void emitMappedValues(QObject *sender)
+ {
+ emitMappedValue(sender, &QSignalMapper::mappedInt, intHash);
+ emitMappedValue(sender, &QSignalMapper::mappedString, stringHash);
+ emitMappedValue(sender, &QSignalMapper::mappedWidget, widgetHash);
+ emitMappedValue(sender, &QSignalMapper::mappedObject, objectHash);
+ }
+
QHash<QObject *, int> intHash;
QHash<QObject *, QString> stringHash;
QHash<QObject *, QWidget*> widgetHash;
QHash<QObject *, QObject*> objectHash;
-
};
/*!
@@ -74,11 +99,12 @@ public:
use lambdas for passing custom parameters to slots. This is less
costly and will simplify the code.
- The class supports the mapping of particular strings or integers
- with particular objects using setMapping(). The objects' signals
- can then be connected to the map() slot which will emit the
- mapped() signal with the string or integer associated with the
- original signalling object. Mappings can be removed later using
+ The class supports the mapping of particular strings, integers,
+ objects and widgets with particular objects using setMapping().
+ The objects' signals can then be connected to the map() slot which
+ will emit a signal (it could be mappedInt(), mappedString(),
+ mappedWidget() and mappedObject()) with a value associated with
+ the original signalling object. Mappings can be removed later using
removeMappings().
Example: Suppose we want to create a custom widget that contains
@@ -106,8 +132,8 @@ public:
created. We connect each button's \c clicked() signal to the
signal mapper's map() slot, and create a mapping in the signal
mapper from each button to the button's text. Finally we connect
- the signal mapper's mapped() signal to the custom widget's \c
- clicked() signal. When the user clicks a button, the custom
+ the signal mapper's mappedString() signal to the custom widget's
+ \c clicked() signal. When the user clicks a button, the custom
widget will emit a single \c clicked() signal whose argument is
the text of the button the user clicked.
@@ -137,7 +163,7 @@ QSignalMapper::~QSignalMapper()
/*!
Adds a mapping so that when map() is signalled from the given \a
- sender, the signal mapped(\a id) is emitted.
+ sender, the signal mappedInt(\a id) is emitted.
There may be at most one integer ID for each sender.
@@ -152,7 +178,7 @@ void QSignalMapper::setMapping(QObject *sender, int id)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a text ) is emitted.
+ the signal mappedString(\a text ) is emitted.
There may be at most one text for each sender.
*/
@@ -165,7 +191,7 @@ void QSignalMapper::setMapping(QObject *sender, const QString &text)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a widget ) is emitted.
+ the signal mappedWidget(\a widget ) is emitted.
There may be at most one widget for each sender.
*/
@@ -178,7 +204,7 @@ void QSignalMapper::setMapping(QObject *sender, QWidget *widget)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a object ) is emitted.
+ the signal mappedObject(\a object ) is emitted.
There may be at most one object for each sender.
*/
@@ -259,20 +285,14 @@ void QSignalMapper::map() { map(sender()); }
*/
void QSignalMapper::map(QObject *sender)
{
- Q_D(QSignalMapper);
- if (d->intHash.contains(sender))
- emit mapped(d->intHash.value(sender));
- if (d->stringHash.contains(sender))
- emit mapped(d->stringHash.value(sender));
- if (d->widgetHash.contains(sender))
- emit mapped(d->widgetHash.value(sender));
- if (d->objectHash.contains(sender))
- emit mapped(d->objectHash.value(sender));
+ d_func()->emitMappedValues(sender);
}
-
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn void QSignalMapper::mapped(int i)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has an integer mapping set. The object's mapped integer is passed
@@ -283,6 +303,8 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(const QString &text)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has a string mapping set. The object's mapped string is passed in
@@ -293,6 +315,8 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(QWidget *widget)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has a widget mapping set. The object's mapped widget is passed in
@@ -303,6 +327,53 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(QObject *object)
+ \obsolete
+ \overload
+
+ This signal is emitted when map() is signalled from an object that
+ has an object mapping set. The object provided by the map is passed in
+ \a object.
+
+ \sa setMapping()
+*/
+#endif
+
+/*!
+ \fn void QSignalMapper::mappedInt(int i)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has an integer mapping set. The object's mapped integer is passed
+ in \a i.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedString(const QString &text)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has a string mapping set. The object's mapped string is passed in
+ \a text.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedWidget(QWidget *widget)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has a widget mapping set. The object's mapped widget is passed in
+ \a widget.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedObject(QObject *object)
+ \since 5.15
This signal is emitted when map() is signalled from an object that
has an object mapping set. The object provided by the map is passed in
diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h
index 0da1e8f87d..592986e6a5 100644
--- a/src/corelib/kernel/qsignalmapper.h
+++ b/src/corelib/kernel/qsignalmapper.h
@@ -66,10 +66,20 @@ public:
QObject *mapping(QObject *object) const;
Q_SIGNALS:
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedInt(int) instead")
void mapped(int);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedString(const QString&) instead")
void mapped(const QString &);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedWidget(QWidget *) instead")
void mapped(QWidget *);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedObject(QObject *) instead")
void mapped(QObject *);
+#endif
+ void mappedInt(int);
+ void mappedString(const QString &);
+ void mappedWidget(QWidget *);
+ void mappedObject(QObject *);
public Q_SLOTS:
void map();
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 4bd8874630..5767d52f6a 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -283,7 +283,7 @@ class QTranslatorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QTranslator)
public:
- enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96 };
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96, Language = 0xa7 };
QTranslatorPrivate() :
#if defined(QT_USE_MMAP)
@@ -316,6 +316,9 @@ public:
uint contextLength;
uint numerusRulesLength;
+ QString language;
+ QString filePath;
+
bool do_load(const QString &filename, const QString &directory);
bool do_load(const uchar *data, qsizetype len, const QString &directory);
QString do_translate(const char *context, const char *sourceText, const char *comment,
@@ -597,8 +600,10 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
}
}
- if (ok && d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength, directory))
+ if (ok && d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength, directory)) {
+ d->filePath = realname;
return true;
+ }
#if defined(QT_USE_MMAP)
if (used_mmap) {
@@ -829,7 +834,9 @@ bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString
break;
}
- if (tag == QTranslatorPrivate::Contexts) {
+ if (tag == QTranslatorPrivate::Language) {
+ language = QString::fromUtf8((const char*)data, blockLen);
+ } else if (tag == QTranslatorPrivate::Contexts) {
contextArray = data;
contextLength = blockLen;
} else if (tag == QTranslatorPrivate::Hashes) {
@@ -1091,6 +1098,9 @@ void QTranslatorPrivate::clear()
qDeleteAll(subTranslators);
subTranslators.clear();
+ language.clear();
+ filePath.clear();
+
if (QCoreApplicationPrivate::isTranslatorInstalled(q))
QCoreApplication::postEvent(QCoreApplication::instance(),
new QEvent(QEvent::LanguageChange));
@@ -1132,6 +1142,32 @@ bool QTranslator::isEmpty() const
&& d->subTranslators.isEmpty();
}
+/*!
+ \since 5.15
+
+ Returns the target language as stored in the translation file.
+ */
+QString QTranslator::language() const
+{
+ Q_D(const QTranslator);
+ return d->language;
+}
+
+/*!
+ \since 5.15
+
+ Returns the path of the loaded translation file.
+
+ The file path is empty if no translation was loaded yet,
+ the loading failed, or if the translation was not loaded
+ from a file.
+ */
+QString QTranslator::filePath() const
+{
+ Q_D(const QTranslator);
+ return d->filePath;
+}
+
QT_END_NAMESPACE
#include "moc_qtranslator.cpp"
diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h
index e7c39191e7..61a39c4089 100644
--- a/src/corelib/kernel/qtranslator.h
+++ b/src/corelib/kernel/qtranslator.h
@@ -63,6 +63,9 @@ public:
virtual bool isEmpty() const;
+ QString language() const;
+ QString filePath() const;
+
bool load(const QString & filename,
const QString & directory = QString(),
const QString & search_delimiters = QString(),
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 4ac26e3048..e3d565f185 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -662,7 +662,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
# endif
#endif
case QMetaType::QDate:
- *dt = QDateTime(*v_cast<QDate>(d));
+ *dt = v_cast<QDate>(d)->startOfDay();
break;
default:
return false;
@@ -1229,7 +1229,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
break;
case QMetaType::QDate:
- *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
+ *static_cast<QCborValue *>(result) = QCborValue(v_cast<QDate>(d)->startOfDay());
break;
case QMetaType::QDateTime:
*static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));