diff --git a/plugins/Marketplace/PackageModel.py b/plugins/Marketplace/PackageModel.py
index 7c2a5d9ae1..29c8abe653 100644
--- a/plugins/Marketplace/PackageModel.py
+++ b/plugins/Marketplace/PackageModel.py
@@ -39,6 +39,7 @@ class PackageModel(QObject):
self._package_type = package_data.get("package_type", "")
self._is_bundled = package_data.get("is_bundled", False)
self._icon_url = package_data.get("icon_url", "")
+ self._marketplace_url = package_data.get("marketplace_url", "")
self._display_name = package_data.get("display_name", catalog.i18nc("@label:property", "Unknown Package"))
tags = package_data.get("tags", [])
self._is_checked_by_ultimaker = (self._package_type == "plugin" and "verified" in tags) or (
@@ -210,6 +211,10 @@ class PackageModel(QObject):
def packageId(self) -> str:
return self._package_id
+ @pyqtProperty(str, constant=True)
+ def marketplaceURL(self)-> str:
+ return self._marketplace_url
+
@pyqtProperty(str, constant = True)
def packageType(self) -> str:
return self._package_type
diff --git a/plugins/Marketplace/resources/images/Plugin.svg b/plugins/Marketplace/resources/images/Plugin.svg
new file mode 100644
index 0000000000..51356d842c
--- /dev/null
+++ b/plugins/Marketplace/resources/images/Plugin.svg
@@ -0,0 +1,3 @@
+
diff --git a/plugins/Marketplace/resources/images/Spool.svg b/plugins/Marketplace/resources/images/Spool.svg
new file mode 100644
index 0000000000..dae9b43030
--- /dev/null
+++ b/plugins/Marketplace/resources/images/Spool.svg
@@ -0,0 +1,3 @@
+
diff --git a/plugins/Marketplace/resources/qml/ManagedPackages.qml b/plugins/Marketplace/resources/qml/ManagedPackages.qml
index 8ccaacea46..3eb77d8485 100644
--- a/plugins/Marketplace/resources/qml/ManagedPackages.qml
+++ b/plugins/Marketplace/resources/qml/ManagedPackages.qml
@@ -13,7 +13,7 @@ Packages
bannerVisible: UM.Preferences.getValue("cura/market_place_show_manage_packages_banner");
bannerIcon: UM.Theme.getIcon("ArrowDoubleCircleRight")
bannerText: catalog.i18nc("@text", "Manage your Ultimaker Cura plugins and material profiles here. Make sure to keep your plugins up to date and backup your setup regularly.")
- bannerReadMoreUrl: "" // TODO add when support page is ready
+ bannerReadMoreUrl: "https://support.ultimaker.com/hc/en-us/articles/4411125921426/?utm_source=cura&utm_medium=software&utm_campaign=marketplace-learn-manage"
onRemoveBanner: function() {
UM.Preferences.setValue("cura/market_place_show_manage_packages_banner", false);
bannerVisible = false;
diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml
index fc6d3cd755..5a30141b32 100644
--- a/plugins/Marketplace/resources/qml/Marketplace.qml
+++ b/plugins/Marketplace/resources/qml/Marketplace.qml
@@ -46,198 +46,182 @@ Window
{
anchors.fill: parent
color: UM.Theme.getColor("main_background")
+ }
+ //The Marketplace can have a page in front of everything with package details. The stack view controls its visibility.
+ StackView
+ {
+ id: contextStack
+ anchors.fill: parent
- //The Marketplace can have a page in front of everything with package details. The stack view controls its visibility.
- StackView
+ initialItem: packageBrowse
+
+ ColumnLayout
{
- id: contextStack
- anchors.fill: parent
+ id: packageBrowse
- initialItem: packageBrowse
+ spacing: UM.Theme.getSize("narrow_margin").height
- ColumnLayout
+ // Page title.
+ Item
{
- id: packageBrowse
+ implicitWidth: parent.width
+ implicitHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
- spacing: UM.Theme.getSize("default_margin").height
-
- // Page title.
- Item
+ Label
{
- Layout.preferredWidth: parent.width
- Layout.preferredHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
-
- Label
+ id: pageTitle
+ anchors
{
- id: pageTitle
- anchors
- {
- left: parent.left
- leftMargin: UM.Theme.getSize("default_margin").width
- right: parent.right
- rightMargin: UM.Theme.getSize("default_margin").width
- bottom: parent.bottom
- }
-
- font: UM.Theme.getFont("large")
- color: UM.Theme.getColor("text")
- text: content.item ? content.item.pageTitle: catalog.i18nc("@title", "Loading...")
+ left: parent.left
+ leftMargin: UM.Theme.getSize("default_margin").width
+ right: parent.right
+ rightMargin: UM.Theme.getSize("default_margin").width
+ bottom: parent.bottom
}
- }
- OnboardBanner
- {
- visible: content.item && content.item.bannerVisible
- text: content.item && content.item.bannerText
- icon: content.item && content.item.bannerIcon
- onRemove: content.item && content.item.onRemoveBanner
- readMoreUrl: content.item && content.item.bannerReadMoreUrl
+ font: UM.Theme.getFont("large")
+ color: UM.Theme.getColor("text")
+ text: content.item ? content.item.pageTitle: catalog.i18nc("@title", "Loading...")
}
+ }
- // Search & Top-Level Tabs
- Item
+ OnboardBanner
+ {
+ visible: content.item && content.item.bannerVisible
+ text: content.item && content.item.bannerText
+ icon: content.item && content.item.bannerIcon
+ onRemove: content.item && content.item.onRemoveBanner
+ readMoreUrl: content.item && content.item.bannerReadMoreUrl
+
+ Layout.fillWidth: true
+ Layout.leftMargin: UM.Theme.getSize("default_margin").width
+ Layout.rightMargin: UM.Theme.getSize("default_margin").width
+ }
+
+ // Search & Top-Level Tabs
+ Item
+ {
+ implicitHeight: childrenRect.height
+ implicitWidth: parent.width - 2 * UM.Theme.getSize("default_margin").width
+ Layout.alignment: Qt.AlignHCenter
+ RowLayout
{
- Layout.preferredHeight: childrenRect.height
- Layout.preferredWidth: parent.width - 2 * UM.Theme.getSize("thin_margin").width
- RowLayout
+ width: parent.width
+ height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height
+ spacing: UM.Theme.getSize("thin_margin").width
+
+ Cura.SearchBar
{
- width: parent.width
- height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height
- spacing: UM.Theme.getSize("thin_margin").width
+ id: searchBar
+ implicitHeight: UM.Theme.getSize("button_icon").height
+ Layout.fillWidth: true
+ onTextEdited: searchStringChanged(text)
+ }
- Item
+ // Page selection.
+ TabBar
+ {
+ id: pageSelectionTabBar
+ Layout.alignment: Qt.AlignRight
+ height: UM.Theme.getSize("button_icon").height
+ spacing: 0
+ background: Rectangle { color: "transparent" }
+ currentIndex: manager.tabShown
+
+ onCurrentIndexChanged:
{
- Layout.preferredHeight: parent.height
- Layout.preferredWidth: searchBar.visible ? UM.Theme.getSize("thin_margin").width : 0
- Layout.fillWidth: ! searchBar.visible
+ manager.tabShown = currentIndex
+ searchBar.text = "";
+ searchBar.visible = currentItem.hasSearch;
+ content.source = currentItem.sourcePage;
}
- Cura.SearchBar
+ PackageTypeTab
{
- id: searchBar
- Layout.preferredHeight: UM.Theme.getSize("button_icon").height
- Layout.fillWidth: true
- onTextEdited: searchStringChanged(text)
+ id: pluginTabText
+ width: implicitWidth
+ text: catalog.i18nc("@button", "Plugins")
+ property string sourcePage: "Plugins.qml"
+ property bool hasSearch: true
}
-
- // Page selection.
- TabBar
+ PackageTypeTab
{
- id: pageSelectionTabBar
- Layout.alignment: Qt.AlignRight
- height: UM.Theme.getSize("button_icon").height
- spacing: 0
- background: Rectangle { color: "transparent" }
- currentIndex: manager.tabShown
+ id: materialsTabText
+ width: implicitWidth
+ text: catalog.i18nc("@button", "Materials")
+ property string sourcePage: "Materials.qml"
+ property bool hasSearch: true
+ }
+ ManagePackagesButton
+ {
+ property string sourcePage: "ManagedPackages.qml"
+ property bool hasSearch: false
- onCurrentIndexChanged:
+ Cura.NotificationIcon
{
- manager.tabShown = currentIndex
- searchBar.text = "";
- searchBar.visible = currentItem.hasSearch;
- content.source = currentItem.sourcePage;
- }
-
- PackageTypeTab
- {
- id: pluginTabText
- width: implicitWidth
- text: catalog.i18nc("@button", "Plugins")
- property string sourcePage: "Plugins.qml"
- property bool hasSearch: true
- }
- PackageTypeTab
- {
- id: materialsTabText
- width: implicitWidth
- text: catalog.i18nc("@button", "Materials")
- property string sourcePage: "Materials.qml"
- property bool hasSearch: true
- }
- ManagePackagesButton
- {
- property string sourcePage: "ManagedPackages.qml"
- property bool hasSearch: false
-
- Cura.NotificationIcon
+ anchors
{
- anchors
- {
- horizontalCenter: parent.right
- verticalCenter: parent.top
- }
- visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
+ horizontalCenter: parent.right
+ verticalCenter: parent.top
+ }
+ visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
- labelText:
- {
- const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
- return itemCount > 9 ? "9+" : itemCount
- }
+ labelText:
+ {
+ const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
+ return itemCount > 9 ? "9+" : itemCount
}
}
}
-
- TextMetrics
- {
- id: pluginTabTextMetrics
- text: pluginTabText.text
- font: pluginTabText.font
- }
- TextMetrics
- {
- id: materialsTabTextMetrics
- text: materialsTabText.text
- font: materialsTabText.font
- }
}
}
+ }
- FontMetrics
- {
- id: fontMetrics
- font: UM.Theme.getFont("default")
- }
+ FontMetrics
+ {
+ id: fontMetrics
+ font: UM.Theme.getFont("default")
+ }
- Cura.TertiaryButton
- {
- text: catalog.i18nc("@info", "Search in the browser")
- iconSource: UM.Theme.getIcon("LinkExternal")
- visible: pageSelectionTabBar.currentItem.hasSearch
- isIconOnRightSide: true
- height: fontMetrics.height
- textFont: fontMetrics.font
- textColor: UM.Theme.getColor("text")
+ Cura.TertiaryButton
+ {
+ text: catalog.i18nc("@info", "Search in the browser")
+ iconSource: UM.Theme.getIcon("LinkExternal")
+ visible: pageSelectionTabBar.currentItem.hasSearch
+ isIconOnRightSide: true
+ height: fontMetrics.height
+ textFont: fontMetrics.font
+ textColor: UM.Theme.getColor("text")
- onClicked: content.item && Qt.openUrlExternally(content.item.searchInBrowserUrl)
- }
+ onClicked: content.item && Qt.openUrlExternally(content.item.searchInBrowserUrl)
+ }
+
+ // Page contents.
+ Rectangle
+ {
+ Layout.preferredWidth: parent.width
+ Layout.fillHeight: true
+ color: UM.Theme.getColor("detail_background")
// Page contents.
- Rectangle
+ Loader
{
- Layout.preferredWidth: parent.width
- Layout.fillHeight: true
- color: UM.Theme.getColor("detail_background")
+ id: content
+ anchors.fill: parent
+ anchors.margins: UM.Theme.getSize("default_margin").width
+ source: "Plugins.qml"
- // Page contents.
- Loader
+ Connections
{
- id: content
- anchors.fill: parent
- anchors.margins: UM.Theme.getSize("default_margin").width
- source: "Plugins.qml"
-
- Connections
+ target: content
+ function onLoaded()
{
- target: content
- function onLoaded()
- {
- pageTitle.text = content.item.pageTitle
- searchStringChanged.connect(handleSearchStringChanged)
- }
- function handleSearchStringChanged(new_search)
- {
- content.item.model.searchString = new_search
- }
+ pageTitle.text = content.item.pageTitle
+ searchStringChanged.connect(handleSearchStringChanged)
+ }
+ function handleSearchStringChanged(new_search)
+ {
+ content.item.model.searchString = new_search
}
}
}
diff --git a/plugins/Marketplace/resources/qml/Materials.qml b/plugins/Marketplace/resources/qml/Materials.qml
index 39fae7042a..ddac8b0bbe 100644
--- a/plugins/Marketplace/resources/qml/Materials.qml
+++ b/plugins/Marketplace/resources/qml/Materials.qml
@@ -10,7 +10,7 @@ Packages
bannerVisible: UM.Preferences.getValue("cura/market_place_show_material_banner")
bannerIcon: UM.Theme.getIcon("Spool")
bannerText: catalog.i18nc("@text", "Select and install material profiles optimised for your Ultimaker 3D printers.")
- bannerReadMoreUrl: "" // TODO add when support page is ready
+ bannerReadMoreUrl: "https://support.ultimaker.com/hc/en-us/articles/360011968360/?utm_source=cura&utm_medium=software&utm_campaign=marketplace-learn-materials"
onRemoveBanner: function() {
UM.Preferences.setValue("cura/market_place_show_material_banner", false);
bannerVisible = false;
diff --git a/plugins/Marketplace/resources/qml/OnboardBanner.qml b/plugins/Marketplace/resources/qml/OnboardBanner.qml
index 25e4b53241..7d973cb74a 100644
--- a/plugins/Marketplace/resources/qml/OnboardBanner.qml
+++ b/plugins/Marketplace/resources/qml/OnboardBanner.qml
@@ -16,10 +16,7 @@ Rectangle
property var onRemove
property string readMoreUrl
- Layout.preferredHeight: childrenRect.height + 2 * UM.Theme.getSize("default_margin").height
- Layout.fillWidth: true
- Layout.margins: UM.Theme.getSize("default_margin").width
-
+ implicitHeight: childrenRect.height + 2 * UM.Theme.getSize("default_margin").height
color: UM.Theme.getColor("action_panel_secondary")
// Icon
diff --git a/plugins/Marketplace/resources/qml/PackageCard.qml b/plugins/Marketplace/resources/qml/PackageCard.qml
index 633d2b25b9..9a5f9beab6 100644
--- a/plugins/Marketplace/resources/qml/PackageCard.qml
+++ b/plugins/Marketplace/resources/qml/PackageCard.qml
@@ -31,64 +31,14 @@ Rectangle
{
id: descriptionLabel
width: parent.width
- property real lastLineWidth: 0; //Store the width of the last line, to properly position the elision.
text: packageData.description
- textFormat: Text.PlainText //Must be plain text, or we won't get onLineLaidOut signals. Don't auto-detect!
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Text.ElideRight
visible: text !== ""
-
- onLineLaidOut:
- {
- if(truncated && line.isLast)
- {
- let max_line_width = parent.width - readMoreButton.width - fontMetrics.advanceWidth("… ") - 2 * UM.Theme.getSize("default_margin").width;
- if(line.implicitWidth > max_line_width)
- {
- line.width = max_line_width;
- }
- else
- {
- line.width = line.implicitWidth - fontMetrics.advanceWidth("…"); //Truncate the ellipsis. We're adding this ourselves.
- }
- descriptionLabel.lastLineWidth = line.implicitWidth;
- }
- }
- }
- Label
- {
- id: tripleDotLabel
- anchors.left: parent.left
- anchors.leftMargin: descriptionLabel.lastLineWidth
- anchors.bottom: descriptionLabel.bottom
-
- text: "… "
- font: descriptionLabel.font
- color: descriptionLabel.color
- visible: descriptionLabel.truncated && descriptionLabel.text !== ""
- }
- Cura.TertiaryButton
- {
- id: readMoreButton
- anchors.right: parent.right
- anchors.bottom: descriptionLabel.bottom
- height: fontMetrics.height //Height of a single line.
-
- text: catalog.i18nc("@info", "Read more")
- iconSource: UM.Theme.getIcon("LinkExternal")
-
- visible: descriptionLabel.truncated && descriptionLabel.text !== ""
- enabled: visible
- leftPadding: UM.Theme.getSize("default_margin").width
- rightPadding: UM.Theme.getSize("wide_margin").width
- textFont: descriptionLabel.font
- isIconOnRightSide: true
-
- onClicked: Qt.openUrlExternally(packageData.packageInfoUrl)
}
}
}
diff --git a/plugins/Marketplace/resources/qml/PackageCardHeader.qml b/plugins/Marketplace/resources/qml/PackageCardHeader.qml
index 3a76f7a959..9e3e673ea2 100644
--- a/plugins/Marketplace/resources/qml/PackageCardHeader.qml
+++ b/plugins/Marketplace/resources/qml/PackageCardHeader.qml
@@ -12,7 +12,7 @@ import Cura 1.6 as Cura
// are combined into the reusable "PackageCardHeader" component
Item
{
- default property alias contents: contentItem.children;
+ default property alias contents: contentItem.children
property var packageData
property bool showManageButtons: false
@@ -32,8 +32,21 @@ Item
}
width: UM.Theme.getSize("card_icon").width
height: width
-
- source: packageData.iconUrl != "" ? packageData.iconUrl : "../images/placeholder.svg"
+ sourceSize.height: height
+ sourceSize.width: width
+ source:
+ {
+ if (packageData.iconUrl != "")
+ {
+ return packageData.iconUrl
+ }
+ switch (packageData.packageType)
+ {
+ case "plugin": return "../images/Plugin.svg";
+ case "material": return "../images/Spool.svg";
+ default: return "../images/placeholder.svg";
+ }
+ }
}
ColumnLayout
@@ -103,7 +116,7 @@ Item
color: externalLinkButton.hovered ? UM.Theme.getColor("action_button_hovered"): "transparent"
radius: externalLinkButton.width / 2
}
- onClicked: Qt.openUrlExternally(packageData.authorInfoUrl)
+ onClicked: Qt.openUrlExternally(packageData.marketplaceURL)
}
}
diff --git a/plugins/Marketplace/resources/qml/PackagePage.qml b/plugins/Marketplace/resources/qml/PackagePage.qml
index 21c400fff2..4384d2843f 100644
--- a/plugins/Marketplace/resources/qml/PackagePage.qml
+++ b/plugins/Marketplace/resources/qml/PackagePage.qml
@@ -40,7 +40,10 @@ Rectangle
id: downloadCount
Layout.preferredWidth: parent.width
Layout.fillHeight: true
-
+ // It's not the perfect way to handle this, since a package really can have 0 downloads
+ // But we re-use the package page for the manage plugins as well. The one user that doesn't see
+ // the num downloads is an acceptable "sacrifice" to make this easy to fix.
+ visible: packageData.downloadCount != "0"
UM.RecolorImage
{
id: downloadsIcon
@@ -53,6 +56,7 @@ Rectangle
Label
{
+
anchors.verticalCenter: downloadsIcon.verticalCenter
color: UM.Theme.getColor("text")
diff --git a/plugins/Marketplace/resources/qml/Packages.qml b/plugins/Marketplace/resources/qml/Packages.qml
index 194c90c248..5cd52e5628 100644
--- a/plugins/Marketplace/resources/qml/Packages.qml
+++ b/plugins/Marketplace/resources/qml/Packages.qml
@@ -53,8 +53,8 @@ ListView
// Vertical ScrollBar, styled similarly to the scrollBar in the settings panel
id: verticalScrollBar
visible: packages.contentHeight > packages.height
-
- background: Item{}
+ anchors.right: parent.right
+ background: Item {}
contentItem: Rectangle
{
@@ -83,7 +83,16 @@ ListView
{
manageableInListView: packages.packagesManageableInListView
packageData: model.package
- width: parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("narrow_margin").width
+ width: {
+ if (verticalScrollBar.visible)
+ {
+ return parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("default_margin").width
+ }
+ else
+ {
+ return parent.width - UM.Theme.getSize("default_margin").width
+ }
+ }
color: cardMouseArea.containsMouse ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("main_background")
}
}
diff --git a/plugins/Marketplace/resources/qml/Plugins.qml b/plugins/Marketplace/resources/qml/Plugins.qml
index 9983a827d8..f1a524c029 100644
--- a/plugins/Marketplace/resources/qml/Plugins.qml
+++ b/plugins/Marketplace/resources/qml/Plugins.qml
@@ -10,7 +10,7 @@ Packages
bannerVisible: UM.Preferences.getValue("cura/market_place_show_plugin_banner")
bannerIcon: UM.Theme.getIcon("Shop")
bannerText: catalog.i18nc("@text", "Streamline your workflow and customize your Ultimaker Cura experience with plugins contributed by our amazing community of users.")
- bannerReadMoreUrl: "" // TODO add when support page is ready
+ bannerReadMoreUrl: "https://support.ultimaker.com/hc/en-us/articles/360011968360/?utm_source=cura&utm_medium=software&utm_campaign=marketplace-learn-plugins"
onRemoveBanner: function() {
UM.Preferences.setValue("cura/market_place_show_plugin_banner", false)
bannerVisible = false;