File indexing completed on 2024-06-09 05:30:59

0001 /*
0002     SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "simplefavoritesmodel.h"
0008 #include "actionlist.h"
0009 #include "appentry.h"
0010 #include "fileentry.h"
0011 #include "systementry.h"
0012 
0013 #include <KLocalizedString>
0014 #include <KStringHandler>
0015 
0016 SimpleFavoritesModel::SimpleFavoritesModel(QObject *parent)
0017     : AbstractModel(parent)
0018     , m_enabled(true)
0019     , m_maxFavorites(-1)
0020     , m_dropPlaceholderIndex(-1)
0021 {
0022 }
0023 
0024 SimpleFavoritesModel::~SimpleFavoritesModel()
0025 {
0026     qDeleteAll(m_entryList);
0027 }
0028 
0029 QString SimpleFavoritesModel::description() const
0030 {
0031     return i18n("Favorites");
0032 }
0033 
0034 QVariant SimpleFavoritesModel::data(const QModelIndex &index, int role) const
0035 {
0036     if (!index.isValid() || index.row() >= rowCount()) {
0037         return QVariant();
0038     }
0039 
0040     if (index.row() == m_dropPlaceholderIndex) {
0041         if (role == Kicker::IsDropPlaceholderRole) {
0042             return true;
0043         } else {
0044             return QVariant();
0045         }
0046     }
0047 
0048     int mappedIndex = index.row();
0049 
0050     if (m_dropPlaceholderIndex != -1 && mappedIndex > m_dropPlaceholderIndex) {
0051         --mappedIndex;
0052     }
0053 
0054     const AbstractEntry *entry = m_entryList.at(mappedIndex);
0055 
0056     // TODO: Use a Switch for Enums.
0057     if (role == Qt::DisplayRole) {
0058         return entry->name();
0059     } else if (role == Kicker::DisplayWrappedRole) {
0060         return KStringHandler::preProcessWrap(entry->name());
0061     } else if (role == Qt::DecorationRole) {
0062         if (!entry->icon().isEmpty())
0063             return entry->icon();
0064         else
0065             return entry->icon();
0066     } else if (role == Kicker::DescriptionRole) {
0067         return entry->description();
0068     } else if (role == Kicker::FavoriteIdRole) {
0069         return entry->id();
0070     } else if (role == Kicker::UrlRole) {
0071         return entry->url();
0072     } else if (role == Kicker::HasActionListRole) {
0073         return entry->hasActions();
0074     } else if (role == Kicker::ActionListRole) {
0075         return entry->actions();
0076     }
0077 
0078     return QVariant();
0079 }
0080 
0081 int SimpleFavoritesModel::rowCount(const QModelIndex &parent) const
0082 {
0083     return parent.isValid() ? 0 : m_entryList.count() + (m_dropPlaceholderIndex != -1 ? 1 : 0);
0084 }
0085 
0086 bool SimpleFavoritesModel::trigger(int row, const QString &actionId, const QVariant &argument)
0087 {
0088     if (row < 0 || row >= m_entryList.count()) {
0089         return false;
0090     }
0091 
0092     return m_entryList.at(row)->run(actionId, argument);
0093 }
0094 
0095 bool SimpleFavoritesModel::enabled() const
0096 {
0097     return m_enabled;
0098 }
0099 
0100 void SimpleFavoritesModel::setEnabled(bool enable)
0101 {
0102     if (m_enabled != enable) {
0103         m_enabled = enable;
0104 
0105         Q_EMIT enabledChanged();
0106     }
0107 }
0108 
0109 QStringList SimpleFavoritesModel::favorites() const
0110 {
0111     return m_favorites;
0112 }
0113 
0114 void SimpleFavoritesModel::setFavorites(const QStringList &favorites)
0115 {
0116     QStringList _favorites(favorites);
0117     _favorites.removeDuplicates();
0118 
0119     if (_favorites != m_favorites) {
0120         m_favorites = _favorites;
0121         refresh();
0122     }
0123 }
0124 
0125 int SimpleFavoritesModel::maxFavorites() const
0126 {
0127     return m_maxFavorites;
0128 }
0129 
0130 void SimpleFavoritesModel::setMaxFavorites(int max)
0131 {
0132     if (m_maxFavorites != max) {
0133         m_maxFavorites = max;
0134 
0135         if (m_maxFavorites != -1 && m_favorites.count() > m_maxFavorites) {
0136             refresh();
0137         }
0138 
0139         Q_EMIT maxFavoritesChanged();
0140     }
0141 }
0142 
0143 bool SimpleFavoritesModel::isFavorite(const QString &id) const
0144 {
0145     return m_favorites.contains(id);
0146 }
0147 
0148 void SimpleFavoritesModel::addFavorite(const QString &id, int index)
0149 {
0150     if (!m_enabled || id.isEmpty()) {
0151         return;
0152     }
0153 
0154     if (m_maxFavorites != -1 && m_favorites.count() == m_maxFavorites) {
0155         return;
0156     }
0157 
0158     AbstractEntry *entry = favoriteFromId(id);
0159 
0160     if (!entry || !entry->isValid()) {
0161         delete entry;
0162         return;
0163     }
0164 
0165     setDropPlaceholderIndex(-1);
0166 
0167     int insertIndex = (index != -1) ? index : m_entryList.count();
0168 
0169     beginInsertRows(QModelIndex(), insertIndex, insertIndex);
0170 
0171     m_entryList.insert(insertIndex, entry);
0172     m_favorites.insert(insertIndex, entry->id());
0173 
0174     endInsertRows();
0175 
0176     Q_EMIT countChanged();
0177     Q_EMIT favoritesChanged();
0178 }
0179 
0180 void SimpleFavoritesModel::removeFavorite(const QString &id)
0181 {
0182     if (!m_enabled || id.isEmpty()) {
0183         return;
0184     }
0185 
0186     int index = m_favorites.indexOf(id);
0187 
0188     if (index != -1) {
0189         setDropPlaceholderIndex(-1);
0190 
0191         beginRemoveRows(QModelIndex(), index, index);
0192 
0193         delete m_entryList[index];
0194         m_entryList.removeAt(index);
0195         m_favorites.removeAt(index);
0196 
0197         endRemoveRows();
0198 
0199         Q_EMIT countChanged();
0200         Q_EMIT favoritesChanged();
0201     }
0202 }
0203 
0204 void SimpleFavoritesModel::moveRow(int from, int to)
0205 {
0206     if (from >= m_favorites.count() || to >= m_favorites.count()) {
0207         return;
0208     }
0209 
0210     if (from == to) {
0211         return;
0212     }
0213 
0214     setDropPlaceholderIndex(-1);
0215 
0216     int modelTo = to + (to > from ? 1 : 0);
0217 
0218     bool ok = beginMoveRows(QModelIndex(), from, from, QModelIndex(), modelTo);
0219 
0220     if (ok) {
0221         m_entryList.move(from, to);
0222         m_favorites.move(from, to);
0223 
0224         endMoveRows();
0225 
0226         Q_EMIT favoritesChanged();
0227     }
0228 }
0229 
0230 int SimpleFavoritesModel::dropPlaceholderIndex() const
0231 {
0232     return m_dropPlaceholderIndex;
0233 }
0234 
0235 void SimpleFavoritesModel::setDropPlaceholderIndex(int index)
0236 {
0237     if (index == -1 && m_dropPlaceholderIndex != -1) {
0238         beginRemoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex);
0239 
0240         m_dropPlaceholderIndex = index;
0241 
0242         endRemoveRows();
0243 
0244         Q_EMIT countChanged();
0245     } else if (index != -1 && m_dropPlaceholderIndex == -1) {
0246         beginInsertRows(QModelIndex(), index, index);
0247 
0248         m_dropPlaceholderIndex = index;
0249 
0250         endInsertRows();
0251 
0252         Q_EMIT countChanged();
0253     } else if (m_dropPlaceholderIndex != index) {
0254         int modelTo = index + (index > m_dropPlaceholderIndex ? 1 : 0);
0255 
0256         bool ok = beginMoveRows(QModelIndex(), m_dropPlaceholderIndex, m_dropPlaceholderIndex, QModelIndex(), modelTo);
0257 
0258         if (ok) {
0259             m_dropPlaceholderIndex = index;
0260 
0261             endMoveRows();
0262         }
0263     }
0264 }
0265 
0266 AbstractModel *SimpleFavoritesModel::favoritesModel()
0267 {
0268     return this;
0269 }
0270 
0271 void SimpleFavoritesModel::refresh()
0272 {
0273     beginResetModel();
0274 
0275     setDropPlaceholderIndex(-1);
0276 
0277     int oldCount = m_entryList.count();
0278 
0279     qDeleteAll(m_entryList);
0280     m_entryList.clear();
0281 
0282     QStringList newFavorites;
0283 
0284     for (const QString &id : std::as_const(m_favorites)) {
0285         AbstractEntry *entry = favoriteFromId(id);
0286 
0287         if (entry && entry->isValid()) {
0288             m_entryList << entry;
0289             newFavorites << entry->id();
0290 
0291             if (m_maxFavorites != -1 && newFavorites.count() == m_maxFavorites) {
0292                 break;
0293             }
0294         } else if (entry) {
0295             delete entry;
0296         }
0297     }
0298 
0299     m_favorites = newFavorites;
0300 
0301     endResetModel();
0302 
0303     if (oldCount != m_entryList.count()) {
0304         Q_EMIT countChanged();
0305     }
0306 
0307     Q_EMIT favoritesChanged();
0308 }
0309 
0310 AbstractEntry *SimpleFavoritesModel::favoriteFromId(const QString &id)
0311 {
0312     const QUrl url(id);
0313     const QString &s = url.scheme();
0314 
0315     if ((s.isEmpty() && id.contains(QLatin1String(".desktop"))) || s == QLatin1String("preferred")) {
0316         return new AppEntry(this, id);
0317     } else if (url.isValid() && !url.scheme().isEmpty()) {
0318         return new FileEntry(this, url);
0319     } else {
0320         return new SystemEntry(this, id);
0321     }
0322 
0323     return nullptr;
0324 }