summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qbasictimer.cpp5
-rw-r--r--src/corelib/kernel/qdeadlinetimer.cpp3
-rw-r--r--src/corelib/kernel/qmetaobject.cpp4
-rw-r--r--src/corelib/kernel/qpointer.qdoc4
-rw-r--r--src/corelib/kernel/qproperty.cpp23
-rw-r--r--src/corelib/kernel/qproperty_p.h29
-rw-r--r--src/corelib/kernel/qpropertyprivate.h4
-rw-r--r--src/corelib/kernel/qtranslator.cpp94
-rw-r--r--src/corelib/kernel/qvariant.cpp4
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}
*/
/*!