2 This file is part of KAddressBook.
4 Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "mainwidget.h"
23 #include "contactswitcher.h"
24 #include "globalcontactmodel.h"
25 #include "modelcolumnmanager.h"
26 #include "printing/printingwizard.h"
27 #include "quicksearchwidget.h"
29 #include "xxportmanager.h"
32 #include "grantleecontactformatter.h"
33 #include "grantleecontactgroupformatter.h"
36 #include "libkdepim/uistatesaver.h"
38 #include <akonadi/etmviewstatesaver.h>
39 #include <akonadi/collectionfilterproxymodel.h>
40 #include <akonadi/collectionmodel.h>
41 #include <akonadi/contact/contactdefaultactions.h>
42 #include <akonadi/contact/contacteditordialog.h>
43 #include <akonadi/contact/contactgroupeditordialog.h>
44 #include <akonadi/contact/contactgroupviewer.h>
45 #include <akonadi/contact/contactsfilterproxymodel.h>
46 #include <akonadi/contact/contactstreemodel.h>
47 #include <akonadi/contact/contactviewer.h>
48 #include <akonadi/contact/standardcontactactionmanager.h>
49 #include <akonadi/control.h>
50 #include <akonadi/entitymimetypefiltermodel.h>
51 #include <akonadi/entitytreeview.h>
52 #include <akonadi/entitytreeviewstatesaver.h>
53 #include <akonadi/itemview.h>
54 #include <akonadi/mimetypechecker.h>
56 #include <kabc/addressee.h>
57 #include <kabc/contactgroup.h>
60 #include <kactioncollection.h>
61 #include <kapplication.h>
62 #include <kcheckableproxymodel.h>
63 #include <kdescendantsproxymodel.h>
65 #include <klineedit.h>
67 #include <kselectionproxymodel.h>
68 #include <kstandarddirs.h>
69 #include <ktextbrowser.h>
70 #include <ktoggleaction.h>
72 #include <kxmlguiwindow.h>
74 #include <QtGui/QAction>
75 #include <QtGui/QHBoxLayout>
76 #include <QtGui/QHeaderView>
77 #include <QtGui/QListView>
78 #include <QtGui/QPrinter>
79 #include <QtGui/QPrintDialog>
80 #include <QtGui/QSortFilterProxyModel>
81 #include <QtGui/QSplitter>
82 #include <QtGui/QStackedWidget>
87 static bool isStructuralCollection( const Akonadi::Collection
&collection
)
89 QStringList mimeTypes
;
90 mimeTypes
<< KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType();
91 const QStringList collectionMimeTypes
= collection
.contentMimeTypes();
92 foreach ( const QString
&mimeType
, mimeTypes
) {
93 if ( collectionMimeTypes
.contains( mimeType
) )
99 class StructuralCollectionsNotCheckableProxy
: public KCheckableProxyModel
{
101 StructuralCollectionsNotCheckableProxy(QObject
* parent
)
102 : KCheckableProxyModel(parent
)
105 /* reimp */ QVariant
data( const QModelIndex
&index
, int role
) const
107 if ( !index
.isValid() )
110 if ( role
== Qt::CheckStateRole
) {
111 // Don't show the checkbox if the collection can't contain incidences
112 const Akonadi::Collection collection
= index
.data( Akonadi::EntityTreeModel::CollectionRole
).value
<Akonadi::Collection
>();
113 if ( collection
.isValid() && isStructuralCollection( collection
) ) {
117 return KCheckableProxyModel::data( index
, role
);
123 MainWidget::MainWidget( KXMLGUIClient
*guiClient
, QWidget
*parent
)
124 : QWidget( parent
), mAllContactsModel( 0 ), mXmlGuiClient( guiClient
)
126 mXXPortManager
= new XXPortManager( this );
129 setupActions( guiClient
->actionCollection() );
132 * The item models, proxies and views have the following structure:
137 * mContactsFilterModel
143 * | mAllContactsModel
146 * mCollectionView selectionProxyModel descendantsModel
149 * | selectionModel | |
151 * proxyModel ---------' | |
154 * mCollectionTree | |
156 * | | _______________/
158 * GlobalContactModel::instance()
161 * GlobalContactModel::instance(): The global contact model (contains collections and items)
162 * mCollectionTree: Filters out all items
163 * proxyModel: Allows the user to select collections by checkboxes
164 * selectionModel: Represents the selected collections that have been selected in
166 * mCollectionView: Shows the collections (address books) in a view
167 * selectionProxyModel: Filters out all collections and items that are no children
168 * of the collections currently selected in selectionModel
169 * mItemTree: Filters out all collections
170 * mContactsFilterModel: Filters the contacts by the content of mQuickSearchWidget
171 * mItemView: Shows the items (contacts and contact groups) in a view
173 * descendantsModel: Flattens the item/collection tree to a list
174 * mAllContactsModel: Provides a list of all available contacts from all address books
177 mCollectionTree
= new Akonadi::EntityMimeTypeFilterModel( this );
178 mCollectionTree
->setDynamicSortFilter( true );
179 mCollectionTree
->setSortCaseSensitivity( Qt::CaseInsensitive
);
180 mCollectionTree
->setSourceModel( GlobalContactModel::instance()->model() );
181 mCollectionTree
->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() );
182 mCollectionTree
->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders
);
184 mCollectionSelectionModel
= new QItemSelectionModel( mCollectionTree
);
185 StructuralCollectionsNotCheckableProxy
*checkableProxyModel
= new StructuralCollectionsNotCheckableProxy( this );
186 checkableProxyModel
->setSelectionModel( mCollectionSelectionModel
);
187 checkableProxyModel
->setSourceModel( mCollectionTree
);
189 mCollectionView
->setModel( checkableProxyModel
);
190 mCollectionView
->setXmlGuiClient( guiClient
);
191 mCollectionView
->header()->setDefaultAlignment( Qt::AlignCenter
);
192 mCollectionView
->header()->setSortIndicatorShown( false );
194 connect( mCollectionView
, SIGNAL(currentChanged(Akonadi::Collection
)),
195 mXXPortManager
, SLOT(setDefaultAddressBook(Akonadi::Collection
)) );
197 KSelectionProxyModel
*selectionProxyModel
= new KSelectionProxyModel( mCollectionSelectionModel
,
199 selectionProxyModel
->setSourceModel( GlobalContactModel::instance()->model() );
200 selectionProxyModel
->setFilterBehavior( KSelectionProxyModel::ChildrenOfExactSelection
);
202 mItemTree
= new Akonadi::EntityMimeTypeFilterModel( this );
203 mItemTree
->setSourceModel( selectionProxyModel
);
204 mItemTree
->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
205 mItemTree
->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders
);
207 mContactsFilterModel
= new Akonadi::ContactsFilterProxyModel( this );
208 mContactsFilterModel
->setSourceModel( mItemTree
);
209 connect( mQuickSearchWidget
, SIGNAL(filterStringChanged(QString
)),
210 mContactsFilterModel
, SLOT(setFilterString(QString
)) );
211 connect( mQuickSearchWidget
, SIGNAL(filterStringChanged(QString
)),
212 this, SLOT(selectFirstItem()) );
213 connect( mQuickSearchWidget
, SIGNAL(arrowDownKeyPressed()),
214 mItemView
, SLOT(setFocus()) );
216 mItemView
->setModel( mContactsFilterModel
);
217 mItemView
->setXmlGuiClient( guiClient
);
218 mItemView
->setSelectionMode( QAbstractItemView::ExtendedSelection
);
219 mItemView
->setRootIsDecorated( false );
220 mItemView
->header()->setDefaultAlignment( Qt::AlignCenter
);
222 mXXPortManager
->setSelectionModel( mItemView
->selectionModel() );
224 mActionManager
= new Akonadi::StandardContactActionManager( guiClient
->actionCollection(), this );
225 mActionManager
->setCollectionSelectionModel( mCollectionView
->selectionModel() );
226 mActionManager
->setItemSelectionModel( mItemView
->selectionModel() );
227 mActionManager
->createAllActions();
229 connect( mItemView
, SIGNAL(currentChanged(Akonadi::Item
)),
230 this, SLOT(itemSelected(Akonadi::Item
)) );
231 connect( mItemView
, SIGNAL(doubleClicked(Akonadi::Item
)),
232 mActionManager
->action( Akonadi::StandardContactActionManager::EditItem
), SLOT(trigger()) );
233 connect( mItemView
->selectionModel(), SIGNAL(currentChanged(QModelIndex
,QModelIndex
)),
234 this, SLOT(itemSelectionChanged(QModelIndex
,QModelIndex
)) );
236 // show the contact details view as default
237 mDetailsViewStack
->setCurrentWidget( mContactDetails
);
239 mContactSwitcher
->setView( mItemView
);
241 Akonadi::Control::widgetNeedsAkonadi( this );
243 mModelColumnManager
= new ModelColumnManager( GlobalContactModel::instance()->model(), this );
244 mModelColumnManager
->setWidget( mItemView
->header() );
245 mModelColumnManager
->load();
247 QMetaObject::invokeMethod( this, "delayedInit", Qt::QueuedConnection
);
250 void MainWidget::delayedInit()
252 // restore previous state
254 const KConfigGroup
group( Settings::self()->config(), "UiState_MainWidgetSplitter" );
255 KPIM::UiStateSaver::restoreState( mMainWidgetSplitter
, group
);
258 const KConfigGroup
group( Settings::self()->config(), "UiState_ContactView" );
259 KPIM::UiStateSaver::restoreState( mItemView
, group
);
262 mXmlGuiClient
->actionCollection()->action( "options_show_simplegui" )->setChecked( Settings::self()->useSimpleMode() );
263 #if defined(HAVE_PRISON)
264 mXmlGuiClient
->actionCollection()->action( "options_show_qrcodes" )->setChecked( showQRCodes() );
267 connect( GlobalContactModel::instance()->model(), SIGNAL(modelAboutToBeReset()), SLOT(saveState()) );
268 connect( GlobalContactModel::instance()->model(), SIGNAL(modelReset()), SLOT(restoreState()) );
269 connect( kapp
, SIGNAL(aboutToQuit()), SLOT(saveState()) );
274 MainWidget::~MainWidget()
276 mModelColumnManager
->store();
279 if ( !Settings::self()->useSimpleMode() ) {
280 // Do not save the splitter values when in simple mode, because we can't
281 // restore them correctly when switching back to normal mode
283 KConfigGroup
group( Settings::self()->config(), "UiState_MainWidgetSplitter" );
284 KPIM::UiStateSaver::saveState( mMainWidgetSplitter
, group
);
288 KConfigGroup
group( Settings::self()->config(), "UiState_ContactView" );
289 KPIM::UiStateSaver::saveState( mItemView
, group
);
294 Settings::self()->writeConfig();
297 void MainWidget::restoreState()
301 Akonadi::ETMViewStateSaver
*saver
= new Akonadi::ETMViewStateSaver
;
302 saver
->setView( mCollectionView
);
304 const KConfigGroup
group( Settings::self()->config(), "CollectionViewState" );
305 saver
->restoreState( group
);
310 Akonadi::ETMViewStateSaver
*saver
= new Akonadi::ETMViewStateSaver
;
311 saver
->setSelectionModel( mCollectionSelectionModel
);
313 const KConfigGroup
group( Settings::self()->config(), "CollectionViewCheckState" );
314 saver
->restoreState( group
);
319 Akonadi::ETMViewStateSaver
*saver
= new Akonadi::ETMViewStateSaver
;
320 saver
->setView( mItemView
);
321 saver
->setSelectionModel( mItemView
->selectionModel() );
323 const KConfigGroup
group( Settings::self()->config(), "ItemViewState" );
324 saver
->restoreState( group
);
328 void MainWidget::saveState()
332 Akonadi::ETMViewStateSaver saver
;
333 saver
.setView( mCollectionView
);
335 KConfigGroup
group( Settings::self()->config(), "CollectionViewState" );
336 saver
.saveState( group
);
342 Akonadi::ETMViewStateSaver saver
;
343 saver
.setSelectionModel( mCollectionSelectionModel
);
345 KConfigGroup
group( Settings::self()->config(), "CollectionViewCheckState" );
346 saver
.saveState( group
);
352 Akonadi::ETMViewStateSaver saver
;
353 saver
.setView( mItemView
);
354 saver
.setSelectionModel( mItemView
->selectionModel() );
356 KConfigGroup
group( Settings::self()->config(), "ItemViewState" );
357 saver
.saveState( group
);
362 void MainWidget::setupGui()
364 // the horizontal main layout
365 QHBoxLayout
*layout
= new QHBoxLayout( this );
366 layout
->setMargin( 0 );
368 // The splitter that contains the three main parts of the gui
369 // - collection view on the left
370 // - item view in the middle
371 // - details pane on the right, that contains
372 // - details view stack on the top
373 // - contact switcher at the bottom
374 mMainWidgetSplitter
= new QSplitter
;
375 mMainWidgetSplitter
->setObjectName( "MainWidgetSplitter" );
377 layout
->addWidget( mMainWidgetSplitter
);
379 // the collection view
380 mCollectionView
= new Akonadi::EntityTreeView();
381 mMainWidgetSplitter
->addWidget( mCollectionView
);
384 mItemView
= new Akonadi::EntityTreeView();
385 mItemView
->setObjectName( "ContactView" );
386 mMainWidgetSplitter
->addWidget( mItemView
);
388 // the details pane that contains the details view stack and contact switcher
389 mDetailsPane
= new QWidget
;
390 mMainWidgetSplitter
->addWidget( mDetailsPane
);
392 QVBoxLayout
*detailsPaneLayout
= new QVBoxLayout( mDetailsPane
);
393 detailsPaneLayout
->setMargin( 0 );
395 // the details view stack
396 mDetailsViewStack
= new QStackedWidget();
397 detailsPaneLayout
->addWidget( mDetailsViewStack
);
399 // the details widget for contacts
400 mContactDetails
= new Akonadi::ContactViewer( mDetailsViewStack
);
401 mDetailsViewStack
->addWidget( mContactDetails
);
403 // the details widget for contact groups
404 mContactGroupDetails
= new Akonadi::ContactGroupViewer( mDetailsViewStack
);
405 mDetailsViewStack
->addWidget( mContactGroupDetails
);
407 // the details widget for empty items
408 mEmptyDetails
= new KTextBrowser( mDetailsViewStack
);
409 mDetailsViewStack
->addWidget( mEmptyDetails
);
411 // the contact switcher for the simple gui mode
412 mContactSwitcher
= new ContactSwitcher
;
413 detailsPaneLayout
->addWidget( mContactSwitcher
);
414 mContactSwitcher
->setVisible( false );
416 // the quick search widget which is embedded in the toolbar action
417 mQuickSearchWidget
= new QuickSearchWidget
;
419 // setup the default actions
420 Akonadi::ContactDefaultActions
*actions
= new Akonadi::ContactDefaultActions( this );
421 actions
->connectToView( mContactDetails
);
422 actions
->connectToView( mContactGroupDetails
);
424 #if 0 // disabled because Grantlee supports no i18n for KDE 4.6 yet
425 Akonadi::GrantleeContactFormatter
*formatter
=
426 new Akonadi::GrantleeContactFormatter( KStandardDirs::locate( "data", QLatin1String( "kaddressbook/viewertemplates/" ) ) );
428 mContactDetails
->setContactFormatter( formatter
);
430 Akonadi::GrantleeContactGroupFormatter
*groupFormatter
=
431 new Akonadi::GrantleeContactGroupFormatter( KStandardDirs::locate( "data", QLatin1String( "kaddressbook/viewertemplates/" ) ) );
433 mContactGroupDetails
->setContactGroupFormatter( groupFormatter
);
437 void MainWidget::setupActions( KActionCollection
*collection
)
440 KToggleAction
*toggleAction
= 0;
442 action
= KStandardAction::print( this, SLOT(print()), collection
);
443 action
->setWhatsThis( i18n( "Print the complete address book or a selected number of contacts." ) );
445 action
= collection
->addAction( "quick_search" );
446 action
->setText( i18n( "Quick search" ) );
447 action
->setDefaultWidget( mQuickSearchWidget
);
449 action
= collection
->addAction( "select_all" );
450 action
->setText( i18n( "Select All" ) );
451 action
->setShortcut( QKeySequence( Qt::CTRL
+ Qt::Key_A
) );
452 action
->setWhatsThis( i18n( "Select all contacts in the current address book view." ) );
453 connect( action
, SIGNAL(triggered(bool)), mItemView
, SLOT(selectAll()) );
455 toggleAction
= collection
->add
<KToggleAction
>( "options_show_simplegui" );
456 toggleAction
->setText( i18n( "Show Simple View" ) );
457 toggleAction
->setWhatsThis( i18n( "Show a simple mode of the address book view." ) );
458 connect( toggleAction
, SIGNAL(toggled(bool)), SLOT(setSimpleGuiMode(bool)) );
460 #if defined(HAVE_PRISON)
461 KToggleAction
*qrtoggleAction
;
462 qrtoggleAction
= collection
->add
<KToggleAction
>( "options_show_qrcodes" );
463 qrtoggleAction
->setText( i18n( "Show QR Codes" ) );
464 qrtoggleAction
->setWhatsThis( i18n( "Show QR Codes in the contact." ) );
465 connect( qrtoggleAction
, SIGNAL(toggled(bool)), SLOT(setQRCodeShow(bool)) );
469 action
= collection
->addAction( "file_import_vcard" );
470 action
->setText( i18n( "Import vCard..." ) );
471 action
->setWhatsThis( i18n( "Import contacts from a vCard file." ) );
472 mXXPortManager
->addImportAction( action
, "vcard30" );
474 action
= collection
->addAction( "file_import_csv" );
475 action
->setText( i18n( "Import CSV file..." ) );
476 action
->setWhatsThis( i18n( "Import contacts from a file in comma separated value format." ) );
477 mXXPortManager
->addImportAction( action
, "csv" );
479 action
= collection
->addAction( "file_import_ldif" );
480 action
->setText( i18n( "Import LDIF file..." ) );
481 action
->setWhatsThis( i18n( "Import contacts from an LDIF file." ) );
482 mXXPortManager
->addImportAction( action
, "ldif" );
484 action
= collection
->addAction( "file_import_ldap" );
485 action
->setText( i18n( "Import from LDAP server..." ) );
486 action
->setWhatsThis( i18n( "Import contacts from an LDAP server." ) );
487 mXXPortManager
->addImportAction( action
, "ldap" );
489 action
= collection
->addAction( "file_import_gmx" );
490 action
->setText( i18n( "Import GMX file..." ) );
491 action
->setWhatsThis( i18n( "Import contacts from a GMX address book file." ) );
492 mXXPortManager
->addImportAction( action
, "gmx" );
496 action
= collection
->addAction( "file_export_vcard30" );
497 action
->setText( i18n( "Export vCard 3.0..." ) );
498 action
->setWhatsThis( i18n( "Export contacts to a vCard 3.0 file." ) );
499 mXXPortManager
->addExportAction( action
, "vcard30" );
501 action
= collection
->addAction( "file_export_vcard21" );
502 action
->setText( i18n( "Export vCard 2.1..." ) );
503 action
->setWhatsThis( i18n( "Export contacts to a vCard 2.1 file." ) );
504 mXXPortManager
->addExportAction( action
, "vcard21" );
506 action
= collection
->addAction( "file_export_csv" );
507 action
->setText( i18n( "Export CSV file..." ) );
508 action
->setWhatsThis( i18n( "Export contacts to a file in comma separated value format." ) );
509 mXXPortManager
->addExportAction( action
, "csv" );
511 action
= collection
->addAction( "file_export_ldif" );
512 action
->setText( i18n( "Export LDIF file..." ) );
513 action
->setWhatsThis( i18n( "Export contacts to an LDIF file." ) );
514 mXXPortManager
->addExportAction( action
, "ldif" );
516 action
= collection
->addAction( "file_export_gmx" );
517 action
->setText( i18n( "Export GMX file..." ) );
518 action
->setWhatsThis( i18n( "Export contacts to a GMX address book file." ) );
519 mXXPortManager
->addExportAction( action
, "gmx" );
522 void MainWidget::print()
525 printer
.setDocName( i18n( "Address Book" ) );
526 printer
.setOutputFileName( "addressbook.pdf" );
527 printer
.setOutputFormat( QPrinter::PdfFormat
);
528 printer
.setCollateCopies( true );
530 QPrintDialog
printDialog( &printer
, this );
531 printDialog
.setWindowTitle( i18n( "Print Contacts" ) );
532 if ( !printDialog
.exec() ) //krazy:exclude=crashy
535 KABPrinting::PrintingWizard
wizard( &printer
, mItemView
->selectionModel(), this );
536 wizard
.setDefaultAddressBook( currentAddressBook() );
541 void MainWidget::newContact()
543 mActionManager
->action( Akonadi::StandardContactActionManager::CreateContact
)->trigger();
546 void MainWidget::newGroup()
548 mActionManager
->action( Akonadi::StandardContactActionManager::CreateContactGroup
)->trigger();
552 * Depending on the mime type of the selected item, this method
553 * brings up the right view on the detail view stack and sets the
554 * selected item on it.
556 void MainWidget::itemSelected( const Akonadi::Item
&item
)
558 if ( Akonadi::MimeTypeChecker::isWantedItem( item
, KABC::Addressee::mimeType() ) ) {
559 mDetailsViewStack
->setCurrentWidget( mContactDetails
);
560 mContactDetails
->setContact( item
);
561 } else if ( Akonadi::MimeTypeChecker::isWantedItem( item
, KABC::ContactGroup::mimeType() ) ) {
562 mDetailsViewStack
->setCurrentWidget( mContactGroupDetails
);
563 mContactGroupDetails
->setContactGroup( item
);
568 * Catch when the selection has gone ( e.g. an empty address book has been selected )
569 * clear the details view in this case.
571 void MainWidget::itemSelectionChanged( const QModelIndex
¤t
, const QModelIndex
& )
573 if ( !current
.isValid() )
574 mDetailsViewStack
->setCurrentWidget( mEmptyDetails
);
577 void MainWidget::selectFirstItem()
579 // Whenever the quick search has changed, we select the first item
580 // in the item view, so that the detailsview is updated
581 if ( mItemView
&& mItemView
->selectionModel() ) {
582 mItemView
->selectionModel()->setCurrentIndex( mItemView
->model()->index( 0, 0 ),
583 QItemSelectionModel::Rows
|
584 QItemSelectionModel::ClearAndSelect
);
588 void MainWidget::setSimpleGuiMode( bool on
)
590 mCollectionView
->setVisible( !on
);
591 mItemView
->setVisible( !on
);
592 mDetailsPane
->setVisible( true );
593 mContactSwitcher
->setVisible( on
);
595 if ( mItemView
->model() ) {
596 mItemView
->setCurrentIndex( mItemView
->model()->index( 0, 0 ) );
599 Settings::self()->setUseSimpleMode( on
);
602 bool MainWidget::showQRCodes()
604 #if defined(HAVE_PRISON)
605 KConfig
config( QLatin1String( "akonadi_contactrc" ) );
606 KConfigGroup
group( &config
, QLatin1String( "View" ) );
607 return group
.readEntry( "QRCodes", true );
613 void MainWidget::setQRCodeShow( bool on
)
615 #if defined(HAVE_PRISON)
616 // must write the configuration setting first before updating the view.
617 KConfig
config( QLatin1String( "akonadi_contactrc" ) );
618 KConfigGroup
group( &config
, QLatin1String( "View" ) );
619 group
.writeEntry( "QRCodes", on
);
621 if ( mItemView
->model() ) {
622 mItemView
->setCurrentIndex( mItemView
->model()->index( 0, 0 ) );
627 Akonadi::Collection
MainWidget::currentAddressBook() const
629 if ( mCollectionView
->selectionModel() && mCollectionView
->selectionModel()->hasSelection() ) {
630 const QModelIndex index
= mCollectionView
->selectionModel()->selectedIndexes().first();
631 const Akonadi::Collection collection
= index
.data( Akonadi::EntityTreeModel::CollectionRole
)
632 .value
<Akonadi::Collection
>();
637 return Akonadi::Collection();
640 QAbstractItemModel
* MainWidget::allContactsModel()
642 if ( !mAllContactsModel
) {
643 KDescendantsProxyModel
*descendantsModel
= new KDescendantsProxyModel( this );
644 descendantsModel
->setSourceModel( GlobalContactModel::instance()->model() );
646 mAllContactsModel
= new Akonadi::EntityMimeTypeFilterModel( this );
647 mAllContactsModel
->setSourceModel( descendantsModel
);
648 mAllContactsModel
->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
649 mAllContactsModel
->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders
);
652 return mAllContactsModel
;
655 #include "mainwidget.moc"