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 }