diff --git a/discover/qml/ApplicationPage.qml b/discover/qml/ApplicationPage.qml --- a/discover/qml/ApplicationPage.qml +++ b/discover/qml/ApplicationPage.qml @@ -45,47 +45,6 @@ } } - Kirigami.OverlaySheet { - id: originsOverlay - bottomPadding: Kirigami.Units.largeSpacing - topPadding: Kirigami.Units.largeSpacing - readonly property alias model: alternativeResourcesView.model - function listBackends() { - var first = true; - var ret = ""; - var m = alternativeResourcesView.model; - for(var i=0, count=m.rowCount(); i" + res.displayOrigin + "" - first = false - } - } - return ret - } - readonly property string sentence: alternativeResourcesView.count <= 1 ? "" : i18n("\nAlso available in %1", listBackends()) - ListView { - id: alternativeResourcesView - model: ResourcesProxyModel { - allBackends: true - resourcesUrl: appInfo.application.url - } - delegate: Kirigami.BasicListItem { - label: displayOrigin - checked: appInfo.application == model.application - onClicked: if(index>=0) { - var res = model.application - console.assert(res) - window.stack.pop() - Navigation.openApplication(res) - } - } - } - } - header: QQC2.ToolBar { anchors { right: parent.right @@ -105,13 +64,6 @@ Item { Layout.fillWidth: true } - Kirigami.Icon { - Layout.preferredHeight: parent.implicitHeight - Layout.preferredWidth: Layout.preferredHeight - - source: appInfo.application.icon - Layout.alignment: Qt.AlignVCenter - } Kirigami.Heading { level: 3 Layout.maximumWidth: parent.width/2 @@ -146,16 +98,105 @@ } } + // Icon, name, caption, screenshots, description and reviews ColumnLayout { spacing: 0 + RowLayout { + Kirigami.Icon { + Layout.preferredHeight: 64 + Layout.preferredWidth: 64 + source: appInfo.application.icon + anchors.margins: 20 + } + ColumnLayout { + spacing: 0 + Kirigami.Heading { + level: 3 + text: appInfo.application.name + maximumLineCount: 1 + elide: Text.ElideRight + horizontalAlignment: Text.AlignBottom + } + Kirigami.Heading { + level: 5 + text: appInfo.application.comment + maximumLineCount: 1 + elide: Text.ElideRight + Layout.alignment: Qt.AlignTop + } + } + } + + Rectangle { + color: Kirigami.Theme.linkColor + Layout.fillWidth: true + height: 1 + anchors.bottomMargin: Kirigami.Units.largeSpacing + } + + ApplicationScreenshots { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.fillWidth: true + resource: appInfo.application + page: appInfo + } + Item { + Layout.fillWidth: true + height: 5 + } + QQC2.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignJustify + wrapMode: Text.WordWrap + text: appInfo.application.longDescription + } + + LinkButton { + id: addonsButton + text: i18n("Addons") + visible: addonsView.containsAddons + onClicked: addonsView.sheetOpen = true + } + + LinkButton { + text: i18n("Review") + onClicked: reviewsSheet.openReviewDialog() + visible: !commentsButton.visible && reviewsModel.backend && reviewsModel.backend.isResourceSupported(appInfo.application) + } + LinkButton { + id: commentsButton + readonly property QtObject rating: appInfo.application.rating + visible: rating && rating.ratingCount>0 && reviewsModel.count + text: i18n("Show reviews (%1)...", rating ? reviewsModel.count : 0) + + onClicked: { + reviewsSheet.open() + } + } + + Item { + height: addonsButton.height + width: 5 + } + + // Details/metadata Kirigami.Heading { - text: appInfo.application.comment - level: 4 + text: i18n("Details") + level: 3 Layout.fillWidth: true + Layout.alignment: Qt.AlignBottom elide: Text.ElideRight - bottomPadding: Kirigami.Units.largeSpacing } - + Rectangle { + color: Kirigami.Theme.linkColor + Layout.fillWidth: true + height: 1 + anchors.bottomMargin: Kirigami.Units.largeSpacing + } + Item { + Layout.fillWidth: true + height: 5 + } GridLayout { rowSpacing: 0 columns: 2 @@ -173,17 +214,35 @@ // Version row QQC2.Label { - readonly property string version: appInfo.application.isInstalled ? appInfo.application.installedVersion : appInfo.application.availableVersion - visible: version.length > 0 Layout.alignment: Qt.AlignRight text: i18n("Version:") } + // Show a regular label for the version and source when there's only one source QQC2.Label { - readonly property string version: appInfo.application.isInstalled ? appInfo.application.installedVersion : appInfo.application.availableVersion - visible: version.length > 0 Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + visible: sourcesCombo.count == 1 + text: appInfo.application.displayOrigin elide: Text.ElideRight - text: version ? version : "" + } + // Show a combobox chooser when there's more than one source available + QQC2.ComboBox { + id: sourcesCombo + visible: sourcesCombo.count > 1 + model: ResourcesProxyModel { + allBackends: true + onIsBusyChanged: if (!isBusy) { + sourcesCombo.currentIndex = indexOf(appInfo.application) + } + resourcesUrl: appInfo.application.url + } + onActivated: if(index>=0) { + var res = model.resourceAt(index) + console.assert(res) + window.stack.pop() + Navigation.openApplication(res) + } + textRole: "displayOrigin" } // Size row @@ -197,20 +256,6 @@ text: i18n("%1", appInfo.application.sizeDescription) } - // Source row - QQC2.Label { - Layout.alignment: Qt.AlignRight - text: i18n("Source:") - } - LinkButton { - Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - enabled: alternativeResourcesView.count > 1 - text: appInfo.application.displayOrigin - elide: Text.ElideRight - onClicked: originsOverlay.open() - } - // License row QQC2.Label { Layout.alignment: Qt.AlignRight @@ -244,61 +289,6 @@ horizontalAlignment: Text.AlignLeft } } - - ApplicationScreenshots { - Layout.topMargin: Kirigami.Units.largeSpacing - Layout.fillWidth: true - resource: appInfo.application - page: appInfo - } - - Kirigami.Heading { - level: 3 - Layout.topMargin: Kirigami.Units.largeSpacing - text: i18n("Description") - Layout.fillWidth: true - visible: appInfo.application.longDescription.length > 0 - } - QQC2.Label { - Layout.fillWidth: true - horizontalAlignment: Text.AlignJustify - wrapMode: Text.WordWrap - text: appInfo.application.longDescription + originsOverlay.sentence - onLinkActivated: { - var idx = parseInt(link, 10) - var res = originsOverlay.model.resourceAt(idx) - window.stack.pop() - Navigation.openApplication(res) - } - } - - LinkButton { - id: addonsButton - text: i18n("Addons") - visible: addonsView.containsAddons - onClicked: addonsView.sheetOpen = true - } - - LinkButton { - text: i18n("Review") - onClicked: reviewsSheet.openReviewDialog() - visible: !commentsButton.visible && reviewsModel.backend && reviewsModel.backend.isResourceSupported(appInfo.application) - } - LinkButton { - id: commentsButton - readonly property QtObject rating: appInfo.application.rating - visible: rating && rating.ratingCount>0 && reviewsModel.count - text: i18n("Show reviews (%1)...", rating ? reviewsModel.count : 0) - - onClicked: { - reviewsSheet.open() - } - } - - Item { - height: addonsButton.height - width: 5 - } } readonly property var addons: AddonsView { diff --git a/libdiscover/resources/AbstractResource.h b/libdiscover/resources/AbstractResource.h --- a/libdiscover/resources/AbstractResource.h +++ b/libdiscover/resources/AbstractResource.h @@ -139,7 +139,7 @@ virtual QString longDescription() = 0; virtual QString origin() const = 0; - QString displayOrigin() const; + QString displayOrigin(); virtual QString section() = 0; ///@returns what kind of mime types the resource can consume diff --git a/libdiscover/resources/AbstractResource.cpp b/libdiscover/resources/AbstractResource.cpp --- a/libdiscover/resources/AbstractResource.cpp +++ b/libdiscover/resources/AbstractResource.cpp @@ -221,7 +221,8 @@ return asid.isEmpty() ? QUrl(backend()->name() + QStringLiteral("://") + packageName()) : QUrl(QStringLiteral("appstream://") + asid); } -QString AbstractResource::displayOrigin() const +QString AbstractResource::displayOrigin() { - return i18nc("origin (backend name)", "%1 (%2)", origin(), backend()->displayName()); + const QString version = state() >= Installed ? installedVersion() : availableVersion(); + return i18nc("version from source (backend)", "%1 from %2 (%3)", version, origin(), backend()->displayName()); }