mirror of
https://invent.kde.org/plasma/plasma-desktop.git
synced 2026-11-03 22:59:45 -09:00
Summary:
Plasma uses inconsistent terminology to refer to KRunner, calling it "Run Command" in
Kicker/Kickoff/etc, but "Plasma Search" in System Settings. For reasons explained in
{T10966} neither term is ideal, and the inconsistency is bad too.
This patch unifies on "Show KRunner" for the action and "KRunner" for the KCM name,
transforming it into a recognizable brand name like Apple's Spotlight.
This patch also makes the icons consistent and adjusts some strings to more clearly
indicate what KRunner is and does.
Test Plan:
{F6842587}
{F6842586}
Reviewers: #vdg, #plasma, ndavis
Reviewed By: #vdg, ndavis
Subscribers: ndavis, plasma-devel, kde-doc-english
Tags: #plasma, #documentation
Maniphest Tasks: T10966
Differential Revision: https://phabricator.kde.org/D21343
301 lines
9.1 KiB
C++
301 lines
9.1 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
|
|
* Copyright (C) 2015 by Eike Hein <hein@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
|
***************************************************************************/
|
|
|
|
#include "computermodel.h"
|
|
#include "actionlist.h"
|
|
#include "simplefavoritesmodel.h"
|
|
|
|
#include <QIcon>
|
|
|
|
#include <KAuthorized>
|
|
#include <KConcatenateRowsProxyModel>
|
|
#include <KFilePlacesModel>
|
|
#include <KLocalizedString>
|
|
#include <KRun>
|
|
#include <Solid/Device>
|
|
|
|
#include "krunner_interface.h"
|
|
|
|
FilteredPlacesModel::FilteredPlacesModel(QObject *parent) : QSortFilterProxyModel(parent)
|
|
, m_placesModel(new KFilePlacesModel(this))
|
|
{
|
|
setSourceModel(m_placesModel);
|
|
sort(0);
|
|
}
|
|
|
|
FilteredPlacesModel::~FilteredPlacesModel()
|
|
{
|
|
}
|
|
|
|
QUrl FilteredPlacesModel::url(const QModelIndex &index) const
|
|
{
|
|
return KFilePlacesModel::convertedUrl(m_placesModel->url(mapToSource(index)));
|
|
}
|
|
|
|
bool FilteredPlacesModel::isDevice(const QModelIndex &index) const
|
|
{
|
|
return m_placesModel->isDevice(mapToSource(index));
|
|
}
|
|
|
|
Solid::Device FilteredPlacesModel::deviceForIndex(const QModelIndex &index) const
|
|
{
|
|
return m_placesModel->deviceForIndex(mapToSource(index));
|
|
}
|
|
|
|
bool FilteredPlacesModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
{
|
|
const QModelIndex index = m_placesModel->index(sourceRow, 0, sourceParent);
|
|
|
|
return !m_placesModel->isHidden(index)
|
|
&& !m_placesModel->data(index, KFilePlacesModel::FixedDeviceRole).toBool();
|
|
}
|
|
|
|
bool FilteredPlacesModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
|
{
|
|
bool lDevice = m_placesModel->isDevice(left);
|
|
bool rDevice = m_placesModel->isDevice(right);
|
|
|
|
if (lDevice && !rDevice) {
|
|
return false;
|
|
} else if (!lDevice && rDevice) {
|
|
return true;
|
|
}
|
|
|
|
return (left.row() < right.row());
|
|
}
|
|
|
|
RunCommandModel::RunCommandModel(QObject *parent) : AbstractModel(parent)
|
|
{
|
|
}
|
|
|
|
RunCommandModel::~RunCommandModel()
|
|
{
|
|
}
|
|
|
|
QString RunCommandModel::description() const
|
|
{
|
|
return QString();
|
|
}
|
|
|
|
QVariant RunCommandModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid()) {
|
|
return QVariant();
|
|
}
|
|
|
|
if (role == Qt::DisplayRole) {
|
|
return i18n("Show KRunner");
|
|
} else if (role == Qt::DecorationRole) {
|
|
return QIcon::fromTheme(QStringLiteral("plasma-search"));
|
|
} else if (role == Kicker::DescriptionRole) {
|
|
return i18n("Search, calculate, or run a command");
|
|
} else if (role == Kicker::GroupRole) {
|
|
return i18n("Applications");
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
int RunCommandModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
return parent.isValid() ? 0 : (KAuthorized::authorize(QStringLiteral("run_command")) ? 1 : 0);
|
|
}
|
|
|
|
Q_INVOKABLE bool RunCommandModel::trigger(int row, const QString &actionId, const QVariant &argument)
|
|
{
|
|
Q_UNUSED(actionId)
|
|
Q_UNUSED(argument)
|
|
|
|
if (row == 0 && KAuthorized::authorize(QStringLiteral("run_command"))) {
|
|
org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"),
|
|
QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
krunner.display();
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
ComputerModel::ComputerModel(QObject *parent) : ForwardingModel(parent)
|
|
, m_concatProxy(new KConcatenateRowsProxyModel(this))
|
|
, m_runCommandModel(new RunCommandModel(this))
|
|
, m_systemAppsModel(new SimpleFavoritesModel(this))
|
|
, m_filteredPlacesModel(new FilteredPlacesModel(this))
|
|
, m_appNameFormat(AppEntry::NameOnly)
|
|
, m_appletInterface(nullptr)
|
|
{
|
|
connect(m_systemAppsModel, &SimpleFavoritesModel::favoritesChanged, this, &ComputerModel::systemApplicationsChanged);
|
|
m_systemAppsModel->setFavorites(QStringList() << QStringLiteral("systemsettings.desktop"));
|
|
|
|
m_concatProxy->addSourceModel(m_runCommandModel);
|
|
m_concatProxy->addSourceModel(m_systemAppsModel);
|
|
m_concatProxy->addSourceModel(m_filteredPlacesModel);
|
|
|
|
setSourceModel(m_concatProxy);
|
|
}
|
|
|
|
ComputerModel::~ComputerModel()
|
|
{
|
|
}
|
|
|
|
QString ComputerModel::description() const
|
|
{
|
|
return i18n("Computer");
|
|
}
|
|
|
|
int ComputerModel::appNameFormat() const
|
|
{
|
|
return m_appNameFormat;
|
|
}
|
|
|
|
void ComputerModel::setAppNameFormat(int format)
|
|
{
|
|
if (m_appNameFormat != (AppEntry::NameFormat)format) {
|
|
m_appNameFormat = (AppEntry::NameFormat)format;
|
|
|
|
m_systemAppsModel->refresh();
|
|
|
|
emit appNameFormatChanged();
|
|
}
|
|
}
|
|
|
|
QObject *ComputerModel::appletInterface() const
|
|
{
|
|
return m_appletInterface;
|
|
}
|
|
|
|
void ComputerModel::setAppletInterface(QObject *appletInterface)
|
|
{
|
|
if (m_appletInterface != appletInterface) {
|
|
m_appletInterface = appletInterface;
|
|
|
|
emit appletInterfaceChanged();
|
|
}
|
|
}
|
|
|
|
QStringList ComputerModel::systemApplications() const
|
|
{
|
|
return m_systemAppsModel->favorites();
|
|
}
|
|
|
|
void ComputerModel::setSystemApplications(const QStringList &apps)
|
|
{
|
|
m_systemAppsModel->setFavorites(apps);
|
|
}
|
|
|
|
QVariant ComputerModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid()) {
|
|
return QVariant();
|
|
}
|
|
|
|
const QModelIndex sourceIndex = m_concatProxy->mapToSource(m_concatProxy->index(index.row(),
|
|
index.column()));
|
|
|
|
bool isPlace = (sourceIndex.model() == m_filteredPlacesModel);
|
|
|
|
if (isPlace) {
|
|
if (role == Kicker::DescriptionRole) {
|
|
if (m_filteredPlacesModel->isDevice(sourceIndex)) {
|
|
Solid::Device device = m_filteredPlacesModel->deviceForIndex(sourceIndex);
|
|
Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
|
|
|
|
if (access) {
|
|
return access->filePath();
|
|
} else {
|
|
return QString();
|
|
}
|
|
} else {
|
|
const QUrl &url = m_filteredPlacesModel->url(sourceIndex);
|
|
return url.toString(QUrl::PreferLocalFile);
|
|
}
|
|
} else if (role == Kicker::FavoriteIdRole) {
|
|
if (!m_filteredPlacesModel->isDevice(sourceIndex)) {
|
|
return m_filteredPlacesModel->url(sourceIndex);
|
|
}
|
|
} else if (role == Kicker::UrlRole) {
|
|
return m_filteredPlacesModel->url(sourceIndex);
|
|
} else if (role == Kicker::GroupRole) {
|
|
return sourceIndex.data(KFilePlacesModel::GroupRole).toString();
|
|
} else if (role == Qt::DisplayRole || role == Qt::DecorationRole) {
|
|
return sourceIndex.data(role);
|
|
}
|
|
} else if (role == Kicker::GroupRole) {
|
|
return i18n("Applications");
|
|
} else {
|
|
return sourceIndex.data(role);
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool ComputerModel::trigger(int row, const QString &actionId, const QVariant &argument)
|
|
{
|
|
const QModelIndex sourceIndex = m_concatProxy->mapToSource(m_concatProxy->index(row, 0));
|
|
|
|
if (sourceIndex.model() == m_filteredPlacesModel) {
|
|
const QUrl &url = m_filteredPlacesModel->url(sourceIndex);
|
|
|
|
if (url.isValid()) {
|
|
new KRun(url, nullptr);
|
|
|
|
return true;
|
|
}
|
|
|
|
Solid::Device device = m_filteredPlacesModel->deviceForIndex(sourceIndex);
|
|
Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
|
|
|
|
if (access && !access->isAccessible()) {
|
|
connect(access, &Solid::StorageAccess::setupDone, this, &ComputerModel::onSetupDone);
|
|
access->setup();
|
|
|
|
return true;
|
|
}
|
|
} else {
|
|
AbstractModel *model = nullptr;
|
|
|
|
if (sourceIndex.model() == m_systemAppsModel) {
|
|
model = m_systemAppsModel;
|
|
} else {
|
|
model = m_runCommandModel;
|
|
}
|
|
|
|
return model->trigger(sourceIndex.row(), actionId, argument);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ComputerModel::onSetupDone(Solid::ErrorType error, QVariant errorData, const QString &udi)
|
|
{
|
|
Q_UNUSED(errorData);
|
|
|
|
if (error != Solid::NoError) {
|
|
return;
|
|
}
|
|
|
|
Solid::Device device(udi);
|
|
Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
|
|
|
|
Q_ASSERT(access);
|
|
|
|
new KRun(QUrl::fromLocalFile(access->filePath()), nullptr);
|
|
}
|