akonadi
agentactionmanager.cpp
00001 /* 00002 Copyright (c) 2010 Tobias Koenig <tokoe@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "agentactionmanager.h" 00021 00022 #include "agentfilterproxymodel.h" 00023 #include "agentinstancecreatejob.h" 00024 #include "agentinstancemodel.h" 00025 #include "agentmanager.h" 00026 #include "agenttypedialog.h" 00027 #include "metatypes.h" 00028 00029 #include <KAction> 00030 #include <KActionCollection> 00031 #include <KDebug> 00032 #include <KInputDialog> 00033 #include <KLocale> 00034 #include <KMessageBox> 00035 00036 #include <QtGui/QItemSelectionModel> 00037 00038 #include <boost/static_assert.hpp> 00039 00040 using namespace Akonadi; 00041 00042 //@cond PRIVATE 00043 00044 static const struct { 00045 const char *name; 00046 const char *label; 00047 const char *icon; 00048 int shortcut; 00049 const char* slot; 00050 } agentActionData[] = { 00051 { "akonadi_agentinstance_create", I18N_NOOP( "&New Agent Instance..." ), "folder-new", 0, SLOT( slotCreateAgentInstance() ) }, 00052 { "akonadi_agentinstance_delete", I18N_NOOP( "&Delete Agent Instance" ), "edit-delete", 0, SLOT( slotDeleteAgentInstance() ) }, 00053 { "akonadi_agentinstance_configure", I18N_NOOP( "&Configure Agent Instance" ), "configure", 0, SLOT( slotConfigureAgentInstance() ) } 00054 }; 00055 static const int numAgentActionData = sizeof agentActionData / sizeof *agentActionData; 00056 00057 BOOST_STATIC_ASSERT( numAgentActionData == AgentActionManager::LastType ); 00058 00062 class AgentActionManager::Private 00063 { 00064 public: 00065 Private( AgentActionManager *parent ) : 00066 q( parent ), 00067 mSelectionModel( 0 ) 00068 { 00069 mActions.fill( 0, AgentActionManager::LastType ); 00070 00071 setContextText( AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle, 00072 i18nc( "@title:window", "New Agent Instance" ) ); 00073 setContextText( AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText, 00074 i18n( "Could not create agent instance: %1" ) ); 00075 setContextText( AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle, 00076 i18n( "Agent instance creation failed" ) ); 00077 00078 setContextText( AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle, 00079 i18nc( "@title:window", "Delete Agent Instance?" ) ); 00080 setContextText( AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxText, 00081 i18n( "Do you really want to delete the selected agent instance?" ) ); 00082 } 00083 00084 void enableAction( AgentActionManager::Type type, bool enable ) 00085 { 00086 Q_ASSERT( type >= 0 && type < AgentActionManager::LastType ); 00087 if ( mActions[ type ] ) 00088 mActions[ type ]->setEnabled( enable ); 00089 } 00090 00091 void updateActions() 00092 { 00093 const AgentInstance::List instances = selectedAgentInstances(); 00094 00095 const bool createActionEnabled = true; 00096 bool deleteActionEnabled = true; 00097 bool configureActionEnabled = true; 00098 00099 if ( instances.isEmpty() ) { 00100 deleteActionEnabled = false; 00101 configureActionEnabled = false; 00102 } 00103 00104 if ( instances.count() == 1 ) { 00105 const AgentInstance instance = instances.first(); 00106 if ( instance.type().capabilities().contains( QLatin1String( "NoConfig" ) ) ) 00107 configureActionEnabled = false; 00108 } 00109 00110 enableAction( CreateAgentInstance, createActionEnabled ); 00111 enableAction( DeleteAgentInstance, deleteActionEnabled ); 00112 enableAction( ConfigureAgentInstance, configureActionEnabled ); 00113 00114 emit q->actionStateUpdated(); 00115 } 00116 00117 AgentInstance::List selectedAgentInstances() const 00118 { 00119 AgentInstance::List instances; 00120 00121 if ( !mSelectionModel ) 00122 return instances; 00123 00124 foreach ( const QModelIndex &index, mSelectionModel->selectedRows() ) { 00125 const AgentInstance instance = index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>(); 00126 if ( instance.isValid() ) 00127 instances << instance; 00128 } 00129 00130 return instances; 00131 } 00132 00133 void slotCreateAgentInstance() 00134 { 00135 Akonadi::AgentTypeDialog dlg( mParentWidget ); 00136 dlg.setCaption( contextText( AgentActionManager::CreateAgentInstance, AgentActionManager::DialogTitle ) ); 00137 00138 foreach ( const QString &mimeType, mMimeTypeFilter ) 00139 dlg.agentFilterProxyModel()->addMimeTypeFilter( mimeType ); 00140 00141 foreach ( const QString &capability, mCapabilityFilter ) 00142 dlg.agentFilterProxyModel()->addCapabilityFilter( capability ); 00143 00144 if ( dlg.exec() ) { 00145 const AgentType agentType = dlg.agentType(); 00146 00147 if ( agentType.isValid() ) { 00148 AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, q ); 00149 q->connect( job, SIGNAL( result( KJob* ) ), SLOT( slotAgentInstanceCreationResult( KJob* ) ) ); 00150 job->configure( mParentWidget ); 00151 job->start(); 00152 } 00153 } 00154 } 00155 00156 void slotDeleteAgentInstance() 00157 { 00158 const AgentInstance::List instances = selectedAgentInstances(); 00159 if ( !instances.isEmpty() ) { 00160 if ( KMessageBox::questionYesNo( mParentWidget, 00161 contextText( AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxText ), 00162 contextText( AgentActionManager::DeleteAgentInstance, AgentActionManager::MessageBoxTitle ), 00163 KStandardGuiItem::del(), 00164 KStandardGuiItem::cancel(), 00165 QString(), 00166 KMessageBox::Dangerous ) 00167 == KMessageBox::Yes ) { 00168 00169 foreach ( const AgentInstance &instance, instances ) 00170 AgentManager::self()->removeInstance( instance ); 00171 } 00172 } 00173 } 00174 00175 void slotConfigureAgentInstance() 00176 { 00177 AgentInstance::List instances = selectedAgentInstances(); 00178 if ( instances.isEmpty() ) 00179 return; 00180 00181 instances.first().configure( mParentWidget ); 00182 } 00183 00184 void slotAgentInstanceCreationResult( KJob *job ) 00185 { 00186 if ( job->error() ) { 00187 KMessageBox::error( mParentWidget, 00188 contextText( AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageText ).arg( job->errorString() ), 00189 contextText( AgentActionManager::CreateAgentInstance, AgentActionManager::ErrorMessageTitle ) ); 00190 } 00191 } 00192 00193 void setContextText( AgentActionManager::Type type, AgentActionManager::TextContext context, const QString &data ) 00194 { 00195 mContextTexts[ type ].insert( context, data ); 00196 } 00197 00198 QString contextText( AgentActionManager::Type type, AgentActionManager::TextContext context ) const 00199 { 00200 return mContextTexts[ type ].value( context ); 00201 } 00202 00203 AgentActionManager *q; 00204 KActionCollection *mActionCollection; 00205 QWidget *mParentWidget; 00206 QItemSelectionModel *mSelectionModel; 00207 QVector<KAction*> mActions; 00208 QStringList mMimeTypeFilter; 00209 QStringList mCapabilityFilter; 00210 00211 typedef QHash<AgentActionManager::TextContext, QString> ContextTexts; 00212 QHash<AgentActionManager::Type, ContextTexts> mContextTexts; 00213 }; 00214 00215 //@endcond 00216 00217 AgentActionManager::AgentActionManager( KActionCollection * actionCollection, QWidget * parent) 00218 : QObject( parent ), 00219 d( new Private( this ) ) 00220 { 00221 d->mParentWidget = parent; 00222 d->mActionCollection = actionCollection; 00223 } 00224 00225 AgentActionManager::~AgentActionManager() 00226 { 00227 delete d; 00228 } 00229 00230 void AgentActionManager::setSelectionModel( QItemSelectionModel *selectionModel ) 00231 { 00232 d->mSelectionModel = selectionModel; 00233 connect( selectionModel, SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ), 00234 SLOT( updateActions() ) ); 00235 } 00236 00237 void AgentActionManager::setMimeTypeFilter( const QStringList &mimeTypes ) 00238 { 00239 d->mMimeTypeFilter = mimeTypes; 00240 } 00241 00242 void AgentActionManager::setCapabilityFilter( const QStringList &capabilities ) 00243 { 00244 d->mCapabilityFilter = capabilities; 00245 } 00246 00247 KAction* AgentActionManager::createAction( Type type ) 00248 { 00249 Q_ASSERT( type >= 0 && type < LastType ); 00250 Q_ASSERT( agentActionData[ type ].name ); 00251 if ( d->mActions[ type ] ) 00252 return d->mActions[ type ]; 00253 00254 KAction *action = new KAction( d->mParentWidget ); 00255 action->setText( i18n( agentActionData[ type ].label ) ); 00256 00257 if ( agentActionData[ type ].icon ) 00258 action->setIcon( KIcon( QString::fromLatin1( agentActionData[ type ].icon ) ) ); 00259 00260 action->setShortcut( agentActionData[ type ].shortcut ); 00261 00262 if ( agentActionData[ type ].slot ) 00263 connect( action, SIGNAL( triggered() ), agentActionData[ type ].slot ); 00264 00265 d->mActionCollection->addAction( QString::fromLatin1( agentActionData[ type ].name), action ); 00266 d->mActions[ type ] = action; 00267 d->updateActions(); 00268 00269 return action; 00270 } 00271 00272 void AgentActionManager::createAllActions() 00273 { 00274 for ( int type = 0; type < LastType; ++type ) 00275 createAction( (Type)type ); 00276 } 00277 00278 KAction * AgentActionManager::action( Type type ) const 00279 { 00280 Q_ASSERT( type >= 0 && type < LastType ); 00281 return d->mActions[ type ]; 00282 } 00283 00284 void AgentActionManager::interceptAction( Type type, bool intercept ) 00285 { 00286 Q_ASSERT( type >= 0 && type < LastType ); 00287 00288 const KAction *action = d->mActions[ type ]; 00289 00290 if ( !action ) 00291 return; 00292 00293 if ( intercept ) 00294 disconnect( action, SIGNAL( triggered() ), this, agentActionData[ type ].slot ); 00295 else 00296 connect( action, SIGNAL( triggered() ), agentActionData[ type ].slot ); 00297 } 00298 00299 AgentInstance::List AgentActionManager::selectedAgentInstances() const 00300 { 00301 return d->selectedAgentInstances(); 00302 } 00303 00304 void AgentActionManager::setContextText( Type type, TextContext context, const QString &text ) 00305 { 00306 d->setContextText( type, context, text ); 00307 } 00308 00309 #include "agentactionmanager.moc"