/* Copyright (c) 2010 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "agentactionmanager.h" #include "agentfilterproxymodel.h" #include "agentinstancecreatejob.h" #include "agentinstancemodel.h" #include "agentmanager.h" #include "agenttypedialog.h" #include "metatypes.h" #include #include #include #include #include #include #include #include #include using namespace Akonadi; //@cond PRIVATE static const struct { const char *name; const char *label; const char *icon; int shortcut; const char *slot; } agentActionData[] = { { "akonadi_agentinstance_create", I18N_NOOP("&New Agent Instance..."), "folder-new", 0, SLOT(slotCreateAgentInstance()) }, { "akonadi_agentinstance_delete", I18N_NOOP("&Delete Agent Instance"), "edit-delete", 0, SLOT(slotDeleteAgentInstance()) }, { "akonadi_agentinstance_configure", I18N_NOOP("&Configure Agent Instance"), "configure", 0, SLOT(slotConfigureAgentInstance()) } }; static const int numAgentActionData = sizeof agentActionData / sizeof * agentActionData; BOOST_STATIC_ASSERT(numAgentActionData == AgentActionManager::LastType); /** * @internal */ class AgentActionManager::Private { public: Private(AgentActionManager *parent) : q(parent) , mSelectionModel(0) { mActions.fill(0, AgentActionManager::LastType); setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle, i18nc("@title:window", "New Agent Instance")); setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText, ki18n("Could not create agent instance: %1")); setContextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle, i18n("Agent instance creation failed")); setContextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle, i18nc("@title:window", "Delete Agent Instance?")); setContextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxText, i18n("Do you really want to delete the selected agent instance?")); } void enableAction(AgentActionManager::Type type, bool enable) { Q_ASSERT(type >= 0 && type < AgentActionManager::LastType); if (mActions[type]) { mActions[type]->setEnabled(enable); } } void updateActions() { const AgentInstance::List instances = selectedAgentInstances(); const bool createActionEnabled = true; bool deleteActionEnabled = true; bool configureActionEnabled = true; if (instances.isEmpty()) { deleteActionEnabled = false; configureActionEnabled = false; } if (instances.count() == 1) { const AgentInstance instance = instances.first(); if (instance.type().capabilities().contains(QLatin1String("NoConfig"))) { configureActionEnabled = false; } } enableAction(CreateAgentInstance, createActionEnabled); enableAction(DeleteAgentInstance, deleteActionEnabled); enableAction(ConfigureAgentInstance, configureActionEnabled); emit q->actionStateUpdated(); } AgentInstance::List selectedAgentInstances() const { AgentInstance::List instances; if (!mSelectionModel) { return instances; } foreach (const QModelIndex &index, mSelectionModel->selectedRows()) { const AgentInstance instance = index.data(AgentInstanceModel::InstanceRole).value(); if (instance.isValid()) { instances << instance; } } return instances; } void slotCreateAgentInstance() { QPointer dlg(new Akonadi::AgentTypeDialog(mParentWidget)); dlg->setCaption(contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle)); foreach (const QString &mimeType, mMimeTypeFilter) { dlg->agentFilterProxyModel()->addMimeTypeFilter(mimeType); } foreach (const QString &capability, mCapabilityFilter) { dlg->agentFilterProxyModel()->addCapabilityFilter(capability); } if (dlg->exec() == QDialog::Accepted && dlg != 0) { const AgentType agentType = dlg->agentType(); if (agentType.isValid()) { AgentInstanceCreateJob *job = new AgentInstanceCreateJob(agentType, q); q->connect(job, SIGNAL(result(KJob*)), SLOT(slotAgentInstanceCreationResult(KJob*))); job->configure(mParentWidget); job->start(); } } delete dlg; } void slotDeleteAgentInstance() { const AgentInstance::List instances = selectedAgentInstances(); if (!instances.isEmpty()) { if (KMessageBox::questionYesNo( mParentWidget, contextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxText), contextText(AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle), KStandardGuiItem::del(), KStandardGuiItem::cancel(), QString(), KMessageBox::Dangerous) == KMessageBox::Yes) { foreach (const AgentInstance &instance, instances) { AgentManager::self()->removeInstance(instance); } } } } void slotConfigureAgentInstance() { AgentInstance::List instances = selectedAgentInstances(); if (instances.isEmpty()) { return; } instances.first().configure(mParentWidget); } void slotAgentInstanceCreationResult(KJob *job) { if (job->error()) { KMessageBox::error( mParentWidget, contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText).arg(job->errorString()), contextText(AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle)); } } void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const QString &data) { mContextTexts[type].insert(context, data); } void setContextText(AgentActionManager::Type type, AgentActionManager::TextContext context, const KLocalizedString &data) { mContextTexts[type].insert(context, data.toString()); } QString contextText(AgentActionManager::Type type, AgentActionManager::TextContext context) const { return mContextTexts[type].value(context); } AgentActionManager *q; KActionCollection *mActionCollection; QWidget *mParentWidget; QItemSelectionModel *mSelectionModel; QVector mActions; QStringList mMimeTypeFilter; QStringList mCapabilityFilter; typedef QHash ContextTexts; QHash mContextTexts; }; //@endcond AgentActionManager::AgentActionManager(KActionCollection *actionCollection, QWidget *parent) : QObject(parent) , d(new Private(this)) { d->mParentWidget = parent; d->mActionCollection = actionCollection; } AgentActionManager::~AgentActionManager() { delete d; } void AgentActionManager::setSelectionModel(QItemSelectionModel *selectionModel) { d->mSelectionModel = selectionModel; connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateActions())); } void AgentActionManager::setMimeTypeFilter(const QStringList &mimeTypes) { d->mMimeTypeFilter = mimeTypes; } void AgentActionManager::setCapabilityFilter(const QStringList &capabilities) { d->mCapabilityFilter = capabilities; } KAction *AgentActionManager::createAction(Type type) { Q_ASSERT(type >= 0 && type < LastType); Q_ASSERT(agentActionData[type].name); if (d->mActions[type]) { return d->mActions[type]; } KAction *action = new KAction(d->mParentWidget); action->setText(i18n(agentActionData[type].label)); if (agentActionData[type].icon) { action->setIcon(KIcon(QString::fromLatin1(agentActionData[type].icon))); } action->setShortcut(agentActionData[type].shortcut); if (agentActionData[type].slot) { connect(action, SIGNAL(triggered()), agentActionData[type].slot); } d->mActionCollection->addAction(QString::fromLatin1(agentActionData[type].name), action); d->mActions[type] = action; d->updateActions(); return action; } void AgentActionManager::createAllActions() { for (int type = 0; type < LastType; ++type) { createAction((Type)type); } } KAction *AgentActionManager::action(Type type) const { Q_ASSERT(type >= 0 && type < LastType); return d->mActions[type]; } void AgentActionManager::interceptAction(Type type, bool intercept) { Q_ASSERT(type >= 0 && type < LastType); const KAction *action = d->mActions[type]; if (!action) { return; } if (intercept) { disconnect(action, SIGNAL(triggered()), this, agentActionData[type].slot); } else { connect(action, SIGNAL(triggered()), agentActionData[type].slot); } } AgentInstance::List AgentActionManager::selectedAgentInstances() const { return d->selectedAgentInstances(); } void AgentActionManager::setContextText(Type type, TextContext context, const QString &text) { d->setContextText(type, context, text); } void AgentActionManager::setContextText(Type type, TextContext context, const KLocalizedString &text) { d->setContextText(type, context, text); } #include "moc_agentactionmanager.cpp"