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 May 10 2012 22:18:36 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:18:36 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.