File indexing completed on 2024-12-22 05:15:19
0001 /* 0002 SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org> 0003 SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "computermodel.h" 0009 #include "actionlist.h" 0010 #include "simplefavoritesmodel.h" 0011 0012 #include <QConcatenateTablesProxyModel> 0013 0014 #include <KAuthorized> 0015 #include <KFilePlacesModel> 0016 #include <KIO/OpenUrlJob> 0017 #include <KLocalizedString> 0018 #include <Solid/Device> 0019 0020 #include "krunner_interface.h" 0021 0022 FilteredPlacesModel::FilteredPlacesModel(QObject *parent) 0023 : QSortFilterProxyModel(parent) 0024 , m_placesModel(new KFilePlacesModel(this)) 0025 { 0026 setSourceModel(m_placesModel); 0027 sort(0); 0028 } 0029 0030 FilteredPlacesModel::~FilteredPlacesModel() 0031 { 0032 } 0033 0034 QUrl FilteredPlacesModel::url(const QModelIndex &index) const 0035 { 0036 return KFilePlacesModel::convertedUrl(m_placesModel->url(mapToSource(index))); 0037 } 0038 0039 bool FilteredPlacesModel::isDevice(const QModelIndex &index) const 0040 { 0041 return m_placesModel->isDevice(mapToSource(index)); 0042 } 0043 0044 Solid::Device FilteredPlacesModel::deviceForIndex(const QModelIndex &index) const 0045 { 0046 return m_placesModel->deviceForIndex(mapToSource(index)); 0047 } 0048 0049 bool FilteredPlacesModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0050 { 0051 const QModelIndex index = m_placesModel->index(sourceRow, 0, sourceParent); 0052 0053 return !m_placesModel->isHidden(index) && !m_placesModel->data(index, KFilePlacesModel::FixedDeviceRole).toBool(); 0054 } 0055 0056 bool FilteredPlacesModel::lessThan(const QModelIndex &left, const QModelIndex &right) const 0057 { 0058 bool lDevice = m_placesModel->isDevice(left); 0059 bool rDevice = m_placesModel->isDevice(right); 0060 0061 if (lDevice && !rDevice) { 0062 return false; 0063 } else if (!lDevice && rDevice) { 0064 return true; 0065 } 0066 0067 return (left.row() < right.row()); 0068 } 0069 0070 RunCommandModel::RunCommandModel(QObject *parent) 0071 : AbstractModel(parent) 0072 { 0073 } 0074 0075 RunCommandModel::~RunCommandModel() 0076 { 0077 } 0078 0079 QString RunCommandModel::description() const 0080 { 0081 return QString(); 0082 } 0083 0084 QVariant RunCommandModel::data(const QModelIndex &index, int role) const 0085 { 0086 if (!index.isValid()) { 0087 return QVariant(); 0088 } 0089 0090 if (role == Qt::DisplayRole) { 0091 return i18n("Show KRunner"); 0092 } else if (role == Qt::DecorationRole) { 0093 return QStringLiteral("plasma-search"); 0094 } else if (role == Kicker::DescriptionRole) { 0095 return i18n("Search, calculate, or run a command"); 0096 } else if (role == Kicker::GroupRole) { 0097 return i18n("Applications"); 0098 } 0099 0100 return QVariant(); 0101 } 0102 0103 int RunCommandModel::rowCount(const QModelIndex &parent) const 0104 { 0105 return parent.isValid() ? 0 : (KAuthorized::authorize(QStringLiteral("run_command")) ? 1 : 0); 0106 } 0107 0108 Q_INVOKABLE bool RunCommandModel::trigger(int row, const QString &actionId, const QVariant &argument) 0109 { 0110 Q_UNUSED(actionId) 0111 Q_UNUSED(argument) 0112 0113 if (row == 0 && KAuthorized::authorize(QStringLiteral("run_command"))) { 0114 org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus()); 0115 krunner.display(); 0116 0117 return true; 0118 } 0119 0120 return false; 0121 } 0122 0123 ComputerModel::ComputerModel(QObject *parent) 0124 : ForwardingModel(parent) 0125 , m_concatProxy(new QConcatenateTablesProxyModel(this)) 0126 , m_runCommandModel(new RunCommandModel(this)) 0127 , m_systemAppsModel(new SimpleFavoritesModel(this)) 0128 , m_filteredPlacesModel(new FilteredPlacesModel(this)) 0129 , m_appNameFormat(AppEntry::NameOnly) 0130 , m_appletInterface(nullptr) 0131 { 0132 connect(m_systemAppsModel, &SimpleFavoritesModel::favoritesChanged, this, &ComputerModel::systemApplicationsChanged); 0133 m_systemAppsModel->setFavorites(QStringList() << QStringLiteral("systemsettings.desktop")); 0134 0135 m_concatProxy->addSourceModel(m_runCommandModel); 0136 m_concatProxy->addSourceModel(m_systemAppsModel); 0137 m_concatProxy->addSourceModel(m_filteredPlacesModel); 0138 0139 setSourceModel(m_concatProxy); 0140 } 0141 0142 ComputerModel::~ComputerModel() 0143 { 0144 } 0145 0146 QString ComputerModel::description() const 0147 { 0148 return i18n("Computer"); 0149 } 0150 0151 int ComputerModel::appNameFormat() const 0152 { 0153 return m_appNameFormat; 0154 } 0155 0156 void ComputerModel::setAppNameFormat(int format) 0157 { 0158 if (m_appNameFormat != (AppEntry::NameFormat)format) { 0159 m_appNameFormat = (AppEntry::NameFormat)format; 0160 0161 m_systemAppsModel->refresh(); 0162 0163 Q_EMIT appNameFormatChanged(); 0164 } 0165 } 0166 0167 QObject *ComputerModel::appletInterface() const 0168 { 0169 return m_appletInterface; 0170 } 0171 0172 void ComputerModel::setAppletInterface(QObject *appletInterface) 0173 { 0174 if (m_appletInterface != appletInterface) { 0175 m_appletInterface = appletInterface; 0176 0177 Q_EMIT appletInterfaceChanged(); 0178 } 0179 } 0180 0181 QStringList ComputerModel::systemApplications() const 0182 { 0183 return m_systemAppsModel->favorites(); 0184 } 0185 0186 void ComputerModel::setSystemApplications(const QStringList &apps) 0187 { 0188 m_systemAppsModel->setFavorites(apps); 0189 } 0190 0191 QVariant ComputerModel::data(const QModelIndex &index, int role) const 0192 { 0193 if (!index.isValid()) { 0194 return QVariant(); 0195 } 0196 0197 const QModelIndex sourceIndex = m_concatProxy->mapToSource(m_concatProxy->index(index.row(), index.column())); 0198 0199 bool isPlace = (sourceIndex.model() == m_filteredPlacesModel); 0200 0201 if (isPlace) { 0202 if (role == Kicker::DescriptionRole) { 0203 if (m_filteredPlacesModel->isDevice(sourceIndex)) { 0204 Solid::Device device = m_filteredPlacesModel->deviceForIndex(sourceIndex); 0205 Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); 0206 0207 if (access) { 0208 return access->filePath(); 0209 } else { 0210 return QString(); 0211 } 0212 } 0213 } else if (role == Kicker::FavoriteIdRole) { 0214 if (!m_filteredPlacesModel->isDevice(sourceIndex)) { 0215 return m_filteredPlacesModel->url(sourceIndex); 0216 } 0217 } else if (role == Kicker::UrlRole) { 0218 return m_filteredPlacesModel->url(sourceIndex); 0219 } else if (role == Kicker::GroupRole) { 0220 return sourceIndex.data(KFilePlacesModel::GroupRole).toString(); 0221 } else if (role == Qt::DisplayRole || role == Qt::DecorationRole) { 0222 return sourceIndex.data(role); 0223 } 0224 } else if (role == Kicker::GroupRole) { 0225 return i18n("Applications"); 0226 } else { 0227 return sourceIndex.data(role); 0228 } 0229 0230 return QVariant(); 0231 } 0232 0233 bool ComputerModel::trigger(int row, const QString &actionId, const QVariant &argument) 0234 { 0235 const QModelIndex sourceIndex = m_concatProxy->mapToSource(m_concatProxy->index(row, 0)); 0236 0237 if (sourceIndex.model() == m_filteredPlacesModel) { 0238 const QUrl &url = m_filteredPlacesModel->url(sourceIndex); 0239 0240 if (url.isValid()) { 0241 auto job = new KIO::OpenUrlJob(url); 0242 job->start(); 0243 0244 return true; 0245 } 0246 0247 Solid::Device device = m_filteredPlacesModel->deviceForIndex(sourceIndex); 0248 Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); 0249 0250 if (access && !access->isAccessible()) { 0251 connect(access, &Solid::StorageAccess::setupDone, this, &ComputerModel::onSetupDone); 0252 access->setup(); 0253 0254 return true; 0255 } 0256 } else { 0257 AbstractModel *model = nullptr; 0258 0259 if (sourceIndex.model() == m_systemAppsModel) { 0260 model = m_systemAppsModel; 0261 } else { 0262 model = m_runCommandModel; 0263 } 0264 0265 return model->trigger(sourceIndex.row(), actionId, argument); 0266 } 0267 0268 return false; 0269 } 0270 0271 void ComputerModel::onSetupDone(Solid::ErrorType error, QVariant errorData, const QString &udi) 0272 { 0273 Q_UNUSED(errorData); 0274 0275 if (error != Solid::NoError) { 0276 return; 0277 } 0278 0279 Solid::Device device(udi); 0280 Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); 0281 0282 Q_ASSERT(access); 0283 0284 auto job = new KIO::OpenUrlJob(QUrl::fromLocalFile(access->filePath())); 0285 job->start(); 0286 }