• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi

standardactionmanager.cpp

00001 /*
00002     Copyright (c) 2008 Volker Krause <vkrause@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 "standardactionmanager.h"
00021 
00022 #include "agentmanager.h"
00023 #include "collectioncreatejob.h"
00024 #include "collectiondeletejob.h"
00025 #include "collectionmodel.h"
00026 #include "collectionutils_p.h"
00027 #include "collectionpropertiesdialog.h"
00028 #include "itemdeletejob.h"
00029 #include "itemmodel.h"
00030 #include "pastehelper.h"
00031 #include "subscriptiondialog.h"
00032 
00033 #include <KAction>
00034 #include <KActionCollection>
00035 #include <KDebug>
00036 #include <KInputDialog>
00037 #include <KLocale>
00038 #include <KMessageBox>
00039 
00040 #include <QtCore/QMimeData>
00041 #include <QtGui/QApplication>
00042 #include <QtGui/QClipboard>
00043 #include <QtGui/QItemSelectionModel>
00044 
00045 #include <boost/static_assert.hpp>
00046 
00047 using namespace Akonadi;
00048 
00049 //@cond PRIVATE
00050 
00051 static const struct {
00052   const char *name;
00053   const char *label;
00054   const char *icon;
00055   int shortcut;
00056   const char* slot;
00057 } actionData[] = {
00058   { "akonadi_collection_create", I18N_NOOP("&New Folder..."), "folder-new", 0, SLOT(slotCreateCollection()) },
00059   { "akonadi_collection_copy", 0, "edit-copy", 0, SLOT(slotCopyCollections()) },
00060   { "akonadi_collection_delete", I18N_NOOP("&Delete Folder"), "edit-delete", 0, SLOT(slotDeleteCollection()) },
00061   { "akonadi_collection_sync", I18N_NOOP("&Synchronize Folder"), "view-refresh", Qt::Key_F5, SLOT(slotSynchronizeCollection()) },
00062   { "akonadi_collection_properties", I18N_NOOP("Folder &Properties..."), "configure", 0, SLOT(slotCollectionProperties()) },
00063   { "akonadi_item_copy", 0, "edit-copy", 0, SLOT(slotCopyItems()) },
00064   { "akonadi_paste", I18N_NOOP("&Paste"), "edit-paste", Qt::CTRL + Qt::Key_V, SLOT(slotPaste()) },
00065   { "akonadi_item_delete", 0, "edit-delete", Qt::Key_Delete, SLOT(slotDeleteItems()) },
00066   { "akonadi_manage_local_subscriptions", I18N_NOOP("Manage Local &Subscriptions..."), 0, 0, SLOT(slotLocalSubscription()) }
00067 };
00068 static const int numActionData = sizeof actionData / sizeof *actionData;
00069 
00070 BOOST_STATIC_ASSERT( numActionData == StandardActionManager::LastType );
00071 
00072 static bool canCreateCollection( const Collection &collection )
00073 {
00074   if ( !( collection.rights() & Collection::CanCreateCollection ) )
00075     return false;
00076 
00077   if ( !collection.contentMimeTypes().contains( Collection::mimeType() ) )
00078     return false;
00079 
00080   return true;
00081 }
00082 
00086 class StandardActionManager::Private
00087 {
00088   public:
00089     Private( StandardActionManager *parent ) :
00090       q( parent ),
00091       collectionSelectionModel( 0 ),
00092       itemSelectionModel( 0 )
00093     {
00094       actions.fill( 0, StandardActionManager::LastType );
00095 
00096       pluralLabels.insert( StandardActionManager::CopyCollections, ki18np( "&Copy Folder", "&Copy %1 Folders" ) );
00097       pluralLabels.insert( StandardActionManager::CopyItems, ki18np( "&Copy Item", "&Copy %1 Items" ) );
00098       pluralLabels.insert( StandardActionManager::DeleteItems, ki18np( "&Delete Item", "&Delete %1 Items" ) );
00099     }
00100 
00101     void enableAction( StandardActionManager::Type type, bool enable )
00102     {
00103       Q_ASSERT( type >= 0 && type < StandardActionManager::LastType );
00104       if ( actions[type] )
00105         actions[type]->setEnabled( enable );
00106     }
00107 
00108     void updatePluralLabel( StandardActionManager::Type type, int count )
00109     {
00110       Q_ASSERT( type >= 0 && type < StandardActionManager::LastType );
00111       if ( actions[type] && pluralLabels.contains( type ) && !pluralLabels.value( type ).isEmpty() ) {
00112         actions[type]->setText( pluralLabels.value( type ).subs( qMax( count, 1 ) ).toString() );
00113       }
00114     }
00115 
00116     void copy( QItemSelectionModel* selModel )
00117     {
00118       Q_ASSERT( selModel );
00119       if ( selModel->selectedRows().count() <= 0 )
00120         return;
00121       QMimeData *mimeData = selModel->model()->mimeData( selModel->selectedRows() );
00122       QApplication::clipboard()->setMimeData( mimeData );
00123     }
00124 
00125     void updateActions()
00126     {
00127       bool singleColSelected = false;
00128       bool multiColSelected = false;
00129       int colCount = 0;
00130       QModelIndex selectedIndex;
00131       if ( collectionSelectionModel ) {
00132         colCount = collectionSelectionModel->selectedRows().count();
00133         singleColSelected = colCount == 1;
00134         multiColSelected = colCount > 0;
00135         if ( singleColSelected )
00136           selectedIndex = collectionSelectionModel->selectedRows().first();
00137       }
00138 
00139       enableAction( CopyCollections, multiColSelected );
00140       enableAction( CollectionProperties, singleColSelected );
00141 
00142       Collection col;
00143       if ( singleColSelected && selectedIndex.isValid() ) {
00144         col = selectedIndex.data( CollectionModel::CollectionRole ).value<Collection>();
00145         enableAction( CreateCollection, canCreateCollection( col ) );
00146         enableAction( DeleteCollections, col.rights() & Collection::CanDeleteCollection );
00147         enableAction( SynchronizeCollections, CollectionUtils::isResource( col ) || CollectionUtils::isFolder( col ) );
00148         enableAction( Paste, PasteHelper::canPaste( QApplication::clipboard()->mimeData(), col ) );
00149       } else {
00150         enableAction( CreateCollection, false );
00151         enableAction( DeleteCollections, false );
00152         enableAction( SynchronizeCollections, false );
00153         enableAction( Paste, false );
00154       }
00155 
00156       bool multiItemSelected = false;
00157       int itemCount = 0;
00158       if ( itemSelectionModel ) {
00159         itemCount = itemSelectionModel->selectedRows().count();
00160         multiItemSelected = itemCount > 0;
00161       }
00162 
00163       enableAction( CopyItems, multiItemSelected );
00164       const bool canDeleteItem = !col.isValid() || (col.rights() & Collection::CanDeleteItem);
00165       enableAction( DeleteItems, multiItemSelected && canDeleteItem );
00166 
00167       updatePluralLabel( CopyCollections, colCount );
00168       updatePluralLabel( CopyItems, itemCount );
00169       updatePluralLabel( DeleteItems, itemCount );
00170 
00171       emit q->actionStateUpdated();
00172     }
00173 
00174     void clipboardChanged( QClipboard::Mode mode )
00175     {
00176       if ( mode == QClipboard::Clipboard )
00177         updateActions();
00178     }
00179 
00180     void slotCreateCollection()
00181     {
00182       const QModelIndex index = collectionSelectionModel->currentIndex();
00183       const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00184 
00185       if ( !canCreateCollection( collection ) )
00186         return;
00187 
00188       const QString name = KInputDialog::getText( i18nc( "@title:window", "New Folder"),
00189                                                   i18nc( "@label:textbox, name of a thing", "Name"),
00190                                                   QString(), 0, parentWidget );
00191       if ( name.isEmpty() )
00192         return;
00193       Collection::Id parentId = index.data( CollectionModel::CollectionIdRole ).toLongLong();
00194       if ( parentId <= 0 )
00195         return;
00196 
00197       Collection col;
00198       col.setName( name );
00199       col.setParent( parentId );
00200       CollectionCreateJob *job = new CollectionCreateJob( col );
00201       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionCreationResult(KJob*)) );
00202     }
00203 
00204     void slotCopyCollections()
00205     {
00206       copy( collectionSelectionModel );
00207     }
00208 
00209     void slotDeleteCollection()
00210     {
00211       Q_ASSERT( collectionSelectionModel );
00212       const QModelIndex index = collectionSelectionModel->currentIndex();
00213       if ( !index.isValid() )
00214         return;
00215 
00216       const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00217       QString text = i18n( "Do you really want to delete folder '%1' and all its sub-folders?", index.data().toString() );
00218       if ( CollectionUtils::isVirtual( collection ) )
00219         text = i18n( "Do you really want to delete the search view '%1'?", index.data().toString() );
00220 
00221       if ( KMessageBox::questionYesNo( parentWidget, text,
00222            i18n("Delete folder?"), KStandardGuiItem::del(), KStandardGuiItem::cancel(),
00223            QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
00224         return;
00225       const Collection::Id colId = index.data( CollectionModel::CollectionIdRole ).toLongLong();
00226       if ( colId <= 0 )
00227         return;
00228 
00229       CollectionDeleteJob *job = new CollectionDeleteJob( Collection( colId ), q );
00230       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionDeletionResult(KJob*)) );
00231     }
00232 
00233     void slotSynchronizeCollection()
00234     {
00235       QModelIndex index = collectionSelectionModel->currentIndex();
00236       if ( !index.isValid() )
00237         return;
00238       const Collection col = index.data( CollectionModel::CollectionRole ).value<Collection>();
00239       AgentManager::self()->synchronizeCollection( col );
00240     }
00241 
00242     void slotCollectionProperties()
00243     {
00244       const QModelIndex index = collectionSelectionModel->currentIndex();
00245       if ( !index.isValid() )
00246         return;
00247       const Collection col = index.data( CollectionModel::CollectionRole ).value<Collection>();
00248       CollectionPropertiesDialog* dlg = new CollectionPropertiesDialog( col, parentWidget );
00249       dlg->show();
00250     }
00251 
00252     void slotCopyItems()
00253     {
00254       copy( itemSelectionModel );
00255     }
00256 
00257     void slotPaste()
00258     {
00259       const QModelIndex index = collectionSelectionModel->currentIndex();
00260       if ( !index.isValid() )
00261         return;
00262       const Collection col = index.data( CollectionModel::CollectionRole ).value<Collection>();
00263       KJob *job = PasteHelper::paste( QApplication::clipboard()->mimeData(), col );
00264       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(pasteResult(KJob*)) );
00265     }
00266 
00267     void slotDeleteItems()
00268     {
00269       if ( KMessageBox::questionYesNo( parentWidget,
00270            i18n( "Do you really want to delete all selected items?" ),
00271            i18n("Delete?"), KStandardGuiItem::del(), KStandardGuiItem::cancel(),
00272            QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
00273         return;
00274 
00275       Q_ASSERT( itemSelectionModel );
00276 
00277       // TODO: fix this once ItemModifyJob can handle item lists
00278       foreach ( const QModelIndex &index, itemSelectionModel->selectedRows() ) {
00279         new ItemDeleteJob( Item( index.data( ItemModel::IdRole ).toLongLong() ), q );
00280       }
00281     }
00282 
00283     void slotLocalSubscription()
00284     {
00285       SubscriptionDialog* dlg = new SubscriptionDialog( parentWidget );
00286       dlg->show();
00287     }
00288 
00289     void collectionCreationResult( KJob *job )
00290     {
00291       if ( job->error() ) {
00292         KMessageBox::error( parentWidget, i18n("Could not create folder: %1", job->errorString()),
00293                             i18n("Folder creation failed") );
00294       }
00295     }
00296 
00297     void collectionDeletionResult( KJob *job )
00298     {
00299       if ( job->error() ) {
00300         KMessageBox::error( parentWidget, i18n("Could not delete folder: %1", job->errorString()),
00301                             i18n("Folder deletion failed") );
00302       }
00303     }
00304 
00305     void pasteResult( KJob *job )
00306     {
00307       if ( job->error() ) {
00308         KMessageBox::error( parentWidget, i18n("Could not paste data: %1", job->errorString()),
00309                             i18n("Paste failed") );
00310       }
00311     }
00312 
00313     StandardActionManager *q;
00314     KActionCollection *actionCollection;
00315     QWidget *parentWidget;
00316     QItemSelectionModel *collectionSelectionModel;
00317     QItemSelectionModel *itemSelectionModel;
00318     QVector<KAction*> actions;
00319     AgentManager *agentManager;
00320     QHash<StandardActionManager::Type, KLocalizedString> pluralLabels;
00321 };
00322 
00323 //@endcond
00324 
00325 StandardActionManager::StandardActionManager( KActionCollection * actionCollection,
00326                                               QWidget * parent) :
00327     QObject( parent ),
00328     d( new Private( this ) )
00329 {
00330   d->parentWidget = parent;
00331   d->actionCollection = actionCollection;
00332   connect( QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), SLOT(clipboardChanged(QClipboard::Mode)) );
00333 }
00334 
00335 StandardActionManager::~ StandardActionManager()
00336 {
00337   delete d;
00338 }
00339 
00340 void StandardActionManager::setCollectionSelectionModel(QItemSelectionModel * selectionModel)
00341 {
00342   d->collectionSelectionModel = selectionModel;
00343   connect( selectionModel, SIGNAL(selectionChanged( const QItemSelection&, const QItemSelection& )),
00344            SLOT(updateActions()) );
00345 }
00346 
00347 void StandardActionManager::setItemSelectionModel(QItemSelectionModel * selectionModel)
00348 {
00349   d->itemSelectionModel = selectionModel;
00350   connect( selectionModel, SIGNAL(selectionChanged( const QItemSelection&, const QItemSelection& )),
00351            SLOT(updateActions()) );
00352 }
00353 
00354 KAction* StandardActionManager::createAction( Type type )
00355 {
00356   Q_ASSERT( type >= 0 && type < LastType );
00357   Q_ASSERT( actionData[type].name );
00358   if ( d->actions[type] )
00359     return d->actions[type];
00360   KAction *action = new KAction( d->parentWidget );
00361   if ( d->pluralLabels.contains( type ) && !d->pluralLabels.value( type ).isEmpty() )
00362     action->setText( d->pluralLabels.value( type ).subs( 1 ).toString() );
00363   else if ( actionData[type].label )
00364     action->setText( i18n( actionData[type].label ) );
00365   if ( actionData[type].icon )
00366     action->setIcon( KIcon( QString::fromLatin1( actionData[type].icon ) ) );
00367   action->setShortcut( actionData[type].shortcut );
00368   if ( actionData[type].slot )
00369     connect( action, SIGNAL(triggered()), actionData[type].slot );
00370   d->actionCollection->addAction( QString::fromLatin1(actionData[type].name), action );
00371   d->actions[type] = action;
00372   d->updateActions();
00373   return action;
00374 }
00375 
00376 void StandardActionManager::createAllActions()
00377 {
00378   for ( int i = 0; i < LastType; ++i )
00379     createAction( (Type)i );
00380 }
00381 
00382 KAction * StandardActionManager::action( Type type ) const
00383 {
00384   Q_ASSERT( type >= 0 && type < LastType );
00385   return d->actions[type];
00386 }
00387 
00388 void StandardActionManager::setActionText(Type type, const KLocalizedString & text)
00389 {
00390   Q_ASSERT( type >= 0 && type < LastType );
00391   d->pluralLabels.insert( type, text );
00392 }
00393 
00394 #include "standardactionmanager.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal