diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qcore_mac_objc.mm | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 88 | ||||
-rw-r--r-- | src/corelib/kernel/qmimedata.cpp | 53 | ||||
-rw-r--r-- | src/corelib/kernel/qsignalmapper.cpp | 115 | ||||
-rw-r--r-- | src/corelib/kernel/qsignalmapper.h | 10 | ||||
-rw-r--r-- | src/corelib/kernel/qtranslator.cpp | 42 | ||||
-rw-r--r-- | src/corelib/kernel/qtranslator.h | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 4 |
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)); |