3
0
mirror of https://github.com/Qortal/Brooklyn.git synced 2025-02-20 22:25:54 +00:00
2022-03-05 22:41:29 +05:00

421 lines
12 KiB
C++

/*
SPDX-FileCopyrightText: 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "plasmaappletitemmodel_p.h"
#include <QFileInfo>
#include <QMimeData>
#include <QStandardPaths>
#include "config-workspace.h"
#include <KAboutData>
#include <KConfig>
#include <KDeclarative/KDeclarative>
#include <KJsonUtils>
#include <KLocalizedString>
#include <KPackage/PackageLoader>
#include <KSycoca>
PlasmaAppletItem::PlasmaAppletItem(const KPluginMetaData &info)
: AbstractItem()
, m_info(info)
, m_runningCount(0)
, m_local(false)
{
const QString api(m_info.value(QStringLiteral("X-Plasma-API")));
if (!api.isEmpty()) {
const QString _f = PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/" + info.pluginId() + '/';
QFileInfo dir(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation, _f, QStandardPaths::LocateDirectory));
m_local = dir.exists() && dir.isWritable();
}
setText(m_info.name() + " - " + m_info.category().toLower());
if (QIcon::hasThemeIcon(info.pluginId())) {
setIcon(QIcon::fromTheme(info.pluginId()));
} else if (!m_info.iconName().isEmpty()) {
setIcon(QIcon::fromTheme(info.iconName()));
} else {
setIcon(QIcon::fromTheme(QStringLiteral("application-x-plasma")));
}
// set plugininfo parts as roles in the model, only way qml can understand it
setData(name(), PlasmaAppletItemModel::NameRole);
setData(pluginName(), PlasmaAppletItemModel::PluginNameRole);
setData(description(), PlasmaAppletItemModel::DescriptionRole);
setData(category().toLower(), PlasmaAppletItemModel::CategoryRole);
setData(license(), PlasmaAppletItemModel::LicenseRole);
setData(website(), PlasmaAppletItemModel::WebsiteRole);
setData(version(), PlasmaAppletItemModel::VersionRole);
setData(author(), PlasmaAppletItemModel::AuthorRole);
setData(email(), PlasmaAppletItemModel::EmailRole);
setData(0, PlasmaAppletItemModel::RunningRole);
setData(m_local, PlasmaAppletItemModel::LocalRole);
}
QString PlasmaAppletItem::pluginName() const
{
return m_info.pluginId();
}
QString PlasmaAppletItem::name() const
{
return m_info.name();
}
QString PlasmaAppletItem::description() const
{
return m_info.description();
}
QString PlasmaAppletItem::license() const
{
return m_info.license();
}
QString PlasmaAppletItem::category() const
{
return m_info.category();
}
QString PlasmaAppletItem::website() const
{
return m_info.website();
}
QString PlasmaAppletItem::version() const
{
return m_info.version();
}
QString PlasmaAppletItem::author() const
{
if (m_info.authors().isEmpty()) {
return QString();
}
return m_info.authors().constFirst().name();
}
QString PlasmaAppletItem::email() const
{
if (m_info.authors().isEmpty()) {
return QString();
}
return m_info.authors().constFirst().emailAddress();
}
int PlasmaAppletItem::running() const
{
return m_runningCount;
}
void PlasmaAppletItem::setRunning(int count)
{
m_runningCount = count;
setData(count, PlasmaAppletItemModel::RunningRole);
emitDataChanged();
}
bool PlasmaAppletItem::matches(const QString &pattern) const
{
const QJsonObject rawData = m_info.rawData();
const QString keywordsList = KJsonUtils::readTranslatedString(rawData, QStringLiteral("Keywords"));
auto keywords = keywordsList.splitRef(QLatin1Char(';'), Qt::SkipEmptyParts);
// Add English name and keywords so users in other languages won't have to switch IME when searching.
if (!QLocale().name().startsWith(QLatin1String("en_"))) {
const QString name(rawData[QStringLiteral("KPlugin")][QStringLiteral("Name")].toString());
keywords << &name << m_info.value(QStringLiteral("Keywords"), QString()).splitRef(QLatin1Char(';'), Qt::SkipEmptyParts);
}
for (const auto &keyword : keywords) {
if (keyword.startsWith(pattern, Qt::CaseInsensitive)) {
return true;
}
}
return AbstractItem::matches(pattern);
}
bool PlasmaAppletItem::isLocal() const
{
return m_local;
}
bool PlasmaAppletItem::passesFiltering(const KCategorizedItemsViewModels::Filter &filter) const
{
if (filter.first == QLatin1String("running")) {
return running();
} else if (filter.first == QLatin1String("local")) {
return isLocal();
} else if (filter.first == QLatin1String("category")) {
return m_info.category().toLower() == filter.second;
} else {
return false;
}
}
QMimeData *PlasmaAppletItem::mimeData() const
{
QMimeData *data = new QMimeData();
QByteArray appletName;
appletName += pluginName().toUtf8();
data->setData(mimeTypes().at(0), appletName);
return data;
}
QStringList PlasmaAppletItem::mimeTypes() const
{
QStringList types;
types << QStringLiteral("text/x-plasmoidservicename");
return types;
}
QVariant PlasmaAppletItem::data(int role) const
{
switch (role) {
case PlasmaAppletItemModel::ScreenshotRole:
// null = not yet done, empty = tried and failed
if (m_screenshot.isNull()) {
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Applet"));
pkg.setDefaultPackageRoot(QStringLiteral("plasma/plasmoids"));
pkg.setPath(m_info.pluginId());
if (pkg.isValid()) {
const_cast<PlasmaAppletItem *>(this)->m_screenshot = pkg.filePath("screenshot");
} else {
const_cast<PlasmaAppletItem *>(this)->m_screenshot = QString();
}
} else if (m_screenshot.isEmpty()) {
return QVariant();
}
return m_screenshot;
case Qt::DecorationRole: {
// null = not yet done, empty = tried and failed
if (m_icon.isNull()) {
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Applet"));
pkg.setDefaultPackageRoot(QStringLiteral("plasma/plasmoids"));
pkg.setPath(m_info.pluginId());
if (pkg.isValid() && pkg.metadata().iconName().startsWith(QLatin1String("/"))) {
const_cast<PlasmaAppletItem *>(this)->m_icon = pkg.filePath("", pkg.metadata().iconName().toUtf8());
} else {
const_cast<PlasmaAppletItem *>(this)->m_icon = QString();
return AbstractItem::data(role);
}
}
if (m_icon.isEmpty()) {
return AbstractItem::data(role);
}
return QIcon(m_icon);
}
default:
return AbstractItem::data(role);
}
}
// PlasmaAppletItemModel
PlasmaAppletItemModel::PlasmaAppletItemModel(QObject *parent)
: QStandardItemModel(parent)
, m_startupCompleted(false)
{
connect(KSycoca::self(), &KSycoca::databaseChanged, this, &PlasmaAppletItemModel::populateModel);
setSortRole(Qt::DisplayRole);
}
QHash<int, QByteArray> PlasmaAppletItemModel::roleNames() const
{
QHash<int, QByteArray> newRoleNames = QAbstractItemModel::roleNames();
newRoleNames[NameRole] = "name";
newRoleNames[PluginNameRole] = "pluginName";
newRoleNames[DescriptionRole] = "description";
newRoleNames[CategoryRole] = "category";
newRoleNames[LicenseRole] = "license";
newRoleNames[WebsiteRole] = "website";
newRoleNames[VersionRole] = "version";
newRoleNames[AuthorRole] = "author";
newRoleNames[EmailRole] = "email";
newRoleNames[RunningRole] = "running";
newRoleNames[LocalRole] = "local";
newRoleNames[ScreenshotRole] = "screenshot";
return newRoleNames;
}
void PlasmaAppletItemModel::populateModel()
{
clear();
auto filter = [this](const KPluginMetaData &plugin) -> bool {
const QStringList provides = plugin.value(QStringLiteral("X-Plasma-Provides"), QStringList());
if (!m_provides.isEmpty()) {
const bool providesFulfilled = std::any_of(m_provides.cbegin(), m_provides.cend(), [&provides](const QString &p) {
return provides.contains(p);
});
if (!providesFulfilled) {
return false;
}
}
if (!plugin.isValid() || plugin.rawData().value(QStringLiteral("NoDisplay")).toBool() || plugin.category() == QLatin1String("Containments")) {
// we don't want to show the hidden category
return false;
}
static const auto formFactors = KDeclarative::KDeclarative::runtimePlatform();
// If runtimePlatformis not defined, accept everything
bool inFormFactor = formFactors.isEmpty();
for (const QString &formFactor : formFactors) {
if (plugin.formFactors().isEmpty() || plugin.formFactors().contains(formFactor)) {
inFormFactor = true;
break;
}
}
if (!inFormFactor) {
return false;
}
return true;
};
const QList<KPluginMetaData> packages =
KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QStringLiteral("plasma/plasmoids"), filter);
for (const KPluginMetaData &plugin : packages) {
appendRow(new PlasmaAppletItem(plugin));
}
Q_EMIT modelPopulated();
}
void PlasmaAppletItemModel::setRunningApplets(const QHash<QString, int> &apps)
{
// for each item, find that string and set the count
for (int r = 0; r < rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p) {
const int running = apps.value(p->pluginName());
p->setRunning(running);
}
}
}
void PlasmaAppletItemModel::setRunningApplets(const QString &name, int count)
{
for (int r = 0; r < rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p && p->pluginName() == name) {
p->setRunning(count);
}
}
}
QStringList PlasmaAppletItemModel::mimeTypes() const
{
QStringList types;
types << QStringLiteral("text/x-plasmoidservicename");
return types;
}
QSet<QString> PlasmaAppletItemModel::categories() const
{
QSet<QString> cats;
for (int r = 0; r < rowCount(); ++r) {
QStandardItem *i = item(r);
PlasmaAppletItem *p = dynamic_cast<PlasmaAppletItem *>(i);
if (p) {
cats.insert(p->category().toLower());
}
}
return cats;
}
QMimeData *PlasmaAppletItemModel::mimeData(const QModelIndexList &indexes) const
{
if (indexes.count() <= 0) {
return nullptr;
}
QStringList types = mimeTypes();
if (types.isEmpty()) {
return nullptr;
}
QMimeData *data = new QMimeData();
QString format = types.at(0);
QByteArray appletNames;
int lastRow = -1;
for (const QModelIndex &index : indexes) {
if (index.row() == lastRow) {
continue;
}
lastRow = index.row();
PlasmaAppletItem *selectedItem = (PlasmaAppletItem *)itemFromIndex(index);
appletNames += '\n' + selectedItem->pluginName().toUtf8();
// qDebug() << selectedItem->pluginName() << index.column() << index.row();
}
data->setData(format, appletNames);
return data;
}
QStringList PlasmaAppletItemModel::provides() const
{
return m_provides;
}
void PlasmaAppletItemModel::setProvides(const QStringList &provides)
{
if (m_provides == provides) {
return;
}
m_provides = provides;
if (m_startupCompleted) {
populateModel();
}
}
void PlasmaAppletItemModel::setApplication(const QString &app)
{
m_application = app;
if (m_startupCompleted) {
populateModel();
}
}
bool PlasmaAppletItemModel::startupCompleted() const
{
return m_startupCompleted;
}
void PlasmaAppletItemModel::setStartupCompleted(bool complete)
{
m_startupCompleted = complete;
}
QString &PlasmaAppletItemModel::Application()
{
return m_application;
}
//#include <plasmaappletitemmodel_p.moc>