diff options
Diffstat (limited to 'src/corelib/kernel')
| -rw-r--r-- | src/corelib/kernel/qbasictimer.cpp | 5 | ||||
| -rw-r--r-- | src/corelib/kernel/qdeadlinetimer.cpp | 3 | ||||
| -rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 4 | ||||
| -rw-r--r-- | src/corelib/kernel/qpointer.qdoc | 4 | ||||
| -rw-r--r-- | src/corelib/kernel/qproperty.cpp | 23 | ||||
| -rw-r--r-- | src/corelib/kernel/qproperty_p.h | 29 | ||||
| -rw-r--r-- | src/corelib/kernel/qpropertyprivate.h | 4 | ||||
| -rw-r--r-- | src/corelib/kernel/qtranslator.cpp | 94 | ||||
| -rw-r--r-- | src/corelib/kernel/qvariant.cpp | 4 |
9 files changed, 107 insertions, 63 deletions
diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp index b843ec1ecfd..62e5a7347d4 100644 --- a/src/corelib/kernel/qbasictimer.cpp +++ b/src/corelib/kernel/qbasictimer.cpp @@ -86,6 +86,11 @@ QT_BEGIN_NAMESPACE /*! \fn QBasicTimer::swap(QBasicTimer &other) + \since 5.14 + \memberswap{timer} +*/ + +/*! \fn swap(QBasicTimer &lhs, QBasicTimer &rhs) \since 5.14 diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index a5d16ddf65d..ea7a23c2dbc 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -978,8 +978,7 @@ QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs) /*! \fn void QDeadlineTimer::swap(QDeadlineTimer &other) - - Swaps this deadline timer with the \a other deadline timer. + \memberswap{deadline timer} */ /*! diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 792fe986563..a9036e02032 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1734,9 +1734,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * /*! \fn QMetaObject::Connection::swap(Connection &other) \since 5.15 - - Swaps this Connection instance with \a other. This operation is very fast - and never fails. + \memberswap{Connection instance} */ /*! diff --git a/src/corelib/kernel/qpointer.qdoc b/src/corelib/kernel/qpointer.qdoc index aebdd68428b..65b4dd649e5 100644 --- a/src/corelib/kernel/qpointer.qdoc +++ b/src/corelib/kernel/qpointer.qdoc @@ -100,9 +100,7 @@ /*! \fn template <class T> void QPointer<T>::swap(QPointer &other) \since 5.6 - - Swaps the contents of this QPointer with the contents of \a other. - This operation is very fast and never fails. + \memberswap{QPointer} */ /*! diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 68f6f424104..a9021822b56 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -226,8 +226,8 @@ void Qt::endPropertyUpdateGroup() data = data->next; } // notify all delayed notifications from binding evaluation - for (const QBindingObserverPtr &observer: bindingObservers) { - QPropertyBindingPrivate *binding = observer.binding(); + for (const auto &bindingPtr: bindingObservers) { + auto *binding = static_cast<QPropertyBindingPrivate *>(bindingPtr.get()); binding->notifyNonRecursive(); } // do the same for properties which only have observers @@ -307,8 +307,9 @@ void QPropertyBindingPrivate::notifyRecursive() void QPropertyBindingPrivate::notifyNonRecursive(const PendingBindingObserverList &bindingObservers) { notifyNonRecursive(); - for (auto &&bindingObserver: bindingObservers) { - bindingObserver.binding()->notifyNonRecursive(); + for (auto &&bindingPtr: bindingObservers) { + auto *binding = static_cast<QPropertyBindingPrivate *>(bindingPtr.get()); + binding->notifyNonRecursive(); } } @@ -622,8 +623,10 @@ void QPropertyBindingData::notifyObservers(QUntypedPropertyData *propertyDataPtr d = QPropertyBindingDataPointer {storage->bindingData(propertyDataPtr)}; if (QPropertyObserverPointer observer = d.firstObserver()) observer.notifyOnlyChangeHandler(propertyDataPtr); - for (auto &&bindingObserver: bindingObservers) - bindingObserver.binding()->notifyNonRecursive(); + for (auto &&bindingPtr: bindingObservers) { + auto *binding = static_cast<QPropertyBindingPrivate *>(bindingPtr.get()); + binding->notifyNonRecursive(); + } } } } @@ -784,9 +787,11 @@ void QPropertyObserverPointer::evaluateBindings(PendingBindingObserverList &bind if (QPropertyObserver::ObserverTag(observer->next.tag()) == QPropertyObserver::ObserverNotifiesBinding) { auto bindingToEvaluate = observer->binding; QPropertyObserverNodeProtector protector(observer); - QBindingObserverPtr bindingObserver(observer); // binding must not be gone after evaluateRecursive_inline - if (bindingToEvaluate->evaluateRecursive_inline(bindingObservers, status)) - bindingObservers.push_back(std::move(bindingObserver)); + // binding must not be gone after evaluateRecursive_inline + QPropertyBindingPrivatePtr currentBinding(observer->binding); + const bool evalStatus = bindingToEvaluate->evaluateRecursive_inline(bindingObservers, status); + if (evalStatus) + bindingObservers.push_back(std::move(currentBinding)); next = protector.next(); } diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h index 15dff50312b..6c5c73b955d 100644 --- a/src/corelib/kernel/qproperty_p.h +++ b/src/corelib/kernel/qproperty_p.h @@ -58,7 +58,7 @@ public: inline QPropertyObserver *operator ->(); }; -using PendingBindingObserverList = QVarLengthArray<QBindingObserverPtr>; +using PendingBindingObserverList = QVarLengthArray<QPropertyBindingPrivatePtr>; // Keep all classes related to QProperty in one compilation unit. Performance of this code is crucial and // we need to allow the compiler to inline where it makes sense. @@ -234,21 +234,12 @@ struct CompatPropertySafePoint struct CurrentCompatPropertyThief { Q_DISABLE_COPY_MOVE(CurrentCompatPropertyThief) + QScopedValueRollback<CompatPropertySafePoint *> m_guard; public: CurrentCompatPropertyThief(QBindingStatus *status) - : status(&status->currentCompatProperty) - , stolen(std::exchange(status->currentCompatProperty, nullptr)) + : m_guard(status->currentCompatProperty, nullptr) { } - - ~CurrentCompatPropertyThief() - { - *status = stolen; - } - -private: - CompatPropertySafePoint **status = nullptr; - CompatPropertySafePoint *stolen = nullptr; }; } @@ -386,11 +377,11 @@ public: QPropertyBindingSourceLocation sourceLocation() const { if (!hasCustomVTable()) - return this->location; - QPropertyBindingSourceLocation location; + return location; + QPropertyBindingSourceLocation result; constexpr auto msg = "Custom location"; - location.fileName = msg; - return location; + result.fileName = msg; + return result; } QPropertyBindingError bindingError() const { return m_error; } QMetaType valueMetaType() const { return metaType; } @@ -666,8 +657,10 @@ public: // evaluateBindings() can trash the observers. We need to re-fetch here. if (QPropertyObserverPointer observer = d.firstObserver()) observer.notifyOnlyChangeHandler(this); - for (auto&& bindingObserver: bindingObservers) - bindingObserver.binding()->notifyNonRecursive(); + for (auto&& bindingPtr: bindingObservers) { + auto *binding = static_cast<QPropertyBindingPrivate *>(bindingPtr.get()); + binding->notifyNonRecursive(); + } } } } diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h index aca6d14c968..f07ced20051 100644 --- a/src/corelib/kernel/qpropertyprivate.h +++ b/src/corelib/kernel/qpropertyprivate.h @@ -29,8 +29,8 @@ class QBindingStorage; template<typename Class, typename T, auto Offset, auto Setter, auto Signal, auto Getter> class QObjectCompatProperty; -struct QBindingObserverPtr; -using PendingBindingObserverList = QVarLengthArray<QBindingObserverPtr>; +class QPropertyBindingPrivatePtr; +using PendingBindingObserverList = QVarLengthArray<QPropertyBindingPrivatePtr>; namespace QtPrivate { // QPropertyBindingPrivatePtr operates on a RefCountingMixin solely so that we can inline diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 2f02eef96c2..75cb0af7312 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -15,13 +15,16 @@ #include "qdatastream.h" #include "qendian.h" #include "qfile.h" -#include "qmap.h" #include "qalgorithms.h" #include "qtranslator_p.h" #include "qlocale.h" +#include "qloggingcategory.h" +#include "qdebug.h" #include "qendian.h" #include "qresource.h" +#include <QtCore/private/qduplicatetracker_p.h> + #if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) # define QT_USE_MMAP # include "private/qcore_unix_p.h" @@ -39,6 +42,8 @@ QT_BEGIN_NAMESPACE +static Q_LOGGING_CATEGORY(lcTranslator, "qt.core.qtranslator") + namespace { enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16, Tag_Obsolete1, Tag_SourceText, Tag_Context, Tag_Comment, Tag_Obsolete2 }; @@ -600,7 +605,10 @@ Q_NEVER_INLINE static bool is_readable_file(const QString &name) { const QFileInfo fi(name); - return fi.isReadable() && fi.isFile(); + const bool isReadableFile = fi.isReadable() && fi.isFile(); + qCDebug(lcTranslator) << "Testing file" << name << isReadableFile; + + return isReadableFile; } static QString find_translation(const QLocale & locale, @@ -609,6 +617,9 @@ static QString find_translation(const QLocale & locale, const QString & directory, const QString & suffix) { + qCDebug(lcTranslator).noquote().nospace() << "Searching translation for " + << filename << prefix << locale << suffix + << " in " << directory; QString path; if (QFileInfo(filename).isRelative()) { path = directory; @@ -619,7 +630,7 @@ static QString find_translation(const QLocale & locale, QString realname; realname += path + filename + prefix; // using += in the hope for some reserve capacity - const int realNameBaseSize = realname.size(); + const qsizetype realNameBaseSize = realname.size(); // see http://www.unicode.org/reports/tr35/#LanguageMatching for inspiration @@ -631,34 +642,71 @@ static QString find_translation(const QLocale & locale, // that the Qt resource system is always case-sensitive, even on // Windows (in other words: this codepath is *not* UNIX-only). QStringList languages = locale.uiLanguages(); - for (int i = languages.size()-1; i >= 0; --i) { - QString lang = languages.at(i); + for (auto &localeName : languages) + localeName.replace(u'-', u'_'); + qCDebug(lcTranslator) << "Requested UI languages" << languages; + + QDuplicateTracker<QString> duplicates(languages.size() * 2); + for (const auto &l : std::as_const(languages)) + (void)duplicates.hasSeen(l); + + for (qsizetype i = languages.size() - 1; i >= 0; --i) { + QString language = languages.at(i); + + // Add candidates for each entry where we progressively truncate sections + // from the end, until a matching language tag is found. For compatibility + // reasons (see QTBUG-124898) we add a special case: if we find a + // language_Script_Territory entry (i.e. an entry with two sections), try + // language_Territory as well as language_Script. Use QDuplicateTracker + // so that we don't add any entries as fallbacks that are already in the + // list anyway. + // This is a kludge, and such entries are added at the end of the candidate + // list; from 6.9 on, this is fixed in QLocale::uiLanguages(). + QStringList fallbacks; + const auto addIfNew = [&duplicates, &fallbacks](const QString &fallback) { + if (!duplicates.hasSeen(fallback)) + fallbacks.append(fallback); + }; + + while (true) { + const qsizetype last = language.lastIndexOf(u'_'); + if (last < 0) // no more sections + break; + + const qsizetype first = language.indexOf(u'_'); + // two sections, add fallback without script + if (first != last && language.count(u'_') == 2) { + QString fallback = language.left(first) + language.mid(last); + addIfNew(fallback); + } + QString fallback = language.left(last); + addIfNew(fallback); + + language.truncate(last); + } + for (qsizetype j = fallbacks.size() - 1; j >= 0; --j) + languages.insert(i + 1, fallbacks.at(j)); + } + + qCDebug(lcTranslator) << "Augmented UI languages" << languages; + for (qsizetype i = languages.size() - 1; i >= 0; --i) { + const QString &lang = languages.at(i); QString lowerLang = lang.toLower(); if (lang != lowerLang) languages.insert(i + 1, lowerLang); } for (QString localeName : std::as_const(languages)) { - localeName.replace(u'-', u'_'); - - // try the complete locale name first and progressively truncate from - // the end until a matching language tag is found (with or without suffix) - for (;;) { - realname += localeName + suffixOrDotQM; - if (is_readable_file(realname)) - return realname; - - realname.truncate(realNameBaseSize + localeName.size()); - if (is_readable_file(realname)) - return realname; + // try each locale with and without suffix + realname += localeName + suffixOrDotQM; + if (is_readable_file(realname)) + return realname; - realname.truncate(realNameBaseSize); + realname.truncate(realNameBaseSize + localeName.size()); + if (is_readable_file(realname)) + return realname; - int rightmost = localeName.lastIndexOf(u'_'); - if (rightmost <= 0) - break; // no truncations anymore, break - localeName.truncate(rightmost); - } + realname.truncate(realNameBaseSize); } const int realNameBaseSizeFallbacks = path.size() + filename.size(); diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 221926d218f..931be20e42c 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1016,9 +1016,7 @@ QVariant &QVariant::operator=(const QVariant &variant) /*! \fn void QVariant::swap(QVariant &other) \since 4.8 - - Swaps variant \a other with this variant. This operation is very - fast and never fails. + \memberswap{variant} */ /*! |
