diff --git a/src/plugins/extensionmanager/extensionmanager.qrc b/src/plugins/extensionmanager/extensionmanager.qrc index b552aaf7b59..c156db17e7d 100644 --- a/src/plugins/extensionmanager/extensionmanager.qrc +++ b/src/plugins/extensionmanager/extensionmanager.qrc @@ -1,5 +1,7 @@ + images/checkmark.png + images/checkmark@2x.png images/download.png images/download@2x.png images/extensionbig.png diff --git a/src/plugins/extensionmanager/extensionsbrowser.cpp b/src/plugins/extensionmanager/extensionsbrowser.cpp index 60d9be94df0..99c13fabdba 100644 --- a/src/plugins/extensionmanager/extensionsbrowser.cpp +++ b/src/plugins/extensionmanager/extensionsbrowser.cpp @@ -59,6 +59,19 @@ constexpr int gapSize = HGapL; constexpr int itemWidth = 330; constexpr int cellWidth = itemWidth + gapSize; +static QString extensionStateDisplayString(ExtensionState state) +{ + switch (state) { + case InstalledEnabled: + return Tr::tr("Loaded"); + case InstalledDisabled: + return Tr::tr("Installed"); + default: + return {}; + } + return {}; +} + class ExtensionItemDelegate : public QItemDelegate { public: @@ -71,6 +84,8 @@ public: constexpr static TextFormat vendorTF {Theme::Token_Text_Muted, UiElement::UiElementLabelSmall, Qt::AlignVCenter | Qt::TextDontClip}; + constexpr static TextFormat stateTF + {vendorTF.themeColor, UiElement::UiElementCaption, vendorTF.drawTextFlags}; constexpr static TextFormat tagsTF {Theme::Token_Text_Default, UiElement::UiElementCaption}; @@ -84,9 +99,9 @@ public: { // +---------------+-------+---------------+----------------------------------------------------------------------+---------------+---------+ // | | | | (ExPaddingGapL) | | | - // | | | +-------------------------------------------------------------+--------+ | | - // | | | | || | | - // | | | +-------------------------------------------------------------+--------+ | | + // | | | +-----------------------------+---------+--------+---------+-----------+ | | + // | | | | |(HGapXxs)||(HGapXxs)|| | | + // | | | +-----------------------------+---------+--------+---------+-----------+ | | // | | | | (VGapXxs) | | | // | | | +--------+--------+--------------+--------+--------+---------+---------+ | | // |(ExPaddingGapL)| |(ExPaddingGapL)||(HGapXs)|(h16)|(HGapXs)||(HGapXxs)||(ExPaddingGapL)|(gapSize)| @@ -116,6 +131,19 @@ public: const QRect itemNameR(x, y, middleColumnW, itemNameTF.lineHeight()); const QString itemName = index.data().toString(); + const QSize checkmarkS(12, 12); + const QRect checkmarkR(x + middleColumnW - checkmarkS.width(), y, + checkmarkS.width(), checkmarkS.height()); + const ExtensionState state = index.data(RoleExtensionState).value(); + const QString stateString = extensionStateDisplayString(state); + const bool showState = (state == InstalledEnabled || state == InstalledDisabled) + && !stateString.isEmpty(); + const QFont stateFont = stateTF.font(); + const QFontMetrics stateFM(stateFont); + const int stateStringWidth = stateFM.horizontalAdvance(stateString); + const QRect stateR(checkmarkR.x() - HGapXxs - stateStringWidth, y, + stateStringWidth, stateTF.lineHeight()); + y += itemNameR.height() + VGapXxs; const QRect vendorRowR(x, y, middleColumnW, vendorRowHeight()); QRect vendorR = vendorRowR; @@ -162,11 +190,22 @@ public: painter->drawText(smallCircle, countTF.drawTextFlags, QString::number(plugins.count())); } { + QRect effectiveR = itemNameR; + if (showState) + effectiveR.setRight(stateR.left() - HGapXxs - 1); painter->setPen(itemNameTF.color()); painter->setFont(itemNameTF.font()); const QString titleElided - = painter->fontMetrics().elidedText(itemName, Qt::ElideRight, itemNameR.width()); - painter->drawText(itemNameR, itemNameTF.drawTextFlags, titleElided); + = painter->fontMetrics().elidedText(itemName, Qt::ElideRight, effectiveR.width()); + painter->drawText(effectiveR, itemNameTF.drawTextFlags, titleElided); + } + if (showState) { + static const QIcon checkmark = Icon({{":/extensionmanager/images/checkmark.png", + stateTF.themeColor}}, Icon::Tint).icon(); + checkmark.paint(painter, checkmarkR); + painter->setPen(stateTF.color()); + painter->setFont(stateTF.font()); + painter->drawText(stateR, stateTF.drawTextFlags, stateString); } { const QString vendor = index.data(RoleVendor).toString(); diff --git a/src/plugins/extensionmanager/extensionsmodel.cpp b/src/plugins/extensionmanager/extensionsmodel.cpp index cda2c525bcc..7a03e84ed05 100644 --- a/src/plugins/extensionmanager/extensionsmodel.cpp +++ b/src/plugins/extensionmanager/extensionsmodel.cpp @@ -358,6 +358,18 @@ static QVariant dataFromExtension(const Extension &extension, int role) return {}; } +ExtensionState extensionState(const QModelIndex &index) +{ + if (index.data(RoleItemType) != ItemTypeExtension) + return None; + + const PluginSpec *ps = pluginSpecForName(index.data(RoleName).toString()); + if (!ps) + return NotInstalled; + + return ps->isEffectivelyEnabled() ? InstalledEnabled : InstalledDisabled; +} + static QString searchText(const QModelIndex &index) { QStringList searchTexts; @@ -370,6 +382,8 @@ static QString searchText(const QModelIndex &index) QVariant ExtensionsModel::data(const QModelIndex &index, int role) const { + if (role == RoleExtensionState) + return extensionState(index); if (role == RoleSearchText) return searchText(index); diff --git a/src/plugins/extensionmanager/extensionsmodel.h b/src/plugins/extensionmanager/extensionsmodel.h index 32ca3ae5ba4..999f7618965 100644 --- a/src/plugins/extensionmanager/extensionsmodel.h +++ b/src/plugins/extensionmanager/extensionsmodel.h @@ -23,6 +23,13 @@ enum ItemType { ItemTypeExtension, }; +enum ExtensionState { + None, // Not a plugin + InstalledEnabled, + InstalledDisabled, + NotInstalled, +}; + enum Role { RoleName = Qt::UserRole, RoleCompatVersion, @@ -32,6 +39,7 @@ enum Role { RoleDescriptionLinks, RoleDescriptionText, RoleDownloadCount, + RoleExtensionState, RoleId, RoleItemType, RoleLicense, diff --git a/src/plugins/extensionmanager/images/checkmark.png b/src/plugins/extensionmanager/images/checkmark.png new file mode 100644 index 00000000000..82c75dc560c Binary files /dev/null and b/src/plugins/extensionmanager/images/checkmark.png differ diff --git a/src/plugins/extensionmanager/images/checkmark@2x.png b/src/plugins/extensionmanager/images/checkmark@2x.png new file mode 100644 index 00000000000..b8425f59dc1 Binary files /dev/null and b/src/plugins/extensionmanager/images/checkmark@2x.png differ diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index a51819744a0..65c163949fc 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -3886,6 +3886,26 @@ d="m 67,422 h 12 m -6,-3.5 V 410 m -3,5.5 3,3 3.03461,-3" sodipodi:nodetypes="ccccccc" /> + + + + +