• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.5 API Reference
  • KDE Home
  • 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 "actionstatemanager_p.h"
00023 #include "agentfilterproxymodel.h"
00024 #include "agentinstancecreatejob.h"
00025 #include "agentmanager.h"
00026 #include "agenttypedialog.h"
00027 #include "collectioncreatejob.h"
00028 #include "collectiondeletejob.h"
00029 #include "collectiondialog.h"
00030 #include "collectionmodel.h"
00031 #include "collectionutils_p.h"
00032 #include "entitytreemodel.h"
00033 #include "favoritecollectionsmodel.h"
00034 #include "itemdeletejob.h"
00035 #include "itemmodel.h"
00036 #include "metatypes.h"
00037 #include "pastehelper_p.h"
00038 #include "specialcollectionattribute_p.h"
00039 #include "collectionpropertiesdialog.h"
00040 #include "subscriptiondialog_p.h"
00041 #include "renamefavoritedialog.h"
00042 #include "trashjob.h"
00043 #include "trashrestorejob.h"
00044 #include "entitydeletedattribute.h"
00045 #include "recentcollectionaction_p.h"
00046 
00047 #include <KAction>
00048 #include <KActionCollection>
00049 #include <KActionMenu>
00050 #include <KDebug>
00051 #include <KInputDialog>
00052 #include <KLocale>
00053 #include <KMenu>
00054 #include <KMessageBox>
00055 #include <KToggleAction>
00056 
00057 #include <QtCore/QMimeData>
00058 #include <QtGui/QApplication>
00059 #include <QtGui/QClipboard>
00060 #include <QtGui/QItemSelectionModel>
00061 #include <QWeakPointer>
00062 
00063 #include <boost/static_assert.hpp>
00064 
00065 using namespace Akonadi;
00066 
00067 //@cond PRIVATE
00068 
00069 enum ActionType
00070 {
00071   NormalAction,
00072   ActionWithAlternative, //Normal action, but with an alternative state
00073   ActionAlternative, //Alternative state of the ActionWithAlternative
00074   MenuAction,
00075   ToggleAction
00076 };
00077 
00078 static const struct {
00079   const char *name;
00080   const char *label;
00081   const char *iconLabel;
00082   const char *icon;
00083   int shortcut;
00084   const char* slot;
00085   ActionType actionType;
00086 } standardActionData[] = {
00087   { "akonadi_collection_create", I18N_NOOP( "&New Folder..." ), I18N_NOOP( "New" ), "folder-new", 0, SLOT(slotCreateCollection()), NormalAction },
00088   { "akonadi_collection_copy", 0, 0, "edit-copy", 0, SLOT(slotCopyCollections()), NormalAction },
00089   { "akonadi_collection_delete", I18N_NOOP( "&Delete Folder" ), I18N_NOOP( "Delete" ), "edit-delete", 0, SLOT(slotDeleteCollection()), NormalAction },
00090   { "akonadi_collection_sync", I18N_NOOP( "&Synchronize Folder" ), I18N_NOOP( "Synchronize" ), "view-refresh", Qt::Key_F5, SLOT(slotSynchronizeCollection()), NormalAction },
00091   { "akonadi_collection_properties", I18N_NOOP( "Folder &Properties" ), I18N_NOOP( "Properties" ), "configure", 0, SLOT(slotCollectionProperties()), NormalAction },
00092   { "akonadi_item_copy", 0, 0, "edit-copy", 0, SLOT(slotCopyItems()), NormalAction },
00093   { "akonadi_paste", I18N_NOOP( "&Paste" ), I18N_NOOP( "Paste" ), "edit-paste", Qt::CTRL + Qt::Key_V, SLOT(slotPaste()), NormalAction },
00094   { "akonadi_item_delete", 0, 0, "edit-delete", Qt::Key_Delete, SLOT(slotDeleteItems()), NormalAction },
00095   { "akonadi_manage_local_subscriptions", I18N_NOOP( "Manage Local &Subscriptions..." ), I18N_NOOP( "Manage Local Subscriptions" ), "folder-bookmarks", 0, SLOT(slotLocalSubscription()), NormalAction },
00096   { "akonadi_collection_add_to_favorites", I18N_NOOP( "Add to Favorite Folders" ), I18N_NOOP( "Add to Favorite" ), "bookmark-new", 0, SLOT(slotAddToFavorites()), NormalAction },
00097   { "akonadi_collection_remove_from_favorites", I18N_NOOP( "Remove from Favorite Folders" ), I18N_NOOP( "Remove from Favorite" ), "edit-delete", 0, SLOT(slotRemoveFromFavorites()), NormalAction },
00098   { "akonadi_collection_rename_favorite", I18N_NOOP( "Rename Favorite..." ), I18N_NOOP( "Rename" ), "edit-rename", 0, SLOT(slotRenameFavorite()), NormalAction },
00099   { "akonadi_collection_copy_to_menu", I18N_NOOP( "Copy Folder To..." ), I18N_NOOP( "Copy To" ), "edit-copy", 0, SLOT(slotCopyCollectionTo(QAction*)), MenuAction },
00100   { "akonadi_item_copy_to_menu", I18N_NOOP( "Copy Item To..." ), I18N_NOOP( "Copy To" ), "edit-copy", 0, SLOT(slotCopyItemTo(QAction*)), MenuAction },
00101   { "akonadi_item_move_to_menu", I18N_NOOP( "Move Item To..." ), I18N_NOOP( "Move To" ), "go-jump", 0, SLOT(slotMoveItemTo(QAction*)), MenuAction },
00102   { "akonadi_collection_move_to_menu", I18N_NOOP( "Move Folder To..." ), I18N_NOOP( "Move To" ), "go-jump", 0, SLOT(slotMoveCollectionTo(QAction*)), MenuAction },
00103   { "akonadi_item_cut", I18N_NOOP( "&Cut Item" ), I18N_NOOP( "Cut" ), "edit-cut", Qt::CTRL + Qt::Key_X, SLOT(slotCutItems()), NormalAction },
00104   { "akonadi_collection_cut", I18N_NOOP( "&Cut Folder" ), I18N_NOOP( "Cut" ), "edit-cut", Qt::CTRL + Qt::Key_X, SLOT(slotCutCollections()), NormalAction },
00105   { "akonadi_resource_create", I18N_NOOP( "Create Resource" ), 0, "folder-new", 0, SLOT(slotCreateResource()), NormalAction },
00106   { "akonadi_resource_delete", I18N_NOOP( "Delete Resource" ), 0, "edit-delete", 0, SLOT(slotDeleteResource()), NormalAction },
00107   { "akonadi_resource_properties", I18N_NOOP( "&Resource Properties" ), I18N_NOOP( "Properties" ), "configure", 0, SLOT(slotResourceProperties()), NormalAction },
00108   { "akonadi_resource_synchronize", I18N_NOOP( "Synchronize Resource" ), I18N_NOOP( "Synchronize" ), "view-refresh", 0, SLOT(slotSynchronizeResource()), NormalAction },
00109   { "akonadi_work_offline", I18N_NOOP( "Work Offline" ), 0, "user-offline", 0, SLOT(slotToggleWorkOffline(bool)), ToggleAction },
00110   { "akonadi_collection_copy_to_dialog", I18N_NOOP( "Copy Folder To..." ), I18N_NOOP( "Copy To" ), "edit-copy", 0, SLOT(slotCopyCollectionTo()), NormalAction },
00111   { "akonadi_collection_move_to_dialog", I18N_NOOP( "Move Folder To..." ), I18N_NOOP( "Move To" ), "go-jump", 0, SLOT(slotMoveCollectionTo()), NormalAction },
00112   { "akonadi_item_copy_to_dialog", I18N_NOOP( "Copy Item To..." ), I18N_NOOP( "Copy To" ), "edit-copy", 0, SLOT(slotCopyItemTo()), NormalAction },
00113   { "akonadi_item_move_to_dialog", I18N_NOOP( "Move Item To..." ), I18N_NOOP( "Move To" ), "go-jump", 0, SLOT(slotMoveItemTo()), NormalAction },
00114   { "akonadi_collection_sync_recursive", I18N_NOOP( "&Synchronize Folder Recursively" ), I18N_NOOP( "Synchronize Recursively" ), "view-refresh", Qt::CTRL + Qt::Key_F5, SLOT(slotSynchronizeCollectionRecursive()), NormalAction },
00115   { "akonadi_move_collection_to_trash", I18N_NOOP( "&Move Folder To Trash" ), I18N_NOOP( "Move Folder To Trash" ), "user-trash", 0, SLOT(slotMoveCollectionToTrash()), NormalAction },
00116   { "akonadi_move_item_to_trash", I18N_NOOP( "&Move Item To Trash" ), I18N_NOOP( "Move Item To Trash" ), "user-trash", 0, SLOT(slotMoveItemToTrash()), NormalAction },
00117   { "akonadi_restore_collection_from_trash", I18N_NOOP( "&Restore Folder From Trash" ), I18N_NOOP( "Restore Folder From Trash" ), "view-refresh", 0, SLOT(slotRestoreCollectionFromTrash()), NormalAction },
00118   { "akonadi_restore_item_from_trash", I18N_NOOP( "&Restore Item From Trash" ), I18N_NOOP( "Restore Item From Trash" ), "view-refresh", 0, SLOT(slotRestoreItemFromTrash()), NormalAction },
00119   { "akonadi_collection_trash_restore", I18N_NOOP( "&Restore Folder From Trash" ), I18N_NOOP( "Restore Folder From Trash" ), "user-trash", 0, SLOT(slotTrashRestoreCollection()), ActionWithAlternative },
00120   { 0, I18N_NOOP( "&Restore Collection From Trash" ), I18N_NOOP( "Restore Collection From Trash" ), "view-refresh", 0, 0, ActionAlternative },
00121   { "akonadi_item_trash_restore", I18N_NOOP( "&Restore Item From Trash" ), I18N_NOOP( "Restore Item From Trash" ), "user-trash", 0, SLOT(slotTrashRestoreItem()), ActionWithAlternative },
00122   { 0, I18N_NOOP( "&Restore Item From Trash" ), I18N_NOOP( "Restore Item From Trash" ), "view-refresh", 0, 0, ActionAlternative },
00123   { "akonadi_collection_sync_favorite_folders", I18N_NOOP( "&Synchronize Favorite Folders" ), I18N_NOOP( "Synchronize Favorite Folders" ), "view-refresh", Qt::CTRL+Qt::SHIFT+Qt::Key_L , SLOT(slotSynchronizeFavoriteCollections()), NormalAction }
00124 
00125 };
00126 static const int numStandardActionData = sizeof standardActionData / sizeof *standardActionData;
00127 
00128 BOOST_STATIC_ASSERT( numStandardActionData == StandardActionManager::LastType );
00129 
00130 static bool canCreateCollection( const Akonadi::Collection &collection )
00131 {
00132   if ( !( collection.rights() & Akonadi::Collection::CanCreateCollection ) )
00133     return false;
00134 
00135   if ( !collection.contentMimeTypes().contains( Akonadi::Collection::mimeType() ) )
00136     return false;
00137 
00138   return true;
00139 }
00140 
00141 static inline bool isRootCollection( const Akonadi::Collection &collection )
00142 {
00143   return (collection == Akonadi::Collection::root());
00144 }
00145 
00146 static void setWorkOffline( bool offline )
00147 {
00148   KConfig config( QLatin1String( "akonadikderc" ) );
00149   KConfigGroup group( &config, QLatin1String( "Actions" ) );
00150 
00151   group.writeEntry( "WorkOffline", offline );
00152 }
00153 
00154 static bool workOffline()
00155 {
00156   KConfig config( QLatin1String( "akonadikderc" ) );
00157   const KConfigGroup group( &config, QLatin1String( "Actions" ) );
00158 
00159   return group.readEntry( "WorkOffline", false );
00160 }
00161 
00162 static QModelIndexList safeSelectedRows( QItemSelectionModel *selectionModel )
00163 {
00164   QModelIndexList selectedRows = selectionModel->selectedRows();
00165   if (!selectedRows.isEmpty())
00166     return selectedRows;
00167 
00168   // try harder for selected rows that don't span the full row for some reason (e.g. due to buggy column adding proxy models etc)
00169   foreach ( const QItemSelectionRange &range, selectionModel->selection() ) {
00170     if ( !range.isValid() || range.isEmpty() )
00171       continue;
00172     const QModelIndex parent = range.parent();
00173     for ( int row = range.top(); row <= range.bottom(); ++row ) {
00174       const QModelIndex index = range.model()->index( row, range.left(), parent );
00175       const Qt::ItemFlags flags = range.model()->flags( index );
00176       if ( (flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled) )
00177         selectedRows.push_back( index );
00178     }
00179   }
00180 
00181   return selectedRows;
00182 }
00183 
00184 
00188 class StandardActionManager::Private
00189 {
00190   public:
00191     Private( StandardActionManager *parent ) :
00192       q( parent ),
00193       collectionSelectionModel( 0 ),
00194       itemSelectionModel( 0 ),
00195       favoritesModel( 0 ),
00196       favoriteSelectionModel( 0 )
00197     {
00198       actions.fill( 0, StandardActionManager::LastType );
00199 
00200       pluralLabels.insert( StandardActionManager::CopyCollections,
00201                            ki18np( "&Copy Folder", "&Copy %1 Folders" ) );
00202       pluralLabels.insert( StandardActionManager::CopyItems,
00203                            ki18np( "&Copy Item", "&Copy %1 Items" ) );
00204       pluralLabels.insert( StandardActionManager::CutItems,
00205                            ki18np( "&Cut Item", "&Cut %1 Items" ) );
00206       pluralLabels.insert( StandardActionManager::CutCollections,
00207                            ki18np( "&Cut Folder", "&Cut %1 Folders" ) );
00208       pluralLabels.insert( StandardActionManager::DeleteItems,
00209                            ki18np( "&Delete Item", "&Delete %1 Items" ) );
00210       pluralLabels.insert( StandardActionManager::DeleteCollections,
00211                            ki18np( "&Delete Folder", "&Delete %1 Folders" ) );
00212       pluralLabels.insert( StandardActionManager::SynchronizeCollections,
00213                            ki18np( "&Synchronize Folder", "&Synchronize %1 Folders" ) );
00214       pluralLabels.insert( StandardActionManager::DeleteResources,
00215                            ki18np( "&Delete Resource", "&Delete %1 Resources" ) );
00216       pluralLabels.insert( StandardActionManager::SynchronizeResources,
00217                            ki18np( "&Synchronize Resource", "&Synchronize %1 Resources" ) );
00218 
00219 
00220       pluralIconLabels.insert( StandardActionManager::CopyCollections,
00221                            ki18np( "Copy Folder", "Copy %1 Folders" ) );
00222       pluralIconLabels.insert( StandardActionManager::CopyItems,
00223                            ki18np( "Copy Item", "Copy %1 Items" ) );
00224       pluralIconLabels.insert( StandardActionManager::CutItems,
00225                            ki18np( "Cut Item", "Cut %1 Items" ) );
00226       pluralIconLabels.insert( StandardActionManager::CutCollections,
00227                            ki18np( "Cut Folder", "Cut %1 Folders" ) );
00228       pluralIconLabels.insert( StandardActionManager::DeleteItems,
00229                            ki18np( "Delete Item", "Delete %1 Items" ) );
00230       pluralIconLabels.insert( StandardActionManager::DeleteCollections,
00231                            ki18np( "Delete Folder", "Delete %1 Folders" ) );
00232       pluralIconLabels.insert( StandardActionManager::SynchronizeCollections,
00233                            ki18np( "Synchronize Folder", "Synchronize %1 Folders" ) );
00234       pluralIconLabels.insert( StandardActionManager::DeleteResources,
00235                            ki18np( "Delete Resource", "Delete %1 Resources" ) );
00236       pluralIconLabels.insert( StandardActionManager::SynchronizeResources,
00237                            ki18np( "Synchronize Resource", "Synchronize %1 Resources" ) );
00238 
00239       setContextText( StandardActionManager::CreateCollection, StandardActionManager::DialogTitle,
00240                       i18nc( "@title:window", "New Folder" ) );
00241       setContextText( StandardActionManager::CreateCollection, StandardActionManager::DialogText,
00242                       i18nc( "@label:textbox name of a thing", "Name" ) );
00243       setContextText( StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageText,
00244                       ki18n( "Could not create folder: %1" ) );
00245       setContextText( StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageTitle,
00246                       i18n( "Folder creation failed" ) );
00247 
00248       setContextText( StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxText,
00249                       ki18np( "Do you really want to delete this folder and all its sub-folders?",
00250                               "Do you really want to delete %1 folders and all their sub-folders?" ) );
00251       setContextText( StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxTitle,
00252                       ki18ncp( "@title:window", "Delete folder?", "Delete folders?" ) );
00253       setContextText( StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageText,
00254                       ki18n( "Could not delete folder: %1" ) );
00255       setContextText( StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageTitle,
00256                       i18n( "Folder deletion failed" ) );
00257 
00258       setContextText( StandardActionManager::CollectionProperties, StandardActionManager::DialogTitle,
00259                       ki18nc( "@title:window", "Properties of Folder %1" ) );
00260 
00261       setContextText( StandardActionManager::DeleteItems, StandardActionManager::MessageBoxText,
00262                       ki18np( "Do you really want to delete the selected item?",
00263                               "Do you really want to delete %1 items?" ) );
00264       setContextText( StandardActionManager::DeleteItems, StandardActionManager::MessageBoxTitle,
00265                       ki18ncp( "@title:window", "Delete item?", "Delete items?" ) );
00266       setContextText( StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText,
00267                       ki18n( "Could not delete item: %1" ) );
00268       setContextText( StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle,
00269                       i18n( "Item deletion failed" ) );
00270 
00271       setContextText( StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogTitle,
00272                       i18nc( "@title:window", "Rename Favorite" ) );
00273       setContextText( StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogText,
00274                       i18nc( "@label:textbox name of the folder", "Name:" ) );
00275 
00276       setContextText( StandardActionManager::CreateResource, StandardActionManager::DialogTitle,
00277                       i18nc( "@title:window", "New Resource" ) );
00278       setContextText( StandardActionManager::CreateResource, StandardActionManager::ErrorMessageText,
00279                       ki18n( "Could not create resource: %1" ) );
00280       setContextText( StandardActionManager::CreateResource, StandardActionManager::ErrorMessageTitle,
00281                       i18n( "Resource creation failed" ) );
00282 
00283       setContextText( StandardActionManager::DeleteResources, StandardActionManager::MessageBoxText,
00284                       ki18np( "Do you really want to delete this resource?",
00285                               "Do you really want to delete %1 resources?" ) );
00286       setContextText( StandardActionManager::DeleteResources, StandardActionManager::MessageBoxTitle,
00287                       ki18ncp( "@title:window", "Delete Resource?", "Delete Resources?" ) );
00288 
00289       setContextText( StandardActionManager::Paste, StandardActionManager::ErrorMessageText,
00290                       ki18n( "Could not paste data: %1" ) );
00291       setContextText( StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle,
00292                       i18n( "Paste failed" ) );
00293 
00294       qRegisterMetaType<Akonadi::Item::List>("Akonadi::Item::List");
00295     }
00296 
00297     void enableAction( int type, bool enable )
00298     {
00299       enableAction( static_cast<StandardActionManager::Type>( type ), enable );
00300     }
00301 
00302     void enableAction( StandardActionManager::Type type, bool enable )
00303     {
00304       Q_ASSERT( type < StandardActionManager::LastType );
00305       if ( actions[type] )
00306         actions[type]->setEnabled( enable );
00307 
00308       // Update the action menu
00309       KActionMenu *actionMenu = qobject_cast<KActionMenu*>( actions[type] );
00310       if ( actionMenu ) {
00311         //get rid of the submenus, they are re-created in enableAction. clear() is not enough, doesn't remove the submenu object instances.
00312         KMenu *menu = actionMenu->menu();
00313         //Not necessary to delete and recreate menu when it was not created
00314         if ( menu->property( "actionType" ).isValid() && menu->isEmpty() )
00315           return;
00316         delete menu;
00317         menu = new KMenu();
00318 
00319         menu->setProperty( "actionType", static_cast<int>( type ) );
00320         q->connect( menu, SIGNAL(aboutToShow()), SLOT(aboutToShowMenu()) );
00321         q->connect( menu, SIGNAL(triggered(QAction*)), standardActionData[ type ].slot );
00322         actionMenu->setMenu( menu );
00323       }
00324     }
00325 
00326     void aboutToShowMenu()
00327     {
00328       QMenu *menu = qobject_cast<QMenu*>( q->sender() );
00329       if ( !menu )
00330         return;
00331 
00332       if ( !menu->isEmpty() )
00333         return;
00334       // collect all selected collections
00335       const Akonadi::Collection::List selectedCollectionsList = selectedCollections();
00336       const StandardActionManager::Type type = static_cast<StandardActionManager::Type>( menu->property( "actionType" ).toInt() );
00337 
00338       QWeakPointer<RecentCollectionAction> recentCollection = new RecentCollectionAction( collectionSelectionModel->model(), menu );
00339       mRecentCollectionsMenu.insert( type, recentCollection );
00340       const QSet<QString> mimeTypes = mimeTypesOfSelection( type );
00341       fillFoldersMenu( selectedCollectionsList,
00342                        mimeTypes,
00343                        type,
00344                        menu,
00345                        collectionSelectionModel->model(),
00346                        QModelIndex() );
00347     }
00348 
00349     void createActionFolderMenu(QMenu *menu, StandardActionManager::Type type)
00350     {
00351       if ( type == CopyCollectionToMenu ||
00352            type == CopyItemToMenu ||
00353            type == MoveItemToMenu ||
00354            type ==MoveCollectionToMenu )
00355       {
00356 
00357         QWeakPointer<RecentCollectionAction> recentCollection = new RecentCollectionAction( collectionSelectionModel->model(), menu );
00358         Collection::List selectedCollectionsList = selectedCollections();
00359         const QSet<QString> mimeTypes = mimeTypesOfSelection( type );
00360         fillFoldersMenu( selectedCollectionsList,
00361                          mimeTypes,
00362                          type,
00363                          menu,
00364                          collectionSelectionModel->model(),
00365                          QModelIndex() );
00366       }
00367     }
00368 
00369 
00370     void updateAlternatingAction( int type )
00371     {
00372       updateAlternatingAction( static_cast<StandardActionManager::Type>( type ) );
00373     }
00374 
00375     void updateAlternatingAction( StandardActionManager::Type type )
00376     {
00377       Q_ASSERT( type < StandardActionManager::LastType );
00378       if (!actions[type]) {
00379         return;
00380       }
00381 
00382       /*
00383        * The same action is stored at the ActionWithAlternative indexes as well as the corresponding ActionAlternative indexes in the actions array.
00384        * The following simply changes the standardActionData
00385        */
00386       if ( ( standardActionData[type].actionType == ActionWithAlternative ) || ( standardActionData[type].actionType == ActionAlternative ) ) {
00387         actions[type]->setText( i18n ( standardActionData[type].label ) );
00388         actions[type]->setIcon( KIcon( QString::fromLatin1( standardActionData[type].icon ) ) );
00389 
00390         if ( pluralLabels.contains( type ) && !pluralLabels.value( type ).isEmpty() )
00391           actions[type]->setText( pluralLabels.value( type ).subs( 1 ).toString() );
00392         else if ( standardActionData[type].label )
00393           actions[type]->setText( i18n( standardActionData[type].label ) );
00394 
00395         if ( pluralIconLabels.contains( type ) && !pluralIconLabels.value( type ).isEmpty() )
00396           actions[type]->setIconText( pluralIconLabels.value( type ).subs( 1 ).toString() );
00397         else if ( standardActionData[type].iconLabel )
00398           actions[type]->setIconText( i18n( standardActionData[type].iconLabel ) );
00399 
00400         if ( standardActionData[type].icon )
00401           actions[type]->setIcon( KIcon( QString::fromLatin1( standardActionData[type].icon ) ) );
00402 
00403         //actions[type]->setShortcut( standardActionData[type].shortcut );
00404 
00405         /*if ( standardActionData[type].slot ) {
00406           switch ( standardActionData[type].actionType ) {
00407             case NormalAction:
00408             case ActionWithAlternative:
00409               connect( action, SIGNAL(triggered()), standardActionData[type].slot );
00410               break;
00411           }
00412         }*/
00413       }
00414     }
00415 
00416     void updatePluralLabel( int type, int count )
00417     {
00418       updatePluralLabel( static_cast<StandardActionManager::Type>( type ), count );
00419     }
00420 
00421     void updatePluralLabel( StandardActionManager::Type type, int count )
00422     {
00423       Q_ASSERT( type < StandardActionManager::LastType );
00424       if ( actions[type] && pluralLabels.contains( type ) && !pluralLabels.value( type ).isEmpty() ) {
00425         actions[type]->setText( pluralLabels.value( type ).subs( qMax( count, 1 ) ).toString() );
00426       }
00427     }
00428 
00429     bool isFavoriteCollection( const Akonadi::Collection &collection )
00430     {
00431       if ( !favoritesModel )
00432         return false;
00433 
00434       return favoritesModel->collections().contains( collection );
00435     }
00436 
00437     void encodeToClipboard( QItemSelectionModel* selectionModel, bool cut = false )
00438     {
00439       Q_ASSERT( selectionModel );
00440       if ( safeSelectedRows( selectionModel ).count() <= 0 )
00441         return;
00442 
00443 #ifndef QT_NO_CLIPBOARD
00444       QMimeData *mimeData = selectionModel->model()->mimeData( safeSelectedRows( selectionModel ) );
00445       markCutAction( mimeData, cut );
00446       QApplication::clipboard()->setMimeData( mimeData );
00447 
00448       QAbstractItemModel *model = const_cast<QAbstractItemModel *>( selectionModel->model() );
00449 
00450       foreach ( const QModelIndex &index, safeSelectedRows( selectionModel ) )
00451         model->setData( index, true, EntityTreeModel::PendingCutRole );
00452 #endif
00453     }
00454 
00455     void updateActions()
00456     {
00457       // collect all selected collections
00458       Collection::List selectedCollectionsList;
00459       if ( collectionSelectionModel ) {
00460         const QModelIndexList rows = safeSelectedRows( collectionSelectionModel );
00461         foreach ( const QModelIndex &index, rows ) {
00462           Collection collection = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
00463           if ( !collection.isValid() )
00464             continue;
00465 
00466           const Collection parentCollection = index.data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
00467           collection.setParentCollection( parentCollection );
00468 
00469           selectedCollectionsList << collection;
00470         }
00471       }
00472 
00473       // collect all selected items
00474       Item::List selectedItems;
00475       if ( itemSelectionModel ) {
00476         const QModelIndexList rows = safeSelectedRows( itemSelectionModel );
00477         foreach ( const QModelIndex &index, rows ) {
00478           Item item = index.data( EntityTreeModel::ItemRole ).value<Item>();
00479           if ( !item.isValid() )
00480             continue;
00481 
00482           const Collection parentCollection = index.data( EntityTreeModel::ParentCollectionRole ).value<Collection>();
00483           item.setParentCollection( parentCollection );
00484 
00485           selectedItems << item;
00486         }
00487       }
00488 
00489       mActionStateManager.updateState( selectedCollectionsList, selectedItems );
00490       if( favoritesModel)
00491         enableAction( StandardActionManager::SynchronizeFavoriteCollections, (favoritesModel->rowCount() > 0));
00492       emit q->actionStateUpdated();
00493     }
00494 
00495 #ifndef QT_NO_CLIPBOARD
00496     void clipboardChanged( QClipboard::Mode mode )
00497     {
00498       if ( mode == QClipboard::Clipboard )
00499         updateActions();
00500     }
00501 #endif
00502 
00503     QItemSelection mapToEntityTreeModel( const QAbstractItemModel *model, const QItemSelection &selection ) const
00504     {
00505       const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel*>( model );
00506       if ( proxy ) {
00507         return mapToEntityTreeModel( proxy->sourceModel(), proxy->mapSelectionToSource( selection ) );
00508       } else {
00509         return selection;
00510       }
00511     }
00512 
00513     QItemSelection mapFromEntityTreeModel( const QAbstractItemModel *model, const QItemSelection &selection ) const
00514     {
00515       const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel*>( model );
00516       if ( proxy ) {
00517         const QItemSelection select = mapFromEntityTreeModel( proxy->sourceModel(), selection );
00518         return proxy->mapSelectionFromSource( select );
00519       } else {
00520         return selection;
00521       }
00522     }
00523 
00524     void collectionSelectionChanged()
00525     {
00526       q->blockSignals( true );
00527 
00528       QItemSelection selection = collectionSelectionModel->selection();
00529       selection = mapToEntityTreeModel( collectionSelectionModel->model(), selection );
00530       selection = mapFromEntityTreeModel( favoritesModel, selection );
00531 
00532       if ( favoriteSelectionModel )
00533         favoriteSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
00534 
00535       q->blockSignals( false );
00536 
00537       updateActions();
00538     }
00539 
00540     void favoriteSelectionChanged()
00541     {
00542       q->blockSignals( true );
00543 
00544       QItemSelection selection = favoriteSelectionModel->selection();
00545       if ( selection.indexes().isEmpty() )
00546         return;
00547 
00548       selection = mapToEntityTreeModel( favoritesModel, selection );
00549       selection = mapFromEntityTreeModel( collectionSelectionModel->model(), selection );
00550 
00551       collectionSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
00552       q->blockSignals( false );
00553 
00554       updateActions();
00555     }
00556 
00557     void slotCreateCollection()
00558     {
00559       Q_ASSERT( collectionSelectionModel );
00560       if ( collectionSelectionModel->selection().indexes().isEmpty() )
00561         return;
00562 
00563       const QModelIndex index = collectionSelectionModel->selection().indexes().at( 0 );
00564       Q_ASSERT( index.isValid() );
00565       const Collection parentCollection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00566       Q_ASSERT( parentCollection.isValid() );
00567 
00568       if ( !canCreateCollection( parentCollection ) )
00569         return;
00570 
00571       const QString name = KInputDialog::getText( contextText( StandardActionManager::CreateCollection, StandardActionManager::DialogTitle ),
00572                                                   contextText( StandardActionManager::CreateCollection, StandardActionManager::DialogText ),
00573                                                   QString(), 0, parentWidget );
00574       if ( name.isEmpty() )
00575         return;
00576 
00577       if ( name.contains( QLatin1Char( '/' ) ) ) {
00578         KMessageBox::error( parentWidget,
00579                             i18n( "We can not add \"/\" in folder name." ),
00580                             i18n( "Create new folder error" ) );
00581 
00582         return;
00583       }
00584 
00585       Collection collection;
00586       collection.setName( name );
00587       collection.setParentCollection( parentCollection );
00588       if ( actions[StandardActionManager::CreateCollection] ) {
00589         const QStringList mts = actions[StandardActionManager::CreateCollection]->property( "ContentMimeTypes" ).toStringList();
00590         if ( !mts.isEmpty() )
00591           collection.setContentMimeTypes( mts );
00592       }
00593       CollectionCreateJob *job = new CollectionCreateJob( collection );
00594       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionCreationResult(KJob*)) );
00595     }
00596 
00597     void slotCopyCollections()
00598     {
00599       encodeToClipboard( collectionSelectionModel );
00600     }
00601 
00602     void slotCutCollections()
00603     {
00604       encodeToClipboard( collectionSelectionModel, true );
00605     }
00606 
00607     Collection::List selectedCollections()
00608     {
00609       Collection::List collections;
00610 
00611       Q_ASSERT( collectionSelectionModel );
00612 
00613       foreach ( const QModelIndex &index, safeSelectedRows( collectionSelectionModel ) ) {
00614         Q_ASSERT( index.isValid() );
00615         const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00616         Q_ASSERT( collection.isValid() );
00617 
00618         collections << collection;
00619       }
00620 
00621       return collections;
00622     }
00623 
00624     void slotDeleteCollection()
00625     {
00626       const Collection::List collections = selectedCollections();
00627       if ( collections.isEmpty() )
00628         return;
00629 
00630       const QString collectionName = collections.first().name();
00631       const QString text = contextText( StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxText,
00632                                         collections.count(), collectionName );
00633 
00634       if ( KMessageBox::questionYesNo( parentWidget, text,
00635            contextText( StandardActionManager::DeleteCollections, StandardActionManager::MessageBoxTitle, collections.count(), collectionName ),
00636            KStandardGuiItem::del(), KStandardGuiItem::cancel(),
00637            QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
00638         return;
00639 
00640       foreach ( const Collection &collection, collections ) {
00641         CollectionDeleteJob *job = new CollectionDeleteJob( collection, q );
00642         q->connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionDeletionResult(KJob*)) );
00643       }
00644     }
00645 
00646     void slotMoveCollectionToTrash()
00647     {
00648       const Collection::List collections = selectedCollections();
00649       if ( collections.isEmpty() )
00650         return;
00651 
00652       foreach ( const Collection &collection, collections ) {
00653         TrashJob *job = new TrashJob( collection, q );
00654         q->connect( job, SIGNAL(result(KJob*)), q, SLOT(moveCollectionToTrashResult(KJob*)) );
00655       }
00656     }
00657 
00658     void slotRestoreCollectionFromTrash()
00659     {
00660       const Collection::List collections = selectedCollections();
00661       if ( collections.isEmpty() )
00662         return;
00663 
00664       foreach ( const Collection &collection, collections ) {
00665         TrashRestoreJob *job = new TrashRestoreJob( collection, q );
00666         q->connect( job, SIGNAL(result(KJob*)), q, SLOT(moveCollectionToTrashResult(KJob*)) );
00667       }
00668     }
00669 
00670     Item::List selectedItems() const
00671     {
00672       Item::List items;
00673 
00674       Q_ASSERT( itemSelectionModel );
00675 
00676       foreach ( const QModelIndex &index, safeSelectedRows( itemSelectionModel ) ) {
00677         Q_ASSERT( index.isValid() );
00678         const Item item = index.data( ItemModel::ItemRole ).value<Item>();
00679         Q_ASSERT( item.isValid() );
00680 
00681         items << item;
00682       }
00683 
00684       return items;
00685     }
00686 
00687     void slotMoveItemToTrash()
00688     {
00689       const Item::List items = selectedItems();
00690       if ( items.isEmpty() )
00691         return;
00692 
00693       TrashJob *job = new TrashJob( items, q );
00694       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(moveItemToTrashResult(KJob*)) );
00695     }
00696 
00697     void slotRestoreItemFromTrash()
00698     {
00699       const Item::List items = selectedItems();
00700       if ( items.isEmpty() )
00701         return;
00702 
00703       TrashRestoreJob *job = new TrashRestoreJob( items, q );
00704       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(moveItemToTrashResult(KJob*)) );
00705     }
00706 
00707     void slotTrashRestoreCollection()
00708     {
00709       const Collection::List collections = selectedCollections();
00710       if ( collections.isEmpty() )
00711         return;
00712 
00713       bool collectionsAreInTrash = false;
00714       foreach ( const Collection &collection, collections ) {
00715         if ( collection.hasAttribute<EntityDeletedAttribute>() ) {
00716           collectionsAreInTrash = true;
00717           break;
00718         }
00719       }
00720 
00721       if (collectionsAreInTrash) {
00722         slotRestoreCollectionFromTrash();
00723       } else {
00724         slotMoveCollectionToTrash();
00725       }
00726     }
00727 
00728     void slotTrashRestoreItem()
00729     {
00730       const Item::List items = selectedItems();
00731       if ( items.isEmpty() )
00732         return;
00733 
00734       bool itemsAreInTrash = false;
00735       foreach ( const Item &item, items ) {
00736         if ( item.hasAttribute<EntityDeletedAttribute>() ) {
00737           itemsAreInTrash = true;
00738           break;
00739         }
00740       }
00741 
00742       if (itemsAreInTrash) {
00743         slotRestoreItemFromTrash();
00744       } else {
00745         slotMoveItemToTrash();
00746       }
00747     }
00748 
00749     void slotSynchronizeCollection()
00750     {
00751       Q_ASSERT( collectionSelectionModel );
00752       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00753       if ( list.isEmpty() )
00754         return;
00755 
00756       const Collection::List collections = selectedCollections();
00757       if ( collections.isEmpty() )
00758         return;
00759 
00760       foreach( const Collection &collection, collections ) {
00761         AgentManager::self()->synchronizeCollection( collection, false );
00762       }
00763     }
00764 
00765     void slotSynchronizeCollectionRecursive()
00766     {
00767       Q_ASSERT( collectionSelectionModel );
00768       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00769       if ( list.isEmpty() )
00770         return;
00771 
00772       const Collection::List collections = selectedCollections();
00773       if ( collections.isEmpty() )
00774         return;
00775 
00776       foreach( const Collection &collection, collections ) {
00777         AgentManager::self()->synchronizeCollection( collection, true );
00778       }
00779     }
00780 
00781     void slotCollectionProperties()
00782     {
00783       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00784       if ( list.isEmpty() )
00785         return;
00786 
00787       const QModelIndex index = list.first();
00788       Q_ASSERT( index.isValid() );
00789 
00790       const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00791       Q_ASSERT( collection.isValid() );
00792 
00793       const QString displayName = collection.hasAttribute<EntityDisplayAttribute>() ? collection.attribute<EntityDisplayAttribute>()->displayName()
00794                                                                                     : collection.name();
00795 
00796       CollectionPropertiesDialog* dlg = new CollectionPropertiesDialog( collection, mCollectionPropertiesPageNames, parentWidget );
00797       dlg->setCaption( contextText( StandardActionManager::CollectionProperties, StandardActionManager::DialogTitle ).arg( displayName ) );
00798       dlg->show();
00799     }
00800 
00801     void slotCopyItems()
00802     {
00803       encodeToClipboard( itemSelectionModel );
00804     }
00805 
00806     void slotCutItems()
00807     {
00808       encodeToClipboard( itemSelectionModel, true );
00809     }
00810 
00811     void slotPaste()
00812     {
00813       Q_ASSERT( collectionSelectionModel );
00814 
00815       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00816       if ( list.isEmpty() )
00817         return;
00818 
00819       const QModelIndex index = list.first();
00820       Q_ASSERT( index.isValid() );
00821 
00822 #ifndef QT_NO_CLIPBOARD
00823       // TODO: Copy or move? We can't seem to cut yet
00824       QAbstractItemModel *model = const_cast<QAbstractItemModel *>( collectionSelectionModel->model() );
00825       const QMimeData *mimeData = QApplication::clipboard()->mimeData();
00826       model->dropMimeData( mimeData, isCutAction( mimeData ) ? Qt::MoveAction : Qt::CopyAction, -1, -1, index );
00827       model->setData( QModelIndex(), false, EntityTreeModel::PendingCutRole );
00828       QApplication::clipboard()->clear();
00829 #endif
00830     }
00831 
00832     void slotDeleteItems()
00833     {
00834       Q_ASSERT( itemSelectionModel );
00835 
00836       Item::List items;
00837       foreach ( const QModelIndex &index, safeSelectedRows( itemSelectionModel ) ) {
00838         bool ok;
00839         const qlonglong id = index.data( ItemModel::IdRole ).toLongLong( &ok );
00840         Q_ASSERT( ok );
00841         items << Item( id );
00842       }
00843 
00844       if ( items.isEmpty() )
00845         return;
00846 
00847       QMetaObject::invokeMethod(q, "slotDeleteItemsDeferred",
00848                                 Qt::QueuedConnection,
00849                                 Q_ARG(Akonadi::Item::List, items));
00850     }
00851 
00852     void slotDeleteItemsDeferred(const Akonadi::Item::List &items)
00853     {
00854       Q_ASSERT( itemSelectionModel );
00855 
00856       if ( KMessageBox::questionYesNo( parentWidget,
00857            contextText( StandardActionManager::DeleteItems, StandardActionManager::MessageBoxText, items.count(), QString() ),
00858            contextText( StandardActionManager::DeleteItems, StandardActionManager::MessageBoxTitle, items.count(), QString() ),
00859            KStandardGuiItem::del(), KStandardGuiItem::cancel(),
00860            QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
00861         return;
00862 
00863       ItemDeleteJob *job = new ItemDeleteJob( items, q );
00864       q->connect( job, SIGNAL(result(KJob*)), q, SLOT(itemDeletionResult(KJob*)) );
00865     }
00866 
00867     void slotLocalSubscription()
00868     {
00869       SubscriptionDialog* dlg = new SubscriptionDialog( mMimeTypeFilter, parentWidget );
00870       dlg->show();
00871     }
00872 
00873     void slotAddToFavorites()
00874     {
00875       Q_ASSERT( collectionSelectionModel );
00876       Q_ASSERT( favoritesModel );
00877       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00878       if ( list.isEmpty() )
00879         return;
00880 
00881       foreach ( const QModelIndex &index, list ) {
00882         Q_ASSERT( index.isValid() );
00883         const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00884         Q_ASSERT( collection.isValid() );
00885 
00886         favoritesModel->addCollection( collection );
00887       }
00888 
00889       updateActions();
00890     }
00891 
00892     void slotRemoveFromFavorites()
00893     {
00894       Q_ASSERT( collectionSelectionModel );
00895       Q_ASSERT( favoritesModel );
00896       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00897       if ( list.isEmpty() )
00898         return;
00899 
00900       foreach ( const QModelIndex &index, list ) {
00901         Q_ASSERT( index.isValid() );
00902         const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00903         Q_ASSERT( collection.isValid() );
00904 
00905         favoritesModel->removeCollection( collection );
00906       }
00907 
00908       updateActions();
00909     }
00910 
00911     void slotRenameFavorite()
00912     {
00913       Q_ASSERT( collectionSelectionModel );
00914       Q_ASSERT( favoritesModel );
00915       const QModelIndexList list = safeSelectedRows( collectionSelectionModel );
00916       if ( list.isEmpty() )
00917         return;
00918       const QModelIndex index = list.first();
00919       Q_ASSERT( index.isValid() );
00920       const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00921       Q_ASSERT( collection.isValid() );
00922 
00923       const QString displayName = collection.hasAttribute<EntityDisplayAttribute>() ? collection.attribute<EntityDisplayAttribute>()->displayName() : collection.name();
00924 
00925       RenameFavoriteDialog dlg(contextText( StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogTitle ),contextText( StandardActionManager::RenameFavoriteCollection, StandardActionManager::DialogText ) , favoritesModel->favoriteLabel( collection ), displayName, parentWidget );
00926       if ( dlg.exec() )
00927       {
00928         favoritesModel->setFavoriteLabel( collection, dlg.newName() );
00929       }
00930     }
00931 
00932     void slotSynchronizeFavoriteCollections()
00933     {
00934       Q_ASSERT( favoritesModel );
00935       foreach( const Collection& collection, favoritesModel->collections() ) {
00936         // there might be virtual collections in favorites which cannot be checked
00937         // so let's be safe here, agentmanager asserts otherwise
00938         if ( !collection.resource().isEmpty() ) {
00939           AgentManager::self()->synchronizeCollection( collection, false );
00940         }
00941       }
00942     }
00943 
00944     void slotCopyCollectionTo()
00945     {
00946       pasteTo( collectionSelectionModel, collectionSelectionModel->model(), CopyCollectionToMenu, Qt::CopyAction );
00947     }
00948 
00949     void slotCopyItemTo()
00950     {
00951       pasteTo( itemSelectionModel, collectionSelectionModel->model(), CopyItemToMenu, Qt::CopyAction );
00952     }
00953 
00954     void slotMoveCollectionTo()
00955     {
00956       pasteTo( collectionSelectionModel, collectionSelectionModel->model(), MoveCollectionToMenu, Qt::MoveAction );
00957     }
00958 
00959     void slotMoveItemTo()
00960     {
00961       pasteTo( itemSelectionModel, collectionSelectionModel->model(), MoveItemToMenu, Qt::MoveAction );
00962     }
00963 
00964     void slotCopyCollectionTo( QAction *action )
00965     {
00966       pasteTo( collectionSelectionModel, action, Qt::CopyAction );
00967     }
00968 
00969     void slotCopyItemTo( QAction *action )
00970     {
00971       pasteTo( itemSelectionModel, action, Qt::CopyAction );
00972     }
00973 
00974     void slotMoveCollectionTo( QAction *action )
00975     {
00976       pasteTo( collectionSelectionModel, action, Qt::MoveAction );
00977     }
00978 
00979     void slotMoveItemTo( QAction *action )
00980     {
00981       pasteTo( itemSelectionModel, action, Qt::MoveAction );
00982     }
00983 
00984     AgentInstance::List selectedAgentInstances() const
00985     {
00986       AgentInstance::List instances;
00987 
00988       Q_ASSERT( collectionSelectionModel );
00989       if ( collectionSelectionModel->selection().indexes().isEmpty() )
00990         return instances;
00991 
00992       foreach ( const QModelIndex &index, collectionSelectionModel->selection().indexes() ) {
00993         Q_ASSERT( index.isValid() );
00994         const Collection collection = index.data( CollectionModel::CollectionRole ).value<Collection>();
00995         Q_ASSERT( collection.isValid() );
00996 
00997         if ( collection.isValid() ) {
00998           const QString identifier = collection.resource();
00999           instances << AgentManager::self()->instance( identifier );
01000         }
01001       }
01002 
01003       return instances;
01004     }
01005 
01006     AgentInstance selectedAgentInstance() const
01007     {
01008       const AgentInstance::List instances = selectedAgentInstances();
01009 
01010       if ( instances.isEmpty() )
01011         return AgentInstance();
01012 
01013       return instances.first();
01014     }
01015 
01016     void slotCreateResource()
01017     {
01018       Akonadi::AgentTypeDialog dlg( parentWidget );
01019       dlg.setCaption( contextText( StandardActionManager::CreateResource, StandardActionManager::DialogTitle ) );
01020 
01021       foreach ( const QString &mimeType, mMimeTypeFilter )
01022         dlg.agentFilterProxyModel()->addMimeTypeFilter( mimeType );
01023 
01024       foreach ( const QString &capability, mCapabilityFilter )
01025         dlg.agentFilterProxyModel()->addCapabilityFilter( capability );
01026 
01027       if ( dlg.exec() ) {
01028         const AgentType agentType = dlg.agentType();
01029 
01030         if ( agentType.isValid() ) {
01031           AgentInstanceCreateJob *job = new AgentInstanceCreateJob( agentType, q );
01032           q->connect( job, SIGNAL(result(KJob*)), SLOT(resourceCreationResult(KJob*)) );
01033           job->configure( parentWidget );
01034           job->start();
01035         }
01036       }
01037     }
01038 
01039     void slotDeleteResource()
01040     {
01041       const AgentInstance::List instances = selectedAgentInstances();
01042       if ( instances.isEmpty() )
01043         return;
01044 
01045       if ( KMessageBox::questionYesNo( parentWidget,
01046            contextText( StandardActionManager::DeleteResources, StandardActionManager::MessageBoxText, instances.count(), instances.first().name() ),
01047            contextText( StandardActionManager::DeleteResources, StandardActionManager::MessageBoxTitle, instances.count(), instances.first().name() ),
01048            KStandardGuiItem::del(), KStandardGuiItem::cancel(),
01049            QString(), KMessageBox::Dangerous ) != KMessageBox::Yes )
01050         return;
01051 
01052       foreach ( const AgentInstance &instance, instances )
01053         AgentManager::self()->removeInstance( instance );
01054     }
01055 
01056     void slotSynchronizeResource()
01057     {
01058       const AgentInstance::List instances = selectedAgentInstances();
01059       if ( instances.isEmpty() )
01060         return;
01061 
01062       foreach ( AgentInstance instance, instances ) { //krazy:exclude=foreach
01063         instance.synchronize();
01064       }
01065     }
01066 
01067     void slotResourceProperties()
01068     {
01069       AgentInstance instance = selectedAgentInstance();
01070       if ( !instance.isValid() )
01071         return;
01072 
01073       instance.configure( parentWidget );
01074     }
01075 
01076     void slotToggleWorkOffline( bool offline )
01077     {
01078       setWorkOffline( offline );
01079 
01080       AgentInstance::List instances = AgentManager::self()->instances();
01081       foreach ( AgentInstance instance, instances ) { //krazy:exclude=foreach
01082         instance.setIsOnline( !offline );
01083       }
01084     }
01085 
01086     void pasteTo( QItemSelectionModel *selectionModel, const QAbstractItemModel *model, StandardActionManager::Type type, Qt::DropAction dropAction )
01087     {
01088       const QSet<QString> mimeTypes = mimeTypesOfSelection( type );
01089 
01090       CollectionDialog dlg( const_cast<QAbstractItemModel*>( model ) );
01091       dlg.setMimeTypeFilter( mimeTypes.toList() );
01092 
01093       if ( type == CopyItemToMenu || type == MoveItemToMenu )
01094         dlg.setAccessRightsFilter( Collection::CanCreateItem );
01095       else if ( type == CopyCollectionToMenu || type == MoveCollectionToMenu )
01096         dlg.setAccessRightsFilter( Collection::CanCreateCollection );
01097 
01098       if ( dlg.exec() ) {
01099         const QModelIndex index = EntityTreeModel::modelIndexForCollection( collectionSelectionModel->model(), dlg.selectedCollection() );
01100         if ( !index.isValid() )
01101           return;
01102 
01103         const QMimeData *mimeData = selectionModel->model()->mimeData( safeSelectedRows( selectionModel ) );
01104 
01105         QAbstractItemModel *model = const_cast<QAbstractItemModel *>( index.model() );
01106         model->dropMimeData( mimeData, dropAction, -1, -1, index );
01107       }
01108     }
01109 
01110     void pasteTo( QItemSelectionModel *selectionModel, QAction *action, Qt::DropAction dropAction )
01111     {
01112       Q_ASSERT( selectionModel );
01113       Q_ASSERT( action );
01114 
01115       if ( safeSelectedRows( selectionModel ).count() <= 0 )
01116         return;
01117 
01118       const QMimeData *mimeData = selectionModel->model()->mimeData( selectionModel->selectedRows() );
01119 
01120       const QModelIndex index = action->data().value<QModelIndex>();
01121       Q_ASSERT( index.isValid() );
01122 
01123       QAbstractItemModel *model = const_cast<QAbstractItemModel *>( index.model() );
01124       const Collection collection = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
01125       addRecentCollection( collection.id() );
01126       model->dropMimeData( mimeData, dropAction, -1, -1, index );
01127     }
01128 
01129     void addRecentCollection( Akonadi::Collection::Id id )
01130     {
01131       QMapIterator<StandardActionManager::Type, QWeakPointer<RecentCollectionAction> > item(mRecentCollectionsMenu);
01132       while (item.hasNext()) {
01133         item.next();
01134         if ( item.value().data() ) {
01135           item.value().data()->addRecentCollection( id );
01136         }
01137       }
01138     }
01139 
01140     void collectionCreationResult( KJob *job )
01141     {
01142       if ( job->error() ) {
01143         KMessageBox::error( parentWidget,
01144                             contextText( StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01145                             contextText( StandardActionManager::CreateCollection, StandardActionManager::ErrorMessageTitle ) );
01146       }
01147     }
01148 
01149     void collectionDeletionResult( KJob *job )
01150     {
01151       if ( job->error() ) {
01152         KMessageBox::error( parentWidget,
01153                             contextText( StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01154                             contextText( StandardActionManager::DeleteCollections, StandardActionManager::ErrorMessageTitle ) );
01155       }
01156     }
01157 
01158     void moveCollectionToTrashResult( KJob *job )
01159     {
01160       if ( job->error() ) {
01161         KMessageBox::error( parentWidget,
01162                             contextText( StandardActionManager::MoveCollectionsToTrash, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01163                             contextText( StandardActionManager::MoveCollectionsToTrash, StandardActionManager::ErrorMessageTitle ) );
01164       }
01165     }
01166 
01167     void moveItemToTrashResult( KJob *job )
01168     {
01169       if ( job->error() ) {
01170         KMessageBox::error( parentWidget,
01171                             contextText( StandardActionManager::MoveItemsToTrash, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01172                             contextText( StandardActionManager::MoveItemsToTrash, StandardActionManager::ErrorMessageTitle ) );
01173       }
01174     }
01175 
01176     void itemDeletionResult( KJob *job )
01177     {
01178       if ( job->error() ) {
01179         KMessageBox::error( parentWidget,
01180                             contextText( StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01181                             contextText( StandardActionManager::DeleteItems, StandardActionManager::ErrorMessageTitle ) );
01182       }
01183     }
01184 
01185     void resourceCreationResult( KJob *job )
01186     {
01187       if ( job->error() ) {
01188         KMessageBox::error( parentWidget,
01189                             contextText( StandardActionManager::CreateResource, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01190                             contextText( StandardActionManager::CreateResource, StandardActionManager::ErrorMessageTitle ) );
01191       }
01192     }
01193 
01194     void pasteResult( KJob *job )
01195     {
01196       if ( job->error() ) {
01197         KMessageBox::error( parentWidget,
01198                             contextText( StandardActionManager::Paste, StandardActionManager::ErrorMessageText ).arg( job->errorString() ),
01199                             contextText( StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle ) );
01200       }
01201     }
01202 
01206     QSet<QString> mimeTypesOfSelection( StandardActionManager::Type type ) const
01207     {
01208       QModelIndexList list;
01209       QSet<QString> mimeTypes;
01210 
01211       const bool isItemAction = ( type == CopyItemToMenu || type == MoveItemToMenu );
01212       const bool isCollectionAction = ( type == CopyCollectionToMenu || type == MoveCollectionToMenu );
01213 
01214       if ( isItemAction ) {
01215         list = safeSelectedRows( itemSelectionModel );
01216         foreach ( const QModelIndex &index, list )
01217           mimeTypes << index.data( EntityTreeModel::MimeTypeRole ).toString();
01218       }
01219 
01220       if ( isCollectionAction ) {
01221         list = safeSelectedRows( collectionSelectionModel );
01222         foreach ( const QModelIndex &index, list ) {
01223           const Collection collection = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
01224 
01225           // The mimetypes that the selected collection can possibly contain
01226           mimeTypes = AgentManager::self()->instance( collection.resource() ).type().mimeTypes().toSet();
01227         }
01228       }
01229 
01230       return mimeTypes;
01231     }
01232 
01236     bool isWritableTargetCollectionForMimeTypes( const Collection &collection, const QSet<QString> &mimeTypes, StandardActionManager::Type type ) const
01237     {
01238       if ( CollectionUtils::isVirtual( collection ) )
01239         return false;
01240 
01241       const bool isItemAction = ( type == CopyItemToMenu || type == MoveItemToMenu );
01242       const bool isCollectionAction = ( type == CopyCollectionToMenu || type == MoveCollectionToMenu );
01243 
01244       const bool canContainRequiredMimeTypes = !collection.contentMimeTypes().toSet().intersect( mimeTypes ).isEmpty();
01245       const bool canCreateNewItems = (collection.rights() & Collection::CanCreateItem);
01246 
01247       const bool canCreateNewCollections = (collection.rights() & Collection::CanCreateCollection);
01248       const bool canContainCollections = collection.contentMimeTypes().contains( Collection::mimeType() );
01249       const bool resourceAllowsRequiredMimeTypes = AgentManager::self()->instance( collection.resource() ).type().mimeTypes().toSet().contains( mimeTypes );
01250 
01251       const bool isReadOnlyForItems = (isItemAction && (!canCreateNewItems || !canContainRequiredMimeTypes));
01252       const bool isReadOnlyForCollections = (isCollectionAction && (!canCreateNewCollections || !canContainCollections || !resourceAllowsRequiredMimeTypes));
01253 
01254       return !(CollectionUtils::isStructural( collection ) || isReadOnlyForItems || isReadOnlyForCollections);
01255     }
01256 
01257     void fillFoldersMenu( const Akonadi::Collection::List& selectedCollectionsList, const QSet<QString>& mimeTypes,  StandardActionManager::Type type, QMenu *menu,
01258                           const QAbstractItemModel *model, QModelIndex parentIndex )
01259     {
01260       const int rowCount = model->rowCount( parentIndex );
01261 
01262       for ( int row = 0; row < rowCount; ++row ) {
01263         const QModelIndex index = model->index( row, 0, parentIndex );
01264         const Collection collection = model->data( index, CollectionModel::CollectionRole ).value<Collection>();
01265 
01266         if ( CollectionUtils::isVirtual( collection ) )
01267           continue;
01268 
01269         const bool readOnly = !isWritableTargetCollectionForMimeTypes( collection, mimeTypes, type );
01270         const bool collectionIsSelected = selectedCollectionsList.contains( collection );
01271 
01272         QString label = model->data( index ).toString();
01273         label.replace( QLatin1String( "&" ), QLatin1String( "&&" ) );
01274 
01275         const QIcon icon = model->data( index, Qt::DecorationRole ).value<QIcon>();
01276 
01277         if ( model->rowCount( index ) > 0 ) {
01278           // new level
01279           QMenu* popup = new QMenu( menu );
01280           const bool moveAction = (type == MoveCollectionToMenu || type == MoveItemToMenu);
01281           popup->setObjectName( QString::fromUtf8( "subMenu" ) );
01282           popup->setTitle( label );
01283           popup->setIcon( icon );
01284 
01285           fillFoldersMenu( selectedCollectionsList, mimeTypes, type, popup, model, index );
01286 
01287           if ( !readOnly ) {
01288             popup->addSeparator();
01289 
01290             QAction *action = popup->addAction( moveAction ? i18n( "Move to This Folder" ) : i18n( "Copy to This Folder" ) );
01291             action->setData( QVariant::fromValue<QModelIndex>( index ) );
01292           }
01293 
01294           menu->addMenu( popup );
01295 
01296         } else {
01297           // insert an item
01298           QAction* action = menu->addAction( icon, label );
01299           action->setData( QVariant::fromValue<QModelIndex>( index ) );
01300           action->setEnabled( !readOnly && !collectionIsSelected );
01301         }
01302       }
01303     }
01304 
01305     void checkModelsConsistency()
01306     {
01307       if ( favoritesModel == 0 || favoriteSelectionModel == 0 ) {
01308         // No need to check when the favorite collections feature is not used
01309         return;
01310       }
01311 
01312       // find the base ETM of the favourites view
01313       const QAbstractItemModel *favModel = favoritesModel;
01314       while ( const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel*>( favModel ) ) {
01315         favModel = proxy->sourceModel();
01316       }
01317 
01318       // Check that the collection selection model maps to the same
01319       // EntityTreeModel than favoritesModel
01320       if ( collectionSelectionModel != 0 ) {
01321         const QAbstractItemModel *model = collectionSelectionModel->model();
01322         while ( const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel*>( model ) ) {
01323           model = proxy->sourceModel();
01324         }
01325 
01326         Q_ASSERT( model == favModel );
01327       }
01328 
01329       // Check that the favorite selection model maps to favoritesModel
01330       const QAbstractItemModel *model = favoriteSelectionModel->model();
01331       while ( const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel*>( model ) ) {
01332         model = proxy->sourceModel();
01333       }
01334       Q_ASSERT( model == favModel );
01335     }
01336 
01337     void markCutAction( QMimeData *mimeData, bool cut ) const
01338     {
01339       if ( !cut )
01340         return;
01341 
01342       const QByteArray cutSelectionData = "1"; //krazy:exclude=doublequote_chars
01343       mimeData->setData( QLatin1String( "application/x-kde.akonadi-cutselection" ), cutSelectionData);
01344     }
01345 
01346     bool isCutAction( const QMimeData *mimeData ) const
01347     {
01348       const QByteArray data = mimeData->data( QLatin1String( "application/x-kde.akonadi-cutselection" ) );
01349       if ( data.isEmpty() )
01350         return false;
01351       else
01352         return (data.at( 0 ) == '1'); // true if 1
01353     }
01354 
01355     void setContextText( StandardActionManager::Type type, StandardActionManager::TextContext context, const QString &data )
01356     {
01357       ContextTextEntry entry;
01358       entry.text = data;
01359 
01360       contextTexts[ type ].insert( context, entry );
01361     }
01362 
01363     void setContextText( StandardActionManager::Type type, StandardActionManager::TextContext context, const KLocalizedString &data )
01364     {
01365       ContextTextEntry entry;
01366       entry.localizedText = data;
01367 
01368       contextTexts[ type ].insert( context, entry );
01369     }
01370 
01371     QString contextText( StandardActionManager::Type type, StandardActionManager::TextContext context ) const
01372     {
01373       return contextTexts[ type ].value( context ).text;
01374     }
01375 
01376     QString contextText( StandardActionManager::Type type, StandardActionManager::TextContext context, int count, const QString &value ) const
01377     {
01378       if ( contextTexts[ type ].value( context ).localizedText.isEmpty() )
01379         return contextTexts[ type ].value( context ).text;
01380 
01381       KLocalizedString text = contextTexts[ type ].value( context ).localizedText;
01382       const QString str = text.subs( count ).toString();
01383       const int argCount = str.count( QRegExp( QLatin1String( "%[0-9]" ) ) );
01384       if ( argCount > 0 ) {
01385         return text.subs( count ).subs( value ).toString();
01386       } else {
01387         return text.subs( count ).toString();
01388       }
01389     }
01390 
01391     StandardActionManager *q;
01392     KActionCollection *actionCollection;
01393     QWidget *parentWidget;
01394     QItemSelectionModel *collectionSelectionModel;
01395     QItemSelectionModel *itemSelectionModel;
01396     FavoriteCollectionsModel *favoritesModel;
01397     QItemSelectionModel *favoriteSelectionModel;
01398     QVector<KAction*> actions;
01399     QHash<StandardActionManager::Type, KLocalizedString> pluralLabels;
01400     QHash<StandardActionManager::Type, KLocalizedString> pluralIconLabels;
01401 
01402     struct ContextTextEntry
01403     {
01404       QString text;
01405       KLocalizedString localizedText;
01406       bool isLocalized;
01407     };
01408 
01409     typedef QHash<StandardActionManager::TextContext, ContextTextEntry> ContextTexts;
01410     QHash<StandardActionManager::Type, ContextTexts> contextTexts;
01411 
01412     ActionStateManager mActionStateManager;
01413 
01414     QStringList mMimeTypeFilter;
01415     QStringList mCapabilityFilter;
01416     QStringList mCollectionPropertiesPageNames;
01417     QMap<StandardActionManager::Type, QWeakPointer<RecentCollectionAction> > mRecentCollectionsMenu;
01418 };
01419 
01420 //@endcond
01421 
01422 StandardActionManager::StandardActionManager( KActionCollection * actionCollection,
01423                                               QWidget * parent) :
01424     QObject( parent ),
01425     d( new Private( this ) )
01426 {
01427   d->parentWidget = parent;
01428   d->actionCollection = actionCollection;
01429   d->mActionStateManager.setReceiver( this );
01430 #ifndef QT_NO_CLIPBOARD
01431   connect( QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), SLOT(clipboardChanged(QClipboard::Mode)) );
01432 #endif
01433 }
01434 
01435 StandardActionManager::~ StandardActionManager()
01436 {
01437   delete d;
01438 }
01439 
01440 void StandardActionManager::setCollectionSelectionModel( QItemSelectionModel * selectionModel )
01441 {
01442   d->collectionSelectionModel = selectionModel;
01443   connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
01444            SLOT(collectionSelectionChanged()) );
01445 
01446   d->checkModelsConsistency();
01447 }
01448 
01449 void StandardActionManager::setItemSelectionModel( QItemSelectionModel * selectionModel )
01450 {
01451   d->itemSelectionModel = selectionModel;
01452   connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
01453            SLOT(updateActions()) );
01454 }
01455 
01456 void StandardActionManager::setFavoriteCollectionsModel( FavoriteCollectionsModel *favoritesModel )
01457 {
01458   d->favoritesModel = favoritesModel;
01459   d->checkModelsConsistency();
01460 }
01461 
01462 void StandardActionManager::setFavoriteSelectionModel( QItemSelectionModel *selectionModel )
01463 {
01464   d->favoriteSelectionModel = selectionModel;
01465   connect( selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
01466            SLOT(favoriteSelectionChanged()) );
01467   d->checkModelsConsistency();
01468 }
01469 
01470 KAction* StandardActionManager::createAction( Type type )
01471 {
01472   Q_ASSERT( type < LastType );
01473   if ( d->actions[type] )
01474     return d->actions[type];
01475   KAction *action = 0;
01476   switch ( standardActionData[type].actionType ) {
01477     case NormalAction:
01478     case ActionWithAlternative:
01479       action = new KAction( d->parentWidget );
01480       break;
01481     case ActionAlternative:
01482       d->actions[type] = d->actions[type-1];
01483       Q_ASSERT( d->actions[type] );
01484       if ( (LastType > type+1) && (standardActionData[type+1].actionType == ActionAlternative) ) {
01485         createAction(static_cast<Type>(type+1)); //ensure that alternative actions are initialized when not created by createAllActions
01486       }
01487       return d->actions[type];
01488     case MenuAction:
01489       action = new KActionMenu( d->parentWidget );
01490       break;
01491     case ToggleAction:
01492       action = new KToggleAction( d->parentWidget );
01493       break;
01494   }
01495 
01496   if ( d->pluralLabels.contains( type ) && !d->pluralLabels.value( type ).isEmpty() )
01497     action->setText( d->pluralLabels.value( type ).subs( 1 ).toString() );
01498   else if ( standardActionData[type].label )
01499     action->setText( i18n( standardActionData[type].label ) );
01500 
01501   if ( d->pluralIconLabels.contains( type ) && !d->pluralIconLabels.value( type ).isEmpty() )
01502     action->setIconText( d->pluralIconLabels.value( type ).subs( 1 ).toString() );
01503   else if ( standardActionData[type].iconLabel )
01504     action->setIconText( i18n( standardActionData[type].iconLabel ) );
01505 
01506   if ( standardActionData[type].icon )
01507     action->setIcon( KIcon( QString::fromLatin1( standardActionData[type].icon ) ) );
01508 
01509   action->setShortcut( standardActionData[type].shortcut );
01510 
01511   if ( standardActionData[type].slot ) {
01512     switch ( standardActionData[type].actionType ) {
01513       case NormalAction:
01514       case ActionWithAlternative:
01515         connect( action, SIGNAL(triggered()), standardActionData[type].slot );
01516         break;
01517       case MenuAction:
01518         {
01519           KActionMenu *actionMenu = qobject_cast<KActionMenu*>( action );
01520           connect( actionMenu->menu(), SIGNAL(triggered(QAction*)), standardActionData[type].slot );
01521         }
01522         break;
01523       case ToggleAction:
01524         {
01525           connect( action, SIGNAL(triggered(bool)), standardActionData[type].slot );
01526         }
01527         break;
01528       case ActionAlternative:
01529         Q_ASSERT(0);
01530     }
01531   }
01532 
01533   if ( type == ToggleWorkOffline ) {
01534     // inititalize the action state with information from config file
01535     disconnect( action, SIGNAL(triggered(bool)), this, standardActionData[type].slot );
01536     action->setChecked( workOffline() );
01537     connect( action, SIGNAL(triggered(bool)), this, standardActionData[type].slot );
01538 
01539     //TODO: find a way to check for updates to the config file
01540   }
01541 
01542   Q_ASSERT( standardActionData[type].name );
01543   d->actionCollection->addAction( QString::fromLatin1(standardActionData[type].name), action );
01544   d->actions[type] = action;
01545   if ( ( standardActionData[type].actionType == ActionWithAlternative ) &&  (standardActionData[type+1].actionType == ActionAlternative)) {
01546     createAction(static_cast<Type>(type+1)); //ensure that alternative actions are initialized when not created by createAllActions
01547   }
01548   d->updateActions();
01549   return action;
01550 }
01551 
01552 void StandardActionManager::createAllActions()
01553 {
01554   for ( uint i = 0; i < LastType; ++i )
01555     createAction( (Type)i );
01556 }
01557 
01558 KAction * StandardActionManager::action( Type type ) const
01559 {
01560   Q_ASSERT( type < LastType );
01561   return d->actions[type];
01562 }
01563 
01564 void StandardActionManager::setActionText( Type type, const KLocalizedString & text )
01565 {
01566   Q_ASSERT( type < LastType );
01567   d->pluralLabels.insert( type, text );
01568   d->updateActions();
01569 }
01570 
01571 void StandardActionManager::interceptAction( Type type, bool intercept )
01572 {
01573   Q_ASSERT( type < LastType );
01574 
01575   const KAction *action = d->actions[type];
01576 
01577   if ( !action )
01578     return;
01579 
01580   if ( intercept )
01581     disconnect( action, SIGNAL(triggered()), this, standardActionData[type].slot );
01582   else
01583     connect( action, SIGNAL(triggered()), standardActionData[type].slot );
01584 }
01585 
01586 Akonadi::Collection::List StandardActionManager::selectedCollections() const
01587 {
01588   Collection::List collections;
01589 
01590   if ( !d->collectionSelectionModel )
01591     return collections;
01592 
01593   foreach ( const QModelIndex &index, safeSelectedRows( d->collectionSelectionModel ) ) {
01594     const Collection collection = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
01595     if ( collection.isValid() )
01596       collections << collection;
01597   }
01598 
01599   return collections;
01600 }
01601 
01602 Item::List StandardActionManager::selectedItems() const
01603 {
01604   Item::List items;
01605 
01606   if ( !d->itemSelectionModel )
01607     return items;
01608 
01609   foreach ( const QModelIndex &index, safeSelectedRows( d->itemSelectionModel ) ) {
01610     const Item item = index.data( EntityTreeModel::ItemRole ).value<Item>();
01611     if ( item.isValid() )
01612       items << item;
01613   }
01614 
01615   return items;
01616 }
01617 
01618 void StandardActionManager::setContextText( Type type, TextContext context, const QString &text )
01619 {
01620   d->setContextText( type, context, text );
01621 }
01622 
01623 void StandardActionManager::setContextText( Type type, TextContext context, const KLocalizedString &text )
01624 {
01625   d->setContextText( type, context, text );
01626 }
01627 
01628 void StandardActionManager::setMimeTypeFilter( const QStringList &mimeTypes )
01629 {
01630   d->mMimeTypeFilter = mimeTypes;
01631 }
01632 
01633 void StandardActionManager::setCapabilityFilter( const QStringList &capabilities )
01634 {
01635   d->mCapabilityFilter = capabilities;
01636 }
01637 
01638 void StandardActionManager::setCollectionPropertiesPageNames( const QStringList &names )
01639 {
01640   d->mCollectionPropertiesPageNames = names;
01641 }
01642 
01643 void StandardActionManager::createActionFolderMenu(QMenu *menu, Type type)
01644 {
01645   d->createActionFolderMenu( menu, type );
01646 }
01647 
01648 
01649 
01650 #include "standardactionmanager.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu Aug 2 2012 15:25:19 by doxygen 1.7.5 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.5 API Reference

Skip menu "kdepimlibs-4.8.5 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