/* SPDX-FileCopyrightText: 2014-2015 Eike Hein SPDX-License-Identifier: GPL-2.0-or-later */ #include "simplefavoritesmodel.h" #include "actionlist.h" #include "appentry.h" #include "fileentry.h" #include "systementry.h" #include #include #include SimpleFavoritesModel::SimpleFavoritesModel(QObject *parent) : AbstractModel(parent) , m_enabled(true) , m_maxFavorites(-1) , m_dropPlaceholderIndex(-1) { connect(KSycoca::self(), &KSycoca::databaseChanged, this, &SimpleFavoritesModel::refresh, Qt::QueuedConnection); } SimpleFavoritesModel::~SimpleFavoritesModel() { qDeleteAll(m_entryList); } QString SimpleFavoritesModel::description() const { return i18n("Favorites"); } QVariant SimpleFavoritesModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() >= rowCount()) { return QVariant(); } if (index.row() == m_dropPlaceholderIndex) { if (role == Kicker::IsDropPlaceholderRole) { return true; } else { return QVariant(); } } int mappedIndex = index.row(); if (m_dropPlaceholderIndex != -1 && mappedIndex > m_dropPlaceholderIndex) { --mappedIndex; } const AbstractEntry *entry = m_entryList.at(mappedIndex); // TODO: Use a Switch for Enums. if (role == Qt::DisplayRole) { return entry->name(); } else if (role == Kicker::DisplayWrappedRole) { return KStringHandler::preProcessWrap(entry->name()); } else if (role == Qt::DecorationRole) { if (!entry->icon().isEmpty()) return entry->icon(); else return entry->icon(); } else if (role == Kicker::CompactNameRole) { return entry->compactName(); } else if (role == Kicker::CompactNameWrappedRole) { return KStringHandler::preProcessWrap(entry->compactName()); } else if (role == Kicker::DescriptionRole) { return entry->description(); } else if (role == Kicker::FavoriteIdRole) { return entry->id(); } else if (role == Kicker::UrlRole) { return entry->url(); } else if (role == Kicker::HasActionListRole) { return entry->hasActions(); } else if (role == Kicker::ActionListRole) { return entry->actions(); } return QVariant(); } int SimpleFavoritesModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : m_entryList.count() + (m_dropPlaceholderIndex != -1 ? 1 : 0); } bool SimpleFavoritesModel::trigger(int row, const QString &actionId, const QVariant &argument) { if (row < 0 || row >= m_entryList.count()) { return false; } return m_entryList.at(row)->run(actionId, argument); } bool SimpleFavoritesModel::enabled() const { return m_enabled; } void SimpleFavoritesModel::setEnabled(bool enable) { if (m_enabled != enable) { m_enabled = enable; Q_EMIT enabledChanged(); } } QStringList SimpleFavoritesModel::favorites() const { return m_favorites; } void SimpleFavoritesModel::setFavorites(const QStringList &favorites) { QStringList _favorites(favorites); _favorites.removeDuplicates(); if (_favorites != m_favorites) { m_favorites = _favorites; refresh(); } } int SimpleFavoritesModel::maxFavorites() const { return m_maxFavorites; } void SimpleFavoritesModel::setMaxFavorites(int max) { if (m_maxFavorites != max) { m_maxFavorites = max; if (m_maxFavorites != -1 && m_favorites.count() > m_maxFavorites) { refresh(); } Q_EMIT maxFavoritesChanged(); } } bool SimpleFavoritesModel::isFavorite(const QString &id) const { return m_favorites.contains(id); } void SimpleFavoritesModel::addFavorite(const QString &id, int index) { if (!m_enabled || id.isEmpty()) { return; } if (m_maxFavorites != -1 && m_favorites.count() == m_maxFavorites) { return; } AbstractEntry *entry = favoriteFromId(id); if (!entry || !entry->isValid()) { delete entry; return; } setDropPlaceholderIndex(-1); int insertIndex = (index != -1) ? index : m_entryList.count(); beginInsertRows(QModelIndex(), insertIndex, insertIndex); m_entryList.insert(insertIndex, entry); m_favorites.insert(insertIndex, entry->id()); endInsertRows(); Q_EMIT countChanged(); Q_EMIT favoritesChanged(); } void SimpleFavoritesModel::removeFavorite(const QString &id) { if (!m_enabled || id.isEmpty()) { return; } int index = m_favorites.indexOf(id); if (index != -1) { setDropPlaceholderIndex(-1); beginRemoveRows(QModelIndex(), index, index); delete m_entryList[index]; m_entryList.removeAt(index); m_favorites.removeAt(index); endRemoveRows(); Q_EMIT countChanged(); Q_EMIT favoritesChanged(); } } void SimpleFavoritesModel::moveRow(int from, int to) { if (from >= m_favorites.count() || to >= m_favorites.count()) { return; } if (from == to) { return; } setDropPlaceholderIndex(-1); int modelTo = to + (to > from ? 1 : 0); bool ok = beginMoveRows(QModelIndex(), from, from, QModelIndex(), modelTo); if (ok) { m_entryList.move(from, to); m_favorites.move(from, to); endMoveRows(); Q_EMIT favoritesChanged(); } } int SimpleFavoritesModel::dropPlaceholderIndex() const { return m_dropPlaceholderIndex; } void SimpleFavoritesModel::setDropPlaceholderIndex(int index) { if (index == -1 && m_dropPlaceholderIndex != -1) { beginRemoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex); m_dropPlaceholderIndex = index; endRemoveRows(); Q_EMIT countChanged(); } else if (index != -1 && m_dropPlaceholderIndex == -1) { beginInsertRows(QModelIndex(), index, index); m_dropPlaceholderIndex = index; endInsertRows(); Q_EMIT countChanged(); } else if (m_dropPlaceholderIndex != index) { int modelTo = index + (index > m_dropPlaceholderIndex ? 1 : 0); bool ok = beginMoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex, QModelIndex(), modelTo); if (ok) { m_dropPlaceholderIndex = index; endMoveRows(); } } } AbstractModel *SimpleFavoritesModel::favoritesModel() { return this; } void SimpleFavoritesModel::refresh() { beginResetModel(); setDropPlaceholderIndex(-1); int oldCount = m_entryList.count(); qDeleteAll(m_entryList); m_entryList.clear(); QStringList newFavorites; for (const QString &id : std::as_const(m_favorites)) { AbstractEntry *entry = favoriteFromId(id); if (entry && entry->isValid()) { m_entryList << entry; newFavorites << entry->id(); if (m_maxFavorites != -1 && newFavorites.count() == m_maxFavorites) { break; } } else if (entry) { delete entry; } } m_favorites = newFavorites; endResetModel(); if (oldCount != m_entryList.count()) { Q_EMIT countChanged(); } Q_EMIT favoritesChanged(); } AbstractEntry *SimpleFavoritesModel::favoriteFromId(const QString &id) { const QUrl url(id); const QString &s = url.scheme(); if ((s.isEmpty() && id.contains(QLatin1String(".desktop"))) || s == QLatin1String("preferred")) { return new AppEntry(this, id); } else if (url.isValid() && !url.scheme().isEmpty()) { return new FileEntry(this, url); } else { return new SystemEntry(this, id); } return nullptr; }