diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-02-05 08:24:15 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-03-18 11:13:46 +0000 |
commit | 90e4e5240705901bb4a5ca9c9e4265d98896cd1a (patch) | |
tree | 72175fa7a705fe7cf4449ff3d2c0759f24d43066 | |
parent | 8576275bb2ea3b80c1f3b2ca63723042209083f7 (diff) |
Qt Designer: Save/restore theme icon values
Use the existing "theme" attribute to store the theme enum name (fully
qualified to be able to distinguish it from an old XDG/file name
theme).
Task-number: QTBUG-121823
Change-Id: I7db33548b20caa86bef5103f9234a277fc21b5b1
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
(cherry picked from commit ac3215b1bb5bfe11095bb4721fea3bf501192a97)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/designer/src/components/formeditor/qdesigner_resource.cpp | 16 | ||||
-rw-r--r-- | src/designer/src/lib/shared/qdesigner_utils.cpp | 36 | ||||
-rw-r--r-- | src/designer/src/lib/shared/qdesigner_utils_p.h | 3 | ||||
-rw-r--r-- | src/designer/src/lib/uilib/resourcebuilder.cpp | 98 | ||||
-rw-r--r-- | src/designer/src/lib/uilib/resourcebuilder_p.h | 5 |
5 files changed, 151 insertions, 7 deletions
diff --git a/src/designer/src/components/formeditor/qdesigner_resource.cpp b/src/designer/src/components/formeditor/qdesigner_resource.cpp index 4c2c6cace..64cff222e 100644 --- a/src/designer/src/components/formeditor/qdesigner_resource.cpp +++ b/src/designer/src/components/formeditor/qdesigner_resource.cpp @@ -5,6 +5,7 @@ #include "formwindow.h" #include "dynamicpropertysheet.h" #include "qdesigner_tabwidget_p.h" +#include "iconloader_p.h" #include "qdesigner_toolbox_p.h" #include "qdesigner_stackedbox_p.h" #include "qdesigner_toolbar_p.h" @@ -173,8 +174,15 @@ QVariant QDesignerResourceBuilder::loadResource(const QDir &workingDirectory, co PropertySheetIconValue icon; DomResourceIcon *di = property->elementIconSet(); const bool hasTheme = di->hasAttributeTheme(); - if (hasTheme) - icon.setTheme(di->attributeTheme()); + if (hasTheme) { + const QString &theme = di->attributeTheme(); + const qsizetype themeEnum = theme.startsWith("QIcon::"_L1) + ? QDesignerResourceBuilder::themeIconIndex(theme) : -1; + if (themeEnum != -1) + icon.setThemeEnum(themeEnum); + else + icon.setTheme(theme); + } if (const int flags = iconStateFlags(di)) { // new, post 4.4 format if (flags & NormalOff) setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->elementNormalOff()->text(), icon, m_lang); @@ -251,7 +259,9 @@ DomProperty *QDesignerResourceBuilder::saveResource(const QDir &workingDirectory if (value.canConvert<PropertySheetIconValue>()) { const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value); const auto &pixmaps = icon.paths(); - const QString theme = icon.theme(); + const int themeEnum = icon.themeEnum(); + const QString theme = themeEnum != -1 + ? QDesignerResourceBuilder::fullyQualifiedThemeIconName(themeEnum) : icon.theme(); if (!pixmaps.isEmpty() || !theme.isEmpty()) { DomResourceIcon *ri = new DomResourceIcon; if (!theme.isEmpty()) diff --git a/src/designer/src/lib/shared/qdesigner_utils.cpp b/src/designer/src/lib/shared/qdesigner_utils.cpp index d4b42ffb7..6095803ba 100644 --- a/src/designer/src/lib/shared/qdesigner_utils.cpp +++ b/src/designer/src/lib/shared/qdesigner_utils.cpp @@ -292,6 +292,7 @@ namespace qdesigner_internal public: PropertySheetIconValue::ModeStateToPixmapMap m_paths; QString m_theme; + int m_themeEnum = -1; }; PropertySheetIconValue::PropertySheetIconValue(const PropertySheetPixmapValue &pixmap) : @@ -323,6 +324,7 @@ namespace qdesigner_internal { const auto *d = p.m_data.constData(); return qHashMulti(qHashRange(d->m_paths.constKeyValueBegin(), d->m_paths.constKeyValueEnd(), seed), + d->m_themeEnum, d->m_theme); } @@ -332,12 +334,14 @@ namespace qdesigner_internal { const auto *lhsd = lhs.m_data.constData(); const auto *rhsd = rhs.m_data.constData(); return lhsd == rhsd - || (lhsd->m_theme == rhsd->m_theme && lhsd->m_paths == rhsd->m_paths); + || (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 @@ -350,6 +354,16 @@ 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{mode, state}; @@ -393,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)) { @@ -515,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) @@ -564,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; } @@ -580,6 +602,9 @@ namespace qdesigner_internal { } if ((diffMask & ThemeIconMask) && theme() == other.theme()) diffMask &= ~ThemeIconMask; + if ((diffMask & ThemeEnumIconMask) && themeEnum() == other.themeEnum()) + diffMask &= ~ThemeEnumIconMask; + return diffMask; } @@ -594,6 +619,7 @@ namespace qdesigner_internal { { PropertySheetIconValue rc(*this); rc.m_data->m_theme.clear(); + rc.m_data->m_themeEnum = -1; return rc; } @@ -608,6 +634,8 @@ namespace qdesigner_internal { } if (mask & ThemeIconMask) setTheme(other.theme()); + if (mask & ThemeEnumIconMask) + setThemeEnum(other.themeEnum()); } const PropertySheetIconValue::ModeStateToPixmapMap &PropertySheetIconValue::paths() const @@ -621,6 +649,8 @@ namespace qdesigner_internal { 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() << "\", "; diff --git a/src/designer/src/lib/shared/qdesigner_utils_p.h b/src/designer/src/lib/shared/qdesigner_utils_p.h index 3199d93b9..223a12337 100644 --- a/src/designer/src/lib/shared/qdesigner_utils_p.h +++ b/src/designer/src/lib/shared/qdesigner_utils_p.h @@ -255,6 +255,9 @@ class QDESIGNER_SHARED_EXPORT PropertySheetIconValue QString theme() const; void setTheme(const QString &); + int themeEnum() const; + void setThemeEnum(int e); + PropertySheetPixmapValue pixmap(QIcon::Mode mode, QIcon::State state) const; void setPixmap(QIcon::Mode mode, QIcon::State state, const PropertySheetPixmapValue &path); // passing the empty path resets the pixmap diff --git a/src/designer/src/lib/uilib/resourcebuilder.cpp b/src/designer/src/lib/uilib/resourcebuilder.cpp index db341c3b8..5afd25439 100644 --- a/src/designer/src/lib/uilib/resourcebuilder.cpp +++ b/src/designer/src/lib/uilib/resourcebuilder.cpp @@ -59,11 +59,17 @@ QVariant QResourceBuilder::loadResource(const QDir &workingDirectory, const DomP const DomResourceIcon *dpi = property->elementIconSet(); if (!dpi->attributeTheme().isEmpty()) { const QString theme = dpi->attributeTheme(); + const qsizetype themeEnum = theme.at(0).isUpper() + ? themeIconNames().indexOf(theme) : -1; + if (themeEnum != -1) { + const auto themeEnumE = static_cast<QIcon::ThemeIcon>(themeEnum); + return QVariant::fromValue(QIcon::fromTheme(themeEnumE)); + } const bool known = QIcon::hasThemeIcon(theme); if (themeDebug) qDebug("Theme %s known %d", qPrintable(theme), known); if (known) - return QVariant::fromValue(QIcon::fromTheme(dpi->attributeTheme())); + return QVariant::fromValue(QIcon::fromTheme(theme)); } // non-empty theme if (const int flags = iconStateFlags(dpi)) { // new, post 4.4 format QIcon icon; @@ -132,6 +138,96 @@ bool QResourceBuilder::isResourceType(const QVariant &value) const return false; } +const QStringList &QResourceBuilder::themeIconNames() +{ + static const QStringList result = { + "AddressBookNew"_L1, "ApplicationExit"_L1, "AppointmentNew"_L1, + "CallStart"_L1, "CallStop"_L1, "ContactNew"_L1, + "DocumentNew"_L1, "DocumentOpen"_L1, "DocumentOpenRecent"_L1, + "DocumentPageSetup"_L1, "DocumentPrint"_L1, "DocumentPrintPreview"_L1, + "DocumentProperties"_L1, "DocumentRevert"_L1, "DocumentSave"_L1, + "DocumentSaveAs"_L1, "DocumentSend"_L1, + "EditClear"_L1, "EditCopy"_L1, "EditCut"_L1, "EditDelete"_L1, + "EditFind"_L1, "EditPaste"_L1, + "EditRedo"_L1, "EditSelectAll"_L1, "EditUndo"_L1, + "FolderNew"_L1, + "FormatIndentLess"_L1, "FormatIndentMore"_L1, + "FormatJustifyCenter"_L1, "FormatJustifyFill"_L1, + "FormatJustifyLeft"_L1, "FormatJustifyRight"_L1, + "FormatTextDirectionLtr"_L1, "FormatTextDirectionRtl"_L1, + "FormatTextBold"_L1, "FormatTextItalic"_L1, + "FormatTextUnderline"_L1, "FormatTextStrikethrough"_L1, + "GoDown"_L1, "GoHome"_L1, "GoNext"_L1, "GoPrevious"_L1, "GoUp"_L1, + "HelpAbout"_L1, "HelpFaq"_L1, + "InsertImage"_L1, "InsertLink"_L1, "InsertText"_L1, + "ListAdd"_L1, "ListRemove"_L1, + "MailForward"_L1, "MailMarkImportant"_L1, "MailMarkRead"_L1, "MailMarkUnread"_L1, + "MailMessageNew"_L1, "MailReplyAll"_L1, "MailReplySender"_L1, + "MailSend"_L1, + "MediaEject"_L1, "MediaPlaybackPause"_L1, "MediaPlaybackStart"_L1, + "MediaPlaybackStop"_L1, "MediaRecord"_L1, "MediaSeekBackward"_L1, + "MediaSeekForward"_L1, "MediaSkipBackward"_L1, + "MediaSkipForward"_L1, + "ObjectRotateLeft"_L1, "ObjectRotateRight"_L1, + "ProcessStop"_L1, + "SystemLockScreen"_L1, "SystemLogOut"_L1, + "SystemSearch"_L1, "SystemReboot"_L1, "SystemShutdown"_L1, + "ToolsCheckSpelling"_L1, + "ViewFullscreen"_L1, "ViewRefresh"_L1, "ViewRestore"_L1, + "WindowClose"_L1, "WindowNew"_L1, + "ZoomFitBest"_L1, "ZoomIn"_L1, "ZoomOut"_L1, + "AudioCard"_L1, "AudioInputMicrophone"_L1, + "Battery"_L1, + "CameraPhoto"_L1, "CameraVideo"_L1, "CameraWeb"_L1, + "Computer"_L1, "DriveHarddisk"_L1, "DriveOptical"_L1, + "InputGaming"_L1, "InputKeyboard"_L1, "InputMouse"_L1, + "InputTablet"_L1, + "MediaFlash"_L1, "MediaOptical"_L1, + "MediaTape"_L1, + "MultimediaPlayer"_L1, + "NetworkWired"_L1, "NetworkWireless"_L1, + "Phone"_L1, "Printer"_L1, "Scanner"_L1, "VideoDisplay"_L1, + "AppointmentMissed"_L1, "AppointmentSoon"_L1, + "AudioVolumeHigh"_L1, "AudioVolumeLow"_L1, "AudioVolumeMedium"_L1, + "AudioVolumeMuted"_L1, + "BatteryCaution"_L1, "BatteryLow"_L1, + "DialogError"_L1, "DialogInformation"_L1, "DialogPassword"_L1, + "DialogQuestion"_L1, "DialogWarning"_L1, + "FolderDragAccept"_L1, "FolderOpen"_L1, "FolderVisiting"_L1, + "ImageLoading"_L1, "ImageMissing"_L1, + "MailAttachment"_L1, "MailUnread"_L1, "MailRead"_L1, + "MailReplied"_L1, + "MediaPlaylistRepeat"_L1, "MediaPlaylistShuffle"_L1, + "NetworkOffline"_L1, + "PrinterPrinting"_L1, + "SecurityHigh"_L1, "SecurityLow"_L1, + "SoftwareUpdateAvailable"_L1, "SoftwareUpdateUrgent"_L1, + "SyncError"_L1, "SyncSynchronizing"_L1, + "UserAvailable"_L1, + "UserOffline"_L1, + "WeatherClear"_L1, "WeatherClearNight"_L1, "WeatherFewClouds"_L1, + "WeatherFewCloudsNight"_L1, "WeatherFog"_L1, "WeatherShowers"_L1, + "WeatherSnow"_L1, "WeatherStorm"_L1 + }; + + return result; +}; + +int QResourceBuilder::themeIconIndex(QStringView name) +{ + const auto lastQual = name.lastIndexOf("::"_L1); + const auto result = lastQual != -1 + ? themeIconNames().indexOf(name.sliced(lastQual + 2)) + : themeIconNames().indexOf(name); + return int(result); +} + +QString QResourceBuilder::fullyQualifiedThemeIconName(int i) +{ + return i >= 0 && i < themeIconNames().size() + ? "QIcon::ThemeIcon::"_L1 + themeIconNames().at(i) : QString{}; +} + #ifdef QFORMINTERNAL_NAMESPACE } // namespace QFormInternal #endif diff --git a/src/designer/src/lib/uilib/resourcebuilder_p.h b/src/designer/src/lib/uilib/resourcebuilder_p.h index a377cddce..721a92541 100644 --- a/src/designer/src/lib/uilib/resourcebuilder_p.h +++ b/src/designer/src/lib/uilib/resourcebuilder_p.h @@ -43,6 +43,11 @@ public: QResourceBuilder(); virtual ~QResourceBuilder(); + // Icon names matching QIcon::ThemeIcon + static const QStringList &themeIconNames(); + static int themeIconIndex(QStringView name); + static QString fullyQualifiedThemeIconName(int i); + virtual QVariant loadResource(const QDir &workingDirectory, const DomProperty *property) const; virtual QVariant toNativeValue(const QVariant &value) const; |