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 "kdescendantsproxymodel_p.h"
26 #include "modelcolumnmanager.h"
27 #include "printing/printingwizard.h"
28 #include "quicksearchwidget.h"
30 #include "standardcontactactionmanager.h"
31 #include "xxportmanager.h"
33 #include <akonadi/akonadi_next/collectionselectionproxymodel.h>
34 #include <akonadi/akonadi_next/etmstatesaver.h>
35 #include <akonadi/collectionfilterproxymodel.h>
36 #include <akonadi/collectionmodel.h>
37 #include <akonadi/contact/contactdefaultactions.h>
38 #include <akonadi/contact/contacteditordialog.h>
39 #include <akonadi/contact/contactgroupeditordialog.h>
40 #include <akonadi/contact/contactgroupviewer.h>
41 #include <akonadi/contact/contactsfilterproxymodel.h>
42 #include <akonadi/contact/contactstreemodel.h>
43 #include <akonadi/contact/contactviewer.h>
44 #include <akonadi/control.h>
45 #include <akonadi/entitymimetypefiltermodel.h>
46 #include <akonadi/entitytreeview.h>
47 #include <akonadi/entitytreeviewstatesaver.h>
48 #include <akonadi/itemview.h>
49 #include <akonadi/mimetypechecker.h>
52 #include <kactioncollection.h>
53 #include <kabc/addressee.h>
54 #include <kabc/contactgroup.h>
55 #include <kapplication.h>
57 #include <klineedit.h>
59 #include <kselectionproxymodel.h>
60 #include <ktextbrowser.h>
61 #include <ktoggleaction.h>
63 #include <kxmlguiwindow.h>
64 #include <libkdepim/uistatesaver.h>
66 #include <QtGui/QAction>
67 #include <QtGui/QHBoxLayout>
68 #include <QtGui/QHeaderView>
69 #include <QtGui/QListView>
70 #include <QtGui/QPrinter>
71 #include <QtGui/QPrintDialog>
72 #include <QtGui/QSortFilterProxyModel>
73 #include <QtGui/QSplitter>
74 #include <QtGui/QStackedWidget>
76 MainWidget::MainWidget( KXMLGUIClient
*guiClient
, QWidget
*parent
)
77 : QWidget( parent
), mAllContactsModel( 0 )
79 mXXPortManager
= new XXPortManager( this );
82 setupActions( guiClient
->actionCollection() );
85 * The item models, proxies and views have the following structure:
90 * mContactsFilterModel
99 * mCollectionView selectionProxyModel descendantsModel
102 * | selectionModel | |
104 * proxyModel ---------' | |
107 * mCollectionTree | |
109 * | | _______________/
111 * GlobalContactModel::instance()
114 * GlobalContactModel::instance(): The global contact model (contains collections and items)
115 * mCollectionTree: Filters out all items
116 * proxyModel: Allows the user to select collections by checkboxes
117 * selectionModel: Represents the selected collections that have been selected in
119 * mCollectionView: Shows the collections (address books) in a view
120 * selectionProxyModel: Filters out all collections and items that are no children
121 * of the collections currently selected in selectionModel
122 * mItemTree: Filters out all collections
123 * mContactsFilterModel: Filters the contacts by the content of mQuickSearchWidget
124 * mItemView: Shows the items (contacts and contact groups) in a view
126 * descendantsModel: Flattens the item/collection tree to a list
127 * mAllContactsModel: Provides a list of all available contacts from all address books
130 mCollectionTree
= new Akonadi::EntityMimeTypeFilterModel( this );
131 mCollectionTree
->setSourceModel( GlobalContactModel::instance()->model() );
132 mCollectionTree
->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() );
133 mCollectionTree
->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders
);
135 Akonadi::CollectionSelectionProxyModel
*proxyModel
= new Akonadi::CollectionSelectionProxyModel( this );
136 proxyModel
->setDynamicSortFilter( true );
137 proxyModel
->setSortCaseSensitivity( Qt::CaseInsensitive
);
139 mCollectionSelectionModel
= new QItemSelectionModel( proxyModel
);
140 proxyModel
->setSelectionModel( mCollectionSelectionModel
);
141 proxyModel
->setSourceModel( mCollectionTree
);
143 mXXPortManager
->setItemModel( allContactsModel() );
145 mCollectionView
->setModel( proxyModel
);
146 mCollectionView
->setXmlGuiClient( guiClient
);
147 mCollectionView
->header()->setDefaultAlignment( Qt::AlignCenter
);
148 mCollectionView
->header()->setSortIndicatorShown( false );
150 connect( mCollectionView
, SIGNAL( currentChanged( const Akonadi::Collection
& ) ),
151 mXXPortManager
, SLOT( setDefaultAddressBook( const Akonadi::Collection
& ) ) );
153 KSelectionProxyModel
*selectionProxyModel
= new KSelectionProxyModel( mCollectionSelectionModel
,
155 selectionProxyModel
->setSourceModel( GlobalContactModel::instance()->model() );
156 selectionProxyModel
->setFilterBehavior( KSelectionProxyModel::ChildrenOfExactSelection
);
158 mItemTree
= new Akonadi::EntityMimeTypeFilterModel( this );
159 mItemTree
->setSourceModel( selectionProxyModel
);
160 mItemTree
->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
161 mItemTree
->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders
);
163 mContactsFilterModel
= new Akonadi::ContactsFilterProxyModel( this );
164 mContactsFilterModel
->setSourceModel( mItemTree
);
165 connect( mQuickSearchWidget
, SIGNAL( filterStringChanged( const QString
& ) ),
166 mContactsFilterModel
, SLOT( setFilterString( const QString
& ) ) );
167 connect( mQuickSearchWidget
, SIGNAL( filterStringChanged( const QString
& ) ),
168 this, SLOT( selectFirstItem() ) );
169 connect( mQuickSearchWidget
, SIGNAL( arrowDownKeyPressed() ),
170 mItemView
, SLOT( setFocus() ) );
172 mItemView
->setModel( mContactsFilterModel
);
173 mItemView
->setXmlGuiClient( guiClient
);
174 mItemView
->setSelectionMode( QAbstractItemView::ExtendedSelection
);
175 mItemView
->setRootIsDecorated( false );
176 mItemView
->header()->setDefaultAlignment( Qt::AlignCenter
);
178 mXXPortManager
->setSelectionModel( mItemView
->selectionModel() );
180 connect( mItemView
, SIGNAL( currentChanged( const Akonadi::Item
& ) ),
181 this, SLOT( itemSelected( const Akonadi::Item
& ) ) );
182 connect( mItemView
, SIGNAL( doubleClicked( const Akonadi::Item
& ) ),
183 this, SLOT( editItem( const Akonadi::Item
& ) ) );
184 connect( mItemView
->selectionModel(), SIGNAL( currentChanged( const QModelIndex
&, const QModelIndex
& ) ),
185 this, SLOT( itemSelectionChanged( const QModelIndex
&, const QModelIndex
& ) ) );
187 // show the contact details view as default
188 mDetailsViewStack
->setCurrentWidget( mContactDetails
);
190 mContactSwitcher
->setView( mItemView
);
192 Akonadi::Control::widgetNeedsAkonadi( this );
194 mActionManager
= new Akonadi::StandardContactActionManager( guiClient
->actionCollection(), this );
195 mActionManager
->setCollectionSelectionModel( mCollectionView
->selectionModel() );
196 mActionManager
->setItemSelectionModel( mItemView
->selectionModel() );
198 mActionManager
->createAllActions();
200 connect( mActionManager
->action( Akonadi::StandardContactActionManager::CreateContact
), SIGNAL( triggered( bool ) ),
201 this, SLOT( newContact() ) );
202 connect( mActionManager
->action( Akonadi::StandardContactActionManager::CreateContactGroup
), SIGNAL( triggered( bool ) ),
203 this, SLOT( newGroup() ) );
204 connect( mActionManager
, SIGNAL( editItem( const Akonadi::Item
& ) ),
205 this, SLOT( editItem( const Akonadi::Item
& ) ) );
207 mModelColumnManager
= new ModelColumnManager( GlobalContactModel::instance()->model(), this );
208 mModelColumnManager
->setWidget( mItemView
->header() );
209 mModelColumnManager
->load();
211 // restore previous state
213 const KConfigGroup
group( Settings::self()->config(), "UiState_MainWidgetSplitter" );
214 KPIM::UiStateSaver::restoreState( mMainWidgetSplitter
, group
);
217 const KConfigGroup
group( Settings::self()->config(), "UiState_ContactView" );
218 KPIM::UiStateSaver::restoreState( mItemView
, group
);
221 guiClient
->actionCollection()->action( "options_show_simplegui" )->setChecked( Settings::self()->useSimpleMode() );
223 connect( GlobalContactModel::instance()->model(), SIGNAL( modelAboutToBeReset() ), SLOT( saveState() ) );
224 connect( GlobalContactModel::instance()->model(), SIGNAL( modelReset() ), SLOT( restoreState() ) );
225 connect( kapp
, SIGNAL( aboutToQuit() ), SLOT( saveState() ) );
230 MainWidget::~MainWidget()
232 mModelColumnManager
->store();
235 if ( !Settings::self()->useSimpleMode() ) {
236 // Do not save the splitter values when in simple mode, because we can't
237 // restore them correctly when switching back to normal mode
239 KConfigGroup
group( Settings::self()->config(), "UiState_MainWidgetSplitter" );
240 KPIM::UiStateSaver::saveState( mMainWidgetSplitter
, group
);
244 KConfigGroup
group( Settings::self()->config(), "UiState_ContactView" );
245 KPIM::UiStateSaver::saveState( mItemView
, group
);
250 Settings::self()->writeConfig();
253 void MainWidget::restoreState()
257 ETMStateSaver
*saver
= new ETMStateSaver
;
258 saver
->setTreeView( mCollectionView
);
260 const KConfigGroup
group( Settings::self()->config(), "CollectionViewState" );
261 saver
->restoreState( group
);
266 ETMStateSaver
*saver
= new ETMStateSaver
;
267 saver
->setSelectionModel( mCollectionSelectionModel
);
269 const KConfigGroup
group( Settings::self()->config(), "CollectionViewCheckState" );
270 saver
->restoreState( group
);
275 ETMStateSaver
*saver
= new ETMStateSaver
;
276 saver
->setTreeView( mItemView
);
277 saver
->setSelectionModel( mItemView
->selectionModel() );
279 const KConfigGroup
group( Settings::self()->config(), "ItemViewState" );
280 saver
->restoreState( group
);
284 void MainWidget::saveState()
289 saver
.setTreeView( mCollectionView
);
291 KConfigGroup
group( Settings::self()->config(), "CollectionViewState" );
292 saver
.saveState( group
);
299 saver
.setSelectionModel( mCollectionSelectionModel
);
301 KConfigGroup
group( Settings::self()->config(), "CollectionViewCheckState" );
302 saver
.saveState( group
);
309 saver
.setTreeView( mItemView
);
310 saver
.setSelectionModel( mItemView
->selectionModel() );
312 KConfigGroup
group( Settings::self()->config(), "ItemViewState" );
313 saver
.saveState( group
);
318 void MainWidget::setupGui()
320 // the horizontal main layout
321 QHBoxLayout
*layout
= new QHBoxLayout( this );
323 // The splitter that contains the three main parts of the gui
324 // - collection view on the left
325 // - item view in the middle
326 // - details pane on the right, that contains
327 // - details view stack on the top
328 // - contact switcher at the bottom
329 mMainWidgetSplitter
= new QSplitter
;
330 mMainWidgetSplitter
->setObjectName( "MainWidgetSplitter" );
332 layout
->addWidget( mMainWidgetSplitter
);
334 // the collection view
335 mCollectionView
= new Akonadi::EntityTreeView();
336 mMainWidgetSplitter
->addWidget( mCollectionView
);
339 mItemView
= new Akonadi::EntityTreeView();
340 mItemView
->setObjectName( "ContactView" );
341 mMainWidgetSplitter
->addWidget( mItemView
);
343 // the details pane that contains the details view stack and contact switcher
344 mDetailsPane
= new QWidget
;
345 mMainWidgetSplitter
->addWidget( mDetailsPane
);
347 QVBoxLayout
*detailsPaneLayout
= new QVBoxLayout( mDetailsPane
);
348 detailsPaneLayout
->setMargin( 0 );
350 // the details view stack
351 mDetailsViewStack
= new QStackedWidget();
352 detailsPaneLayout
->addWidget( mDetailsViewStack
);
354 // the details widget for contacts
355 mContactDetails
= new Akonadi::ContactViewer( mDetailsViewStack
);
356 mDetailsViewStack
->addWidget( mContactDetails
);
358 // the details widget for contact groups
359 mContactGroupDetails
= new Akonadi::ContactGroupViewer( mDetailsViewStack
);
360 mDetailsViewStack
->addWidget( mContactGroupDetails
);
362 // the details widget for empty items
363 mEmptyDetails
= new KTextBrowser( mDetailsViewStack
);
364 mDetailsViewStack
->addWidget( mEmptyDetails
);
366 // the contact switcher for the simple gui mode
367 mContactSwitcher
= new ContactSwitcher
;
368 detailsPaneLayout
->addWidget( mContactSwitcher
);
369 mContactSwitcher
->setVisible( false );
371 // the quick search widget which is embedded in the toolbar action
372 mQuickSearchWidget
= new QuickSearchWidget
;
374 // setup the default actions
375 Akonadi::ContactDefaultActions
*actions
= new Akonadi::ContactDefaultActions( this );
376 actions
->connectToView( mContactDetails
);
377 actions
->connectToView( mContactGroupDetails
);
380 void MainWidget::setupActions( KActionCollection
*collection
)
383 KToggleAction
*toggleAction
= 0;
385 action
= KStandardAction::print( this, SLOT( print() ), collection
);
386 action
->setWhatsThis( i18n( "Print the complete address book or a selected number of contacts." ) );
388 action
= collection
->addAction( "quick_search" );
389 action
->setText( i18n( "Quick search" ) );
390 action
->setDefaultWidget( mQuickSearchWidget
);
392 action
= collection
->addAction( "select_all" );
393 action
->setText( i18n( "Select All" ) );
394 action
->setShortcut( QKeySequence( Qt::CTRL
+ Qt::Key_A
) );
395 action
->setWhatsThis( i18n( "Select all contacts in the current address book view." ) );
396 connect( action
, SIGNAL( triggered( bool ) ), mItemView
, SLOT( selectAll() ) );
398 toggleAction
= collection
->add
<KToggleAction
>( "options_show_collectionview" );
399 toggleAction
->setText( i18n( "Show Address Books View" ) );
400 toggleAction
->setWhatsThis( i18n( "Toggle whether the address books view shall be visible." ) );
401 toggleAction
->setCheckedState( KGuiItem( i18n( "Hide Address Books View" ) ) );
402 toggleAction
->setChecked( true );
403 connect( toggleAction
, SIGNAL( toggled( bool ) ), SLOT( setCollectionViewVisible( bool ) ) );
405 toggleAction
= collection
->add
<KToggleAction
>( "options_show_itemview" );
406 toggleAction
->setText( i18n( "Show Contacts View" ) );
407 toggleAction
->setWhatsThis( i18n( "Toggle whether the contacts view shall be visible." ) );
408 toggleAction
->setCheckedState( KGuiItem( i18n( "Hide Contacts View" ) ) );
409 toggleAction
->setChecked( true );
410 connect( toggleAction
, SIGNAL( toggled( bool ) ), SLOT( setItemViewVisible( bool ) ) );
412 toggleAction
= collection
->add
<KToggleAction
>( "options_show_detailsview" );
413 toggleAction
->setText( i18n( "Show Details View" ) );
414 toggleAction
->setWhatsThis( i18n( "Toggle whether the details view shall be visible." ) );
415 toggleAction
->setCheckedState( KGuiItem( i18n( "Hide Details View" ) ) );
416 toggleAction
->setChecked( true );
417 connect( toggleAction
, SIGNAL( toggled( bool ) ), SLOT( setDetailsViewVisible( bool ) ) );
419 toggleAction
= collection
->add
<KToggleAction
>( "options_show_simplegui" );
420 toggleAction
->setText( i18n( "Show Simple View" ) );
421 action
->setWhatsThis( i18n( "Show a simple mode of the address book view." ) );
422 connect( toggleAction
, SIGNAL( toggled( bool ) ), SLOT( setSimpleGuiMode( bool ) ) );
425 action
= collection
->addAction( "file_import_vcard" );
426 action
->setText( i18n( "Import vCard..." ) );
427 action
->setWhatsThis( i18n( "Import contacts from a vCard file." ) );
428 mXXPortManager
->addImportAction( action
, "vcard30" );
430 action
= collection
->addAction( "file_import_csv" );
431 action
->setText( i18n( "Import CSV file..." ) );
432 action
->setWhatsThis( i18n( "Import contacts from a file in comma separated value format." ) );
433 mXXPortManager
->addImportAction( action
, "csv" );
435 action
= collection
->addAction( "file_import_ldif" );
436 action
->setText( i18n( "Import LDIF file..." ) );
437 action
->setWhatsThis( i18n( "Import contacts from an LDIF file." ) );
438 mXXPortManager
->addImportAction( action
, "ldif" );
440 action
= collection
->addAction( "file_import_ldap" );
441 action
->setText( i18n( "Import from LDAP server..." ) );
442 action
->setWhatsThis( i18n( "Import contacts from an LDAP server." ) );
443 mXXPortManager
->addImportAction( action
, "ldap" );
445 action
= collection
->addAction( "file_import_gmx" );
446 action
->setText( i18n( "Import GMX file..." ) );
447 action
->setWhatsThis( i18n( "Import contacts from a GMX address book file." ) );
448 mXXPortManager
->addImportAction( action
, "gmx" );
452 action
= collection
->addAction( "file_export_vcard30" );
453 action
->setText( i18n( "Export vCard 3.0..." ) );
454 action
->setWhatsThis( i18n( "Export contacts to a vCard 3.0 file." ) );
455 mXXPortManager
->addExportAction( action
, "vcard30" );
457 action
= collection
->addAction( "file_export_vcard21" );
458 action
->setText( i18n( "Export vCard 2.1..." ) );
459 action
->setWhatsThis( i18n( "Export contacts to a vCard 2.1 file." ) );
460 mXXPortManager
->addExportAction( action
, "vcard21" );
462 action
= collection
->addAction( "file_export_csv" );
463 action
->setText( i18n( "Export CSV file..." ) );
464 action
->setWhatsThis( i18n( "Export contacts to a file in comma separated value format." ) );
465 mXXPortManager
->addExportAction( action
, "csv" );
467 action
= collection
->addAction( "file_export_ldif" );
468 action
->setText( i18n( "Export LDIF file..." ) );
469 action
->setWhatsThis( i18n( "Export contacts to an LDIF file." ) );
470 mXXPortManager
->addExportAction( action
, "ldif" );
472 action
= collection
->addAction( "file_export_gmx" );
473 action
->setText( i18n( "Export GMX file..." ) );
474 action
->setWhatsThis( i18n( "Export contacts to a GMX address book file." ) );
475 mXXPortManager
->addExportAction( action
, "gmx" );
478 void MainWidget::print()
481 printer
.setDocName( i18n( "Address Book" ) );
482 printer
.setOutputFileName( "addressbook.pdf" );
483 printer
.setOutputFormat( QPrinter::PdfFormat
);
484 printer
.setCollateCopies( true );
486 QPrintDialog
printDialog( &printer
, this );
487 printDialog
.setWindowTitle( i18n( "Print Contacts" ) );
488 if ( !printDialog
.exec() ) //krazy:exclude=crashy
491 KABPrinting::PrintingWizard
wizard( &printer
, allContactsModel(),
492 mItemView
->selectionModel(), this );
493 wizard
.setDefaultAddressBook( currentAddressBook() );
498 void MainWidget::newContact()
500 Akonadi::ContactEditorDialog
dlg( Akonadi::ContactEditorDialog::CreateMode
, this );
501 dlg
.setDefaultAddressBook( currentAddressBook() );
506 void MainWidget::newGroup()
508 Akonadi::ContactGroupEditorDialog
dlg( Akonadi::ContactGroupEditorDialog::CreateMode
, this );
509 dlg
.setDefaultAddressBook( currentAddressBook() );
514 void MainWidget::editItem( const Akonadi::Item
&reference
)
516 if ( Akonadi::MimeTypeChecker::isWantedItem( reference
, KABC::Addressee::mimeType() ) ) {
517 editContact( reference
);
518 } else if ( Akonadi::MimeTypeChecker::isWantedItem( reference
, KABC::ContactGroup::mimeType() ) ) {
519 editGroup( reference
);
524 * Depending on the mime type of the selected item, this method
525 * brings up the right view on the detail view stack and sets the
526 * selected item on it.
528 void MainWidget::itemSelected( const Akonadi::Item
&item
)
530 if ( Akonadi::MimeTypeChecker::isWantedItem( item
, KABC::Addressee::mimeType() ) ) {
531 mDetailsViewStack
->setCurrentWidget( mContactDetails
);
532 mContactDetails
->setContact( item
);
533 } else if ( Akonadi::MimeTypeChecker::isWantedItem( item
, KABC::ContactGroup::mimeType() ) ) {
534 mDetailsViewStack
->setCurrentWidget( mContactGroupDetails
);
535 mContactGroupDetails
->setContactGroup( item
);
540 * Catch when the selection has gone ( e.g. an empty address book has been selected )
541 * clear the details view in this case.
543 void MainWidget::itemSelectionChanged( const QModelIndex
¤t
, const QModelIndex
& )
545 if ( !current
.isValid() )
546 mDetailsViewStack
->setCurrentWidget( mEmptyDetails
);
549 void MainWidget::selectFirstItem()
551 // Whenever the quick search has changed, we select the first item
552 // in the item view, so that the detailsview is updated
553 if ( mItemView
&& mItemView
->selectionModel() ) {
554 mItemView
->selectionModel()->setCurrentIndex( mItemView
->model()->index( 0, 0 ),
555 QItemSelectionModel::Rows
|
556 QItemSelectionModel::ClearAndSelect
);
560 void MainWidget::setCollectionViewVisible( bool visible
)
562 mCollectionView
->setVisible( visible
);
565 void MainWidget::setItemViewVisible( bool visible
)
567 mItemView
->setVisible( visible
);
570 void MainWidget::setDetailsViewVisible( bool visible
)
572 mDetailsPane
->setVisible( visible
);
575 void MainWidget::setSimpleGuiMode( bool on
)
577 mCollectionView
->setVisible( !on
);
578 mItemView
->setVisible( !on
);
579 mDetailsPane
->setVisible( true );
580 mContactSwitcher
->setVisible( on
);
582 if ( mItemView
->model() )
583 mItemView
->setCurrentIndex( mItemView
->model()->index( 0, 0 ) );
585 Settings::self()->setUseSimpleMode( on
);
588 void MainWidget::editContact( const Akonadi::Item
&contact
)
590 Akonadi::ContactEditorDialog
dlg( Akonadi::ContactEditorDialog::EditMode
, this );
591 dlg
.setContact( contact
);
595 void MainWidget::editGroup( const Akonadi::Item
&group
)
597 Akonadi::ContactGroupEditorDialog
dlg( Akonadi::ContactGroupEditorDialog::EditMode
, this );
598 dlg
.setContactGroup( group
);
602 Akonadi::Collection
MainWidget::currentAddressBook() const
604 if ( mCollectionView
->selectionModel() && mCollectionView
->selectionModel()->hasSelection() ) {
605 const QModelIndex index
= mCollectionView
->selectionModel()->selectedIndexes().first();
606 const Akonadi::Collection collection
= index
.data( Akonadi::EntityTreeModel::CollectionRole
)
607 .value
<Akonadi::Collection
>();
612 return Akonadi::Collection();
615 QAbstractItemModel
* MainWidget::allContactsModel()
617 if ( !mAllContactsModel
) {
618 KDescendantsProxyModel
*descendantsModel
= new KDescendantsProxyModel( this );
619 descendantsModel
->setSourceModel( GlobalContactModel::instance()->model() );
621 mAllContactsModel
= new Akonadi::EntityMimeTypeFilterModel( this );
622 mAllContactsModel
->setSourceModel( descendantsModel
);
623 mAllContactsModel
->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
624 mAllContactsModel
->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders
);
627 return mAllContactsModel
;
630 #include "mainwidget.moc"