• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kaddressbook

  • sources
  • kde-4.12
  • kdepim
  • kaddressbook
mainwidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KAddressBook.
3 
4  Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
5 
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.
10 
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.
15 
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.
19 */
20 
21 #include "mainwidget.h"
22 #include "contactswitcher.h"
23 #include "globalcontactmodel.h"
24 #include "modelcolumnmanager.h"
25 #include "printing/printingwizard.h"
26 #include "quicksearchwidget.h"
27 #include "settings.h"
28 #include "xxportmanager.h"
29 
30 #include "kaddressbookgrantlee/formatter/grantleecontactformatter.h"
31 #include "kaddressbookgrantlee/formatter/grantleecontactgroupformatter.h"
32 #include "grantleetheme/grantleethememanager.h"
33 #include "grantleetheme/globalsettings_base.h"
34 
35 #include "libkdepim/misc/uistatesaver.h"
36 
37 #include <pimcommon/acl/collectionaclpage.h>
38 #include <pimcommon/acl/imapaclattribute.h>
39 
40 #include <Akonadi/ETMViewStateSaver>
41 #include <Akonadi/CollectionFilterProxyModel>
42 #include <Akonadi/CollectionModel>
43 #include <Akonadi/Control>
44 #include <Akonadi/EntityMimeTypeFilterModel>
45 #include <Akonadi/EntityTreeView>
46 #include <Akonadi/ItemView>
47 #include <Akonadi/MimeTypeChecker>
48 #include <Akonadi/AttributeFactory>
49 #include <Akonadi/CollectionPropertiesDialog>
50 #include <Akonadi/Contact/ContactDefaultActions>
51 #include <Akonadi/Contact/ContactGroupEditorDialog>
52 #include <Akonadi/Contact/ContactGroupViewer>
53 #include <Akonadi/Contact/ContactsFilterProxyModel>
54 #include <Akonadi/Contact/ContactsTreeModel>
55 #include <Akonadi/Contact/ContactViewer>
56 #include <Akonadi/Contact/StandardContactActionManager>
57 
58 #include <KABC/Addressee>
59 #include <KABC/ContactGroup>
60 
61 #include <KAction>
62 #include <KActionCollection>
63 #include <KActionMenu>
64 #include <KApplication>
65 #include <KCheckableProxyModel>
66 #include <kdescendantsproxymodel.h> //krazy:exclude=camelcase TODO wait for kdelibs4.9
67 #include <KIcon>
68 #include <KLineEdit>
69 #include <KLocale>
70 #include <KSelectionProxyModel>
71 #include <KStandardDirs>
72 #include <KTextBrowser>
73 #include <KToggleAction>
74 #include <KToolBar>
75 #include <KXmlGuiWindow>
76 #include <KCMultiDialog>
77 #include <kdeprintdialog.h>
78 #include <KPrintPreview>
79 
80 #include <QAction>
81 #include <QActionGroup>
82 #include <QHBoxLayout>
83 #include <QHeaderView>
84 #include <QListView>
85 #include <QPrinter>
86 #include <QPrintDialog>
87 #include <QSortFilterProxyModel>
88 #include <QSplitter>
89 #include <QStackedWidget>
90 
91 namespace {
92 static bool isStructuralCollection( const Akonadi::Collection &collection )
93 {
94  QStringList mimeTypes;
95  mimeTypes << KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType();
96  const QStringList collectionMimeTypes = collection.contentMimeTypes();
97  foreach ( const QString &mimeType, mimeTypes ) {
98  if ( collectionMimeTypes.contains( mimeType ) ) {
99  return false;
100  }
101  }
102  return true;
103 }
104 
105 class StructuralCollectionsNotCheckableProxy : public KCheckableProxyModel
106 {
107  public:
108  StructuralCollectionsNotCheckableProxy( QObject *parent )
109  : KCheckableProxyModel( parent )
110  {
111  }
112 
113  /* reimp */QVariant data( const QModelIndex &index, int role ) const
114  {
115  if ( !index.isValid() ) {
116  return QVariant();
117  }
118 
119  if ( role == Qt::CheckStateRole ) {
120  // Don't show the checkbox if the collection can't contain incidences
121  const Akonadi::Collection collection =
122  index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
123  if ( collection.isValid() && isStructuralCollection( collection ) ) {
124  return QVariant();
125  }
126  }
127  return KCheckableProxyModel::data( index, role );
128  }
129 };
130 
131 }
132 
133 MainWidget::MainWidget( KXMLGUIClient *guiClient, QWidget *parent )
134  : QWidget( parent ), mAllContactsModel( 0 ), mXmlGuiClient( guiClient ), mGrantleeThemeManager(0)
135 {
136  mXXPortManager = new XXPortManager( this );
137  Akonadi::AttributeFactory::registerAttribute<PimCommon::ImapAclAttribute>();
138 
139  setupGui();
140  setupActions( guiClient->actionCollection() );
141 
142  /*
143  * The item models, proxies and views have the following structure:
144  *
145  * mItemView
146  * ^
147  * |
148  * mContactsFilterModel
149  * ^
150  * |
151  * mItemTree
152  * ^
153  * |
154  * | mAllContactsModel
155  * | ^
156  * | |
157  * mCollectionView selectionProxyModel descendantsModel
158  * ^ ^ ^ ^
159  * | | | |
160  * | selectionModel | |
161  * | | | |
162  * proxyModel ---------' | |
163  * ^ | |
164  * | | |
165  * mCollectionTree | |
166  * ^ | |
167  * | | _______________/
168  * \ / /
169  * GlobalContactModel::instance()
170  *
171  *
172  * GlobalContactModel::instance(): The global contact model (contains collections and items)
173  * mCollectionTree: Filters out all items
174  * proxyModel: Allows the user to select collections by checkboxes
175  * selectionModel: Represents the selected collections that have been
176  * selected in proxyModel
177  * mCollectionView: Shows the collections (address books) in a view
178  * selectionProxyModel: Filters out all collections and items that are no children
179  * of the collections currently selected in selectionModel
180  * mItemTree: Filters out all collections
181  * mContactsFilterModel: Filters the contacts by the content of mQuickSearchWidget
182  * mItemView: Shows the items (contacts and contact groups) in a view
183  *
184  * descendantsModel: Flattens the item/collection tree to a list
185  * mAllContactsModel: Provides a list of all available contacts from all
186  * address books
187  */
188 
189  mCollectionTree = new Akonadi::EntityMimeTypeFilterModel( this );
190  mCollectionTree->setDynamicSortFilter( true );
191  mCollectionTree->setSortCaseSensitivity( Qt::CaseInsensitive );
192  mCollectionTree->setSourceModel( GlobalContactModel::instance()->model() );
193  mCollectionTree->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() );
194  mCollectionTree->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders );
195 
196  mCollectionSelectionModel = new QItemSelectionModel( mCollectionTree );
197  StructuralCollectionsNotCheckableProxy *checkableProxyModel =
198  new StructuralCollectionsNotCheckableProxy( this );
199  checkableProxyModel->setSelectionModel( mCollectionSelectionModel );
200  checkableProxyModel->setSourceModel( mCollectionTree );
201 
202  mCollectionView->setModel( checkableProxyModel );
203  mCollectionView->setXmlGuiClient( guiClient );
204  mCollectionView->header()->setDefaultAlignment( Qt::AlignCenter );
205  mCollectionView->header()->setSortIndicatorShown( false );
206 
207  connect( mCollectionView->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
208  SLOT(slotCheckNewCalendar(QModelIndex,int,int)) );
209 
210  connect( mCollectionView, SIGNAL(currentChanged(Akonadi::Collection)),
211  mXXPortManager, SLOT(setDefaultAddressBook(Akonadi::Collection)) );
212 
213  KSelectionProxyModel *selectionProxyModel =
214  new KSelectionProxyModel( mCollectionSelectionModel, this );
215  selectionProxyModel->setSourceModel( GlobalContactModel::instance()->model() );
216  selectionProxyModel->setFilterBehavior( KSelectionProxyModel::ChildrenOfExactSelection );
217 
218  mItemTree = new Akonadi::EntityMimeTypeFilterModel( this );
219  mItemTree->setSourceModel( selectionProxyModel );
220  mItemTree->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
221  mItemTree->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders );
222 
223  mContactsFilterModel = new Akonadi::ContactsFilterProxyModel( this );
224  mContactsFilterModel->setSourceModel( mItemTree );
225  connect( mQuickSearchWidget, SIGNAL(filterStringChanged(QString)),
226  mContactsFilterModel, SLOT(setFilterString(QString)) );
227  connect( mQuickSearchWidget, SIGNAL(filterStringChanged(QString)),
228  this, SLOT(selectFirstItem()) );
229  connect( mQuickSearchWidget, SIGNAL(arrowDownKeyPressed()),
230  mItemView, SLOT(setFocus()) );
231 
232  mItemView->setModel( mContactsFilterModel );
233  mItemView->setXmlGuiClient( guiClient );
234  mItemView->setSelectionMode( QAbstractItemView::ExtendedSelection );
235  mItemView->setRootIsDecorated( false );
236  mItemView->header()->setDefaultAlignment( Qt::AlignCenter );
237 
238  mXXPortManager->setSelectionModel( mItemView->selectionModel() );
239 
240  mActionManager = new Akonadi::StandardContactActionManager( guiClient->actionCollection(), this );
241  mActionManager->setCollectionSelectionModel( mCollectionView->selectionModel() );
242  mActionManager->setItemSelectionModel( mItemView->selectionModel() );
243 
244  QList<Akonadi::StandardActionManager::Type> standardActions;
245  standardActions << Akonadi::StandardActionManager::CreateCollection
246  << Akonadi::StandardActionManager::CopyCollections
247  << Akonadi::StandardActionManager::DeleteCollections
248  << Akonadi::StandardActionManager::SynchronizeCollections
249  << Akonadi::StandardActionManager::CollectionProperties
250  << Akonadi::StandardActionManager::CopyItems
251  << Akonadi::StandardActionManager::Paste
252  << Akonadi::StandardActionManager::DeleteItems
253  << Akonadi::StandardActionManager::CutItems
254  << Akonadi::StandardActionManager::CutCollections
255  << Akonadi::StandardActionManager::CreateResource
256  << Akonadi::StandardActionManager::DeleteResources
257  << Akonadi::StandardActionManager::ResourceProperties
258  << Akonadi::StandardActionManager::SynchronizeResources
259  << Akonadi::StandardActionManager::SynchronizeCollectionsRecursive;
260 
261  Q_FOREACH( Akonadi::StandardActionManager::Type standardAction, standardActions ) {
262  mActionManager->createAction( standardAction );
263  }
264 
265  QList<Akonadi::StandardContactActionManager::Type> contactActions;
266  contactActions << Akonadi::StandardContactActionManager::CreateContact
267  << Akonadi::StandardContactActionManager::CreateContactGroup
268  << Akonadi::StandardContactActionManager::EditItem;
269 
270  Q_FOREACH( Akonadi::StandardContactActionManager::Type contactAction, contactActions ) {
271  mActionManager->createAction( contactAction );
272  }
273  static bool pageRegistered = false;
274 
275  if ( !pageRegistered ) {
276  Akonadi::CollectionPropertiesDialog::registerPage( new PimCommon::CollectionAclPageFactory );
277  pageRegistered = true;
278  }
279 
280  const QStringList pages =
281  QStringList() << QLatin1String( "Akonadi::CollectionGeneralPropertiesPage" )
282  << QLatin1String( "Akonadi::CachePolicyPage" )
283  << QLatin1String( "PimCommon::CollectionAclPage" );
284 
285  mActionManager->setCollectionPropertiesPageNames( pages );
286 
287  connect( mItemView, SIGNAL(currentChanged(Akonadi::Item)),
288  this, SLOT(itemSelected(Akonadi::Item)) );
289  connect( mItemView, SIGNAL(doubleClicked(Akonadi::Item)),
290  mActionManager->action( Akonadi::StandardContactActionManager::EditItem ),
291  SLOT(trigger()) );
292  connect( mItemView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
293  this, SLOT(itemSelectionChanged(QModelIndex,QModelIndex)) );
294 
295  // show the contact details view as default
296  mDetailsViewStack->setCurrentWidget( mContactDetails );
297 
298  mContactSwitcher->setView( mItemView );
299 
300  Akonadi::Control::widgetNeedsAkonadi( this );
301 
302  mModelColumnManager = new ModelColumnManager( GlobalContactModel::instance()->model(), this );
303  mModelColumnManager->setWidget( mItemView->header() );
304  mModelColumnManager->load();
305 
306  QMetaObject::invokeMethod( this, "delayedInit", Qt::QueuedConnection );
307 }
308 
309 void MainWidget::configure()
310 {
311  KCMultiDialog dlg( this );
312  dlg.addModule( QLatin1String("akonadicontact_actions.desktop") );
313  dlg.addModule( QLatin1String("kcmldap.desktop") );
314 
315  dlg.exec();
316 }
317 
318 void MainWidget::delayedInit()
319 {
320  setViewMode(0); // get default from settings
321 
322  const KConfigGroup group( Settings::self()->config(), "UiState_ContactView" );
323  KPIM::UiStateSaver::restoreState( mItemView, group );
324 
325 #if defined(HAVE_PRISON)
326  mXmlGuiClient->
327  actionCollection()->
328  action( QLatin1String("options_show_qrcodes") )->setChecked( showQRCodes() );
329 #endif
330 
331  connect( GlobalContactModel::instance()->model(), SIGNAL(modelAboutToBeReset()),
332  SLOT(saveState()) );
333  connect( GlobalContactModel::instance()->model(), SIGNAL(modelReset()),
334  SLOT(restoreState()) );
335  connect( kapp, SIGNAL(aboutToQuit()), SLOT(saveState()) );
336 
337  restoreState();
338 }
339 
340 MainWidget::~MainWidget()
341 {
342  mModelColumnManager->store();
343  saveSplitterStates();
344 
345  KConfigGroup group( Settings::self()->config(), "UiState_ContactView" );
346  KPIM::UiStateSaver::saveState( mItemView, group );
347 
348  saveState();
349  delete mGrantleeThemeManager;
350 
351  Settings::self()->writeConfig();
352 }
353 
354 void MainWidget::restoreState()
355 {
356  // collection view
357  {
358  Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
359  saver->setView( mCollectionView );
360 
361  const KConfigGroup group( Settings::self()->config(), "CollectionViewState" );
362  saver->restoreState( group );
363  }
364 
365  // collection view
366  {
367  Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
368  saver->setSelectionModel( mCollectionSelectionModel );
369 
370  const KConfigGroup group( Settings::self()->config(), "CollectionViewCheckState" );
371  saver->restoreState( group );
372  }
373 
374  // item view
375  {
376  Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
377  saver->setView( mItemView );
378  saver->setSelectionModel( mItemView->selectionModel() );
379 
380  const KConfigGroup group( Settings::self()->config(), "ItemViewState" );
381  saver->restoreState( group );
382  }
383 }
384 
385 void MainWidget::saveState()
386 {
387  // collection view
388  {
389  Akonadi::ETMViewStateSaver saver;
390  saver.setView( mCollectionView );
391 
392  KConfigGroup group( Settings::self()->config(), "CollectionViewState" );
393  saver.saveState( group );
394  group.sync();
395  }
396 
397  // collection view
398  {
399  Akonadi::ETMViewStateSaver saver;
400  saver.setSelectionModel( mCollectionSelectionModel );
401 
402  KConfigGroup group( Settings::self()->config(), "CollectionViewCheckState" );
403  saver.saveState( group );
404  group.sync();
405  }
406 
407  // item view
408  {
409  Akonadi::ETMViewStateSaver saver;
410  saver.setView( mItemView );
411  saver.setSelectionModel( mItemView->selectionModel() );
412 
413  KConfigGroup group( Settings::self()->config(), "ItemViewState" );
414  saver.saveState( group );
415  group.sync();
416  }
417 }
418 
419 void MainWidget::setupGui()
420 {
421  // the horizontal main layout
422  QHBoxLayout *layout = new QHBoxLayout( this );
423  layout->setMargin( 0 );
424 
425  // Splitter 1 contains the two main parts of the GUI:
426  // - collection and item view splitter 2 on the left (see below)
427  // - details pane on the right, that contains
428  // - details view stack on the top
429  // - contact switcher at the bottom
430  mMainWidgetSplitter1 = new QSplitter(Qt::Horizontal);
431  mMainWidgetSplitter1->setObjectName( QLatin1String("MainWidgetSplitter1") );
432  layout->addWidget( mMainWidgetSplitter1 );
433 
434  // Splitter 2 contains the remaining parts of the GUI:
435  // - collection view on either the left or the top
436  // - item view on either the right or the bottom
437  // The orientation of this splitter is changed for either
438  // a three or two column view; in simple mode it is hidden.
439  mMainWidgetSplitter2 = new QSplitter(Qt::Vertical);
440  mMainWidgetSplitter2->setObjectName( QLatin1String("MainWidgetSplitter2") );
441  mMainWidgetSplitter1->addWidget( mMainWidgetSplitter2 );
442 
443  // the collection view
444  mCollectionView = new Akonadi::EntityTreeView();
445  mMainWidgetSplitter2->addWidget( mCollectionView );
446 
447  // the items view
448  mItemView = new Akonadi::EntityTreeView();
449  mItemView->setObjectName( QLatin1String("ContactView") );
450  mItemView->setDefaultPopupMenu( QLatin1String( "akonadi_itemview_contextmenu" ) );
451  mItemView->setAlternatingRowColors(true);
452  mMainWidgetSplitter2->addWidget( mItemView );
453 
454  // the details pane that contains the details view stack and contact switcher
455  mDetailsPane = new QWidget;
456  mMainWidgetSplitter1->addWidget( mDetailsPane );
457 
458  mMainWidgetSplitter1->setStretchFactor( 1, 9 ); // maximum width for detail
459  mMainWidgetSplitter2->setStretchFactor( 1, 9 ); // for intuitive resizing
460  mMainWidgetSplitter2->setChildrenCollapsible(false);
461  mMainWidgetSplitter1->setChildrenCollapsible(false);
462 
463  QVBoxLayout *detailsPaneLayout = new QVBoxLayout( mDetailsPane );
464  detailsPaneLayout->setMargin( 0 );
465 
466  // the details view stack
467  mDetailsViewStack = new QStackedWidget();
468  detailsPaneLayout->addWidget( mDetailsViewStack );
469 
470  // the details widget for contacts
471  mContactDetails = new Akonadi::ContactViewer( mDetailsViewStack );
472  mDetailsViewStack->addWidget( mContactDetails );
473 
474  // the details widget for contact groups
475  mContactGroupDetails = new Akonadi::ContactGroupViewer( mDetailsViewStack );
476  mDetailsViewStack->addWidget( mContactGroupDetails );
477 
478  // the details widget for empty items
479  mEmptyDetails = new KTextBrowser( mDetailsViewStack );
480  mDetailsViewStack->addWidget( mEmptyDetails );
481 
482  // the contact switcher for the simple gui mode
483  mContactSwitcher = new ContactSwitcher;
484  detailsPaneLayout->addWidget( mContactSwitcher );
485  mContactSwitcher->setVisible( false );
486 
487  // the quick search widget which is embedded in the toolbar action
488  mQuickSearchWidget = new QuickSearchWidget;
489 
490  // setup the default actions
491  Akonadi::ContactDefaultActions *actions = new Akonadi::ContactDefaultActions( this );
492  actions->connectToView( mContactDetails );
493  actions->connectToView( mContactGroupDetails );
494  mFormatter = new KAddressBookGrantlee::GrantleeContactFormatter;
495 
496  mContactDetails->setContactFormatter( mFormatter );
497 
498  mGroupFormatter = new KAddressBookGrantlee::GrantleeContactGroupFormatter;
499 
500  mContactGroupDetails->setContactGroupFormatter( mGroupFormatter );
501 }
502 
503 void MainWidget::setupActions( KActionCollection *collection )
504 {
505  mGrantleeThemeManager = new GrantleeTheme::GrantleeThemeManager(QString::fromLatin1( "theme.desktop" ), collection, QLatin1String("kaddressbook/viewertemplates/"));
506  mGrantleeThemeManager->setDownloadNewStuffConfigFile(QLatin1String("kaddressbook_themes.knsrc"));
507  connect(mGrantleeThemeManager, SIGNAL(grantleeThemeSelected()), this, SLOT(slotGrantleeThemeSelected()));
508  connect(mGrantleeThemeManager, SIGNAL(updateThemes()), this, SLOT(slotGrantleeThemesUpdated()));
509 
510 
511  KActionMenu *themeMenu = new KActionMenu(i18n("&Themes"), this);
512  collection->addAction(QLatin1String("theme_menu"), themeMenu );
513 
514  initGrantleeThemeName();
515  QActionGroup *group = new QActionGroup( this );
516  mGrantleeThemeManager->setThemeMenu(themeMenu);
517  mGrantleeThemeManager->setActionGroup(group);
518 
519  KAction *action = KStandardAction::print( this, SLOT(print()), collection );
520  action->setWhatsThis(
521  i18nc( "@info:whatsthis",
522  "Print the complete address book or a selected number of contacts." ) );
523 
524  if(KPrintPreview::isAvailable())
525  KStandardAction::printPreview( this, SLOT(printPreview()), collection );
526 
527  action = collection->addAction( QLatin1String("quick_search") );
528  action->setText( i18n( "Quick search" ) );
529  action->setDefaultWidget( mQuickSearchWidget );
530 
531  action = collection->addAction( QLatin1String("select_all") );
532  action->setText( i18n( "Select All" ) );
533  action->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_A ) );
534  action->setWhatsThis( i18n( "Select all contacts in the current address book view." ) );
535  connect( action, SIGNAL(triggered(bool)), mItemView, SLOT(selectAll()) );
536 
537 #if defined(HAVE_PRISON)
538  KToggleAction *qrtoggleAction;
539  qrtoggleAction = collection->add<KToggleAction>( QLatin1String("options_show_qrcodes") );
540  qrtoggleAction->setText( i18n( "Show QR Codes" ) );
541  qrtoggleAction->setWhatsThis( i18n( "Show QR Codes in the contact." ) );
542  connect( qrtoggleAction, SIGNAL(toggled(bool)), SLOT(setQRCodeShow(bool)) );
543 #endif
544 
545  mViewModeGroup = new QActionGroup( this );
546 
547  KAction *act = new KAction( i18nc( "@action:inmenu", "Simple (one column)" ), mViewModeGroup );
548  act->setCheckable( true );
549  act->setData( 1 );
550  act->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_1 ) );
551  act->setWhatsThis( i18n( "Show a simple mode of the address book view." ) );
552  collection->addAction( QLatin1String("view_mode_simple"), act );
553 
554  act = new KAction( i18nc( "@action:inmenu", "Two Columns" ), mViewModeGroup );
555  act->setCheckable( true );
556  act->setData( 2 );
557  act->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_2 ) );
558  collection->addAction( QLatin1String("view_mode_2columns"), act );
559 
560  act = new KAction( i18nc( "@action:inmenu", "Three Columns" ), mViewModeGroup );
561  act->setCheckable( true );
562  act->setData( 3 );
563  act->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_3 ) );
564  collection->addAction( QLatin1String("view_mode_3columns"), act );
565 
566  connect( mViewModeGroup, SIGNAL(triggered(QAction*)), SLOT(setViewMode(QAction*)) );
567 
568  // import actions
569  action = collection->addAction( QLatin1String("file_import_vcard") );
570  action->setText( i18n( "Import vCard..." ) );
571  action->setWhatsThis( i18n( "Import contacts from a vCard file." ) );
572  mXXPortManager->addImportAction( action, QLatin1String("vcard30") );
573 
574  action = collection->addAction( QLatin1String("file_import_csv") );
575  action->setText( i18n( "Import CSV file..." ) );
576  action->setWhatsThis( i18n( "Import contacts from a file in comma separated value format." ) );
577  mXXPortManager->addImportAction( action, QLatin1String("csv") );
578 
579  action = collection->addAction( QLatin1String("file_import_ldif") );
580  action->setText( i18n( "Import LDIF file..." ) );
581  action->setWhatsThis( i18n( "Import contacts from an LDIF file." ) );
582  mXXPortManager->addImportAction( action, QLatin1String("ldif") );
583 
584  action = collection->addAction( QLatin1String("file_import_ldap") );
585  action->setText( i18n( "Import From LDAP server..." ) );
586  action->setWhatsThis( i18n( "Import contacts from an LDAP server." ) );
587  mXXPortManager->addImportAction( action, QLatin1String("ldap") );
588 
589  action = collection->addAction( QLatin1String("file_import_gmx") );
590  action->setText( i18n( "Import GMX file..." ) );
591  action->setWhatsThis( i18n( "Import contacts from a GMX address book file." ) );
592  mXXPortManager->addImportAction( action, QLatin1String("gmx") );
593 
594  // export actions
595  action = collection->addAction( QLatin1String("file_export_vcard30") );
596  action->setText( i18n( "Export vCard 3.0..." ) );
597  action->setWhatsThis( i18n( "Export contacts to a vCard 3.0 file." ) );
598  mXXPortManager->addExportAction( action, QLatin1String("vcard30") );
599 
600  action = collection->addAction( QLatin1String("file_export_vcard21") );
601  action->setText( i18n( "Export vCard 2.1..." ) );
602  action->setWhatsThis( i18n( "Export contacts to a vCard 2.1 file." ) );
603  mXXPortManager->addExportAction( action, QLatin1String("vcard21") );
604 
605  action = collection->addAction( QLatin1String("file_export_csv") );
606  action->setText( i18n( "Export CSV file..." ) );
607  action->setWhatsThis( i18n( "Export contacts to a file in comma separated value format." ) );
608  mXXPortManager->addExportAction( action, QLatin1String("csv") );
609 
610  action = collection->addAction( QLatin1String("file_export_ldif") );
611  action->setText( i18n( "Export LDIF file..." ) );
612  action->setWhatsThis( i18n( "Export contacts to an LDIF file." ) );
613  mXXPortManager->addExportAction( action, QLatin1String("ldif") );
614 
615  action = collection->addAction( QLatin1String("file_export_gmx") );
616  action->setText( i18n( "Export GMX file..." ) );
617  action->setWhatsThis( i18n( "Export contacts to a GMX address book file." ) );
618  mXXPortManager->addExportAction( action, QLatin1String("gmx") );
619 
620  KToggleAction *actTheme = mGrantleeThemeManager->actionForTheme();
621  if (actTheme)
622  actTheme->setChecked(true);
623 
624 }
625 
626 void MainWidget::printPreview()
627 {
628  QPrinter printer;
629  printer.setDocName( i18n( "Address Book" ) );
630  printer.setOutputFileName( Settings::self()->defaultFileName() );
631  printer.setOutputFormat( QPrinter::PdfFormat );
632  printer.setCollateCopies( true );
633 
634  KPrintPreview previewdlg( &printer, this );
635  KABPrinting::PrintingWizard wizard( &printer, mItemView->selectionModel(), this );
636  wizard.setDefaultAddressBook( currentAddressBook() );
637 
638  const int result = wizard.exec();
639  if (result)
640  previewdlg.exec();
641 }
642 
643 void MainWidget::print()
644 {
645  QPrinter printer;
646  printer.setDocName( i18n( "Address Book" ) );
647  printer.setOutputFileName( Settings::self()->defaultFileName() );
648  printer.setOutputFormat( QPrinter::PdfFormat );
649  printer.setCollateCopies( true );
650 
651  QPrintDialog printDialog(KdePrint::createPrintDialog(&printer));
652 
653  printDialog.setWindowTitle( i18n( "Print Contacts" ) );
654  if ( !printDialog.exec() ) { //krazy:exclude=crashy
655  return;
656  }
657 
658  KABPrinting::PrintingWizard wizard( &printer, mItemView->selectionModel(), this );
659  wizard.setDefaultAddressBook( currentAddressBook() );
660 
661  wizard.exec(); //krazy:exclude=crashy
662 
663  Settings::self()->setDefaultFileName( printer.outputFileName() );
664  Settings::self()->setPrintingStyle( wizard.printingStyle() );
665  Settings::self()->setSortOrder( wizard.sortOrder() );
666 }
667 
668 void MainWidget::newContact()
669 {
670  mActionManager->action( Akonadi::StandardContactActionManager::CreateContact )->trigger();
671 }
672 
673 void MainWidget::newGroup()
674 {
675  mActionManager->action( Akonadi::StandardContactActionManager::CreateContactGroup )->trigger();
676 }
677 
683 void MainWidget::itemSelected( const Akonadi::Item &item )
684 {
685  if ( Akonadi::MimeTypeChecker::isWantedItem( item, KABC::Addressee::mimeType() ) ) {
686  mDetailsViewStack->setCurrentWidget( mContactDetails );
687  mContactDetails->setContact( item );
688  } else if ( Akonadi::MimeTypeChecker::isWantedItem( item, KABC::ContactGroup::mimeType() ) ) {
689  mDetailsViewStack->setCurrentWidget( mContactGroupDetails );
690  mContactGroupDetails->setContactGroup( item );
691  }
692 }
693 
698 void MainWidget::itemSelectionChanged( const QModelIndex &current, const QModelIndex & )
699 {
700  if ( !current.isValid() ) {
701  mDetailsViewStack->setCurrentWidget( mEmptyDetails );
702  }
703 }
704 
705 void MainWidget::selectFirstItem()
706 {
707  // Whenever the quick search has changed, we select the first item
708  // in the item view, so that the detailsview is updated
709  if ( mItemView && mItemView->selectionModel() ) {
710  mItemView->selectionModel()->setCurrentIndex( mItemView->model()->index( 0, 0 ),
711  QItemSelectionModel::Rows |
712  QItemSelectionModel::ClearAndSelect );
713  }
714 }
715 
716 bool MainWidget::showQRCodes()
717 {
718 #if defined(HAVE_PRISON)
719  KConfig config( QLatin1String( "akonadi_contactrc" ) );
720  KConfigGroup group( &config, QLatin1String( "View" ) );
721  return group.readEntry( "QRCodes", true );
722 #else
723  return true;
724 #endif
725 }
726 
727 void MainWidget::setQRCodeShow( bool on )
728 {
729 #if defined(HAVE_PRISON)
730  // must write the configuration setting first before updating the view.
731  KConfig config( QLatin1String( "akonadi_contactrc" ) );
732  KConfigGroup group( &config, QLatin1String( "View" ) );
733  group.writeEntry( "QRCodes", on );
734  if ( mItemView->model() ) {
735  mItemView->setCurrentIndex( mItemView->model()->index( 0, 0 ) );
736  }
737 #else
738  Q_UNUSED( on );
739 #endif
740 }
741 
742 Akonadi::Collection MainWidget::currentAddressBook() const
743 {
744  if ( mCollectionView->selectionModel() && mCollectionView->selectionModel()->hasSelection() ) {
745  const QModelIndex index = mCollectionView->selectionModel()->selectedIndexes().first();
746  const Akonadi::Collection collection =
747  index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
748 
749  return collection;
750  }
751 
752  return Akonadi::Collection();
753 }
754 
755 QAbstractItemModel *MainWidget::allContactsModel()
756 {
757  if ( !mAllContactsModel ) {
758  KDescendantsProxyModel *descendantsModel = new KDescendantsProxyModel( this );
759  descendantsModel->setSourceModel( GlobalContactModel::instance()->model() );
760 
761  mAllContactsModel = new Akonadi::EntityMimeTypeFilterModel( this );
762  mAllContactsModel->setSourceModel( descendantsModel );
763  mAllContactsModel->addMimeTypeExclusionFilter( Akonadi::Collection::mimeType() );
764  mAllContactsModel->setHeaderGroup( Akonadi::EntityTreeModel::ItemListHeaders );
765  }
766 
767  return mAllContactsModel;
768 }
769 
770 void MainWidget::setViewMode( QAction *action )
771 {
772  setViewMode( action->data().toInt() );
773 }
774 
775 void MainWidget::setViewMode( int mode )
776 {
777  int currentMode = Settings::self()->viewMode();
778  //kDebug() << "cur" << currentMode << "new" << mode;
779  if ( mode == currentMode ) return; // nothing to do
780 
781  if ( mode == 0 ) {
782  mode = currentMode;// initialisation, no save
783  } else {
784  saveSplitterStates(); // for 2- or 3-column mode
785  }
786  if ( mode == 1 ) { // simple mode
787  mMainWidgetSplitter2->setVisible( false );
788  mDetailsPane->setVisible( true );
789  mContactSwitcher->setVisible( true );
790  }
791  else {
792  mMainWidgetSplitter2->setVisible( true );
793  mContactSwitcher->setVisible( false );
794 
795  if ( mode == 2 ) { // 2 columns
796  mMainWidgetSplitter2->setOrientation( Qt::Vertical );
797  }
798  else if ( mode == 3 ) { // 3 columns
799  mMainWidgetSplitter2->setOrientation( Qt::Horizontal );
800  }
801  }
802 
803  Settings::self()->setViewMode( mode ); // save new mode in settings
804  restoreSplitterStates(); // restore state for new mode
805  mViewModeGroup->actions().at( mode-1 )->setChecked( true );
806 
807  if ( mItemView->model() ) {
808  mItemView->setCurrentIndex( mItemView->model()->index( 0, 0 ) );
809  }
810 }
811 
812 void MainWidget::saveSplitterStates() const
813 {
814  // The splitter states are saved separately for each column view mode,
815  // but only if not in simple mode (1 column).
816  int currentMode = Settings::self()->viewMode();
817  if ( currentMode == 1 )
818  return;
819 
820  QString groupName = QString::fromLatin1( "UiState_MainWidgetSplitter_%1" ).arg( currentMode );
821  //kDebug() << "saving to group" << groupName;
822  KConfigGroup group( Settings::self()->config(), groupName );
823  KPIM::UiStateSaver::saveState( mMainWidgetSplitter1, group );
824  KPIM::UiStateSaver::saveState( mMainWidgetSplitter2, group );
825 }
826 
827 void MainWidget::restoreSplitterStates()
828 {
829  // The splitter states are restored as appropriate for the current
830  // column view mode, but not for simple mode (1 column).
831  int currentMode = Settings::self()->viewMode();
832  if ( currentMode == 1 )
833  return;
834 
835  QString groupName = QString::fromLatin1( "UiState_MainWidgetSplitter_%1" ).arg( currentMode );
836  //kDebug() << "restoring from group" << groupName;
837  KConfigGroup group( Settings::self()->config(), groupName );
838  KPIM::UiStateSaver::restoreState( mMainWidgetSplitter1, group );
839  KPIM::UiStateSaver::restoreState( mMainWidgetSplitter2, group );
840 }
841 
842 void MainWidget::initGrantleeThemeName()
843 {
844  QString themeName = GrantleeTheme::GrantleeSettings::self()->grantleeThemeName();
845  if (themeName.isEmpty()) {
846  themeName = QLatin1String("default");
847  }
848  mFormatter->setGrantleeTheme(mGrantleeThemeManager->theme(themeName));
849  mGroupFormatter->setGrantleeTheme(mGrantleeThemeManager->theme(themeName));
850 }
851 
852 void MainWidget::slotGrantleeThemeSelected()
853 {
854  initGrantleeThemeName();
855  if ( mItemView->model() ) {
856  mItemView->setCurrentIndex( mItemView->model()->index( 0, 0 ) );
857  }
858 }
859 
860 void MainWidget::slotGrantleeThemesUpdated()
861 {
862  if ( mItemView->model() ) {
863  mItemView->setCurrentIndex( mItemView->model()->index( 0, 0 ) );
864  }
865 }
866 
867 Akonadi::EntityTreeModel *MainWidget::entityTreeModel() const
868 {
869  QAbstractProxyModel *proxy = qobject_cast<QAbstractProxyModel*>( mCollectionView->model() );
870  while( proxy ) {
871  Akonadi::EntityTreeModel *etm = qobject_cast<Akonadi::EntityTreeModel*>( proxy->sourceModel() );
872  if ( etm ) {
873  return etm;
874  }
875  proxy = qobject_cast<QAbstractProxyModel*>( proxy->sourceModel() );
876  }
877 
878  kWarning() << "Couldn't find EntityTreeModel";
879  return 0;
880 }
881 
882 void MainWidget::slotCheckNewCalendar( const QModelIndex &parent, int begin, int end )
883 {
884  // HACK: Check newly created calendars
885  Akonadi::EntityTreeModel *etm = entityTreeModel();
886  if ( etm && etm->isCollectionTreeFetched() ) {
887  for( int row=begin; row<=end; ++row ) {
888  QModelIndex index = mCollectionView->model()->index( row, 0, parent );
889  if ( index.isValid() )
890  mCollectionView->model()->setData( index, Qt::Checked, Qt::CheckStateRole );
891  }
892  if ( parent.isValid() ) {
893  mCollectionView->setExpanded( parent, true );
894  }
895  }
896 }
897 
898 
899 #include "mainwidget.moc"
Settings::setSortOrder
static void setSortOrder(int v)
Set Default sort order.
Definition: settings.h:103
ModelColumnManager::store
void store()
Stores the user configuration.
Definition: modelcolumnmanager.cpp:52
KABPrinting::PrintingWizard
The PrintingWizard combines pages common for all print styles and those provided by the respective st...
Definition: printingwizard.h:55
globalcontactmodel.h
MainWidget::print
void print()
Definition: mainwidget.cpp:643
KABPrinting::PrintingWizard::setDefaultAddressBook
void setDefaultAddressBook(const Akonadi::Collection &addressBook)
Sets the default addressbook of the contact selection.
Definition: printingwizard.cpp:108
MainWidget::configure
void configure()
Definition: mainwidget.cpp:309
QObject
GlobalContactModel::instance
static GlobalContactModel * instance()
Returns the global contact model instance.
Definition: globalcontactmodel.cpp:62
Settings::self
static Settings * self()
Definition: settings.cpp:19
MainWidget::newContact
void newContact()
Definition: mainwidget.cpp:668
xxportmanager.h
XXPortManager::setSelectionModel
void setSelectionModel(QItemSelectionModel *model)
Sets the model that contains the current selection.
Definition: xxportmanager.cpp:69
contactswitcher.h
XXPortManager::addImportAction
void addImportAction(QAction *action, const QString &identifier)
Adds a new action to import contacts.
Definition: xxportmanager.cpp:57
Settings::viewMode
static int viewMode()
Get Viewing mode.
Definition: settings.h:167
ModelColumnManager::load
void load()
Loads the user configuration and applies it to the model.
Definition: modelcolumnmanager.cpp:40
ModelColumnManager::setWidget
void setWidget(QWidget *view)
Sets the widget that shall provide a RMB menu to configure the columns to be shown.
Definition: modelcolumnmanager.cpp:64
modelcolumnmanager.h
MainWidget::printPreview
void printPreview()
Definition: mainwidget.cpp:626
ContactSwitcher
A widget to switch between the contacts of an contact view.
Definition: contactswitcher.h:37
mainwidget.h
quicksearchwidget.h
ContactSwitcher::setView
void setView(QAbstractItemView *view)
Sets the view the contact switcher shall work on.
Definition: contactswitcher.cpp:59
printingwizard.h
MainWidget::~MainWidget
~MainWidget()
Definition: mainwidget.cpp:340
MainWidget::MainWidget
MainWidget(KXMLGUIClient *guiClient, QWidget *parent=0)
Definition: mainwidget.cpp:133
settings.h
XXPortManager
The class that manages import and export of contacts.
Definition: xxportmanager.h:40
Settings::setDefaultFileName
static void setDefaultFileName(const QString &v)
Set DefaultFileName.
Definition: settings.h:49
Settings::setViewMode
static void setViewMode(int v)
Set Viewing mode.
Definition: settings.h:157
QuickSearchWidget
The quick search widget from the toolbar.
Definition: quicksearchwidget.h:39
MainWidget::newGroup
void newGroup()
Definition: mainwidget.cpp:673
ModelColumnManager
A manager for the contacts model columns.
Definition: modelcolumnmanager.h:39
Settings::setPrintingStyle
static void setPrintingStyle(int v)
Set Printing style.
Definition: settings.h:76
XXPortManager::addExportAction
void addExportAction(QAction *action, const QString &identifier)
Adds a new action to export contacts.
Definition: xxportmanager.cpp:63
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kaddressbook

Skip menu "kaddressbook"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal