• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

akonadi

actionstatemanager.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 "actionstatemanager_p.h"
00021 
00022 #include "agentmanager.h"
00023 #include "collectionutils_p.h"
00024 #include "pastehelper_p.h"
00025 #include "specialcollectionattribute_p.h"
00026 #include "standardactionmanager.h"
00027 
00028 #include <akonadi/entitydeletedattribute.h>
00029 
00030 #include <QtGui/QApplication>
00031 #include <QtGui/QClipboard>
00032 
00033 using namespace Akonadi;
00034 
00035 static bool canCreateSubCollection( const Collection &collection )
00036 {
00037   if ( !( collection.rights() & Collection::CanCreateCollection ) )
00038     return false;
00039 
00040   if ( !collection.contentMimeTypes().contains( Collection::mimeType() ) )
00041     return false;
00042 
00043   return true;
00044 }
00045 
00046 static inline bool canContainItems( const Collection &collection )
00047 {
00048   if ( collection.contentMimeTypes().isEmpty() )
00049     return false;
00050 
00051   if ( (collection.contentMimeTypes().count() == 1) &&
00052        (collection.contentMimeTypes().first() == Collection::mimeType()) )
00053     return false;
00054 
00055   return true;
00056 }
00057 
00058 ActionStateManager::ActionStateManager()
00059   : mReceiver( 0 )
00060 {
00061 }
00062 
00063 ActionStateManager::~ActionStateManager()
00064 {
00065 }
00066 
00067 void ActionStateManager::setReceiver( QObject *object )
00068 {
00069   mReceiver = object;
00070 }
00071 
00072 void ActionStateManager::updateState( const Collection::List &collections, const Item::List &items )
00073 {
00074   const int collectionCount = collections.count();
00075   const bool singleCollectionSelected = (collectionCount == 1);
00076   const bool multipleCollectionsSelected = (collectionCount > 1);
00077   const bool atLeastOneCollectionSelected = (singleCollectionSelected || multipleCollectionsSelected);
00078 
00079   const int itemCount = items.count();
00080   const bool singleItemSelected = (itemCount == 1);
00081   const bool multipleItemsSelected = (itemCount > 1);
00082   const bool atLeastOneItemSelected = (singleItemSelected || multipleItemsSelected);
00083 
00084   const bool listOfCollectionNotEmpty = collections.isEmpty() ? false : true;
00085   bool canDeleteCollections = listOfCollectionNotEmpty;
00086   if ( canDeleteCollections )
00087   {
00088     foreach ( const Collection &collection, collections ) {
00089       // do we have the necessary rights?
00090       if ( !(collection.rights() & Collection::CanDeleteCollection) ) {
00091         canDeleteCollections = false;
00092         break;
00093       }
00094 
00095       if ( isRootCollection( collection ) ) {
00096         canDeleteCollections = false;
00097         break;
00098       }
00099 
00100       if ( isResourceCollection( collection ) ) {
00101         canDeleteCollections = false;
00102         break;
00103       }
00104     }
00105   }
00106 
00107   bool canCutCollections = canDeleteCollections; // we must be able to delete for cutting
00108   foreach ( const Collection &collection, collections ) {
00109     if ( isSpecialCollection( collection ) ) {
00110       canCutCollections = false;
00111       break;
00112     }
00113 
00114     if ( !isFolderCollection( collection ) ) {
00115       canCutCollections = false;
00116       break;
00117     }
00118   }
00119 
00120   const bool canMoveCollections = canCutCollections; // we must be able to cut for moving
00121 
00122   bool canCopyCollections = listOfCollectionNotEmpty;
00123   if ( canCopyCollections ) {
00124     foreach ( const Collection &collection, collections ) {
00125       if ( isRootCollection( collection ) ) {
00126         canCopyCollections = false;
00127         break;
00128       }
00129 
00130       if ( !isFolderCollection( collection ) ) {
00131         canCopyCollections = false;
00132         break;
00133       }
00134     }
00135   }
00136   bool canAddToFavoriteCollections = listOfCollectionNotEmpty;
00137   if ( canAddToFavoriteCollections ) {
00138     foreach ( const Collection &collection, collections ) {
00139       if ( isRootCollection( collection ) ) {
00140         canAddToFavoriteCollections = false;
00141         break;
00142       }
00143 
00144       if ( isFavoriteCollection( collection ) ) {
00145         canAddToFavoriteCollections = false;
00146         break;
00147       }
00148 
00149       if ( !isFolderCollection( collection ) ) {
00150         canAddToFavoriteCollections = false;
00151         break;
00152       }
00153 
00154       if ( !canContainItems( collection ) ) {
00155         canAddToFavoriteCollections = false;
00156         break;
00157       }
00158     }
00159   }
00160   bool canRemoveFromFavoriteCollections = listOfCollectionNotEmpty;
00161   foreach ( const Collection &collection, collections ) {
00162     if ( !isFavoriteCollection( collection ) ) {
00163       canRemoveFromFavoriteCollections = false;
00164       break;
00165     }
00166   }
00167 
00168   bool collectionsAreFolders = listOfCollectionNotEmpty;
00169 
00170   foreach ( const Collection &collection, collections ) {
00171     if ( !isFolderCollection( collection ) ) {
00172       collectionsAreFolders = false;
00173       break;
00174     }
00175   }
00176 
00177   bool collectionsAreInTrash = false;
00178   foreach ( const Collection &collection, collections ) {
00179     if ( collection.hasAttribute<EntityDeletedAttribute>() ) {
00180       collectionsAreInTrash = true;
00181       break;
00182     }
00183   }
00184 
00185   bool atLeastOneCollectionCanHaveItems = false;
00186   foreach ( const Collection &collection, collections ) {
00187     if ( collectionCanHaveItems( collection ) ) {
00188       atLeastOneCollectionCanHaveItems = true;
00189       break;
00190     }
00191   }
00192 
00193   const Collection collection = (!collections.isEmpty() ? collections.first() : Collection());
00194 
00195   // collection specific actions
00196   enableAction( StandardActionManager::CreateCollection, singleCollectionSelected && // we can create only inside one collection
00197                                                          canCreateSubCollection( collection ) ); // we need the necessary rights
00198 
00199   enableAction( StandardActionManager::DeleteCollections, canDeleteCollections );
00200 
00201   enableAction( StandardActionManager::CopyCollections, canCopyCollections );
00202 
00203   enableAction( StandardActionManager::CutCollections, canCutCollections );
00204 
00205   enableAction( StandardActionManager::CopyCollectionToMenu, canCopyCollections );
00206 
00207   enableAction( StandardActionManager::MoveCollectionToMenu, canMoveCollections );
00208 
00209   enableAction( StandardActionManager::MoveCollectionsToTrash, atLeastOneCollectionSelected && canMoveCollections && !collectionsAreInTrash );
00210 
00211   enableAction( StandardActionManager::RestoreCollectionsFromTrash, atLeastOneCollectionSelected && canMoveCollections && collectionsAreInTrash );
00212 
00213   enableAction( StandardActionManager::CopyCollectionToDialog, canCopyCollections );
00214 
00215   enableAction( StandardActionManager::MoveCollectionToDialog, canMoveCollections );
00216 
00217   enableAction( StandardActionManager::CollectionProperties, singleCollectionSelected && // we can only configure one collection at a time
00218                                                              !isRootCollection( collection ) ); // we can not configure the root collection
00219 
00220   enableAction( StandardActionManager::SynchronizeCollections, atLeastOneCollectionCanHaveItems ); // it must be a valid folder collection
00221 
00222   enableAction( StandardActionManager::SynchronizeCollectionsRecursive, atLeastOneCollectionSelected &&
00223                                                                collectionsAreFolders ); // it must be a valid folder collection
00224 #ifndef QT_NO_CLIPBOARD
00225   enableAction( StandardActionManager::Paste, singleCollectionSelected && // we can paste only into a single collection
00226                                               PasteHelper::canPaste( QApplication::clipboard()->mimeData(), collection ) ); // there must be data on the clipboard
00227 #else
00228   enableAction( StandardActionManager::Paste, false ); // no support for clipboard -> no paste
00229 #endif
00230 
00231   // favorite collections specific actions
00232   enableAction( StandardActionManager::AddToFavoriteCollections, canAddToFavoriteCollections );
00233 
00234   enableAction( StandardActionManager::RemoveFromFavoriteCollections, canRemoveFromFavoriteCollections );
00235 
00236   enableAction( StandardActionManager::RenameFavoriteCollection, singleCollectionSelected && // we can rename only one collection at a time
00237                                                                  isFavoriteCollection( collection ) ); // it must be a favorite collection already
00238 
00239   // resource specific actions
00240   int resourceCollectionCount = 0;
00241   bool canDeleteResources = true;
00242   bool canConfigureResource = true;
00243   bool canSynchronizeResources = true;
00244   foreach ( const Collection &collection, collections ) {
00245     if ( isResourceCollection( collection ) ) {
00246       resourceCollectionCount++;
00247 
00248       // check that the 'NoConfig' flag is not set for the resource
00249       if ( hasResourceCapability( collection, QLatin1String( "NoConfig" ) ) )
00250         canConfigureResource = false;
00251 
00252     } else {
00253       // we selected a non-resource collection
00254       canDeleteResources = false;
00255       canConfigureResource = false;
00256       canSynchronizeResources = false;
00257     }
00258   }
00259 
00260   if ( resourceCollectionCount == 0 ) {
00261     // not a single resource collection has been selected
00262     canDeleteResources = false;
00263     canConfigureResource = false;
00264     canSynchronizeResources = false;
00265   }
00266 
00267   enableAction( StandardActionManager::CreateResource, true );
00268   enableAction( StandardActionManager::DeleteResources, canDeleteResources );
00269   enableAction( StandardActionManager::ResourceProperties, canConfigureResource );
00270   enableAction( StandardActionManager::SynchronizeResources, canSynchronizeResources );
00271 
00272   if (collectionsAreInTrash) {
00273     updateAlternatingAction( StandardActionManager::MoveToTrashRestoreCollectionAlternative );
00274     //updatePluralLabel( StandardActionManager::MoveToTrashRestoreCollectionAlternative, collectionCount );
00275   } else {
00276     updateAlternatingAction( StandardActionManager::MoveToTrashRestoreCollection );
00277   }
00278   enableAction( StandardActionManager::MoveToTrashRestoreCollection, atLeastOneCollectionSelected && canMoveCollections );
00279 
00280   // item specific actions
00281   bool canDeleteItems = (items.count() > 0); //TODO: fixme
00282   foreach ( const Item &item, items ) {
00283     const Collection parentCollection = item.parentCollection();
00284     if ( !parentCollection.isValid() )
00285       continue;
00286 
00287     canDeleteItems = canDeleteItems && (parentCollection.rights() & Collection::CanDeleteItem);
00288   }
00289 
00290   bool itemsAreInTrash = false;
00291   foreach ( const Item &item, items ) {
00292     if ( item.hasAttribute<EntityDeletedAttribute>() ) {
00293       itemsAreInTrash = true;
00294       break;
00295     }
00296   }
00297 
00298   enableAction( StandardActionManager::CopyItems, atLeastOneItemSelected ); // we need items to work with
00299 
00300   enableAction( StandardActionManager::CutItems, atLeastOneItemSelected && // we need items to work with
00301                                                  canDeleteItems ); // we need the necessary rights
00302 
00303   enableAction( StandardActionManager::DeleteItems, atLeastOneItemSelected && // we need items to work with
00304                                                     canDeleteItems ); // we need the necessary rights
00305 
00306   enableAction( StandardActionManager::CopyItemToMenu, atLeastOneItemSelected ); // we need items to work with
00307 
00308   enableAction( StandardActionManager::MoveItemToMenu, atLeastOneItemSelected && // we need items to work with
00309                                                        canDeleteItems ); // we need the necessary rights
00310 
00311   enableAction( StandardActionManager::MoveItemsToTrash, atLeastOneItemSelected && canDeleteItems && !itemsAreInTrash );
00312 
00313   enableAction( StandardActionManager::RestoreItemsFromTrash, atLeastOneItemSelected && itemsAreInTrash );
00314 
00315   enableAction( StandardActionManager::CopyItemToDialog, atLeastOneItemSelected ); // we need items to work with
00316 
00317   enableAction( StandardActionManager::MoveItemToDialog, atLeastOneItemSelected && // we need items to work with
00318                                                        canDeleteItems ); // we need the necessary rights
00319 
00320   if (itemsAreInTrash) {
00321     updateAlternatingAction( StandardActionManager::MoveToTrashRestoreItemAlternative );
00322     //updatePluralLabel( StandardActionManager::MoveToTrashRestoreItemAlternative, itemCount );
00323   } else {
00324     updateAlternatingAction( StandardActionManager::MoveToTrashRestoreItem );
00325   }
00326   enableAction( StandardActionManager::MoveToTrashRestoreItem, atLeastOneItemSelected && // we need items to work with
00327   canDeleteItems ); // we need the necessary rights
00328 
00329   // update the texts of the actions
00330   updatePluralLabel( StandardActionManager::CopyCollections, collectionCount );
00331   updatePluralLabel( StandardActionManager::CopyItems, itemCount );
00332   updatePluralLabel( StandardActionManager::DeleteItems, itemCount );
00333   updatePluralLabel( StandardActionManager::CutItems, itemCount );
00334   updatePluralLabel( StandardActionManager::CutCollections, collectionCount );
00335   updatePluralLabel( StandardActionManager::DeleteCollections, collectionCount );
00336   updatePluralLabel( StandardActionManager::SynchronizeCollections, collectionCount );
00337   updatePluralLabel( StandardActionManager::SynchronizeCollectionsRecursive, collectionCount );
00338   updatePluralLabel( StandardActionManager::DeleteResources, resourceCollectionCount );
00339   updatePluralLabel( StandardActionManager::SynchronizeResources, resourceCollectionCount );
00340 
00341 }
00342 
00343 bool ActionStateManager::isRootCollection( const Collection &collection ) const
00344 {
00345   return CollectionUtils::isRoot( collection );
00346 }
00347 
00348 bool ActionStateManager::isResourceCollection( const Collection &collection ) const
00349 {
00350   return CollectionUtils::isResource( collection );
00351 }
00352 
00353 bool ActionStateManager::isFolderCollection( const Collection &collection ) const
00354 {
00355   return (CollectionUtils::isFolder( collection ) ||
00356           CollectionUtils::isResource( collection ) ||
00357           CollectionUtils::isStructural( collection ));
00358 }
00359 
00360 bool ActionStateManager::isSpecialCollection( const Collection &collection ) const
00361 {
00362   return collection.hasAttribute<SpecialCollectionAttribute>();
00363 }
00364 
00365 bool ActionStateManager::isFavoriteCollection( const Collection &collection ) const
00366 {
00367   if ( !mReceiver )
00368     return false;
00369 
00370   bool result = false;
00371   QMetaObject::invokeMethod( mReceiver, "isFavoriteCollection", Qt::DirectConnection,
00372                              Q_RETURN_ARG( bool, result ), Q_ARG( Akonadi::Collection, collection ) );
00373 
00374   return result;
00375 }
00376 
00377 bool ActionStateManager::hasResourceCapability( const Collection &collection, const QString &capability ) const
00378 {
00379   const Akonadi::AgentInstance instance = AgentManager::self()->instance( collection.resource() );
00380 
00381   return instance.type().capabilities().contains( capability );
00382 }
00383 
00384 bool ActionStateManager::collectionCanHaveItems( const Collection &collection ) const
00385 {
00386   return !( collection.contentMimeTypes() == ( QStringList() << QLatin1String( "inode/directory" ) ) ||
00387             CollectionUtils::isStructural( collection ) );
00388 }
00389 
00390 void ActionStateManager::enableAction( int action, bool state )
00391 {
00392   if ( !mReceiver )
00393     return;
00394 
00395   QMetaObject::invokeMethod( mReceiver, "enableAction", Qt::DirectConnection, Q_ARG( int, action ), Q_ARG( bool, state ) );
00396 }
00397 
00398 void ActionStateManager::updatePluralLabel( int action, int count )
00399 {
00400   if ( !mReceiver )
00401     return;
00402 
00403   QMetaObject::invokeMethod( mReceiver, "updatePluralLabel", Qt::DirectConnection, Q_ARG( int, action ), Q_ARG( int, count ) );
00404 }
00405 
00406 void ActionStateManager::updateAlternatingAction( int action )
00407 {
00408   if ( !mReceiver )
00409     return;
00410 
00411   QMetaObject::invokeMethod( mReceiver, "updateAlternatingAction", Qt::DirectConnection, Q_ARG( int, action ));
00412 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:14 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

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

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal