diff --git a/components/shellprivate/widgetexplorer/plasmaappletitemmodel.cpp b/components/shellprivate/widgetexplorer/plasmaappletitemmodel.cpp index 0d0e749b2..1ae2984b9 100644 --- a/components/shellprivate/widgetexplorer/plasmaappletitemmodel.cpp +++ b/components/shellprivate/widgetexplorer/plasmaappletitemmodel.cpp @@ -1,457 +1,472 @@ /* * Copyright (C) 2007 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library/Lesser General Public License * version 2, or (at your option) any later version, as published by the * Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library/Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "plasmaappletitemmodel_p.h" #include #include #include #include #include #include #include "config-workspace.h" #include #include #include PlasmaAppletItem::PlasmaAppletItem(PlasmaAppletItemModel *model, const KPluginInfo& info, FilterFlags flags) : QObject(model), m_model(model), m_info(info), m_runningCount(0), m_favorite(flags & Favorite), m_local(false) { const QString api(m_info.property(QStringLiteral("X-Plasma-API")).toString()); if (!api.isEmpty()) { const QString _f = PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/" + info.pluginName() + '/'; QFileInfo dir(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation, _f, QStandardPaths::LocateDirectory)); m_local = dir.exists() && dir.isWritable(); } //attrs.insert("recommended", flags & Recommended ? true : false); setText(m_info.name() + " - "+ m_info.category().toLower()); if (QIcon::hasThemeIcon(info.pluginName())) { setIcon(QIcon::fromTheme(info.pluginName())); } else if (!m_info.icon().isEmpty()) { setIcon(QIcon::fromTheme(info.icon())); } else { setIcon(QIcon::fromTheme(QStringLiteral("application-x-plasma"))); } //set plugininfo parts as roles in the model, only way qml can understand it setData(info.name(), PlasmaAppletItemModel::NameRole); setData(info.pluginName(), PlasmaAppletItemModel::PluginNameRole); setData(info.comment(), PlasmaAppletItemModel::DescriptionRole); setData(info.category().toLower(), PlasmaAppletItemModel::CategoryRole); setData(info.license(), PlasmaAppletItemModel::LicenseRole); setData(info.website(), PlasmaAppletItemModel::WebsiteRole); setData(info.version(), PlasmaAppletItemModel::VersionRole); setData(info.author(), PlasmaAppletItemModel::AuthorRole); setData(info.email(), PlasmaAppletItemModel::EmailRole); setData(0, PlasmaAppletItemModel::RunningRole); setData(m_local, PlasmaAppletItemModel::LocalRole); } QString PlasmaAppletItem::pluginName() const { return m_info.pluginName(); } QString PlasmaAppletItem::name() const { return m_info.name(); } QString PlasmaAppletItem::description() const { return m_info.comment(); } 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 { return m_info.author(); } QString PlasmaAppletItem::email() const { return m_info.email(); } 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 { if (m_info.service()) { const QStringList keywords = m_info.property(QStringLiteral("Keywords")).toStringList(); foreach (const QString &keyword, keywords) { if (keyword.startsWith(pattern, Qt::CaseInsensitive)) { return true; } } } return AbstractItem::matches(pattern); } bool PlasmaAppletItem::isFavorite() const { return m_favorite; } void PlasmaAppletItem::setFavorite(bool favorite) { if (m_favorite != favorite) { m_favorite = favorite; m_model->setFavorite(m_info.pluginName(), favorite); emitDataChanged(); } } 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; } PlasmaAppletItemModel* PlasmaAppletItem::appletItemModel() { return m_model; } 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.pluginName()); if (pkg.isValid()) { const_cast(this)->m_screenshot = pkg.filePath("screenshot"); } else { const_cast(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.pluginName()); if (pkg.isValid() && pkg.metadata().iconName().startsWith(QLatin1String("/"))) { const_cast(this)->m_icon = pkg.filePath("", pkg.metadata().iconName().toUtf8()); } else { const_cast(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) + : QStandardItemModel(parent), + m_startupCompleted(false) { KConfig config(QStringLiteral("plasmarc")); m_configGroup = KConfigGroup(&config, "Applet Browser"); m_favorites = m_configGroup.readEntry("favorites").split(','); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(populateModel(QStringList))); setSortRole(Qt::DisplayRole); } QHash PlasmaAppletItemModel::roleNames() const { QHash 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(const QStringList &whatChanged) { if (!whatChanged.isEmpty() && !whatChanged.contains(QStringLiteral("services"))) { return; } clear(); //qDebug() << "populating model, our application is" << m_application; //qDebug() << "number of applets is" // << Plasma::Applet::listAppletInfo(QString(), m_application).count(); QString constraint; bool first = true; foreach (const QString prov, m_provides) { if (!first) { constraint += QLatin1String(" or "); } first = false; constraint += "'" + prov + "' in [X-Plasma-Provides]"; } KPluginInfo::List list = KPluginInfo::fromMetaData(KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Applet"), QStringLiteral("plasma/plasmoids")).toVector()); KPluginTrader::applyConstraints(list, constraint); for (auto info : list) { //qDebug() << info.pluginName() << "NoDisplay" << info.property("NoDisplay").toBool(); if (!info.isValid() || info.property(QStringLiteral("NoDisplay")).toBool() || info.category() == QLatin1String("Containments")) { // we don't want to show the hidden category continue; } bool inFormFactor = true; foreach (const QString &formFactor, KDeclarative::KDeclarative::runtimePlatform()) { if (!info.formFactors().isEmpty() && !info.formFactors().contains(formFactor)) { inFormFactor = false; } } if (!inFormFactor) { continue; } //qDebug() << info.pluginName() << " is the name of the plugin at" << info.entryPath(); //qDebug() << info.name() << info.property("X-Plasma-Thumbnail"); PlasmaAppletItem::FilterFlags flags(PlasmaAppletItem::NoFilter); if (m_favorites.contains(info.pluginName())) { flags |= PlasmaAppletItem::Favorite; } appendRow(new PlasmaAppletItem(this, info, flags)); } emit modelPopulated(); } void PlasmaAppletItemModel::setRunningApplets(const QHash &apps) { //foreach item, find that string and set the count for (int r = 0; r < rowCount(); ++r) { QStandardItem *i = item(r); PlasmaAppletItem *p = dynamic_cast(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(i); if (p && p->pluginName() == name) { p->setRunning(count); } } } QStringList PlasmaAppletItemModel::mimeTypes() const { QStringList types; types << QStringLiteral("text/x-plasmoidservicename"); return types; } QSet PlasmaAppletItemModel::categories() const { QSet cats; for (int r = 0; r < rowCount(); ++r) { QStandardItem *i = item(r); PlasmaAppletItem *p = dynamic_cast(i); if (p) { cats.insert(p->category().toLower()); } } return cats; } QMimeData *PlasmaAppletItemModel::mimeData(const QModelIndexList &indexes) const { //qDebug() << "GETTING MIME DATA\n"; if (indexes.count() <= 0) { return 0; } QStringList types = mimeTypes(); if (types.isEmpty()) { return 0; } QMimeData *data = new QMimeData(); QString format = types.at(0); QByteArray appletNames; int lastRow = -1; foreach (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; } void PlasmaAppletItemModel::setFavorite(const QString &plugin, bool favorite) { if (favorite) { if (!m_favorites.contains(plugin)) { m_favorites.append(plugin); } } else { m_favorites.removeAll(plugin); } m_configGroup.writeEntry("favorites", m_favorites.join(QStringLiteral(","))); m_configGroup.sync(); } QStringList PlasmaAppletItemModel::provides() const { return m_provides; } void PlasmaAppletItemModel::setProvides(const QStringList &provides) { if (m_provides == provides) { return; } m_provides = provides; - populateModel(); + if (m_startupCompleted) { + populateModel(); + } } void PlasmaAppletItemModel::setApplication(const QString &app) { m_application = app; - populateModel(); + 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 diff --git a/components/shellprivate/widgetexplorer/plasmaappletitemmodel_p.h b/components/shellprivate/widgetexplorer/plasmaappletitemmodel_p.h index 8189ba7e4..8919fbd47 100644 --- a/components/shellprivate/widgetexplorer/plasmaappletitemmodel_p.h +++ b/components/shellprivate/widgetexplorer/plasmaappletitemmodel_p.h @@ -1,134 +1,138 @@ /* * Copyright (C) 2007 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library/Lesser General Public License * version 2, or (at your option) any later version, as published by the * Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library/Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PLASMA_PLASMAAPPLETITEMMODEL_P_H #define PLASMA_PLASMAAPPLETITEMMODEL_P_H #include #include #include "kcategorizeditemsviewmodels_p.h" class PlasmaAppletItemModel; /** * Implementation of the KCategorizedItemsViewModels::AbstractItem */ class PlasmaAppletItem : public QObject, public KCategorizedItemsViewModels::AbstractItem { Q_OBJECT public: enum FilterFlag { NoFilter = 0, Favorite = 1 }; Q_DECLARE_FLAGS(FilterFlags, FilterFlag) PlasmaAppletItem(PlasmaAppletItemModel *model, const KPluginInfo& info, FilterFlags flags = NoFilter); QString pluginName() const; QString name() const override; QString category() const; QString description() const override; QString license() const; QString website() const; QString version() const; QString author() const; QString email() const; QVariant data(int role = Qt::UserRole + 1) const override; int running() const override; bool isLocal() const; bool isFavorite() const override; void setFavorite(bool favorite) override; PlasmaAppletItemModel* appletItemModel(); bool matches(const QString &pattern) const override; //set how many instances of this applet are running void setRunning(int count) override; bool passesFiltering(const KCategorizedItemsViewModels::Filter & filter) const override; QMimeData *mimeData() const; QStringList mimeTypes() const; private: PlasmaAppletItemModel * m_model; KPluginInfo m_info; QString m_screenshot; QString m_icon; int m_runningCount; bool m_favorite; bool m_local; }; class PlasmaAppletItemModel : public QStandardItemModel { Q_OBJECT public: enum Roles { NameRole = Qt::UserRole+1, PluginNameRole = Qt::UserRole+2, DescriptionRole = Qt::UserRole+3, CategoryRole = Qt::UserRole+4, LicenseRole = Qt::UserRole+5, WebsiteRole = Qt::UserRole+6, VersionRole = Qt::UserRole+7, AuthorRole = Qt::UserRole+8, EmailRole = Qt::UserRole+9, RunningRole = Qt::UserRole+10, LocalRole = Qt::UserRole+11, ScreenshotRole = Qt::UserRole+12 }; explicit PlasmaAppletItemModel(QObject * parent = 0); QStringList mimeTypes() const override; QSet categories() const; QMimeData *mimeData(const QModelIndexList &indexes) const override; void setFavorite(const QString &plugin, bool favorite); void setApplication(const QString &app); void setRunningApplets(const QHash &apps); void setRunningApplets(const QString &name, int count); QString &Application(); QStringList provides() const; void setProvides(const QStringList &provides); QHash roleNames() const override; + bool startupCompleted() const; + void setStartupCompleted(bool complete); + Q_SIGNALS: void modelPopulated(); private: QString m_application; QStringList m_favorites; QStringList m_provides; KConfigGroup m_configGroup; + bool m_startupCompleted : 1; private Q_SLOTS: void populateModel(const QStringList &whatChanged = QStringList()); }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlasmaAppletItem::FilterFlags) #endif /*PLASMAAPPLETSMODEL_H_*/ diff --git a/components/shellprivate/widgetexplorer/widgetexplorer.cpp b/components/shellprivate/widgetexplorer/widgetexplorer.cpp index d4b903550..914368ab1 100644 --- a/components/shellprivate/widgetexplorer/widgetexplorer.cpp +++ b/components/shellprivate/widgetexplorer/widgetexplorer.cpp @@ -1,509 +1,510 @@ /* * Copyright (C) 2007 by Ivan Cukic * Copyright (C) 2009 by Ana Cecília Martins * Copyright 2013 by Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library/Lesser General Public License * version 2, or (at your option) any later version, as published by the * Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library/Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "widgetexplorer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kcategorizeditemsviewmodels_p.h" #include "plasmaappletitemmodel_p.h" #include "openwidgetassistant_p.h" #include "config-workspace.h" using namespace KActivities; using namespace KCategorizedItemsViewModels; using namespace Plasma; WidgetAction::WidgetAction(QObject *parent) : QAction(parent) { } WidgetAction::WidgetAction(const QIcon &icon, const QString &text, QObject *parent) : QAction(icon, text, parent) { } class WidgetExplorerPrivate { public: WidgetExplorerPrivate(WidgetExplorer *w) : q(w), containment(0), itemModel(w), filterModel(w), activitiesConsumer(new KActivities::Consumer()) { QObject::connect(activitiesConsumer.data(), &Consumer::currentActivityChanged, q, [this] { initRunningApplets(); }); } void initFilters(); void initRunningApplets(); void containmentDestroyed(); void addContainment(Containment *containment); /** * Tracks a new running applet */ void appletAdded(Plasma::Applet *applet); /** * A running applet is no more */ void appletRemoved(Plasma::Applet *applet); WidgetExplorer *q; QString application; Plasma::Containment *containment; QHash runningApplets; // applet name => count //extra hash so we can look up the names of deleted applets QHash appletNames; QPointer openAssistant; KPackage::Package *package; PlasmaAppletItemModel itemModel; KCategorizedItemsViewModels::DefaultFilterModel filterModel; bool showSpecialFilters = true; DefaultItemFilterProxyModel filterItemModel; QPointer newStuffDialog; QScopedPointer activitiesConsumer; }; void WidgetExplorerPrivate::initFilters() { filterModel.clear(); filterModel.addFilter(i18n("All Widgets"), KCategorizedItemsViewModels::Filter(), QIcon::fromTheme(QStringLiteral("plasma"))); if (showSpecialFilters) { // Filters: Special filterModel.addFilter(i18n("Running"), KCategorizedItemsViewModels::Filter(QStringLiteral("running"), true), QIcon::fromTheme(QStringLiteral("dialog-ok"))); filterModel.addFilter(i18n("Uninstallable"), KCategorizedItemsViewModels::Filter(QStringLiteral("local"), true), QIcon::fromTheme(QStringLiteral("list-remove"))); filterModel.addSeparator(i18n("Categories:")); } typedef QPair catPair; QMap categories; QSet existingCategories = itemModel.categories(); //foreach (const QString &category, Plasma::Applet::listCategories(application)) { QStringList cats; const QList list = PluginLoader::self()->listAppletInfo(QString()); for (auto& info : list) { if (!info.isValid()) { continue; } if (info.property(QStringLiteral("NoDisplay")).toBool() || info.category() == QLatin1String("Containments") || info.category().isEmpty()) { // we don't want to show the hidden category continue; } const QString c = info.category(); if (-1 == cats.indexOf(c)) { cats << c; } } qWarning() << "TODO: port listCategories()"; foreach (const QString &category, cats) { const QString lowerCaseCat = category.toLower(); if (existingCategories.contains(lowerCaseCat)) { const QString trans = i18nd("libplasma5", category.toLocal8Bit()); categories.insert(trans.toLower(), qMakePair(trans, lowerCaseCat)); } } foreach (const catPair &category, categories) { filterModel.addFilter(category.first, KCategorizedItemsViewModels::Filter(QStringLiteral("category"), category.second)); } } void WidgetExplorer::classBegin() { } void WidgetExplorer::componentComplete() { + d->itemModel.setStartupCompleted(true); setApplication(); d->initRunningApplets(); } QObject *WidgetExplorer::widgetsModel() const { return &d->filterItemModel; } QObject *WidgetExplorer::filterModel() const { return &d->filterModel; } bool WidgetExplorer::showSpecialFilters() const { return d->showSpecialFilters; } void WidgetExplorer::setShowSpecialFilters(bool show) { if (d->showSpecialFilters != show) { d->showSpecialFilters = show; d->initFilters(); emit showSpecialFiltersChanged(); } } QList WidgetExplorer::widgetsMenuActions() { QList actionList; QSignalMapper *mapper = new QSignalMapper(this); QObject::connect(mapper, SIGNAL(mapped(QString)), this, SLOT(downloadWidgets(QString))); WidgetAction *action = new WidgetAction(QIcon::fromTheme(QStringLiteral("applications-internet")), i18n("Download New Plasma Widgets"), this); QObject::connect(action, SIGNAL(triggered(bool)), mapper, SLOT(map())); mapper->setMapping(action, QString()); actionList << action; action = new WidgetAction(this); action->setSeparator(true); actionList << action; action = new WidgetAction(QIcon::fromTheme(QStringLiteral("package-x-generic")), i18n("Install Widget From Local File..."), this); QObject::connect(action, &QAction::triggered, this, &WidgetExplorer::openWidgetFile); actionList << action; return actionList; } QList WidgetExplorer::extraActions() const { QList actionList; // foreach (QAction *action, actions()) { // FIXME: where did actions() come from? // actionList << action; // } qWarning() << "extraactions needs reimplementation"; return actionList; } void WidgetExplorerPrivate::initRunningApplets() { //get applets from corona, count them, send results to model if (!containment) { return; } Plasma::Corona *c = containment->corona(); //we've tried our best to get a corona //we don't want just one containment, we want them all if (!c) { qWarning() << "WidgetExplorer failed to find corona"; return; } appletNames.clear(); runningApplets.clear(); const QList containments = c->containments(); for (Containment *containment : containments) { if (containment->containmentType() == Plasma::Types::DesktopContainment && containment->activity() != activitiesConsumer->currentActivity()) { continue; } addContainment(containment); } //qDebug() << runningApplets; itemModel.setRunningApplets(runningApplets); } void WidgetExplorerPrivate::addContainment(Containment *containment) { QObject::connect(containment, SIGNAL(appletAdded(Plasma::Applet*)), q, SLOT(appletAdded(Plasma::Applet*))); QObject::connect(containment, SIGNAL(appletRemoved(Plasma::Applet*)), q, SLOT(appletRemoved(Plasma::Applet*))); foreach (Applet *applet, containment->applets()) { if (applet->pluginMetaData().isValid()) { Containment *childContainment = applet->property("containment").value(); if (childContainment) { addContainment(childContainment); } runningApplets[applet->pluginMetaData().pluginId()]++; } else { qDebug() << "Invalid plugin metadata. :("; } } } void WidgetExplorerPrivate::containmentDestroyed() { containment = 0; } void WidgetExplorerPrivate::appletAdded(Plasma::Applet *applet) { if (!applet->pluginMetaData().isValid()) { return; } QString name = applet->pluginMetaData().pluginId(); runningApplets[name]++; appletNames.insert(applet, name); itemModel.setRunningApplets(name, runningApplets[name]); } void WidgetExplorerPrivate::appletRemoved(Plasma::Applet *applet) { QString name = appletNames.take(applet); int count = 0; if (runningApplets.contains(name)) { count = runningApplets[name] - 1; if (count < 1) { runningApplets.remove(name); } else { runningApplets[name] = count; } } itemModel.setRunningApplets(name, count); } //WidgetExplorer WidgetExplorer::WidgetExplorer(QObject *parent) : QObject(parent), d(new WidgetExplorerPrivate(this)) { d->filterItemModel.setSortCaseSensitivity(Qt::CaseInsensitive); d->filterItemModel.setDynamicSortFilter(true); d->filterItemModel.setSourceModel(&d->itemModel); d->filterItemModel.sort(0); } WidgetExplorer::~WidgetExplorer() { delete d; } void WidgetExplorer::setApplication(const QString &app) { if (d->application == app && !app.isEmpty()) { return; } d->application = app; d->itemModel.setApplication(app); d->initFilters(); d->itemModel.setRunningApplets(d->runningApplets); emit applicationChanged(); } QString WidgetExplorer::application() { return d->application; } QStringList WidgetExplorer::provides() const { return d->itemModel.provides(); } void WidgetExplorer::setProvides(const QStringList &provides) { if (d->itemModel.provides() == provides) { return; } d->itemModel.setProvides(provides); emit providesChanged(); } void WidgetExplorer::setContainment(Plasma::Containment *containment) { if (d->containment != containment) { if (d->containment) { d->containment->disconnect(this); } d->containment = containment; if (d->containment) { connect(d->containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed())); connect(d->containment, &Applet::immutabilityChanged, this, &WidgetExplorer::immutabilityChanged); } d->initRunningApplets(); emit containmentChanged(); } } Containment *WidgetExplorer::containment() const { return d->containment; } Plasma::Corona *WidgetExplorer::corona() const { if (d->containment) { return d->containment->corona(); } return 0; } void WidgetExplorer::addApplet(const QString &pluginName) { const QString p = PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/"+pluginName; qWarning() << "--------> load applet: " << pluginName << " relpath: " << p; QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, p, QStandardPaths::LocateDirectory); qDebug() << " .. pathes: " << dirs; if (!dirs.count()) { qWarning() << "Failed to find plasmoid path for " << pluginName; return; } if (d->containment) { d->containment->createApplet(dirs.first()); } } void WidgetExplorer::immutabilityChanged(Plasma::Types::ImmutabilityType type) { if (type != Plasma::Types::Mutable) { emit shouldClose(); } } void WidgetExplorer::downloadWidgets(const QString &type) { Q_UNUSED(type); if (!d->newStuffDialog) { d->newStuffDialog = new KNS3::DownloadDialog( QLatin1String("plasmoids.knsrc") ); d->newStuffDialog.data()->setWindowTitle(i18n("Download New Plasma Widgets")); connect(d->newStuffDialog.data(), SIGNAL(accepted()), SLOT(newStuffFinished())); } d->newStuffDialog.data()->show(); emit shouldClose(); } void WidgetExplorer::openWidgetFile() { Plasma::OpenWidgetAssistant *assistant = d->openAssistant.data(); if (!assistant) { assistant = new Plasma::OpenWidgetAssistant(0); d->openAssistant = assistant; } KWindowSystem::setOnDesktop(assistant->winId(), KWindowSystem::currentDesktop()); assistant->setAttribute(Qt::WA_DeleteOnClose, true); assistant->show(); assistant->raise(); assistant->setFocus(); emit shouldClose(); } void WidgetExplorer::uninstall(const QString &pluginName) { static const QString packageRoot = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/"; KPackage::PackageStructure *structure = KPackage::PackageLoader::self()->loadPackageStructure(QStringLiteral("Plasma/Applet")); KPackage::Package pkg(structure); pkg.uninstall(pluginName, packageRoot); //FIXME: moreefficient way rather a linear scan? for (int i = 0; i < d->itemModel.rowCount(); ++i) { QStandardItem *item = d->itemModel.item(i); if (item->data(PlasmaAppletItemModel::PluginNameRole).toString() == pluginName) { d->itemModel.takeRow(i); break; } } // now remove all instances of that applet if (corona()) { const auto &containments = corona()->containments(); foreach (Containment *c, containments) { const auto &applets = c->applets(); foreach (Applet *applet, applets) { const auto &appletInfo = applet->pluginMetaData(); if (appletInfo.isValid() && appletInfo.pluginId() == pluginName) { applet->destroy(); } } } } } #include "moc_widgetexplorer.cpp"