Akonadi

agentactionmanager.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "agentactionmanager.h"
8
9#include "agentfilterproxymodel.h"
10#include "agentinstancecreatejob.h"
11#include "agentinstancemodel.h"
12#include "agentmanager.h"
13#include "agenttypedialog.h"
14
15#include <KActionCollection>
16#include <KLocalizedString>
17#include <KMessageBox>
18#include <QAction>
19#include <QIcon>
20
21#include <KLazyLocalizedString>
22#include <QItemSelectionModel>
23#include <QPointer>
24
25using namespace Akonadi;
26
27/// @cond PRIVATE
28
29static const struct {
30 const char *name;
32 const char *icon;
33 int shortcut;
34 const char *slot;
35} agentActionData[] = {{"akonadi_agentinstance_create", kli18n("&New Agent Instance..."), "folder-new", 0, SLOT(slotCreateAgentInstance())},
36 {"akonadi_agentinstance_delete", kli18n("&Delete Agent Instance"), "edit-delete", 0, SLOT(slotDeleteAgentInstance())},
37 {"akonadi_agentinstance_configure", kli18n("&Configure Agent Instance"), "configure", 0, SLOT(slotConfigureAgentInstance())}};
38static const int numAgentActionData = sizeof agentActionData / sizeof *agentActionData;
39
40static_assert(numAgentActionData == AgentActionManager::LastType, "agentActionData table does not match AgentActionManager types");
41
42/**
43 * @internal
44 */
45class Akonadi::AgentActionManagerPrivate
46{
47public:
48 explicit AgentActionManagerPrivate(AgentActionManager *parent)
49 : q(parent)
50 {
51 mActions.fill(nullptr, AgentActionManager::LastType);
52
53 setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle, i18nc("@title:window", "New Agent Instance"));
54
55 setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText, ki18n("Could not create agent instance: %1"));
56
59 i18nc("@title:window", "Agent Instance Creation Failed"));
60
61 setContextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle, i18nc("@title:window", "Delete Agent Instance?"));
62
65 i18n("Do you really want to delete the selected agent instance?"));
66 }
67
68 void enableAction(AgentActionManager::Type type, bool enable)
69 {
70 Q_ASSERT(type >= 0 && type < AgentActionManager::LastType);
71 if (QAction *act = mActions[type]) {
72 act->setEnabled(enable);
73 }
74 }
75
76 void updateActions()
77 {
78 const AgentInstance::List instances = selectedAgentInstances();
79
80 const bool createActionEnabled = true;
81 bool deleteActionEnabled = true;
82 bool configureActionEnabled = true;
83
84 if (instances.isEmpty()) {
85 deleteActionEnabled = false;
86 configureActionEnabled = false;
87 }
88
89 if (instances.count() == 1) {
90 const AgentInstance &instance = instances.first();
91 if (instance.type().capabilities().contains(QLatin1StringView("NoConfig"))) {
92 configureActionEnabled = false;
93 }
94 }
95
96 enableAction(AgentActionManager::CreateAgentInstance, createActionEnabled);
97 enableAction(AgentActionManager::DeleteAgentInstance, deleteActionEnabled);
98 enableAction(AgentActionManager::ConfigureAgentInstance, configureActionEnabled);
99
100 Q_EMIT q->actionStateUpdated();
101 }
102
103 AgentInstance::List selectedAgentInstances() const
104 {
105 AgentInstance::List instances;
106
107 if (!mSelectionModel) {
108 return instances;
109 }
110
111 const QModelIndexList lstModelIndex = mSelectionModel->selectedRows();
112 for (const QModelIndex &index : lstModelIndex) {
113 const auto instance = index.data(AgentInstanceModel::InstanceRole).value<AgentInstance>();
114 if (instance.isValid()) {
115 instances << instance;
116 }
117 }
118
119 return instances;
120 }
121
122 void slotCreateAgentInstance()
123 {
126
127 for (const QString &mimeType : std::as_const(mMimeTypeFilter)) {
128 dlg->agentFilterProxyModel()->addMimeTypeFilter(mimeType);
129 }
130
131 for (const QString &capability : std::as_const(mCapabilityFilter)) {
132 dlg->agentFilterProxyModel()->addCapabilityFilter(capability);
133 }
134
135 if (dlg->exec() == QDialog::Accepted) {
136 const AgentType agentType = dlg->agentType();
137
138 if (agentType.isValid()) {
139 auto job = new AgentInstanceCreateJob(agentType, q);
140 q->connect(job, &KJob::result, q, [this](KJob *job) {
141 slotAgentInstanceCreationResult(job);
142 });
143 job->configure(mParentWidget);
144 job->start();
145 }
146 }
147 delete dlg;
148 }
149
150 void slotDeleteAgentInstance()
151 {
152 const AgentInstance::List instances = selectedAgentInstances();
153 if (!instances.isEmpty()) {
154 if (KMessageBox::questionTwoActions(mParentWidget,
159 QString(),
161 == KMessageBox::ButtonCode::PrimaryAction) {
162 for (const AgentInstance &instance : instances) {
163 AgentManager::self()->removeInstance(instance);
164 }
165 }
166 }
167 }
168
169 void slotConfigureAgentInstance()
170 {
171 AgentInstance::List instances = selectedAgentInstances();
172 if (instances.isEmpty()) {
173 return;
174 }
175
176 instances.first().configure(mParentWidget);
177 }
178
179 void slotAgentInstanceCreationResult(KJob *job)
180 {
181 if (job->error()) {
182 KMessageBox::error(mParentWidget,
185 }
186 }
187
188 void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const QString &data)
189 {
190 mContextTexts[type].insert(context, data);
191 }
192
193 void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const KLocalizedString &data)
194 {
195 mContextTexts[type].insert(context, data.toString());
196 }
197
199 {
200 return mContextTexts[type].value(context);
201 }
202
203 AgentActionManager *const q;
204 KActionCollection *mActionCollection = nullptr;
205 QWidget *mParentWidget = nullptr;
206 QItemSelectionModel *mSelectionModel = nullptr;
207 QList<QAction *> mActions;
208 QStringList mMimeTypeFilter;
209 QStringList mCapabilityFilter;
210
213};
214
215/// @endcond
216
218 : QObject(parent)
219 , d(new AgentActionManagerPrivate(this))
220{
221 d->mParentWidget = parent;
222 d->mActionCollection = actionCollection;
223}
224
226
228{
229 d->mSelectionModel = selectionModel;
230 connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() {
231 d->updateActions();
232 });
233}
234
236{
237 d->mMimeTypeFilter = mimeTypes;
238}
239
241{
242 d->mCapabilityFilter = capabilities;
243}
244
246{
247 Q_ASSERT(type >= 0 && type < LastType);
248 Q_ASSERT(agentActionData[type].name);
249 if (QAction *act = d->mActions[type]) {
250 return act;
251 }
252
253 auto action = new QAction(d->mParentWidget);
254 action->setText(agentActionData[type].label.toString());
255
256 if (agentActionData[type].icon) {
258 }
259
260 action->setShortcut(agentActionData[type].shortcut);
261
262 if (agentActionData[type].slot) {
263 connect(action, SIGNAL(triggered()), agentActionData[type].slot);
264 }
265
266 d->mActionCollection->addAction(QString::fromLatin1(agentActionData[type].name), action);
267 d->mActions[type] = action;
268 d->updateActions();
269
270 return action;
271}
272
274{
275 for (int type = 0; type < LastType; ++type) {
276 auto action = createAction(static_cast<Type>(type));
278 }
279}
280
282{
283 Q_ASSERT(type >= 0 && type < LastType);
284 return d->mActions[type];
285}
286
288{
289 Q_ASSERT(type >= 0 && type < LastType);
290
291 const QAction *action = d->mActions[type];
292
293 if (!action) {
294 return;
295 }
296
297 if (intercept) {
298 disconnect(action, SIGNAL(triggered()), this, agentActionData[type].slot);
299 } else {
300 connect(action, SIGNAL(triggered()), agentActionData[type].slot);
301 }
302}
303
305{
306 return d->selectedAgentInstances();
307}
308
310{
311 d->setContextText(type, context, text);
312}
313
315{
316 d->setContextText(type, context, text);
317}
318
319#include "moc_agentactionmanager.cpp"
Represents one agent instance and takes care of communication with it.
Manages generic actions for agent and agent instance views.
~AgentActionManager() override
Destroys the agent action manager.
void setContextText(Type type, TextContext context, const QString &text)
Sets the text of the action type for the given context.
void interceptAction(Type type, bool intercept=true)
Sets whether the default implementation for the given action type shall be executed when the action i...
Akonadi::AgentInstance::List selectedAgentInstances() const
Returns the list of agent instances that are currently selected.
void setCapabilityFilter(const QStringList &capabilities)
Sets the capability filter that will be used when creating new agent instances.
Type
Describes the supported actions.
@ CreateAgentInstance
Creates an agent instance.
@ ConfigureAgentInstance
Configures the selected agent instance.
@ DeleteAgentInstance
Deletes the selected agent instance.
void createAllActions()
Convenience method to create all standard actions.
QAction * createAction(Type type)
Creates the action of the given type and adds it to the action collection specified in the constructo...
AgentActionManager(KActionCollection *actionCollection, QWidget *parent=nullptr)
Creates a new agent action manager.
void setMimeTypeFilter(const QStringList &mimeTypes)
Sets the mime type filter that will be used when creating new agent instances.
void setSelectionModel(QItemSelectionModel *model)
Sets the agent selection model based on which the actions should operate.
QAction * action(Type type) const
Returns the action of the given type, 0 if it has not been created (yet).
TextContext
Describes the text context that can be customized.
@ DialogTitle
The window title of a dialog.
@ MessageBoxText
The text of a message box.
@ ErrorMessageTitle
The window title of an error message.
@ MessageBoxTitle
The window title of a message box.
@ ErrorMessageText
The text of an error message.
Job for creating new agent instances.
@ InstanceRole
The agent instance itself.
A dialog to select an available agent type.
virtual QString errorString() const
int error() const
void result(KJob *job)
virtual Q_SCRIPTABLE void start()=0
QString toString() const
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
KGuiItem cancel()
KGuiItem del()
QString label(StandardShortcut id)
QString name(StandardShortcut id)
const QList< QKeySequence > & shortcut(StandardShortcut id)
A glue between Qt and the standard library.
void setIcon(const QIcon &icon)
void setShortcut(const QKeySequence &shortcut)
void setText(const QString &text)
QIcon fromTheme(const QString &name)
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
T qobject_cast(QObject *object)
QString fromLatin1(QByteArrayView str)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.