Fixed plugins categories and thumbnails
|
@ -27,6 +27,7 @@ MuseScore {
|
|||
version: "3.5"
|
||||
description: qsTr("This plugin colors notes in the selection depending on their pitch as per the Boomwhackers convention")
|
||||
menuPath: "Plugins.Notes.Color Notes"
|
||||
categoryCode: "color-notes"
|
||||
|
||||
property variant colors : [ // "#rrggbb" with rr, gg, and bb being the hex values for red, green, and blue, respectively
|
||||
"#e21c48", // C
|
|
@ -26,6 +26,7 @@ MuseScore {
|
|||
description: "This plugin adds courtesy accidentals"
|
||||
menuPath: "Plugins.Accidentals.Add Courtesy Accidentals"
|
||||
requiresScore: true
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
// configuration
|
||||
// This has changed for MuseScore v3
|
|
@ -28,6 +28,7 @@ MuseScore {
|
|||
version: "1.0"
|
||||
description: "This plugin adds courtesy accidentals"
|
||||
menuPath: "Plugins.Accidentals.Configure Courtesy Accidentals"
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
requiresScore: true
|
||||
|
|
@ -25,6 +25,7 @@ MuseScore {
|
|||
version: "1.0"
|
||||
description: "This plugin removes courtesy accidentals"
|
||||
menuPath: "Plugins.Accidentals.Remove Courtesy Accidentals"
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
//pluginType: "dock"
|
||||
requiresScore: true
|
|
@ -26,6 +26,8 @@ MuseScore {
|
|||
menuPath: "Plugins.Composing Tools.Mirror Intervals"
|
||||
description: "Mirrors (inverts) intervals about a given pivot note"
|
||||
pluginType: "dialog"
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
width: 250
|
||||
height: 150
|
||||
|
|
@ -17,6 +17,7 @@ MuseScore {
|
|||
menuPath: "Plugins.NewRetrograde"
|
||||
description: "Takes a selection of notes and reverses them."
|
||||
version: "1.0"
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
function retrogradeSelection() {
|
||||
var cursor = curScore.newCursor(); // get the selection
|
|
@ -22,6 +22,7 @@ MuseScore {
|
|||
version: "3.6"
|
||||
description: "This plugin names notes as per your language setting"
|
||||
menuPath: "Plugins.Notes." + "Note Names"
|
||||
categoryCode: "composing-arranging-tools"
|
||||
|
||||
// Small note name size is fraction of the full font size.
|
||||
property real fontSizeMini: 0.7;
|
|
@ -27,6 +27,8 @@ MuseScore {
|
|||
menuPath: "Plugins.Playback.Tuning"
|
||||
description: "Apply various temperaments and tunings"
|
||||
pluginType: "dialog"
|
||||
categoryCode: "playback"
|
||||
|
||||
width: 790
|
||||
height: 544
|
||||
|
|
@ -27,6 +27,8 @@ MuseScore {
|
|||
menuPath: "Plugins.Playback.Modal_Tuning"
|
||||
description: "Apply various temperaments and tunings"
|
||||
pluginType: "dialog"
|
||||
categoryCode: "playback"
|
||||
|
||||
width: 860
|
||||
height: 722
|
||||
|
|
@ -27,6 +27,8 @@ MuseScore {
|
|||
menuPath: "Plugins.Playback.Temperaments"
|
||||
description: "Apply various temperaments and tunings"
|
||||
pluginType: "dialog"
|
||||
categoryCode: "playback"
|
||||
|
||||
width: 900
|
||||
height: 722
|
||||
|
|
@ -137,7 +137,7 @@ FocusScope {
|
|||
|
||||
for (var i = 0; i < categories.length; ++i) {
|
||||
var category = categories[i]
|
||||
result.push({ "text": category, "value": category })
|
||||
result.push({ "text": category.title, "value": category.code })
|
||||
}
|
||||
|
||||
model = result
|
||||
|
|
|
@ -621,13 +621,36 @@ MenuItemList AppMenuModel::makePluginsItems()
|
|||
{
|
||||
MenuItemList result;
|
||||
|
||||
for (const PluginInfo& plugin : pluginsService()->plugins(IPluginsService::Enabled).val) {
|
||||
MenuItem* pluginItem = makeMenuItem(plugin.codeKey.toStdString(), plugin.name);
|
||||
if (!pluginItem) {
|
||||
continue;
|
||||
}
|
||||
IPluginsService::CategoryInfoMap categories = pluginsService()->categories();
|
||||
PluginInfoMap enabledPlugins = pluginsService()->plugins(IPluginsService::Enabled).val;
|
||||
|
||||
result << pluginItem;
|
||||
std::map<std::string, MenuItemList> categoriesMap;
|
||||
MenuItemList pluginsWithoutCategories;
|
||||
for (const PluginInfo& plugin : values(enabledPlugins)) {
|
||||
std::string categoryStr = plugin.categoryCode.toStdString();
|
||||
if (contains(categories, categoryStr)) {
|
||||
MenuItemList& items = categoriesMap[categoryStr];
|
||||
items << makeMenuItem(plugin.codeKey.toStdString(), plugin.name);
|
||||
} else {
|
||||
pluginsWithoutCategories << makeMenuItem(plugin.codeKey.toStdString(), plugin.name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : categoriesMap) {
|
||||
QString categoryTitle = QString::fromStdString(value(categories, it.first, ""));
|
||||
result << makeMenu(categoryTitle, it.second);
|
||||
}
|
||||
|
||||
std::sort(result.begin(), result.end(), [](const MenuItem& l, const MenuItem& r) {
|
||||
return l.title() < r.title();
|
||||
});
|
||||
|
||||
std::sort(pluginsWithoutCategories.begin(), pluginsWithoutCategories.end(), [](const MenuItem& l, const MenuItem& r) {
|
||||
return l.title() < r.title();
|
||||
});
|
||||
|
||||
for (MenuItem* plugin : pluginsWithoutCategories) {
|
||||
result << plugin;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -47,6 +47,8 @@ class MScore;
|
|||
// @P pluginType QString type may be dialog, dock, or not defined.
|
||||
// @P dockArea QString where to dock on main screen. left,top,bottom, right(default)
|
||||
// @P requiresScore bool whether the plugin requires an existing score to run
|
||||
// @P thumbnailName QString the thumbnail of this plugin
|
||||
// @P categoryCode QString the code of category this plugin belongs to
|
||||
// @P division int number of MIDI ticks for 1/4 note (read only)
|
||||
// @P mscoreVersion int complete version number of MuseScore in the form: MMmmuu (read only)
|
||||
// @P mscoreMajorVersion int 1st part of the MuseScore version (read only)
|
||||
|
@ -63,10 +65,11 @@ class QmlPlugin : public QQuickItem
|
|||
|
||||
QString _menuPath;
|
||||
QString _pluginType;
|
||||
QString _dockArea;
|
||||
bool _requiresScore = true;
|
||||
QString _version;
|
||||
QString _description;
|
||||
QString _thumbnailName;
|
||||
QString _categoryCode;
|
||||
|
||||
protected:
|
||||
QString _filePath; // the path of the source file, without file name
|
||||
|
@ -89,11 +92,13 @@ public:
|
|||
QString description() const { return _description; }
|
||||
void setFilePath(const QString s) { _filePath = s; }
|
||||
QString filePath() const { return _filePath; }
|
||||
void setThumbnailName(const QString& s) { _thumbnailName = s; }
|
||||
QString thumbnailName() const { return _thumbnailName; }
|
||||
void setCategoryCode(const QString& s) { _categoryCode = s; }
|
||||
QString categoryCode() const { return _categoryCode; }
|
||||
|
||||
void setPluginType(const QString& s) { _pluginType = s; }
|
||||
QString pluginType() const { return _pluginType; }
|
||||
void setDockArea(const QString& s) { _dockArea = s; }
|
||||
QString dockArea() const { return _dockArea; }
|
||||
void setRequiresScore(bool b) { _requiresScore = b; }
|
||||
bool requiresScore() const { return _requiresScore; }
|
||||
|
||||
|
|
|
@ -94,6 +94,10 @@ class PluginAPI : public mu::engraving::QmlPlugin
|
|||
Q_PROPERTY(QString dockArea READ dockArea WRITE setDockArea)
|
||||
/** Whether the plugin requires an existing score to run, default is `true` */
|
||||
Q_PROPERTY(bool requiresScore READ requiresScore WRITE setRequiresScore)
|
||||
/** The name of the thumbnail that should be next to the plugin */
|
||||
Q_PROPERTY(QString thumbnailName READ thumbnailName WRITE setThumbnailName)
|
||||
/** The code of the category */
|
||||
Q_PROPERTY(QString categoryCode READ categoryCode WRITE setCategoryCode)
|
||||
/**
|
||||
* \brief Number of MIDI ticks for 1/4 note (read only)
|
||||
* \see \ref ticklength
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
#include "pluginsactioncontroller.h"
|
||||
|
||||
#include "containers.h"
|
||||
#include "translation.h"
|
||||
#include "log.h"
|
||||
|
||||
|
@ -41,7 +42,7 @@ void PluginsActionController::registerPlugins()
|
|||
{
|
||||
dispatcher()->unReg(this);
|
||||
|
||||
for (const PluginInfo& plugin : service()->plugins().val) {
|
||||
for (const PluginInfo& plugin : values(service()->plugins().val)) {
|
||||
dispatcher()->reg(this, plugin.codeKey.toStdString(), [this, codeKey = plugin.codeKey]() {
|
||||
onPluginTriggered(codeKey);
|
||||
});
|
||||
|
@ -59,7 +60,7 @@ void PluginsActionController::onPluginTriggered(const CodeKey& codeKey)
|
|||
bool found = false;
|
||||
QString pluginName;
|
||||
|
||||
for (const PluginInfo& plugin : plugins) {
|
||||
for (const PluginInfo& plugin : values(plugins)) {
|
||||
if (plugin.codeKey == codeKey) {
|
||||
enabled = plugin.enabled;
|
||||
found = true;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "ui/uitypes.h"
|
||||
|
||||
#include "translation.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "view/pluginview.h"
|
||||
|
||||
#include "containers.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace mu::plugins;
|
||||
|
@ -56,17 +57,17 @@ void PluginsService::reloadPlugins()
|
|||
m_pluginsChanged.notify();
|
||||
}
|
||||
|
||||
mu::RetVal<PluginInfoList> PluginsService::plugins(PluginsStatus status) const
|
||||
mu::RetVal<PluginInfoMap> PluginsService::plugins(PluginsStatus status) const
|
||||
{
|
||||
PluginInfoList result;
|
||||
PluginInfoMap result;
|
||||
|
||||
for (const PluginInfo& plugin: m_plugins) {
|
||||
for (const PluginInfo& plugin: values(m_plugins)) {
|
||||
if (isAccepted(plugin.codeKey, status)) {
|
||||
result << plugin;
|
||||
result.insert({ plugin.codeKey, plugin });
|
||||
}
|
||||
}
|
||||
|
||||
return RetVal<PluginInfoList>::make_ok(result);
|
||||
return RetVal<PluginInfoMap>::make_ok(result);
|
||||
}
|
||||
|
||||
Notification PluginsService::pluginsChanged() const
|
||||
|
@ -74,6 +75,15 @@ Notification PluginsService::pluginsChanged() const
|
|||
return m_pluginsChanged;
|
||||
}
|
||||
|
||||
PluginsService::CategoryInfoMap PluginsService::categories() const
|
||||
{
|
||||
return {
|
||||
{ "composing-arranging-tools", trc("plugin", "Composing/arranging tools") },
|
||||
{ "color-notes", trc("plugin", "Colour notes") },
|
||||
{ "playback", trc("plugin", "Playback") }
|
||||
};
|
||||
}
|
||||
|
||||
bool PluginsService::isAccepted(const CodeKey& codeKey, PluginsStatus status) const
|
||||
{
|
||||
switch (status) {
|
||||
|
@ -84,11 +94,11 @@ bool PluginsService::isAccepted(const CodeKey& codeKey, PluginsStatus status) co
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginInfoList PluginsService::readPlugins() const
|
||||
PluginInfoMap PluginsService::readPlugins() const
|
||||
{
|
||||
TRACEFUNC;
|
||||
|
||||
PluginInfoList result;
|
||||
PluginInfoMap result;
|
||||
io::paths_t pluginsPaths = scanFileSystemForPlugins();
|
||||
|
||||
const PluginConfigurationHash& pluginsConfigurationHash = pluginsConfiguration();
|
||||
|
@ -104,12 +114,18 @@ PluginInfoList PluginsService::readPlugins() const
|
|||
info.description = view.description();
|
||||
info.version = view.version();
|
||||
info.enabled = pluginsConfigurationHash.value(info.codeKey).enabled;
|
||||
info.categoryCode = view.categoryCode();
|
||||
|
||||
QString thumbnailName = view.thumbnailName();
|
||||
if (!thumbnailName.isEmpty()) {
|
||||
info.thumbnailUrl = io::dirpath(pluginPath).toQString() + "/" + thumbnailName;
|
||||
}
|
||||
|
||||
auto sequences = shortcutsRegister()->shortcut(info.codeKey.toStdString()).sequences;
|
||||
info.shortcuts = Shortcut::sequencesToString(sequences);
|
||||
|
||||
if (info.isValid()) {
|
||||
result << info;
|
||||
result.insert({ info.codeKey, info });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,14 +187,14 @@ mu::Ret PluginsService::setEnable(const CodeKey& codeKey, bool enable)
|
|||
|
||||
PluginInfo& PluginsService::pluginInfo(const CodeKey& codeKey)
|
||||
{
|
||||
for (PluginInfo& plugin: m_plugins) {
|
||||
if (plugin.codeKey == codeKey) {
|
||||
return plugin;
|
||||
}
|
||||
auto it = m_plugins.find(codeKey);
|
||||
|
||||
if (it == m_plugins.end()) {
|
||||
static PluginInfo _dummy;
|
||||
return _dummy;
|
||||
}
|
||||
|
||||
static PluginInfo _dummy;
|
||||
return _dummy;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void PluginsService::registerShortcuts()
|
||||
|
@ -189,7 +205,8 @@ void PluginsService::registerShortcuts()
|
|||
|
||||
ShortcutList shortcuts;
|
||||
|
||||
for (const PluginInfo& plugin : m_plugins) {
|
||||
for (auto& it : m_plugins) {
|
||||
PluginInfo& plugin = it.second;
|
||||
Shortcut shortcut;
|
||||
shortcut.action = plugin.codeKey.toStdString();
|
||||
|
||||
|
@ -251,9 +268,10 @@ void PluginsService::onShortcutsChanged()
|
|||
|
||||
PluginConfigurationHash pluginsConfigurationHash = this->pluginsConfiguration();
|
||||
|
||||
PluginInfoList changedPlugins;
|
||||
std::vector<PluginInfo> changedPlugins;
|
||||
|
||||
for (PluginInfo& plugin : m_plugins) {
|
||||
for (auto& it : m_plugins) {
|
||||
PluginInfo& plugin = it.second;
|
||||
const Shortcut shortcut = shortcutsRegister()->shortcut(plugin.codeKey.toStdString());
|
||||
if (shortcut.sequences.empty() && !pluginsConfigurationHash.contains(plugin.codeKey)) {
|
||||
continue;
|
||||
|
|
|
@ -47,9 +47,11 @@ public:
|
|||
|
||||
void reloadPlugins() override;
|
||||
|
||||
mu::RetVal<PluginInfoList> plugins(PluginsStatus status = PluginsStatus::All) const override;
|
||||
mu::RetVal<PluginInfoMap> plugins(PluginsStatus status = PluginsStatus::All) const override;
|
||||
async::Notification pluginsChanged() const override;
|
||||
|
||||
CategoryInfoMap categories() const override;
|
||||
|
||||
Ret setEnable(const CodeKey& codeKey, bool enable) override;
|
||||
|
||||
Ret run(const CodeKey& codeKey) override;
|
||||
|
@ -64,14 +66,14 @@ private:
|
|||
const IPluginsConfiguration::PluginsConfigurationHash& pluginsConfiguration() const;
|
||||
void setPluginsConfiguration(const IPluginsConfiguration::PluginsConfigurationHash& pluginsConfiguration);
|
||||
|
||||
PluginInfoList readPlugins() const;
|
||||
PluginInfoMap readPlugins() const;
|
||||
io::paths_t scanFileSystemForPlugins() const;
|
||||
|
||||
PluginInfo& pluginInfo(const CodeKey& codeKey);
|
||||
|
||||
void registerShortcuts();
|
||||
|
||||
mutable PluginInfoList m_plugins;
|
||||
mutable PluginInfoMap m_plugins;
|
||||
async::Notification m_pluginsChanged;
|
||||
async::Channel<PluginInfo> m_pluginChanged;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "ui/view/iconcodes.h"
|
||||
#include "context/uicontext.h"
|
||||
|
||||
#include "containers.h"
|
||||
#include "translation.h"
|
||||
#include "log.h"
|
||||
|
||||
|
@ -46,7 +47,7 @@ const mu::ui::UiActionList& PluginsUiActions::actionsList() const
|
|||
{
|
||||
UiActionList result;
|
||||
|
||||
for (const PluginInfo& plugin : m_service->plugins().val) {
|
||||
for (const PluginInfo& plugin : values(m_service->plugins().val)) {
|
||||
UiAction action;
|
||||
action.code = codeFromQString(plugin.codeKey);
|
||||
action.context = mu::context::UiCtxNotationOpened;
|
||||
|
|
|
@ -42,9 +42,12 @@ public:
|
|||
|
||||
virtual void reloadPlugins() = 0;
|
||||
|
||||
virtual RetVal<PluginInfoList> plugins(PluginsStatus status = All) const = 0;
|
||||
virtual RetVal<PluginInfoMap> plugins(PluginsStatus status = All) const = 0;
|
||||
virtual async::Notification pluginsChanged() const = 0;
|
||||
|
||||
using CategoryInfoMap = std::map<std::string /*code*/, std::string /*title*/>;
|
||||
virtual CategoryInfoMap categories() const = 0;
|
||||
|
||||
virtual Ret setEnable(const CodeKey& codeKey, bool enable) = 0;
|
||||
|
||||
virtual Ret run(const CodeKey& codeKey) = 0;
|
||||
|
|
|
@ -4,13 +4,7 @@
|
|||
<file>qml/MuseScore/Plugins/PluginsPage.qml</file>
|
||||
<file>qml/MuseScore/Plugins/internal/PluginItem.qml</file>
|
||||
<file>qml/MuseScore/Plugins/internal/PluginsListView.qml</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder1.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder2.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder3.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder4.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder5.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder6.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder7.jpeg</file>
|
||||
<file>qml/MuseScore/Plugins/internal/EnablePanel.qml</file>
|
||||
<file>qml/MuseScore/Plugins/internal/placeholders/placeholder.jpeg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -40,7 +40,7 @@ struct PluginInfo
|
|||
QUrl detailsUrl;
|
||||
QString name;
|
||||
QString description;
|
||||
QString category;
|
||||
QString categoryCode;
|
||||
bool enabled = false;
|
||||
bool hasUpdate = false;
|
||||
QVersionNumber version;
|
||||
|
@ -50,7 +50,7 @@ struct PluginInfo
|
|||
bool operator==(const PluginInfo& other) const { return other.codeKey == codeKey; }
|
||||
};
|
||||
|
||||
using PluginInfoList = QList<PluginInfo>;
|
||||
using PluginInfoMap = std::map<CodeKey, PluginInfo>;
|
||||
}
|
||||
|
||||
#endif // MU_PLUGINS_IPLUGINSCONFIGURATION_H
|
||||
|
|
Before Width: | Height: | Size: 437 KiB After Width: | Height: | Size: 437 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 219 KiB |
Before Width: | Height: | Size: 253 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 97 KiB |
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "pluginsmodel.h"
|
||||
|
||||
#include "containers.h"
|
||||
#include "translation.h"
|
||||
#include "log.h"
|
||||
|
||||
|
@ -51,36 +52,19 @@ void PluginsModel::load()
|
|||
beginResetModel();
|
||||
m_plugins.clear();
|
||||
|
||||
// TODO: this is temporary solution and will be changed in future
|
||||
QList<QString> thumbnailUrlExamples {
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder1.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder2.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder3.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder4.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder5.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder6.jpeg",
|
||||
"qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder7.jpeg"
|
||||
};
|
||||
|
||||
QList<QString> categoriesExamples {
|
||||
"Simplified notation",
|
||||
"Other",
|
||||
"Accidentals",
|
||||
"Notes & Rests",
|
||||
"Chord symbols"
|
||||
};
|
||||
|
||||
RetVal<PluginInfoList> plugins = service()->plugins();
|
||||
RetVal<PluginInfoMap> plugins = service()->plugins();
|
||||
if (!plugins.ret) {
|
||||
LOGE() << plugins.ret.toString();
|
||||
}
|
||||
|
||||
for (int i = 0; i < plugins.val.size(); ++i) {
|
||||
plugins.val[i].thumbnailUrl = thumbnailUrlExamples[i % thumbnailUrlExamples.size()];
|
||||
plugins.val[i].category = categoriesExamples[i % categoriesExamples.size()];
|
||||
m_plugins << plugins.val[i];
|
||||
for (const PluginInfo& plugin : values(plugins.val)) {
|
||||
m_plugins << plugin;
|
||||
}
|
||||
|
||||
std::sort(m_plugins.begin(), m_plugins.end(), [](const PluginInfo& l, const PluginInfo& r) {
|
||||
return l.name < r.name;
|
||||
});
|
||||
|
||||
Channel<PluginInfo> pluginChanged = service()->pluginChanged();
|
||||
pluginChanged.onReceive(this, [this](const PluginInfo& plugin) {
|
||||
updatePlugin(plugin);
|
||||
|
@ -105,11 +89,16 @@ QVariant PluginsModel::data(const QModelIndex& index, int role) const
|
|||
case rDescription:
|
||||
return plugin.description;
|
||||
case rThumbnailUrl:
|
||||
//! TODO
|
||||
if (plugin.thumbnailUrl.isEmpty()) {
|
||||
return "qrc:/qml/MuseScore/Plugins/internal/placeholders/placeholder.jpeg";
|
||||
}
|
||||
|
||||
return plugin.thumbnailUrl;
|
||||
case rEnabled:
|
||||
return plugin.enabled;
|
||||
case rCategory:
|
||||
return plugin.category;
|
||||
return plugin.categoryCode;
|
||||
case rVersion:
|
||||
return plugin.version.toString();
|
||||
case rShortcuts:
|
||||
|
@ -169,15 +158,19 @@ void PluginsModel::reloadPlugins()
|
|||
service()->reloadPlugins();
|
||||
}
|
||||
|
||||
QStringList PluginsModel::categories() const
|
||||
QVariantList PluginsModel::categories() const
|
||||
{
|
||||
QSet<QString> result;
|
||||
QVariantList result;
|
||||
|
||||
for (const PluginInfo& plugin: m_plugins) {
|
||||
result << plugin.category;
|
||||
for (const auto& category: service()->categories()) {
|
||||
QVariantMap obj;
|
||||
obj["code"] = QString::fromStdString(category.first);
|
||||
obj["title"] = QString::fromStdString(category.second);
|
||||
|
||||
result << obj;
|
||||
}
|
||||
|
||||
return result.values();
|
||||
return result;
|
||||
}
|
||||
|
||||
void PluginsModel::updatePlugin(const PluginInfo& plugin)
|
||||
|
@ -187,7 +180,7 @@ void PluginsModel::updatePlugin(const PluginInfo& plugin)
|
|||
PluginInfo tmp = m_plugins[i];
|
||||
m_plugins[i] = plugin;
|
||||
m_plugins[i].thumbnailUrl = tmp.thumbnailUrl;
|
||||
m_plugins[i].category = tmp.category;
|
||||
m_plugins[i].categoryCode = tmp.categoryCode;
|
||||
QModelIndex index = createIndex(i, 0);
|
||||
emit dataChanged(index, index);
|
||||
return;
|
||||
|
|
|
@ -22,22 +22,24 @@
|
|||
#ifndef MU_PLUGINS_PLUGINSMODEL_H
|
||||
#define MU_PLUGINS_PLUGINSMODEL_H
|
||||
|
||||
#include "ipluginsservice.h"
|
||||
#include "iinteractive.h"
|
||||
|
||||
#include "modularity/ioc.h"
|
||||
#include "async/asyncable.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
|
||||
#include "async/asyncable.h"
|
||||
|
||||
#include "modularity/ioc.h"
|
||||
#include "iinteractive.h"
|
||||
#include "ipluginsservice.h"
|
||||
#include "ipluginsconfiguration.h"
|
||||
|
||||
namespace mu::plugins {
|
||||
class PluginsModel : public QAbstractListModel, public async::Asyncable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
INJECT(plugins, IPluginsService, service)
|
||||
INJECT(plugins, framework::IInteractive, interactive)
|
||||
INJECT(plugins, IPluginsService, service)
|
||||
INJECT(plugins, IPluginsConfiguration, configuration)
|
||||
|
||||
public:
|
||||
explicit PluginsModel(QObject* parent = nullptr);
|
||||
|
@ -51,7 +53,7 @@ public:
|
|||
Q_INVOKABLE void editShortcut(QString codeKey);
|
||||
Q_INVOKABLE void reloadPlugins();
|
||||
|
||||
Q_INVOKABLE QStringList categories() const;
|
||||
Q_INVOKABLE QVariantList categories() const;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
|
|
@ -99,6 +99,24 @@ QVersionNumber PluginView::version() const
|
|||
return QVersionNumber::fromString(m_qmlPlugin->version());
|
||||
}
|
||||
|
||||
QString PluginView::thumbnailName() const
|
||||
{
|
||||
IF_ASSERT_FAILED(m_qmlPlugin) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return m_qmlPlugin->thumbnailName();
|
||||
}
|
||||
|
||||
QString PluginView::categoryCode() const
|
||||
{
|
||||
IF_ASSERT_FAILED(m_qmlPlugin) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return m_qmlPlugin->categoryCode();
|
||||
}
|
||||
|
||||
void PluginView::run()
|
||||
{
|
||||
IF_ASSERT_FAILED(m_qmlPlugin && m_component) {
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
QString name() const;
|
||||
QString description() const;
|
||||
QVersionNumber version() const;
|
||||
QString thumbnailName() const;
|
||||
QString categoryCode() const;
|
||||
|
||||
void run();
|
||||
|
||||
|
|