File indexing completed on 2025-01-05 04:47:06
0001 /* 0002 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "agentactionmanager.h" 0008 0009 #include "agentfilterproxymodel.h" 0010 #include "agentinstancecreatejob.h" 0011 #include "agentinstancemodel.h" 0012 #include "agentmanager.h" 0013 #include "agenttypedialog.h" 0014 0015 #include <KActionCollection> 0016 #include <KLocalizedString> 0017 #include <KMessageBox> 0018 #include <QAction> 0019 #include <QIcon> 0020 0021 #include <KLazyLocalizedString> 0022 #include <QItemSelectionModel> 0023 #include <QPointer> 0024 0025 using namespace Akonadi; 0026 0027 /// @cond PRIVATE 0028 0029 static const struct { 0030 const char *name; 0031 const KLazyLocalizedString label; 0032 const char *icon; 0033 int shortcut; 0034 const char *slot; 0035 } agentActionData[] = {{"akonadi_agentinstance_create", kli18n("&New Agent Instance..."), "folder-new", 0, SLOT(slotCreateAgentInstance())}, 0036 {"akonadi_agentinstance_delete", kli18n("&Delete Agent Instance"), "edit-delete", 0, SLOT(slotDeleteAgentInstance())}, 0037 {"akonadi_agentinstance_configure", kli18n("&Configure Agent Instance"), "configure", 0, SLOT(slotConfigureAgentInstance())}}; 0038 static const int numAgentActionData = sizeof agentActionData / sizeof *agentActionData; 0039 0040 static_assert(numAgentActionData == AgentActionManager::LastType, "agentActionData table does not match AgentActionManager types"); 0041 0042 /** 0043 * @internal 0044 */ 0045 class Akonadi::AgentActionManagerPrivate 0046 { 0047 public: 0048 explicit AgentActionManagerPrivate(AgentActionManager *parent) 0049 : q(parent) 0050 { 0051 mActions.fill(nullptr, AgentActionManager::LastType); 0052 0053 setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle, i18nc("@title:window", "New Agent Instance")); 0054 0055 setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText, ki18n("Could not create agent instance: %1")); 0056 0057 setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle, i18nc("@title:window", "Agent Instance Creation Failed")); 0058 0059 setContextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle, i18nc("@title:window", "Delete Agent Instance?")); 0060 0061 setContextText(AgentActionManager::DeleteAgentInstance, 0062 AgentActionManager::MessageBoxText, 0063 i18n("Do you really want to delete the selected agent instance?")); 0064 } 0065 0066 void enableAction(AgentActionManager::Type type, bool enable) 0067 { 0068 Q_ASSERT(type >= 0 && type < AgentActionManager::LastType); 0069 if (QAction *act = mActions[type]) { 0070 act->setEnabled(enable); 0071 } 0072 } 0073 0074 void updateActions() 0075 { 0076 const AgentInstance::List instances = selectedAgentInstances(); 0077 0078 const bool createActionEnabled = true; 0079 bool deleteActionEnabled = true; 0080 bool configureActionEnabled = true; 0081 0082 if (instances.isEmpty()) { 0083 deleteActionEnabled = false; 0084 configureActionEnabled = false; 0085 } 0086 0087 if (instances.count() == 1) { 0088 const AgentInstance &instance = instances.first(); 0089 if (instance.type().capabilities().contains(QLatin1StringView("NoConfig"))) { 0090 configureActionEnabled = false; 0091 } 0092 } 0093 0094 enableAction(AgentActionManager::CreateAgentInstance, createActionEnabled); 0095 enableAction(AgentActionManager::DeleteAgentInstance, deleteActionEnabled); 0096 enableAction(AgentActionManager::ConfigureAgentInstance, configureActionEnabled); 0097 0098 Q_EMIT q->actionStateUpdated(); 0099 } 0100 0101 AgentInstance::List selectedAgentInstances() const 0102 { 0103 AgentInstance::List instances; 0104 0105 if (!mSelectionModel) { 0106 return instances; 0107 } 0108 0109 const QModelIndexList lstModelIndex = mSelectionModel->selectedRows(); 0110 for (const QModelIndex &index : lstModelIndex) { 0111 const auto instance = index.data(AgentInstanceModel::InstanceRole).value<AgentInstance>(); 0112 if (instance.isValid()) { 0113 instances << instance; 0114 } 0115 } 0116 0117 return instances; 0118 } 0119 0120 void slotCreateAgentInstance() 0121 { 0122 QPointer<Akonadi::AgentTypeDialog> dlg(new Akonadi::AgentTypeDialog(mParentWidget)); 0123 dlg->setWindowTitle(contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle)); 0124 0125 for (const QString &mimeType : std::as_const(mMimeTypeFilter)) { 0126 dlg->agentFilterProxyModel()->addMimeTypeFilter(mimeType); 0127 } 0128 0129 for (const QString &capability : std::as_const(mCapabilityFilter)) { 0130 dlg->agentFilterProxyModel()->addCapabilityFilter(capability); 0131 } 0132 0133 if (dlg->exec() == QDialog::Accepted) { 0134 const AgentType agentType = dlg->agentType(); 0135 0136 if (agentType.isValid()) { 0137 auto job = new AgentInstanceCreateJob(agentType, q); 0138 q->connect(job, &KJob::result, q, [this](KJob *job) { 0139 slotAgentInstanceCreationResult(job); 0140 }); 0141 job->configure(mParentWidget); 0142 job->start(); 0143 } 0144 } 0145 delete dlg; 0146 } 0147 0148 void slotDeleteAgentInstance() 0149 { 0150 const AgentInstance::List instances = selectedAgentInstances(); 0151 if (!instances.isEmpty()) { 0152 if (KMessageBox::questionTwoActions(mParentWidget, 0153 contextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxText), 0154 contextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle), 0155 KStandardGuiItem::del(), 0156 KStandardGuiItem::cancel(), 0157 QString(), 0158 KMessageBox::Dangerous) 0159 == KMessageBox::ButtonCode::PrimaryAction) { 0160 for (const AgentInstance &instance : instances) { 0161 AgentManager::self()->removeInstance(instance); 0162 } 0163 } 0164 } 0165 } 0166 0167 void slotConfigureAgentInstance() 0168 { 0169 AgentInstance::List instances = selectedAgentInstances(); 0170 if (instances.isEmpty()) { 0171 return; 0172 } 0173 0174 instances.first().configure(mParentWidget); 0175 } 0176 0177 void slotAgentInstanceCreationResult(KJob *job) 0178 { 0179 if (job->error()) { 0180 KMessageBox::error(mParentWidget, 0181 contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText).arg(job->errorString()), 0182 contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle)); 0183 } 0184 } 0185 0186 void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const QString &data) 0187 { 0188 mContextTexts[type].insert(context, data); 0189 } 0190 0191 void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const KLocalizedString &data) 0192 { 0193 mContextTexts[type].insert(context, data.toString()); 0194 } 0195 0196 QString contextText(AgentActionManager::Type type, AgentActionManager::TextContext context) const 0197 { 0198 return mContextTexts[type].value(context); 0199 } 0200 0201 AgentActionManager *const q; 0202 KActionCollection *mActionCollection = nullptr; 0203 QWidget *mParentWidget = nullptr; 0204 QItemSelectionModel *mSelectionModel = nullptr; 0205 QList<QAction *> mActions; 0206 QStringList mMimeTypeFilter; 0207 QStringList mCapabilityFilter; 0208 0209 using ContextTexts = QHash<AgentActionManager::TextContext, QString>; 0210 QHash<AgentActionManager::Type, ContextTexts> mContextTexts; 0211 }; 0212 0213 /// @endcond 0214 0215 AgentActionManager::AgentActionManager(KActionCollection *actionCollection, QWidget *parent) 0216 : QObject(parent) 0217 , d(new AgentActionManagerPrivate(this)) 0218 { 0219 d->mParentWidget = parent; 0220 d->mActionCollection = actionCollection; 0221 } 0222 0223 AgentActionManager::~AgentActionManager() = default; 0224 0225 void AgentActionManager::setSelectionModel(QItemSelectionModel *selectionModel) 0226 { 0227 d->mSelectionModel = selectionModel; 0228 connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() { 0229 d->updateActions(); 0230 }); 0231 } 0232 0233 void AgentActionManager::setMimeTypeFilter(const QStringList &mimeTypes) 0234 { 0235 d->mMimeTypeFilter = mimeTypes; 0236 } 0237 0238 void AgentActionManager::setCapabilityFilter(const QStringList &capabilities) 0239 { 0240 d->mCapabilityFilter = capabilities; 0241 } 0242 0243 QAction *AgentActionManager::createAction(Type type) 0244 { 0245 Q_ASSERT(type >= 0 && type < LastType); 0246 Q_ASSERT(agentActionData[type].name); 0247 if (QAction *act = d->mActions[type]) { 0248 return act; 0249 } 0250 0251 auto action = new QAction(d->mParentWidget); 0252 action->setText(agentActionData[type].label.toString()); 0253 0254 if (agentActionData[type].icon) { 0255 action->setIcon(QIcon::fromTheme(QString::fromLatin1(agentActionData[type].icon))); 0256 } 0257 0258 action->setShortcut(agentActionData[type].shortcut); 0259 0260 if (agentActionData[type].slot) { 0261 connect(action, SIGNAL(triggered()), agentActionData[type].slot); 0262 } 0263 0264 d->mActionCollection->addAction(QString::fromLatin1(agentActionData[type].name), action); 0265 d->mActions[type] = action; 0266 d->updateActions(); 0267 0268 return action; 0269 } 0270 0271 void AgentActionManager::createAllActions() 0272 { 0273 for (int type = 0; type < LastType; ++type) { 0274 auto action = createAction(static_cast<Type>(type)); 0275 Q_UNUSED(action) 0276 } 0277 } 0278 0279 QAction *AgentActionManager::action(Type type) const 0280 { 0281 Q_ASSERT(type >= 0 && type < LastType); 0282 return d->mActions[type]; 0283 } 0284 0285 void AgentActionManager::interceptAction(Type type, bool intercept) 0286 { 0287 Q_ASSERT(type >= 0 && type < LastType); 0288 0289 const QAction *action = d->mActions[type]; 0290 0291 if (!action) { 0292 return; 0293 } 0294 0295 if (intercept) { 0296 disconnect(action, SIGNAL(triggered()), this, agentActionData[type].slot); 0297 } else { 0298 connect(action, SIGNAL(triggered()), agentActionData[type].slot); 0299 } 0300 } 0301 0302 AgentInstance::List AgentActionManager::selectedAgentInstances() const 0303 { 0304 return d->selectedAgentInstances(); 0305 } 0306 0307 void AgentActionManager::setContextText(Type type, TextContext context, const QString &text) 0308 { 0309 d->setContextText(type, context, text); 0310 } 0311 0312 void AgentActionManager::setContextText(Type type, TextContext context, const KLocalizedString &text) 0313 { 0314 d->setContextText(type, context, text); 0315 } 0316 0317 #include "moc_agentactionmanager.cpp"