Akonadi

agentactionmanager.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Tobias Koenig <[email protected]>
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 
25 using namespace Akonadi;
26 
27 /// @cond PRIVATE
28 
29 static 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())}};
38 static const int numAgentActionData = sizeof agentActionData / sizeof *agentActionData;
39 
40 static_assert(numAgentActionData == AgentActionManager::LastType, "agentActionData table does not match AgentActionManager types");
41 
42 /**
43  * @internal
44  */
45 class Akonadi::AgentActionManagerPrivate
46 {
47 public:
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 
57  setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle, i18nc("@title:window", "Agent Instance Creation Failed"));
58 
59  setContextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle, i18nc("@title:window", "Delete Agent Instance?"));
60 
63  i18n("Do you really want to delete the selected agent instance?"));
64  }
65 
66  void enableAction(AgentActionManager::Type type, bool enable)
67  {
68  Q_ASSERT(type >= 0 && type < AgentActionManager::LastType);
69  if (QAction *act = mActions[type]) {
70  act->setEnabled(enable);
71  }
72  }
73 
74  void updateActions()
75  {
76  const AgentInstance::List instances = selectedAgentInstances();
77 
78  const bool createActionEnabled = true;
79  bool deleteActionEnabled = true;
80  bool configureActionEnabled = true;
81 
82  if (instances.isEmpty()) {
83  deleteActionEnabled = false;
84  configureActionEnabled = false;
85  }
86 
87  if (instances.count() == 1) {
88  const AgentInstance &instance = instances.first();
89  if (instance.type().capabilities().contains(QLatin1String("NoConfig"))) {
90  configureActionEnabled = false;
91  }
92  }
93 
94  enableAction(AgentActionManager::CreateAgentInstance, createActionEnabled);
95  enableAction(AgentActionManager::DeleteAgentInstance, deleteActionEnabled);
96  enableAction(AgentActionManager::ConfigureAgentInstance, configureActionEnabled);
97 
98  Q_EMIT q->actionStateUpdated();
99  }
100 
101  AgentInstance::List selectedAgentInstances() const
102  {
103  AgentInstance::List instances;
104 
105  if (!mSelectionModel) {
106  return instances;
107  }
108 
109  const QModelIndexList lstModelIndex = mSelectionModel->selectedRows();
110  for (const QModelIndex &index : lstModelIndex) {
111  const auto instance = index.data(AgentInstanceModel::InstanceRole).value<AgentInstance>();
112  if (instance.isValid()) {
113  instances << instance;
114  }
115  }
116 
117  return instances;
118  }
119 
120  void slotCreateAgentInstance()
121  {
124 
125  for (const QString &mimeType : std::as_const(mMimeTypeFilter)) {
126  dlg->agentFilterProxyModel()->addMimeTypeFilter(mimeType);
127  }
128 
129  for (const QString &capability : std::as_const(mCapabilityFilter)) {
130  dlg->agentFilterProxyModel()->addCapabilityFilter(capability);
131  }
132 
133  if (dlg->exec() == QDialog::Accepted) {
134  const AgentType agentType = dlg->agentType();
135 
136  if (agentType.isValid()) {
137  auto job = new AgentInstanceCreateJob(agentType, q);
138  q->connect(job, &KJob::result, q, [this](KJob *job) {
139  slotAgentInstanceCreationResult(job);
140  });
141  job->configure(mParentWidget);
142  job->start();
143  }
144  }
145  delete dlg;
146  }
147 
148  void slotDeleteAgentInstance()
149  {
150  const AgentInstance::List instances = selectedAgentInstances();
151  if (!instances.isEmpty()) {
152  if (KMessageBox::questionTwoActions(mParentWidget,
157  QString(),
159  == KMessageBox::ButtonCode::PrimaryAction) {
160  for (const AgentInstance &instance : instances) {
161  AgentManager::self()->removeInstance(instance);
162  }
163  }
164  }
165  }
166 
167  void slotConfigureAgentInstance()
168  {
169  AgentInstance::List instances = selectedAgentInstances();
170  if (instances.isEmpty()) {
171  return;
172  }
173 
174  instances.first().configure(mParentWidget);
175  }
176 
177  void slotAgentInstanceCreationResult(KJob *job)
178  {
179  if (job->error()) {
180  KMessageBox::error(mParentWidget,
183  }
184  }
185 
186  void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const QString &data)
187  {
188  mContextTexts[type].insert(context, data);
189  }
190 
191  void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const KLocalizedString &data)
192  {
193  mContextTexts[type].insert(context, data.toString());
194  }
195 
196  QString contextText(AgentActionManager::Type type, AgentActionManager::TextContext context) const
197  {
198  return mContextTexts[type].value(context);
199  }
200 
201  AgentActionManager *const q;
202  KActionCollection *mActionCollection = nullptr;
203  QWidget *mParentWidget = nullptr;
204  QItemSelectionModel *mSelectionModel = nullptr;
205  QVector<QAction *> mActions;
206  QStringList mMimeTypeFilter;
207  QStringList mCapabilityFilter;
208 
211 };
212 
213 /// @endcond
214 
216  : QObject(parent)
217  , d(new AgentActionManagerPrivate(this))
218 {
219  d->mParentWidget = parent;
220  d->mActionCollection = actionCollection;
221 }
222 
224 
226 {
227  d->mSelectionModel = selectionModel;
228  connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() {
229  d->updateActions();
230  });
231 }
232 
234 {
235  d->mMimeTypeFilter = mimeTypes;
236 }
237 
239 {
240  d->mCapabilityFilter = capabilities;
241 }
242 
244 {
245  Q_ASSERT(type >= 0 && type < LastType);
246  Q_ASSERT(agentActionData[type].name);
247  if (QAction *act = d->mActions[type]) {
248  return act;
249  }
250 
251  auto action = new QAction(d->mParentWidget);
252  action->setText(agentActionData[type].label.toString());
253 
254  if (agentActionData[type].icon) {
255  action->setIcon(QIcon::fromTheme(QString::fromLatin1(agentActionData[type].icon)));
256  }
257 
258  action->setShortcut(agentActionData[type].shortcut);
259 
260  if (agentActionData[type].slot) {
261  connect(action, SIGNAL(triggered()), agentActionData[type].slot);
262  }
263 
264  d->mActionCollection->addAction(QString::fromLatin1(agentActionData[type].name), action);
265  d->mActions[type] = action;
266  d->updateActions();
267 
268  return action;
269 }
270 
272 {
273  for (int type = 0; type < LastType; ++type) {
274  auto action = createAction(static_cast<Type>(type));
275  Q_UNUSED(action)
276  }
277 }
278 
280 {
281  Q_ASSERT(type >= 0 && type < LastType);
282  return d->mActions[type];
283 }
284 
285 void AgentActionManager::interceptAction(Type type, bool intercept)
286 {
287  Q_ASSERT(type >= 0 && type < LastType);
288 
289  const QAction *action = d->mActions[type];
290 
291  if (!action) {
292  return;
293  }
294 
295  if (intercept) {
296  disconnect(action, SIGNAL(triggered()), this, agentActionData[type].slot);
297  } else {
298  connect(action, SIGNAL(triggered()), agentActionData[type].slot);
299  }
300 }
301 
303 {
304  return d->selectedAgentInstances();
305 }
306 
308 {
309  d->setContextText(type, context, text);
310 }
311 
313 {
314  d->setContextText(type, context, text);
315 }
316 
317 #include "moc_agentactionmanager.cpp"
bool isValid() const
Returns whether the agent type is valid.
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
QAction * action(Type type) const
Returns the action of the given type, 0 if it has not been created (yet).
@ InstanceRole
The agent instance itself.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
const QList< QKeySequence > & shortcut(StandardShortcut id)
virtual Q_SCRIPTABLE void start()=0
Akonadi::AgentInstance::List selectedAgentInstances() const
Returns the list of agent instances that are currently selected.
AgentType type() const
Returns the agent type of this instance.
void result(KJob *job)
~AgentActionManager() override
Destroys the agent action manager.
A representation of an agent type.
@ ErrorMessageTitle
The window title of an error message.
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QIcon fromTheme(const QString &name)
AgentActionManager(KActionCollection *actionCollection, QWidget *parent=nullptr)
Creates a new agent action manager.
QVector< AgentInstance > List
Describes a list of agent instances.
@ DeleteAgentInstance
Deletes the selected agent instance.
void setShortcut(const QKeySequence &shortcut)
QString toString() const
@ ErrorMessageText
The text of an error message.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
TextContext
Describes the text context that can be customized.
KGuiItem cancel()
void removeInstance(const AgentInstance &instance)
Removes the given agent instance.
QStringList capabilities() const
Returns the list of supported capabilities of the agent type.
void setIcon(const QIcon &icon)
@ MessageBoxText
The text of a message box.
QString i18n(const char *text, const TYPE &arg...)
@ MessageBoxTitle
The window title of a message box.
void setCapabilityFilter(const QStringList &capabilities)
Sets the capability filter that will be used when creating new agent instances.
Type
Describes the supported actions.
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...
void setText(const QString &text)
Manages generic actions for agent and agent instance views.
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QAction * createAction(Type type)
Creates the action of the given type and adds it to the action collection specified in the constructo...
@ DialogTitle
The window title of a dialog.
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString label(StandardShortcut id)
KGuiItem del()
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString fromLatin1(const char *str, int size)
QString name(StandardShortcut id)
@ CreateAgentInstance
Creates an agent instance.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void createAllActions()
Convenience method to create all standard actions.
static AgentManager * self()
Returns the global instance of the agent manager.
void setSelectionModel(QItemSelectionModel *model)
Sets the agent selection model based on which the actions should operate.
A dialog to select an available agent type.
void setMimeTypeFilter(const QStringList &mimeTypes)
Sets the mime type filter that will be used when creating new agent instances.
virtual QString errorString() const
int error() const
@ ConfigureAgentInstance
Configures the selected agent instance.
bool isValid() const
Returns whether the agent instance object is valid.
A representation of an agent instance.
QObject * parent() const const
Job for creating new agent instances.
Helper integration between Akonadi and Qt.
@ LastType
Marks last action.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon May 8 2023 03:52:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.