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

akonadi

entitytreeview.cpp

00001 /*
00002     Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
00003     Copyright (c) 2008 Stephen Kelly <steveire@gmail.com>
00004 
00005     This library is free software; you can redistribute it and/or modify it
00006     under the terms of the GNU Library General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or (at your
00008     option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful, but WITHOUT
00011     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013     License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to the
00017     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018     02110-1301, USA.
00019 */
00020 
00021 #include "entitytreeview.h"
00022 
00023 #include "dragdropmanager_p.h"
00024 
00025 #include <QtCore/QDebug>
00026 #include <QtCore/QTimer>
00027 #include <QtGui/QApplication>
00028 #include <QtGui/QDragMoveEvent>
00029 #include <QtGui/QHeaderView>
00030 #include <QtGui/QMenu>
00031 
00032 #include <KAction>
00033 #include <KLocale>
00034 #include <KMessageBox>
00035 #include <KUrl>
00036 #include <KXMLGUIFactory>
00037 
00038 #include <akonadi/collection.h>
00039 #include <akonadi/control.h>
00040 #include <akonadi/item.h>
00041 #include <akonadi/entitytreemodel.h>
00042 
00043 #include <kdebug.h>
00044 #include <kxmlguiclient.h>
00045 
00046 using namespace Akonadi;
00047 
00051 class EntityTreeView::Private
00052 {
00053 public:
00054   Private( EntityTreeView *parent )
00055       : mParent( parent ), mDragDropManager( new DragDropManager( mParent ) ), mXmlGuiClient( 0 )
00056   {
00057   }
00058 
00059   void init();
00060   void itemClicked( const QModelIndex& );
00061   void itemDoubleClicked( const QModelIndex& );
00062   void itemCurrentChanged( const QModelIndex& );
00063 
00064   void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
00065 
00066   EntityTreeView *mParent;
00067   QBasicTimer mDragExpandTimer;
00068   DragDropManager *mDragDropManager;
00069   KXMLGUIClient *mXmlGuiClient;
00070 };
00071 
00072 void EntityTreeView::Private::init()
00073 {
00074   mParent->header()->setClickable( true );
00075   mParent->header()->setStretchLastSection( false );
00076 //   mParent->setRootIsDecorated( false );
00077 
00078   // QTreeView::autoExpandDelay has very strange behaviour. It toggles the collapse/expand state
00079   // of the item the cursor is currently over when a timer event fires.
00080   // The behaviour we want is to expand a collapsed row on drag-over, but not collapse it.
00081   // mDragExpandTimer is used to achieve this.
00082 //   mParent->setAutoExpandDelay ( QApplication::startDragTime() );
00083 
00084   mParent->setSortingEnabled( true );
00085   mParent->sortByColumn( 0, Qt::AscendingOrder );
00086   mParent->setEditTriggers( QAbstractItemView::EditKeyPressed );
00087   mParent->setAcceptDrops( true );
00088   mParent->setDropIndicatorShown( true );
00089   mParent->setDragDropMode( DragDrop );
00090   mParent->setDragEnabled( true );
00091 
00092   mParent->connect( mParent, SIGNAL( clicked( const QModelIndex& ) ),
00093                     mParent, SLOT( itemClicked( const QModelIndex& ) ) );
00094   mParent->connect( mParent, SIGNAL( doubleClicked( const QModelIndex& ) ),
00095                     mParent, SLOT( itemDoubleClicked( const QModelIndex& ) ) );
00096 
00097   Control::widgetNeedsAkonadi( mParent );
00098 }
00099 
00100 void EntityTreeView::Private::slotSelectionChanged( const QItemSelection & selected, const QItemSelection& )
00101 {
00102   const int column = 0;
00103   foreach ( const QItemSelectionRange &range, selected ) {
00104     const QModelIndex index = range.topLeft();
00105 
00106     if ( index.column() > 0 )
00107       continue;
00108 
00109     for ( int row = index.row(); row <= range.bottomRight().row(); ++row ) {
00110       // Don't use canFetchMore here. We need to bypass the check in
00111       // the EntityFilterModel when it shows only collections.
00112       mParent->model()->fetchMore( index.sibling( row, column ) );
00113     }
00114   }
00115 }
00116 
00117 void EntityTreeView::Private::itemClicked( const QModelIndex &index )
00118 {
00119   if ( !index.isValid() )
00120     return;
00121 
00122   const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00123   if ( collection.isValid() ) {
00124     emit mParent->clicked( collection );
00125   } else {
00126     const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00127     if ( item.isValid() )
00128       emit mParent->clicked( item );
00129   }
00130 }
00131 
00132 void EntityTreeView::Private::itemDoubleClicked( const QModelIndex &index )
00133 {
00134   if ( !index.isValid() )
00135     return;
00136 
00137   const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00138   if ( collection.isValid() ) {
00139     emit mParent->doubleClicked( collection );
00140   } else {
00141     const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00142     if ( item.isValid() )
00143       emit mParent->doubleClicked( item );
00144   }
00145 }
00146 
00147 void EntityTreeView::Private::itemCurrentChanged( const QModelIndex &index )
00148 {
00149   if ( !index.isValid() )
00150     return;
00151 
00152   const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00153   if ( collection.isValid() ) {
00154     emit mParent->currentChanged( collection );
00155   } else {
00156     const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00157     if ( item.isValid() )
00158       emit mParent->currentChanged( item );
00159   }
00160 }
00161 
00162 EntityTreeView::EntityTreeView( QWidget * parent )
00163   : QTreeView( parent ),
00164     d( new Private( this ) )
00165 {
00166   setSelectionMode( QAbstractItemView::SingleSelection );
00167   d->init();
00168 }
00169 
00170 EntityTreeView::EntityTreeView( KXMLGUIClient *xmlGuiClient, QWidget * parent )
00171   : QTreeView( parent ),
00172     d( new Private( this ) )
00173 {
00174   d->mXmlGuiClient = xmlGuiClient;
00175   d->init();
00176 }
00177 
00178 EntityTreeView::~EntityTreeView()
00179 {
00180   delete d->mDragDropManager;
00181   delete d;
00182 }
00183 
00184 void EntityTreeView::setModel( QAbstractItemModel * model )
00185 {
00186   if ( selectionModel() ) {
00187     disconnect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00188            this, SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00189 
00190     disconnect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00191            this, SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00192   }
00193 
00194   QTreeView::setModel( model );
00195   header()->setStretchLastSection( true );
00196 
00197   connect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00198            SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00199 
00200   connect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00201            SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00202 }
00203 
00204 
00205 void EntityTreeView::timerEvent( QTimerEvent *event )
00206 {
00207   if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
00208     const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
00209     if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
00210       setExpanded( indexAt( pos ), true );
00211   }
00212 
00213   QTreeView::timerEvent( event );
00214 }
00215 
00216 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
00217 {
00218   d->mDragExpandTimer.start( QApplication::startDragTime() , this );
00219 
00220   if ( d->mDragDropManager->dropAllowed( event ) ) {
00221     // All urls are supported. process the event.
00222     QTreeView::dragMoveEvent( event );
00223     return;
00224   }
00225 
00226   event->setDropAction( Qt::IgnoreAction );
00227   return;
00228 }
00229 
00230 void EntityTreeView::dropEvent( QDropEvent * event )
00231 {
00232   if ( d->mDragDropManager->processDropEvent( event ) )
00233     QTreeView::dropEvent( event );
00234 }
00235 
00236 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
00237 {
00238   if ( !d->mXmlGuiClient || !model())
00239     return;
00240 
00241   const QModelIndex index = indexAt( event->pos() );
00242 
00243   QMenu *popup = 0;
00244 
00245   // check if the index under the cursor is a collection or item
00246   const Item item = model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00247   if ( item.isValid() )
00248     popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00249                                  QLatin1String( "akonadi_itemview_contextmenu" ), d->mXmlGuiClient ) );
00250   else
00251     popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00252                                  QLatin1String( "akonadi_collectionview_contextmenu" ), d->mXmlGuiClient ) );
00253   if ( popup )
00254     popup->exec( event->globalPos() );
00255 }
00256 
00257 void EntityTreeView::setXmlGuiClient( KXMLGUIClient * xmlGuiClient )
00258 {
00259   d->mXmlGuiClient = xmlGuiClient;
00260 }
00261 
00262 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
00263 {
00264   d->mDragDropManager->startDrag( supportedActions );
00265 }
00266 
00267 #include "entitytreeview.moc"

akonadi

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

KDE-PIM Libraries

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