diff --git a/src/core/pluginmanager.cpp b/src/core/pluginmanager.cpp
index 0a8dad6eca..b68a122a9a 100644
--- a/src/core/pluginmanager.cpp
+++ b/src/core/pluginmanager.cpp
@@ -228,7 +228,9 @@ void PluginManager::refreshAppPlugins()
QString name = candidate.fileName();
QString description;
QString author;
+ QString homepage;
QString icon;
+ QString version;
const QString metadataPath = QStringLiteral( "%1/metadata.txt" ).arg( candidate.absoluteFilePath() );
if ( QFileInfo::exists( metadataPath ) )
@@ -237,12 +239,23 @@ void PluginManager::refreshAppPlugins()
name = metadata.value( "name", candidate.fileName() ).toString();
description = metadata.value( "description" ).toString();
author = metadata.value( "author" ).toString();
+ homepage = metadata.value( "homepage" ).toString();
+ if ( !homepage.isEmpty() )
+ {
+ // Only tolerate http(s) URLs
+ const QUrl url( homepage );
+ if ( !url.scheme().startsWith( QStringLiteral( "http" ) ) )
+ {
+ homepage.clear();
+ }
+ }
if ( !metadata.value( "icon" ).toString().isEmpty() )
{
icon = QStringLiteral( "%1/%2" ).arg( candidate.absoluteFilePath(), metadata.value( "icon" ).toString() );
}
+ version = metadata.value( "version" ).toString();
}
- mAvailableAppPlugins.insert( candidate.fileName(), PluginInformation( candidate.fileName(), name, description, author, icon, path ) );
+ mAvailableAppPlugins.insert( candidate.fileName(), PluginInformation( candidate.fileName(), name, description, author, homepage, icon, version, path ) );
}
}
}
@@ -408,6 +421,19 @@ void PluginManager::installFromUrl( const QString &url )
} );
}
+void PluginManager::uninstall( const QString &uuid )
+{
+ if ( mAvailableAppPlugins.contains( uuid ) )
+ {
+ disableAppPlugin( uuid );
+
+ QFileInfo fi( mAvailableAppPlugins[uuid].path() );
+ fi.absoluteDir().removeRecursively();
+
+ refreshAppPlugins();
+ }
+}
+
QString PluginManager::findProjectPlugin( const QString &projectPath )
{
const QFileInfo fi( projectPath );
diff --git a/src/core/pluginmanager.h b/src/core/pluginmanager.h
index 0ac661a221..7be7e30b0d 100644
--- a/src/core/pluginmanager.h
+++ b/src/core/pluginmanager.h
@@ -28,15 +28,19 @@ class PluginInformation
Q_PROPERTY( QString name READ name )
Q_PROPERTY( QString description READ description )
Q_PROPERTY( QString author READ author )
+ Q_PROPERTY( QString homepage READ homepage )
Q_PROPERTY( QString icon READ icon )
+ Q_PROPERTY( QString version READ version )
public:
- PluginInformation( const QString &uuid = QString(), const QString &name = QString(), const QString &description = QString(), const QString &author = QString(), const QString &icon = QString(), const QString &path = QString() )
+ PluginInformation( const QString &uuid = QString(), const QString &name = QString(), const QString &description = QString(), const QString &author = QString(), const QString &homepage = QString(), const QString &icon = QString(), const QString &version = QString(), const QString &path = QString() )
: mUuid( uuid )
, mName( name )
, mDescription( description )
, mAuthor( author )
+ , mHomepage( homepage )
, mIcon( icon )
+ , mVersion( version )
, mPath( path )
{}
~PluginInformation() = default;
@@ -45,7 +49,9 @@ class PluginInformation
QString name() const { return mName; }
QString description() const { return mDescription; }
QString author() const { return mAuthor; }
+ QString homepage() const { return mHomepage; }
QString icon() const { return mIcon; }
+ QString version() const { return mVersion; }
QString path() const { return mPath; }
private:
@@ -53,7 +59,9 @@ class PluginInformation
QString mName;
QString mDescription;
QString mAuthor;
+ QString mHomepage;
QString mIcon;
+ QString mVersion;
QString mPath;
};
@@ -89,6 +97,7 @@ class PluginManager : public QObject
void restoreAppPlugins();
Q_INVOKABLE void installFromUrl( const QString &url );
+ Q_INVOKABLE void uninstall( const QString &uuid );
static QString findProjectPlugin( const QString &projectPath );
diff --git a/src/qml/PluginManagerSettings.qml b/src/qml/PluginManagerSettings.qml
index fd9c19141e..ba86826b3e 100644
--- a/src/qml/PluginManagerSettings.qml
+++ b/src/qml/PluginManagerSettings.qml
@@ -101,8 +101,11 @@ Popup {
MouseArea {
anchors.fill: parent
onClicked: {
- toggleEnabledPlugin.checked = !toggleEnabledPlugin.checked
- toggleEnabledPlugin.clicked()
+ if (!Enabled) {
+ pluginManager.enableAppPlugin(Uuid)
+ } else {
+ pluginManager.disableAppPlugin(Uuid)
+ }
}
}
}
@@ -115,7 +118,7 @@ Popup {
onClicked: {
Enabled = checked == true
- if (checked) {
+ if (Enabled) {
pluginManager.enableAppPlugin(Uuid)
} else {
pluginManager.disableAppPlugin(Uuid)
@@ -128,10 +131,13 @@ Popup {
Label {
Layout.fillWidth: true
- text: qsTr('Authored by %1').arg(Author)
+ text: (Homepage != ''
+ ? qsTr('Authored by %1%2%3').arg('').arg(Author).arg('')
+ : qsTr('Authored by %1').arg(Author)) + (Version != "" ? ' (' + Version + ')' : '')
font: Theme.tipFont
color: Theme.secondaryTextColor
wrapMode: Text.WordWrap
+ onLinkActivated: Qt.openUrlExternally(link)
}
Label {
@@ -141,6 +147,20 @@ Popup {
color: Theme.secondaryTextColor
wrapMode: Text.WordWrap
}
+
+ Label {
+ Layout.fillWidth: true
+ text: "" + qsTr("Uninstall this plugin") + ""
+ font: Theme.tipFont
+ color: Theme.secondaryTextColor
+ wrapMode: Text.WordWrap
+
+ onLinkActivated: (link) => {
+ uninstallConfirmation.pluginName = Name
+ uninstallConfirmation.pluginUuid = Uuid
+ uninstallConfirmation.open()
+ }
+ }
}
}
}
@@ -216,6 +236,43 @@ Popup {
}
}
+ Dialog {
+ id: uninstallConfirmation
+ title: "Uninstall Plugin"
+ parent: mainWindow.contentItem
+ x: ( mainWindow.width - width ) / 2
+ y: ( mainWindow.height - height - 80 ) / 2
+
+ property string pluginName: ""
+ property string pluginUuid: ""
+
+ Column {
+ width: childrenRect.width
+ height: childrenRect.height
+ spacing: 10
+
+ TextMetrics {
+ id: uninstallLabelMetrics
+ font: uninstallLabel.font
+ text: uninstallLabel.text
+ }
+
+ Label {
+ id: uninstallLabel
+ width: mainWindow.width - 60 < uninstallLabelMetrics.width ? mainWindow.width - 60 : uninstallLabelMetrics.width
+ text: qsTr("Are you sure you want to uninstall `%1`?").arg(uninstallConfirmation.pluginName)
+ wrapMode: Text.WordWrap
+ font: Theme.defaultFont
+ color: Theme.mainTextColor
+ }
+ }
+
+ standardButtons: Dialog.Ok | Dialog.Cancel
+ onAccepted: {
+ pluginManager.uninstall(pluginUuid)
+ }
+ }
+
Connections {
target: pluginManager
@@ -265,7 +322,7 @@ Popup {
pluginsList.model.clear()
for (const plugin of pluginManager.availableAppPlugins) {
- pluginsList.model.append({"Uuid":plugin.uuid, "Enabled":pluginManager.isAppPluginEnabled(plugin.uuid), "Name":plugin.name, "Description":plugin.description, "Author":plugin.author, "Icon": plugin.icon})
+ pluginsList.model.append({"Uuid":plugin.uuid, "Enabled":pluginManager.isAppPluginEnabled(plugin.uuid), "Name":plugin.name, "Description":plugin.description, "Author":plugin.author, "Homepage":plugin.homepage, "Icon": plugin.icon, "Version": plugin.version})
}
}