Fix assert when Mail-Followup-To contains two emails, as Ossi's Mutt does
[kdepim.git] / kaddressbook / mainwidget.cpp
blob98d4720114d127214194d96669f57e5a12fa3684
1 /*
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"
28 #include "settings.h"
29 #include "xxportmanager.h"
31 #ifdef GRANTLEE_FOUND
32 #include "grantleecontactformatter.h"
33 #include "grantleecontactgroupformatter.h"
34 #endif
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>
59 #include <kaction.h>
60 #include <kactioncollection.h>
61 #include <kapplication.h>
62 #include <kcheckableproxymodel.h>
63 #include <kdescendantsproxymodel.h>
64 #include <kicon.h>
65 #include <klineedit.h>
66 #include <klocale.h>
67 #include <kselectionproxymodel.h>
68 #include <kstandarddirs.h>
69 #include <ktextbrowser.h>
70 #include <ktoggleaction.h>
71 #include <ktoolbar.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>
86 namespace {
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 ) )
94 return false;
96 return true;
99 class StructuralCollectionsNotCheckableProxy : public KCheckableProxyModel {
100 public:
101 StructuralCollectionsNotCheckableProxy(QObject* parent)
102 : KCheckableProxyModel(parent)
105 /* reimp */ QVariant data( const QModelIndex &index, int role ) const
107 if ( !index.isValid() )
108 return QVariant();
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 ) ) {
114 return QVariant();
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 );
128 setupGui();
129 setupActions( guiClient->actionCollection() );
132 * The item models, proxies and views have the following structure:
134 * mItemView
137 * mContactsFilterModel
140 * mItemTree
143 * | mAllContactsModel
144 * | ^
145 * | |
146 * mCollectionView selectionProxyModel descendantsModel
147 * ^ ^ ^ ^
148 * | | | |
149 * | selectionModel | |
150 * | | | |
151 * proxyModel ---------' | |
152 * ^ | |
153 * | | |
154 * mCollectionTree | |
155 * ^ | |
156 * | | _______________/
157 * \ / /
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
165 * proxyModel
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,
198 this );
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() );
265 #endif
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()) );
271 restoreState();
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 );
292 saveState();
294 Settings::self()->writeConfig();
297 void MainWidget::restoreState()
299 // collection view
301 Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
302 saver->setView( mCollectionView );
304 const KConfigGroup group( Settings::self()->config(), "CollectionViewState" );
305 saver->restoreState( group );
308 // collection view
310 Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
311 saver->setSelectionModel( mCollectionSelectionModel );
313 const KConfigGroup group( Settings::self()->config(), "CollectionViewCheckState" );
314 saver->restoreState( group );
317 // item view
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()
330 // collection view
332 Akonadi::ETMViewStateSaver saver;
333 saver.setView( mCollectionView );
335 KConfigGroup group( Settings::self()->config(), "CollectionViewState" );
336 saver.saveState( group );
337 group.sync();
340 // collection view
342 Akonadi::ETMViewStateSaver saver;
343 saver.setSelectionModel( mCollectionSelectionModel );
345 KConfigGroup group( Settings::self()->config(), "CollectionViewCheckState" );
346 saver.saveState( group );
347 group.sync();
350 // item view
352 Akonadi::ETMViewStateSaver saver;
353 saver.setView( mItemView );
354 saver.setSelectionModel( mItemView->selectionModel() );
356 KConfigGroup group( Settings::self()->config(), "ItemViewState" );
357 saver.saveState( group );
358 group.sync();
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 );
383 // the items view
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 );
434 #endif
437 void MainWidget::setupActions( KActionCollection *collection )
439 KAction *action = 0;
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)) );
466 #endif
468 // import actions
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" );
495 // export actions
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()
524 QPrinter printer;
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
533 return;
535 KABPrinting::PrintingWizard wizard( &printer, mItemView->selectionModel(), this );
536 wizard.setDefaultAddressBook( currentAddressBook() );
538 wizard.exec();
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 &current, 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 );
608 #else
609 return true;
610 #endif
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 ) );
624 #endif
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>();
634 return 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"