From dbda61e0305c90ced90d76cf95ff80f57aa2741e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 28 Oct 2014 13:27:54 +0100 Subject: [PATCH] use a simple model for the application list --- CMakeLists.txt | 2 + qmlcomponents/CMakeLists.txt | 16 +++ qmlcomponents/Messages.sh | 4 + qmlcomponents/applicationlistmodel.cpp | 139 ++++++++++++++++++++ qmlcomponents/applicationlistmodel.h | 71 ++++++++++ qmlcomponents/qmldir | 2 + qmlcomponents/satellitecomponentsplugin.cpp | 52 ++++++++ qmlcomponents/satellitecomponentsplugin.h | 39 ++++++ shell/contents/components/HomeLauncher.qml | 12 +- shell/contents/defaults | 2 +- shell/contents/views/Desktop.qml | 19 +-- 11 files changed, 335 insertions(+), 23 deletions(-) create mode 100644 qmlcomponents/CMakeLists.txt create mode 100644 qmlcomponents/Messages.sh create mode 100644 qmlcomponents/applicationlistmodel.cpp create mode 100644 qmlcomponents/applicationlistmodel.h create mode 100644 qmlcomponents/qmldir create mode 100644 qmlcomponents/satellitecomponentsplugin.cpp create mode 100644 qmlcomponents/satellitecomponentsplugin.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0502b2d0..c7697fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,3 +38,5 @@ plasma_install_package(look-and-feel org.kde.satellite.phone look-and-feel) plasma_install_package(shell org.kde.satellite.phone shells) install(DIRECTORY wallpaper/ DESTINATION "${WALLPAPER_INSTALL_DIR}/org.kde.satellite.lockers") +add_subdirectory(qmlcomponents) + diff --git a/qmlcomponents/CMakeLists.txt b/qmlcomponents/CMakeLists.txt new file mode 100644 index 00000000..9a7b5937 --- /dev/null +++ b/qmlcomponents/CMakeLists.txt @@ -0,0 +1,16 @@ +project(satellitecomponents) + +set(satellitecomponents_SRCS + satellitecomponentsplugin.cpp + applicationlistmodel.cpp + ) + +add_library(satellitecomponentsplugin SHARED ${satellitecomponents_SRCS}) +target_link_libraries(satellitecomponentsplugin Qt5::Core Qt5::Widgets Qt5::Qml Qt5::Quick KF5::Declarative KF5::I18n KF5::KIOCore KF5::KIOWidgets) + +install(TARGETS satellitecomponentsplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/satellite/components) + + +install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/satellite/components) + + diff --git a/qmlcomponents/Messages.sh b/qmlcomponents/Messages.sh new file mode 100644 index 00000000..1e8a5bf4 --- /dev/null +++ b/qmlcomponents/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml` -L Java -o $podir/libsatellitecomponentsplugin.pot +rm -f rc.cpp + diff --git a/qmlcomponents/applicationlistmodel.cpp b/qmlcomponents/applicationlistmodel.cpp new file mode 100644 index 00000000..63b6e342 --- /dev/null +++ b/qmlcomponents/applicationlistmodel.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2014 Antonis Tsiapaliokas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 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. + */ + +// Self +#include "applicationlistmodel.h" + +// Qt +#include +#include + +// KDE +#include +#include +#include +#include +#include +#include +#include + +ApplicationListModel::ApplicationListModel(QObject *parent) + : QAbstractListModel(parent) +{ + loadApplications(); +} + +ApplicationListModel::~ApplicationListModel() +{ +} + +QHash ApplicationListModel::roleNames() const +{ + QHash roleNames; + roleNames[ApplicationNameRole] = "ApplicationNameRole"; + roleNames[ApplicationIconRole] = "ApplicationIconRole"; + roleNames[ApplicationStorageIdRole] = "ApplicationStorageIdRole"; + roleNames[ApplicationEntryPathRole] = "ApplicationEntryPathRole"; + + return roleNames; +} + + +void ApplicationListModel::loadApplications() +{ + beginResetModel(); + + KServiceGroup::Ptr group = KServiceGroup::root(); + if (!group || !group->isValid()) return; + KServiceGroup::List subGroupList = group->entries(true); + + // Iterate over all entries in the group + for(KServiceGroup::List::ConstIterator it = subGroupList.begin();it != subGroupList.end(); it++) { + KSycocaEntry::Ptr groupEntry = (*it); + + if (groupEntry->isType(KST_KServiceGroup) && groupEntry->name() != "System") { + KServiceGroup::Ptr serviceGroup = static_cast(groupEntry); + + if (!serviceGroup->noDisplay()) { + KServiceGroup::List entryGroupList = serviceGroup->entries(true); + + for(KServiceGroup::List::ConstIterator it = entryGroupList.begin(); it != entryGroupList.end(); it++) { + KSycocaEntry::Ptr entry = (*it); + ApplicationData data; + if (entry->isType(KST_KService)) { + KService::Ptr service = static_cast(entry); + if (service->isApplication()) { + KPluginInfo plugin(service); + data.name = plugin.name(); + data.icon = plugin.icon(); + data.storageId = service->storageId(); + data.entryPath = plugin.entryPath(); + m_applicationList << data; + } + } + } + } + } + } + + endResetModel(); + emit countChanged(); +} + +QVariant ApplicationListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + switch (role) { + case Qt::DisplayRole: + case ApplicationNameRole: + return m_applicationList.at(index.row()).name; + case ApplicationIconRole: + return m_applicationList.at(index.row()).icon; + case ApplicationStorageIdRole: + return m_applicationList.at(index.row()).storageId; + case ApplicationEntryPathRole: + return m_applicationList.at(index.row()).entryPath; + + default: + return QVariant(); + } +} + +int ApplicationListModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + + return m_applicationList.count(); +} + +void ApplicationListModel::runApplication(const QString &storageId) { + if (storageId.isEmpty()) { + return; + } + + KService::Ptr service = KService::serviceByStorageId(storageId); + KRun::run(*service, QList(), 0); +} + +#include "applicationlistmodel.moc" diff --git a/qmlcomponents/applicationlistmodel.h b/qmlcomponents/applicationlistmodel.h new file mode 100644 index 00000000..e963e9ce --- /dev/null +++ b/qmlcomponents/applicationlistmodel.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 Antonis Tsiapaliokas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 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 APPLICATIONLISTMODEL_H +#define APPLICATIONLISTMODEL_H + +// Qt +#include +#include +#include + +class QString; + +struct ApplicationData { + QString name; + QString icon; + QString storageId; + QString entryPath; +}; + +class ApplicationListModel : public QAbstractListModel { + Q_OBJECT + + Q_PROPERTY(int count READ count NOTIFY countChanged) + +public: + ApplicationListModel(QObject *parent = 0); + virtual ~ApplicationListModel(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + + int count() { return m_applicationList.count(); } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + + QHash roleNames() const Q_DECL_OVERRIDE; + + enum Roles { + ApplicationNameRole = Qt::UserRole + 1, + ApplicationIconRole = Qt::UserRole + 2, + ApplicationStorageIdRole = Qt::UserRole + 3, + ApplicationEntryPathRole = Qt::UserRole + 4 + }; + + Q_INVOKABLE void runApplication(const QString &storageId); + +Q_SIGNALS: + void countChanged(); + +private: + QList m_applicationList; + void loadApplications(); +}; + +#endif // APPLICATIONLISTMODEL_H diff --git a/qmlcomponents/qmldir b/qmlcomponents/qmldir new file mode 100644 index 00000000..0909bc86 --- /dev/null +++ b/qmlcomponents/qmldir @@ -0,0 +1,2 @@ +module org.kde.satellite.components +plugin satellitecomponentsplugin \ No newline at end of file diff --git a/qmlcomponents/satellitecomponentsplugin.cpp b/qmlcomponents/satellitecomponentsplugin.cpp new file mode 100644 index 00000000..df97eab3 --- /dev/null +++ b/qmlcomponents/satellitecomponentsplugin.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2009 by Alan Alpert + * Copyright 2010 by Ménard Alexis + * Copyright 2010 by Marco Martin + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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 Library General Public License for more details + * + * You should have received a copy of the GNU Library 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 "satellitecomponentsplugin.h" + +#include +#include +#include +#include +#include + +#include "applicationlistmodel.h" + +void SatelliteComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ + QQmlExtensionPlugin::initializeEngine(engine, uri); + + if (!engine->rootContext()->contextObject()) { + KDeclarative::KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(engine); + kdeclarative.setupBindings(); + } +} + +void SatelliteComponentsPlugin::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.satellite.components")); + + qmlRegisterType(uri, 0, 1, "ApplicationListModel"); +} + + +#include "satellitecomponentsplugin.moc" + diff --git a/qmlcomponents/satellitecomponentsplugin.h b/qmlcomponents/satellitecomponentsplugin.h new file mode 100644 index 00000000..f2a5c86f --- /dev/null +++ b/qmlcomponents/satellitecomponentsplugin.h @@ -0,0 +1,39 @@ +/* + * Copyright 2009 by Alan Alpert + * Copyright 2010 by Ménard Alexis + * Copyright 2010 by Marco Martin + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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 Library General Public License for more details + * + * You should have received a copy of the GNU Library 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 SATELLITECOMPONENTSPLUGIN_H +#define SATELLITECOMPONENTSPLUGIN_H + +#include +#include + +class SatelliteComponentsPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void initializeEngine(QQmlEngine *engine, const char *uri); + void registerTypes(const char *uri); + +}; + +#endif diff --git a/shell/contents/components/HomeLauncher.qml b/shell/contents/components/HomeLauncher.qml index 9842c9a4..85f12b05 100644 --- a/shell/contents/components/HomeLauncher.qml +++ b/shell/contents/components/HomeLauncher.qml @@ -7,19 +7,16 @@ MouseArea { width: applications.cellWidth height: width onClicked: { - console.log("Clicked: " + model.entryPath) - krun.openUrl(model.entryPath) + console.log("Clicked: " + model.ApplicationStorageIdRole) + appListModel.runApplication(model.ApplicationStorageIdRole) } - Kio.KRun { - id: krun - } PlasmaCore.IconItem { id: icon anchors.centerIn: parent width: units.iconSizes.large height: width - source: iconName + source: model.ApplicationIconRole } Text { @@ -35,7 +32,8 @@ MouseArea { horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter - text: name + text: model.ApplicationNameRole + font.pixelSize: theme.smallestFont.pixelSize color: "white" } } diff --git a/shell/contents/defaults b/shell/contents/defaults index 2cd1253f..eb563795 100644 --- a/shell/contents/defaults +++ b/shell/contents/defaults @@ -2,7 +2,7 @@ LookAndFeelPackage=org.kde.satellite.phone [Desktop] -Containment=null +Containment=org.kde.desktopcontainment ToolBox= [Desktop][ContainmentActions] diff --git a/shell/contents/views/Desktop.qml b/shell/contents/views/Desktop.qml index 848ee2ca..8b70d00a 100644 --- a/shell/contents/views/Desktop.qml +++ b/shell/contents/views/Desktop.qml @@ -22,6 +22,7 @@ import QtQuick 2.0 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.shell 2.0 as Shell +import org.kde.satellite.components 0.1 as SatelliteComponents import "../components" Item { @@ -330,20 +331,8 @@ Item { } } - PlasmaCore.DataSource { - id: applicationsSource - - engine: "apps" - interval: 0 - connectedSources: sources - - onSourceAdded: { - connectSource(source); - } - - onSourceRemoved: { - disconnectSource(source); - } + SatelliteComponents.ApplicationListModel { + id: appListModel } GridView { @@ -358,7 +347,7 @@ Item { z: 1 cellWidth: stripe.height * 2 cellHeight: cellWidth - model: PlasmaCore.DataModel { dataSource: applicationsSource } + model: appListModel snapMode: GridView.SnapToRow clip: true delegate: HomeLauncher {}