summaryrefslogtreecommitdiffstats
path: root/src/designer/src/lib/shared/qdesigner_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/designer/src/lib/shared/qdesigner_utils.cpp')
-rw-r--r--src/designer/src/lib/shared/qdesigner_utils.cpp299
1 files changed, 158 insertions, 141 deletions
diff --git a/src/designer/src/lib/shared/qdesigner_utils.cpp b/src/designer/src/lib/shared/qdesigner_utils.cpp
index 8ac1c4836..67ff4df2d 100644
--- a/src/designer/src/lib/shared/qdesigner_utils.cpp
+++ b/src/designer/src/lib/shared/qdesigner_utils.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Designer of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qdesigner_utils_p.h"
#include "qdesigner_propertycommand_p.h"
@@ -38,15 +13,20 @@
#include <QtDesigner/taskmenu.h>
#include <QtDesigner/qextensionmanager.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qprocess.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qdebug.h>
#include <QtCore/qqueue.h>
#include <QtCore/qshareddata.h>
+#include <QtCore/qstandardpaths.h>
#include <QtWidgets/qapplication.h>
#include <QtGui/qicon.h>
+#include <QtGui/qpalette.h>
#include <QtGui/qpixmap.h>
#include <QtWidgets/qlistwidget.h>
#include <QtWidgets/qtreewidget.h>
@@ -55,8 +35,27 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
namespace qdesigner_internal
{
+ // ### FIXME Qt 8: Remove (QTBUG-96005)
+ QString legacyDataDirectory()
+ {
+ return QDir::homePath() + u"/.designer"_s;
+ }
+
+ QString dataDirectory()
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
+ return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
+ + u'/' + QCoreApplication::organizationName() + u"/Designer"_s;
+#else
+ return legacyDataDirectory();
+#endif
+ }
+
+
QDESIGNER_SHARED_EXPORT void designerWarning(const QString &message)
{
qWarning("Designer: %s", qPrintable(message));
@@ -159,18 +158,19 @@ namespace qdesigner_internal
{
return QCoreApplication::translate("DesignerMetaEnum",
"%1 is not a valid enumeration value of '%2'.")
- .arg(value).arg(name());
+ .arg(value).arg(enumName());
}
QString DesignerMetaEnum::messageParseFailed(const QString &s) const
{
return QCoreApplication::translate("DesignerMetaEnum",
"'%1' could not be converted to an enumeration value of type '%2'.")
- .arg(s, name());
+ .arg(s, enumName());
}
// -------------- DesignerMetaFlags
- DesignerMetaFlags::DesignerMetaFlags(const QString &name, const QString &scope, const QString &separator) :
- MetaEnum<uint>(name, scope, separator)
+ DesignerMetaFlags::DesignerMetaFlags(const QString &enumName, const QString &scope,
+ const QString &separator) :
+ MetaEnum<uint>(enumName, scope, separator)
{
}
@@ -178,18 +178,18 @@ namespace qdesigner_internal
{
QStringList rc;
const uint v = static_cast<uint>(ivalue);
- for (auto it = keyToValueMap().constBegin(), cend = keyToValueMap().constEnd(); it != cend; ++it ) {
- const uint itemValue = it.value();
+ for (auto it = keyToValueMap().begin(), end = keyToValueMap().end(); it != end; ++it) {
+ const uint itemValue = it->second;
// Check for equality first as flag values can be 0 or -1, too. Takes preference over a bitwise flag
if (v == itemValue) {
rc.clear();
- rc.push_back(it.key());
+ rc.push_back(it->first);
return rc;
}
// Do not add 0-flags (None-flags)
if (itemValue)
if ((v & itemValue) == itemValue)
- rc.push_back(it.key());
+ rc.push_back(it->first);
}
return rc;
}
@@ -201,16 +201,14 @@ namespace qdesigner_internal
if (flagIds.isEmpty())
return QString();
- const QChar delimiter = QLatin1Char('|');
QString rc;
- const QStringList::const_iterator cend = flagIds.constEnd();
- for (QStringList::const_iterator it = flagIds.constBegin(); it != cend; ++it) {
+ for (const auto &id : flagIds) {
if (!rc.isEmpty())
- rc += delimiter ;
+ rc += u'|';
if (sm == FullyQualified)
- appendQualifiedName(*it, rc);
+ appendQualifiedName(id, rc);
else
- rc += *it;
+ rc += id;
}
return rc;
}
@@ -225,9 +223,9 @@ namespace qdesigner_internal
}
uint flags = 0;
bool valueOk = true;
- QStringList keys = s.split(QString(QLatin1Char('|')));
- for (auto it = keys.constBegin(), cend = keys.constEnd(); it != cend; ++it) {
- const uint flagValue = keyToValue(*it, &valueOk);
+ const auto keys = QStringView{s}.split(u'|');
+ for (const auto &key : keys) {
+ const uint flagValue = keyToValue(key, &valueOk);
if (!valueOk) {
flags = 0;
break;
@@ -243,7 +241,7 @@ namespace qdesigner_internal
{
return QCoreApplication::translate("DesignerMetaFlags",
"'%1' could not be converted to a flag value of type '%2'.")
- .arg(s, name());
+ .arg(s, enumName());
}
// ---------- PropertySheetEnumValue
@@ -276,12 +274,7 @@ namespace qdesigner_internal
{
if (const QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
return lang->isLanguageResource(path) ? LanguageResourcePixmap : FilePixmap;
- return path.startsWith(QLatin1Char(':')) ? ResourcePixmap : FilePixmap;
- }
-
- int PropertySheetPixmapValue::compare(const PropertySheetPixmapValue &other) const
- {
- return m_path.compare(other.m_path);
+ return path.startsWith(u':') ? ResourcePixmap : FilePixmap;
}
QString PropertySheetPixmapValue::path() const
@@ -302,6 +295,7 @@ namespace qdesigner_internal
public:
PropertySheetIconValue::ModeStateToPixmapMap m_paths;
QString m_theme;
+ int m_themeEnum = -1;
};
PropertySheetIconValue::PropertySheetIconValue(const PropertySheetPixmapValue &pixmap) :
@@ -317,52 +311,37 @@ namespace qdesigner_internal
PropertySheetIconValue::~PropertySheetIconValue() = default;
- PropertySheetIconValue::PropertySheetIconValue(const PropertySheetIconValue &rhs) :
- m_data(rhs.m_data)
- {
- }
+ PropertySheetIconValue::PropertySheetIconValue(const PropertySheetIconValue &rhs) noexcept = default;
+ PropertySheetIconValue &PropertySheetIconValue::operator=(const PropertySheetIconValue &rhs) = default;
- PropertySheetIconValue &PropertySheetIconValue::operator=(const PropertySheetIconValue &rhs)
- {
- if (this != &rhs)
- m_data.operator=(rhs.m_data);
- return *this;
- }
+ PropertySheetIconValue::PropertySheetIconValue(PropertySheetIconValue &&) noexcept = default;
+ PropertySheetIconValue &PropertySheetIconValue::operator=(PropertySheetIconValue &&) noexcept = default;
+
+} // namespace qdesigner_internal
+
+namespace qdesigner_internal {
- bool PropertySheetIconValue::equals(const PropertySheetIconValue &rhs) const
+ size_t qHash(const PropertySheetIconValue &p, size_t seed) noexcept
{
- return m_data->m_theme == rhs.m_data->m_theme && m_data->m_paths == rhs.m_data->m_paths;
+ // qHash for paths making use of the existing QPair hash functions.
+ const auto *d = p.m_data.constData();
+ return qHashMulti(seed, d->m_paths, d->m_themeEnum, d->m_theme);
}
- bool PropertySheetIconValue::operator<(const PropertySheetIconValue &other) const
+ bool comparesEqual(const PropertySheetIconValue &lhs,
+ const PropertySheetIconValue &rhs) noexcept
{
- if (const int themeCmp = m_data->m_theme.compare(other.m_data->m_theme))
- return themeCmp < 0;
- auto itThis = m_data->m_paths.cbegin();
- auto itThisEnd = m_data->m_paths.cend();
- auto itOther = other.m_data->m_paths.cbegin();
- auto itOtherEnd = other.m_data->m_paths.cend();
- while (itThis != itThisEnd && itOther != itOtherEnd) {
- const ModeStateKey thisPair = itThis.key();
- const ModeStateKey otherPair = itOther.key();
- if (thisPair < otherPair)
- return true;
- if (otherPair < thisPair)
- return false;
- const int crc = itThis.value().compare(itOther.value());
- if (crc < 0)
- return true;
- if (crc > 0)
- return false;
- ++itThis;
- ++itOther;
- }
- return itOther != itOtherEnd;
+ const auto *lhsd = lhs.m_data.constData();
+ const auto *rhsd = rhs.m_data.constData();
+ return lhsd == rhsd
+ || (lhsd->m_themeEnum == rhsd->m_themeEnum
+ && lhsd->m_theme == rhsd->m_theme && lhsd->m_paths == rhsd->m_paths);
}
bool PropertySheetIconValue::isEmpty() const
{
- return m_data->m_theme.isEmpty() && m_data->m_paths.isEmpty();
+ return m_data->m_themeEnum == -1 && m_data->m_theme.isEmpty()
+ && m_data->m_paths.isEmpty();
}
QString PropertySheetIconValue::theme() const
@@ -375,15 +354,25 @@ namespace qdesigner_internal
m_data->m_theme = t;
}
+ int PropertySheetIconValue::themeEnum() const
+ {
+ return m_data->m_themeEnum;
+ }
+
+ void PropertySheetIconValue::setThemeEnum(int e)
+ {
+ m_data->m_themeEnum = e;
+ }
+
PropertySheetPixmapValue PropertySheetIconValue::pixmap(QIcon::Mode mode, QIcon::State state) const
{
- const ModeStateKey pair = qMakePair(mode, state);
+ const ModeStateKey pair{mode, state};
return m_data->m_paths.value(pair);
}
void PropertySheetIconValue::setPixmap(QIcon::Mode mode, QIcon::State state, const PropertySheetPixmapValue &pixmap)
{
- const ModeStateKey pair = qMakePair(mode, state);
+ const ModeStateKey pair{mode, state};
if (pixmap.path().isEmpty())
m_data->m_paths.remove(pair);
else
@@ -392,7 +381,7 @@ namespace qdesigner_internal
QPixmap DesignerPixmapCache::pixmap(const PropertySheetPixmapValue &value) const
{
- QMap<PropertySheetPixmapValue, QPixmap>::const_iterator it = m_cache.constFind(value);
+ const auto it = m_cache.constFind(value);
if (it != m_cache.constEnd())
return it.value();
@@ -418,6 +407,11 @@ namespace qdesigner_internal
return it.value();
// Match on the theme first if it is available.
+ if (value.themeEnum() != -1) {
+ const QIcon themeIcon = QIcon::fromTheme(static_cast<QIcon::ThemeIcon>(value.themeEnum()));
+ m_cache.insert(value, themeIcon);
+ return themeIcon;
+ }
if (!value.theme().isEmpty()) {
const QString theme = value.theme();
if (QIcon::hasThemeIcon(theme)) {
@@ -452,14 +446,6 @@ namespace qdesigner_internal
PropertySheetTranslatableData::PropertySheetTranslatableData(bool translatable, const QString &disambiguation, const QString &comment) :
m_translatable(translatable), m_disambiguation(disambiguation), m_comment(comment) { }
- bool PropertySheetTranslatableData::equals(const PropertySheetTranslatableData &rhs) const
- {
- return m_translatable == rhs.m_translatable
- && m_disambiguation == rhs.m_disambiguation
- && m_comment == rhs.m_comment
- && m_id == rhs.m_id;
- }
-
PropertySheetStringValue::PropertySheetStringValue(const QString &value,
bool translatable, const QString &disambiguation, const QString &comment) :
PropertySheetTranslatableData(translatable, disambiguation, comment), m_value(value) {}
@@ -474,11 +460,6 @@ namespace qdesigner_internal
m_value = value;
}
- bool PropertySheetStringValue::equals(const PropertySheetStringValue &rhs) const
- {
- return m_value == rhs.m_value && PropertySheetTranslatableData::equals(rhs);
- }
-
PropertySheetStringListValue::PropertySheetStringListValue(const QStringList &value,
bool translatable,
const QString &disambiguation,
@@ -497,11 +478,6 @@ namespace qdesigner_internal
m_value = value;
}
- bool PropertySheetStringListValue::equals(const PropertySheetStringListValue &rhs) const
- {
- return m_value == rhs.m_value && PropertySheetTranslatableData::equals(rhs);
- }
-
QStringList m_value;
@@ -542,12 +518,6 @@ namespace qdesigner_internal
return m_standardKey != QKeySequence::UnknownKey;
}
- bool PropertySheetKeySequenceValue::equals(const PropertySheetKeySequenceValue &rhs) const
- {
- return m_value == rhs.m_value && m_standardKey == rhs.m_standardKey
- && PropertySheetTranslatableData::equals(rhs);
- }
-
/* IconSubPropertyMask: Assign each icon sub-property (pixmaps for the
* various states/modes and the theme) a flag bit (see QFont) so that they
* can be handled individually when assigning property values to
@@ -564,7 +534,8 @@ namespace qdesigner_internal
ActiveOnIconMask = 0x20,
SelectedOffIconMask = 0x40,
SelectedOnIconMask = 0x80,
- ThemeIconMask = 0x10000
+ ThemeIconMask = 0x10000,
+ ThemeEnumIconMask = 0x20000
};
static inline uint iconStateToSubPropertyFlag(QIcon::Mode mode, QIcon::State state)
@@ -582,28 +553,28 @@ namespace qdesigner_internal
return state == QIcon::On ? NormalOnIconMask : NormalOffIconMask;
}
- static inline QPair<QIcon::Mode, QIcon::State> subPropertyFlagToIconModeState(unsigned flag)
+ static inline std::pair<QIcon::Mode, QIcon::State> subPropertyFlagToIconModeState(unsigned flag)
{
switch (flag) {
case NormalOnIconMask:
- return qMakePair(QIcon::Normal, QIcon::On);
+ return {QIcon::Normal, QIcon::On};
case DisabledOffIconMask:
- return qMakePair(QIcon::Disabled, QIcon::Off);
+ return {QIcon::Disabled, QIcon::Off};
case DisabledOnIconMask:
- return qMakePair(QIcon::Disabled, QIcon::On);
+ return {QIcon::Disabled, QIcon::On};
case ActiveOffIconMask:
- return qMakePair(QIcon::Active, QIcon::Off);
+ return {QIcon::Active, QIcon::Off};
case ActiveOnIconMask:
- return qMakePair(QIcon::Active, QIcon::On);
+ return {QIcon::Active, QIcon::On};
case SelectedOffIconMask:
- return qMakePair(QIcon::Selected, QIcon::Off);
+ return {QIcon::Selected, QIcon::Off};
case SelectedOnIconMask:
- return qMakePair(QIcon::Selected, QIcon::On);
+ return {QIcon::Selected, QIcon::On};
case NormalOffIconMask:
default:
break;
}
- return qMakePair(QIcon::Normal, QIcon::Off);
+ return {QIcon::Normal, QIcon::Off};
}
uint PropertySheetIconValue::mask() const
@@ -613,6 +584,8 @@ namespace qdesigner_internal
flags |= iconStateToSubPropertyFlag(it.key().first, it.key().second);
if (!m_data->m_theme.isEmpty())
flags |= ThemeIconMask;
+ if (m_data->m_themeEnum != -1)
+ flags |= ThemeEnumIconMask;
return flags;
}
@@ -622,13 +595,16 @@ namespace qdesigner_internal
for (int i = 0; i < 8; i++) {
const uint flag = 1 << i;
if (diffMask & flag) { // if state is set in both icons, compare the values
- const QPair<QIcon::Mode, QIcon::State> state = subPropertyFlagToIconModeState(flag);
+ const auto state = subPropertyFlagToIconModeState(flag);
if (pixmap(state.first, state.second) == other.pixmap(state.first, state.second))
diffMask &= ~flag;
}
}
if ((diffMask & ThemeIconMask) && theme() == other.theme())
diffMask &= ~ThemeIconMask;
+ if ((diffMask & ThemeEnumIconMask) && themeEnum() == other.themeEnum())
+ diffMask &= ~ThemeEnumIconMask;
+
return diffMask;
}
@@ -643,6 +619,7 @@ namespace qdesigner_internal
{
PropertySheetIconValue rc(*this);
rc.m_data->m_theme.clear();
+ rc.m_data->m_themeEnum = -1;
return rc;
}
@@ -657,6 +634,8 @@ namespace qdesigner_internal
}
if (mask & ThemeIconMask)
setTheme(other.theme());
+ if (mask & ThemeEnumIconMask)
+ setThemeEnum(other.themeEnum());
}
const PropertySheetIconValue::ModeStateToPixmapMap &PropertySheetIconValue::paths() const
@@ -664,17 +643,24 @@ namespace qdesigner_internal
return m_data->m_paths;
}
- QDESIGNER_SHARED_EXPORT QDebug operator<<(QDebug d, const PropertySheetIconValue &p)
+ QDESIGNER_SHARED_EXPORT QDebug operator<<(QDebug debug, const PropertySheetIconValue &p)
{
- QDebug nospace = d.nospace();
- nospace << "PropertySheetIconValue theme='" << p.theme() << "' ";
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug.noquote();
+ debug << "PropertySheetIconValue(mask=0x" << Qt::hex << p.mask() << Qt::dec << ", ";
+ if (p.themeEnum() != -1)
+ debug << "theme=" << p.themeEnum() << ", ";
+ if (!p.theme().isEmpty())
+ debug << "XDG theme=\"" << p.theme() << "\", ";
const PropertySheetIconValue::ModeStateToPixmapMap &paths = p.paths();
- for (auto it = paths.constBegin(), cend = paths.constEnd(); it != cend; ++it)
- nospace << " mode=" << it.key().first << ",state=" << it.key().second
- << ",'" << it.value().path() << '\'';
- nospace << " mask=0x" << QString::number(p.mask(), 16);
- return d;
+ for (auto it = paths.constBegin(), cend = paths.constEnd(); it != cend; ++it) {
+ debug << " mode=" << it.key().first << ",state=" << it.key().second
+ << ", \"" << it.value().path() << '"';
+ }
+ debug << ')';
+ return debug;
}
QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand *createTextPropertyCommand(const QString &propertyName, const QString &text, QObject *object, QDesignerFormWindowInterface *fw)
@@ -701,8 +687,8 @@ namespace qdesigner_internal
}
}
if (!action) {
- if (const QDesignerTaskMenuExtension *taskMenu = qobject_cast<QDesignerTaskMenuExtension *>(
- core->extensionManager()->extension(managedWidget, QStringLiteral("QDesignerInternalTaskMenuExtension")))) {
+ if (const auto *taskMenu = qobject_cast<QDesignerTaskMenuExtension *>(
+ core->extensionManager()->extension(managedWidget, u"QDesignerInternalTaskMenuExtension"_s))) {
action = taskMenu->preferredEditAction();
if (!action) {
const auto actions = taskMenu->taskActions();
@@ -719,12 +705,25 @@ namespace qdesigner_internal
{
QProcess uic;
QStringList arguments;
- QString binary = QLibraryInfo::path(QLibraryInfo::BinariesPath) + QStringLiteral("/uic");
+ static constexpr auto uicBinary =
+ QOperatingSystemVersion::currentType() != QOperatingSystemVersion::Windows
+ ? "/uic"_L1 : "/uic.exe"_L1;
+ QString binary = QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath) + uicBinary;
+ // In a PySide6 installation, there is no libexec directory; uic.exe is
+ // in the main wheel directory next to designer.exe.
+ if (!QFileInfo::exists(binary))
+ binary = QCoreApplication::applicationDirPath() + uicBinary;
+ if (!QFileInfo::exists(binary)) {
+ errorMessage = QApplication::translate("Designer", "%1 does not exist.").
+ arg(QDir::toNativeSeparators(binary));
+ return false;
+ }
+
switch (language) {
case UicLanguage::Cpp:
break;
case UicLanguage::Python:
- arguments << QLatin1String("-g") << QLatin1String("python");
+ arguments << u"-g"_s << u"python"_s;
break;
}
arguments << fileName;
@@ -754,14 +753,14 @@ namespace qdesigner_internal
Q_ASSERT(qname.isEmpty() == false);
- if (qname.count() > 1 && qname.at(1).isUpper()) {
+ if (qname.size() > 1 && qname.at(1).isUpper()) {
const QChar first = qname.at(0);
- if (first == QLatin1Char('Q') || first == QLatin1Char('K'))
+ if (first == u'Q' || first == u'K')
qname.remove(0, 1);
}
- const int len = qname.count();
- for (int i = 0; i < len && qname.at(i).isUpper(); i++)
+ const qsizetype len = qname.size();
+ for (qsizetype i = 0; i < len && qname.at(i).isUpper(); ++i)
qname[i] = qname.at(i).toLower();
return qname;
@@ -782,6 +781,24 @@ namespace qdesigner_internal
m_widget->setUpdatesEnabled(true);
}
+// from qpalette.cpp
+quint64 paletteResolveMask(QPalette::ColorGroup colorGroup,
+ QPalette::ColorRole colorRole)
+{
+ if (colorRole == QPalette::Accent)
+ colorRole = QPalette::NoRole; // See qtbase/17c589df94a2245ee92d45839c2cba73566d7310
+ const auto offset = quint64(QPalette::NColorRoles - 1) * quint64(colorGroup);
+ const auto bitPos = quint64(colorRole) + offset;
+ return 1ull << bitPos;
+}
+
+quint64 paletteResolveMask(QPalette::ColorRole colorRole)
+{
+ return paletteResolveMask(QPalette::Active, colorRole)
+ | paletteResolveMask(QPalette::Inactive, colorRole)
+ | paletteResolveMask(QPalette::Disabled, colorRole);
+}
+
} // namespace qdesigner_internal
QT_END_NAMESPACE