Revert "port to kicker model"

This reverts commit 4e4cc5abc2.
This commit is contained in:
Marco Martin 2019-09-18 13:55:07 +02:00
parent 29609b0e7a
commit abc112ed1c
4 changed files with 213 additions and 96 deletions

View file

@ -39,9 +39,13 @@
ApplicationListModel::ApplicationListModel(HomeScreen *parent) ApplicationListModel::ApplicationListModel(HomeScreen *parent)
: QSortFilterProxyModel(parent), : QAbstractListModel(parent),
m_homeScreen(parent) m_homeScreen(parent)
{ {
//can't use the new syntax as this signal is overloaded
connect(KSycoca::self(), SIGNAL(databaseChanged(const QStringList &)),
this, SLOT(sycocaDbChanged(const QStringList &)));
loadSettings(); loadSettings();
} }
@ -60,23 +64,128 @@ void ApplicationListModel::loadSettings()
m_appPositions[app] = i; m_appPositions[app] = i;
++i; ++i;
} }
loadApplications();
} }
QHash<int, QByteArray> ApplicationListModel::roleNames() const QHash<int, QByteArray> ApplicationListModel::roleNames() const
{ {
QHash<int, QByteArray> roleNames; QHash<int, QByteArray> roleNames;
if (sourceModel()) { roleNames[ApplicationNameRole] = "ApplicationNameRole";
roleNames = sourceModel()->roleNames(); roleNames[ApplicationIconRole] = "ApplicationIconRole";
} roleNames[ApplicationStorageIdRole] = "ApplicationStorageIdRole";
roleNames[ApplicationEntryPathRole] = "ApplicationEntryPathRole";
roleNames[SortKeyRole] = "SortKeyRole"; roleNames[ApplicationOriginalRowRole] = "ApplicationOriginalRowRole";
roleNames[ApplicationStartupNotifyRole] = "ApplicationStartupNotifyRole";
roleNames[ApplicationLocationRole] = "ApplicationLocationRole"; roleNames[ApplicationLocationRole] = "ApplicationLocationRole";
const_cast<ApplicationListModel *>(this)->m_urlRole = roleNames.key("url");
return roleNames; return roleNames;
} }
void ApplicationListModel::sycocaDbChanged(const QStringList &changes)
{
if (!changes.contains("apps") && !changes.contains("xdgdata-apps")) {
return;
}
m_applicationList.clear();
loadApplications();
}
bool appNameLessThan(const ApplicationData &a1, const ApplicationData &a2)
{
return a1.name.toLower() < a2.name.toLower();
}
void ApplicationListModel::loadApplications()
{
auto cfg = KSharedConfig::openConfig("applications-blacklistrc");
auto blgroup = KConfigGroup(cfg, QStringLiteral("Applications"));
// This is only temporary to get a clue what those apps' desktop files are called
// I'll remove it once I've done a blacklist
QStringList bl;
QStringList blacklist = blgroup.readEntry("blacklist", QStringList());
beginResetModel();
m_applicationList.clear();
KServiceGroup::Ptr group = KServiceGroup::root();
if (!group || !group->isValid()) return;
KServiceGroup::List subGroupList = group->entries(true);
QMap<int, ApplicationData> orderedList;
QList<ApplicationData> unorderedList;
// Iterate over all entries in the group
while (!subGroupList.isEmpty()) {
KSycocaEntry::Ptr groupEntry = subGroupList.first();
subGroupList.pop_front();
if (groupEntry->isType(KST_KServiceGroup)) {
KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup* >(groupEntry.data()));
if (!serviceGroup->noDisplay()) {
KServiceGroup::List entryGroupList = serviceGroup->entries(true);
for(KServiceGroup::List::ConstIterator it = entryGroupList.constBegin(); it != entryGroupList.constEnd(); it++) {
KSycocaEntry::Ptr entry = (*it);
if (entry->isType(KST_KServiceGroup)) {
KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup* >(entry.data()));
subGroupList << serviceGroup;
} else if (entry->property("Exec").isValid()) {
KService::Ptr service(static_cast<KService* >(entry.data()));
if (service->isApplication() &&
!blacklist.contains(service->desktopEntryName()) &&
service->showOnCurrentPlatform() &&
!service->property("Terminal", QVariant::Bool).toBool()) {
bl << service->desktopEntryName();
ApplicationData data;
data.name = service->name();
data.icon = service->icon();
data.storageId = service->storageId();
data.entryPath = service->exec();
data.startupNotify = service->property("StartupNotify").toBool();
if (m_favorites.contains(data.storageId)) {
data.location = Favorites;
} else if (m_desktopItems.contains(data.storageId)) {
data.location = Desktop;
}
auto it = m_appPositions.constFind(service->storageId());
if (it != m_appPositions.constEnd()) {
orderedList[*it] = data;
} else {
unorderedList << data;
}
}
}
}
}
}
}
blgroup.writeEntry("allapps", bl);
blgroup.writeEntry("blacklist", blacklist);
cfg->sync();
std::sort(unorderedList.begin(), unorderedList.end(), appNameLessThan);
m_applicationList << orderedList.values();
m_applicationList << unorderedList;
endResetModel();
emit countChanged();
}
QVariant ApplicationListModel::data(const QModelIndex &index, int role) const QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
{ {
@ -85,117 +194,127 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
} }
switch (role) { switch (role) {
case SortKeyRole: { case Qt::DisplayRole:
const QString url = QSortFilterProxyModel::data(index, m_urlRole).toString(); case ApplicationNameRole:
if (m_appOrder.contains(url)) { return m_applicationList.at(index.row()).name;
return QString::number(m_appOrder.indexOf(url)) + QStringLiteral("_") + QSortFilterProxyModel::data(index, Qt::DisplayRole).toString(); case ApplicationIconRole:
} else { return m_applicationList.at(index.row()).icon;
return QStringLiteral("z_") + QSortFilterProxyModel::data(index, Qt::DisplayRole).toString(); case ApplicationStorageIdRole:
} return m_applicationList.at(index.row()).storageId;
} case ApplicationEntryPathRole:
return m_applicationList.at(index.row()).entryPath;
case ApplicationLocationRole: { case ApplicationOriginalRowRole:
const QString url = QSortFilterProxyModel::data(index, m_urlRole).toString(); return index.row();
if (m_favorites.contains(url)) { case ApplicationStartupNotifyRole:
return Favorites; return m_applicationList.at(index.row()).startupNotify;
} else if (m_desktopItems.contains(url)) { case ApplicationLocationRole:
return Desktop; return m_applicationList.at(index.row()).location;
} else {
return Grid;
}
}
default: default:
return QSortFilterProxyModel::data(index, role); return QVariant();
} }
} }
//TODO: remove?
Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return nullptr; return nullptr;
return Qt::ItemIsDragEnabled|QSortFilterProxyModel::flags(index); return Qt::ItemIsDragEnabled|QAbstractItemModel::flags(index);
} }
int ApplicationListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_applicationList.count();
}
void ApplicationListModel::moveRow(const QModelIndex& /* sourceParent */, int sourceRow, const QModelIndex& /* destinationParent */, int destinationChild)
{
moveItem(sourceRow, destinationChild);
}
void ApplicationListModel::setLocation(int row, LauncherLocation location) void ApplicationListModel::setLocation(int row, LauncherLocation location)
{ {
if (row < 0 || row >= rowCount()) { if (row < 0 || row >= m_applicationList.length()) {
return; return;
} }
const QString url = data(index(row, 0), m_urlRole).toString(); ApplicationData &data = m_applicationList[row];
if (data.location == location) {
if (url.isEmpty()) {
return; return;
} }
if (location == Favorites && !m_favorites.contains(url)) { if (location == Favorites) {qWarning()<<"favoriting"<<row<<data.name;
qWarning()<<"favoriting"<<row;
// Deny favorites when full // Deny favorites when full
if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount) { if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount) {
return; return;
} }
m_favorites.insert(row, url); m_favorites.insert(row, data.storageId);
m_homeScreen->config().writeEntry("Favorites", m_favorites); m_homeScreen->config().writeEntry("Favorites", m_favorites);
emit favoriteCountChanged(); emit favoriteCountChanged();
// Out of favorites // Out of favorites
} else if (m_favorites.contains(url)) { } else if (data.location == Favorites) {
m_favorites.removeAll(url); m_favorites.removeAll(data.storageId);
m_homeScreen->config().writeEntry("Favorites", m_favorites); m_homeScreen->config().writeEntry("Favorites", m_favorites);
emit favoriteCountChanged(); emit favoriteCountChanged();
} }
// In Desktop // In Desktop
if (location == Desktop && m_desktopItems.contains(url)) { if (location == Desktop) {
m_desktopItems.insert(url); m_desktopItems.insert(data.storageId);
m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList());
// Out of Desktop // Out of Desktop
} else if (m_desktopItems.contains(url)) { } else if (data.location == Desktop) {
m_desktopItems.remove(url); m_desktopItems.remove(data.storageId);
m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList()); m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.toList());
} }
data.location = location;
emit m_homeScreen->configNeedsSaving(); emit m_homeScreen->configNeedsSaving();
emit dataChanged(index(row, 0), index(row, 0)); emit dataChanged(index(row, 0), index(row, 0));
} }
void ApplicationListModel::moveItem(int row, int destination) void ApplicationListModel::moveItem(int row, int destination)
{ {
if (row < 0 || destination < 0 || row >= rowCount() || if (row < 0 || destination < 0 || row >= m_applicationList.length() ||
destination >= rowCount() || row == destination) { destination >= m_applicationList.length() || row == destination) {
return; return;
} }
if (destination > row) { if (destination > row) {
++destination; ++destination;
} }
const QString url = data(index(row, 0), m_urlRole).toString(); beginMoveRows(QModelIndex(), row, row, QModelIndex(), destination);
if (url.isEmpty()) {
return;
}
if (m_appOrder.length() < qMax(row, destination)) {
for (int i = m_appOrder.length(); i <= qMax(row, destination); ++i) {
m_appOrder << data(index(i, 0), m_urlRole).toString();
}
}
if (destination > row) { if (destination > row) {
m_appOrder.insert(destination, url); ApplicationData data = m_applicationList.at(row);
m_appOrder.takeAt(row); m_applicationList.insert(destination, data);
m_applicationList.takeAt(row);
} else { } else {
m_appOrder.takeAt(row); ApplicationData data = m_applicationList.takeAt(row);
m_appOrder.insert(destination, url); m_applicationList.insert(destination, data);
}
m_appOrder.clear();
m_appPositions.clear();
int i = 0;
for (auto app : m_applicationList) {
m_appOrder << app.storageId;
m_appPositions[app.storageId] = i;
++i;
} }
m_homeScreen->config().writeEntry("AppOrder", m_appOrder); m_homeScreen->config().writeEntry("AppOrder", m_appOrder);
endMoveRows();
} }
void ApplicationListModel::runApplication(const QString &storageId) void ApplicationListModel::runApplication(const QString &storageId)
@ -225,7 +344,7 @@ void ApplicationListModel::setMaxFavoriteCount(int count)
m_favorites.pop_back(); m_favorites.pop_back();
} }
emit favoriteCountChanged(); emit favoriteCountChanged();
/*TODO
int i = 0; int i = 0;
for (auto &app : m_applicationList) { for (auto &app : m_applicationList) {
if (i >= count && app.location == Favorites) { if (i >= count && app.location == Favorites) {
@ -233,7 +352,7 @@ void ApplicationListModel::setMaxFavoriteCount(int count)
emit dataChanged(index(i, 0), index(i, 0)); emit dataChanged(index(i, 0), index(i, 0));
} }
++i; ++i;
}*/ }
} }
m_maxFavoriteCount = count; m_maxFavoriteCount = count;

View file

@ -22,7 +22,7 @@
// Qt // Qt
#include <QObject> #include <QObject>
#include <QSortFilterProxyModel> #include <QAbstractListModel>
#include <QList> #include <QList>
#include "homescreen.h" #include "homescreen.h"
@ -31,7 +31,16 @@ class QString;
class ApplicationListModel; class ApplicationListModel;
class ApplicationListModel : public QSortFilterProxyModel { struct ApplicationData {
QString name;
QString icon;
QString storageId;
QString entryPath;
int location = 0; //FIXME
bool startupNotify = true;
};
class ApplicationListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
@ -47,7 +56,12 @@ public:
Q_ENUM(LauncherLocation) Q_ENUM(LauncherLocation)
enum Roles { enum Roles {
SortKeyRole = Qt::UserRole + 100, ApplicationNameRole = Qt::UserRole + 1,
ApplicationIconRole,
ApplicationStorageIdRole,
ApplicationEntryPathRole,
ApplicationOriginalRowRole,
ApplicationStartupNotifyRole,
ApplicationLocationRole ApplicationLocationRole
}; };
@ -56,7 +70,11 @@ public:
void loadSettings(); void loadSettings();
int count() const { return rowCount(); } int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
void moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
int count() const { return m_applicationList.count(); }
int favoriteCount() const { return m_favorites.count();} int favoriteCount() const { return m_favorites.count();}
int maxFavoriteCount() const; int maxFavoriteCount() const;
@ -74,7 +92,10 @@ public:
Q_INVOKABLE void runApplication(const QString &storageId); Q_INVOKABLE void runApplication(const QString &storageId);
Q_INVOKABLE void loadApplications();
public Q_SLOTS: public Q_SLOTS:
void sycocaDbChanged(const QStringList &change);
Q_SIGNALS: Q_SIGNALS:
void countChanged(); void countChanged();
@ -82,9 +103,10 @@ Q_SIGNALS:
void maxFavoriteCountChanged(); void maxFavoriteCountChanged();
private: private:
QList<ApplicationData> m_applicationList;
HomeScreen *m_homeScreen = nullptr; HomeScreen *m_homeScreen = nullptr;
int m_maxFavoriteCount = 0; int m_maxFavoriteCount = 0;
int m_urlRole = 0;
QStringList m_appOrder; QStringList m_appOrder;
QStringList m_favorites; QStringList m_favorites;
QSet<QString> m_desktopItems; QSet<QString> m_desktopItems;

View file

@ -47,7 +47,7 @@ ContainmentLayoutManager.ItemContainer {
opacity: dragActive ? 0.4 : 1 opacity: dragActive ? 0.4 : 1
key: model.url key: model.ApplicationStorageIdRole
property real dragCenterX property real dragCenterX
property real dragCenterY property real dragCenterY
@ -93,8 +93,8 @@ ContainmentLayoutManager.ItemContainer {
onClicked: { onClicked: {
clickFedbackAnimation.target = delegate; clickFedbackAnimation.target = delegate;
clickFedbackAnimation.running = true; clickFedbackAnimation.running = true;
feedbackWindow.title = model.display; feedbackWindow.title = modelData.ApplicationNameRole;
feedbackWindow.icon = model.decoration; feedbackWindow.icon = modelData.ApplicationIconRole;
feedbackWindow.state = "open"; feedbackWindow.state = "open";
plasmoid.nativeInterface.applicationListModel.runApplication(modelData.ApplicationStorageIdRole); plasmoid.nativeInterface.applicationListModel.runApplication(modelData.ApplicationStorageIdRole);
@ -112,7 +112,7 @@ ContainmentLayoutManager.ItemContainer {
Layout.minimumHeight: parent.height - root.reservedSpaceForLabel Layout.minimumHeight: parent.height - root.reservedSpaceForLabel
Layout.preferredHeight: Layout.minimumHeight Layout.preferredHeight: Layout.minimumHeight
source: model.decoration source: modelData ? modelData.ApplicationIconRole : ""
Behavior on scale { Behavior on scale {
NumberAnimation { NumberAnimation {
duration: units.longDuration duration: units.longDuration
@ -133,7 +133,7 @@ ContainmentLayoutManager.ItemContainer {
maximumLineCount: 2 maximumLineCount: 2
elide: Text.ElideRight elide: Text.ElideRight
text: model.display text: model.ApplicationNameRole
font.pixelSize: theme.defaultFont.pixelSize font.pixelSize: theme.defaultFont.pixelSize
color: model.ApplicationLocationRole == ApplicationListModel.Desktop ? "white" : theme.textColor color: model.ApplicationLocationRole == ApplicationListModel.Desktop ? "white" : theme.textColor

View file

@ -29,8 +29,6 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
import org.kde.phone.homescreen 1.0 import org.kde.phone.homescreen 1.0
import org.kde.plasma.private.kicker 0.1 as Kicker
LauncherContainer { LauncherContainer {
id: root id: root
@ -41,28 +39,6 @@ LauncherContainer {
frame.width: width frame.width: width
Kicker.RootModel {
id: kickerRootModel
appNameFormat: 0
autoPopulate: false
flat: true
sorted: true
showSeparators: false
appletInterface: plasmoid
paginate: false
showAllApps: true
showTopLevelItems: false
showRecentApps: false
showRecentDocs: false
showRecentContacts: false
recentOrdering: 0
Component.onCompleted: {
kickerRootModel.refresh();
plasmoid.nativeInterface.applicationListModel.sourceModel = kickerRootModel.modelForRow(0);
}
}
Repeater { Repeater {
model: plasmoid.nativeInterface.applicationListModel model: plasmoid.nativeInterface.applicationListModel
delegate: Delegate { delegate: Delegate {