00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qfile.h>
00025 #include <qlayout.h>
00026 #include <qwidgetstack.h>
00027
00028 #include <libkdepim/kvcarddrag.h>
00029 #include <kabc/addressbook.h>
00030 #include <kabc/vcardconverter.h>
00031 #include <kactionclasses.h>
00032 #include <kconfig.h>
00033 #include <kdebug.h>
00034 #include <kdeversion.h>
00035 #include <kiconloader.h>
00036 #include <klocale.h>
00037 #include <kmessagebox.h>
00038 #include <kmultipledrag.h>
00039 #include <ktempdir.h>
00040 #include <ktrader.h>
00041 #include <kurldrag.h>
00042
00043 #include "addviewdialog.h"
00044 #include "addresseeutil.h"
00045 #include "core.h"
00046 #include "filtereditdialog.h"
00047 #include "filterselectionwidget.h"
00048 #include "kabprefs.h"
00049
00050 #include "viewmanager.h"
00051
00052 ViewManager::ViewManager( KAB::Core *core, QWidget *parent, const char *name )
00053 : QWidget( parent, name ), mCore( core ), mActiveView( 0 ),
00054 mFilterSelectionWidget( 0 )
00055 {
00056 initGUI();
00057 initActions();
00058
00059 mViewDict.setAutoDelete( true );
00060
00061 createViewFactories();
00062 }
00063
00064 ViewManager::~ViewManager()
00065 {
00066 unloadViews();
00067 mViewFactoryDict.clear();
00068 }
00069
00070 void ViewManager::restoreSettings()
00071 {
00072 mViewNameList = KABPrefs::instance()->viewNames();
00073 QString activeViewName = KABPrefs::instance()->currentView();
00074
00075 mActionSelectView->setItems( mViewNameList );
00076
00077
00078 mFilterList = Filter::restore( mCore->config(), "Filter" );
00079 mFilterSelectionWidget->setItems( filterNames() );
00080 mFilterSelectionWidget->setCurrentItem( KABPrefs::instance()->currentFilter() );
00081
00082
00083
00084 QDictIterator<KAddressBookView> it( mViewDict );
00085 for ( it.toFirst(); it.current(); ++it ) {
00086 KConfigGroupSaver saver( mCore->config(), it.currentKey() );
00087 it.current()->readConfig( mCore->config() );
00088 }
00089
00090 setActiveView( activeViewName );
00091
00092 mActionDeleteView->setEnabled( mViewNameList.count() > 1 );
00093 }
00094
00095 void ViewManager::saveSettings()
00096 {
00097 QDictIterator<KAddressBookView> it( mViewDict );
00098 for ( it.toFirst(); it.current(); ++it ) {
00099 KConfigGroupSaver saver( mCore->config(), it.currentKey() );
00100 (*it)->writeConfig( mCore->config() );
00101 }
00102
00103 Filter::save( mCore->config(), "Filter", mFilterList );
00104 KABPrefs::instance()->setCurrentFilter( mFilterSelectionWidget->currentItem() );
00105
00106
00107 KABPrefs::instance()->setViewNames( mViewNameList );
00108
00109 if ( mActiveView )
00110 KABPrefs::instance()->setCurrentView( mActiveView->caption() );
00111 }
00112
00113 QStringList ViewManager::selectedUids() const
00114 {
00115 if ( mActiveView ) {
00116 return mActiveView->selectedUids();
00117 } else
00118 return QStringList();
00119 }
00120
00121 QStringList ViewManager::selectedEmails() const
00122 {
00123 if ( mActiveView )
00124 return mActiveView->selectedEmails();
00125 else
00126 return QStringList();
00127 }
00128
00129 KABC::Addressee::List ViewManager::selectedAddressees() const
00130 {
00131 KABC::Addressee::List list;
00132
00133 const QStringList uids = selectedUids();
00134 QStringList::ConstIterator it;
00135 for ( it = uids.begin(); it != uids.end(); ++it ) {
00136 KABC::Addressee addr = mCore->addressBook()->findByUid( *it );
00137 if ( !addr.isEmpty() )
00138 list.append( addr );
00139 }
00140
00141 return list;
00142 }
00143
00144 void ViewManager::setFilterSelectionWidget( FilterSelectionWidget *wdg )
00145 {
00146 mFilterSelectionWidget = wdg;
00147 }
00148
00149 KABC::Field *ViewManager::currentSortField() const
00150 {
00151 if ( mActiveView )
00152 return mActiveView->sortField();
00153 else
00154 return 0;
00155 }
00156
00157 KABC::Field::List ViewManager::viewFields() const
00158 {
00159
00160
00161
00162
00163
00164 return KABC::Field::List();
00165 }
00166
00167 void ViewManager::setSelected( const QString &uid, bool selected )
00168 {
00169 if ( mActiveView )
00170 mActiveView->setSelected( uid, selected );
00171 }
00172
00173 void ViewManager::setFirstSelected( bool selected )
00174 {
00175 if ( mActiveView )
00176 mActiveView->setFirstSelected( selected );
00177 }
00178
00179 void ViewManager::unloadViews()
00180 {
00181 mViewDict.clear();
00182 mActiveView = 0;
00183 }
00184
00185 void ViewManager::setActiveView( const QString &name )
00186 {
00187 KAddressBookView *view = 0;
00188
00189
00190 if ( mActiveView && ( mActiveView->caption() == name ) )
00191 return;
00192
00193
00194
00195
00196
00197
00198 view = mViewDict.find( name );
00199
00200
00201 if ( view == 0 ) {
00202 KConfig *config = mCore->config();
00203 KConfigGroupSaver saver( config, name );
00204 QString type = config->readEntry( "Type", "Table" );
00205
00206 kdDebug(5720) << "ViewManager::setActiveView: creating view - " << name << endl;
00207
00208 ViewFactory *factory = mViewFactoryDict.find( type );
00209 if ( factory )
00210 view = factory->view( mCore, mViewWidgetStack );
00211
00212 if ( view ) {
00213 view->setCaption( name );
00214 mViewDict.insert( name, view );
00215 mViewWidgetStack->addWidget( view );
00216 view->readConfig( config );
00217
00218
00219 connect( view, SIGNAL( selected( const QString& ) ),
00220 SIGNAL( selected( const QString & ) ) );
00221 connect( view, SIGNAL( executed( const QString& ) ),
00222 SIGNAL( executed( const QString& ) ) );
00223 connect( view, SIGNAL( modified() ), SIGNAL( modified() ) );
00224 connect( view, SIGNAL( dropped( QDropEvent* ) ),
00225 SLOT( dropped( QDropEvent* ) ) );
00226 connect( view, SIGNAL( startDrag() ), SLOT( startDrag() ) );
00227 connect( view, SIGNAL( sortFieldChanged() ), SIGNAL( sortFieldChanged() ) );
00228 }
00229 }
00230
00231
00232 if ( view ) {
00233 mActiveView = view;
00234 mViewWidgetStack->raiseWidget( view );
00235
00236
00237
00238 if ( view->defaultFilterType() == KAddressBookView::None ) {
00239 mFilterSelectionWidget->setCurrentItem( 0 );
00240 setActiveFilter( 0 );
00241 } else if ( view->defaultFilterType() == KAddressBookView::Active ) {
00242 setActiveFilter( mFilterSelectionWidget->currentItem() );
00243 } else {
00244 uint pos = filterPosition( view->defaultFilterName() );
00245 mFilterSelectionWidget->setCurrentItem( pos );
00246 setActiveFilter( pos );
00247 }
00248
00249
00250
00251 mActiveView->refresh();
00252
00253 } else
00254 kdDebug(5720) << "ViewManager::setActiveView: unable to find view\n";
00255 }
00256
00257 void ViewManager::refreshView( const QString &uid )
00258 {
00259 if ( mActiveView )
00260 mActiveView->refresh( uid );
00261 }
00262
00263 void ViewManager::editView()
00264 {
00265 if ( !mActiveView )
00266 return;
00267
00268 ViewFactory *factory = mViewFactoryDict.find( mActiveView->type() );
00269 ViewConfigureWidget *wdg = 0;
00270
00271 if ( factory ) {
00272
00273 Filter::save( mCore->config(), "Filter", mFilterList );
00274
00275 wdg = factory->configureWidget( mCore->addressBook(), 0 );
00276 }
00277
00278 if ( wdg ) {
00279 ViewConfigureDialog dlg( wdg, mActiveView->caption(), this );
00280
00281 KConfigGroupSaver saver( mCore->config(), mActiveView->caption() );
00282 dlg.restoreSettings( mCore->config() );
00283
00284 if ( dlg.exec() ) {
00285 dlg.saveSettings( mCore->config() );
00286 mActiveView->readConfig( mCore->config() );
00287
00288
00289
00290 if ( mActiveView->defaultFilterType() == KAddressBookView::None ) {
00291 mFilterSelectionWidget->setCurrentItem( 0 );
00292 setActiveFilter( 0 );
00293 } else if ( mActiveView->defaultFilterType() == KAddressBookView::Active ) {
00294 setActiveFilter( mFilterSelectionWidget->currentItem() );
00295 } else {
00296 uint pos = filterPosition( mActiveView->defaultFilterName() );
00297 mFilterSelectionWidget->setCurrentItem( pos );
00298 setActiveFilter( pos );
00299 }
00300
00301 mActiveView->refresh();
00302 emit viewFieldsChanged();
00303 }
00304 }
00305 }
00306
00307 void ViewManager::deleteView()
00308 {
00309 QString text = i18n( "<qt>Are you sure that you want to delete the view <b>%1</b>?</qt>" )
00310 .arg( mActiveView->caption() );
00311 QString caption = i18n( "Confirm Delete" );
00312
00313 if ( KMessageBox::warningContinueCancel( this, text, caption, KGuiItem( i18n("&Delete"), "editdelete") ) == KMessageBox::Continue ) {
00314 mViewNameList.remove( mActiveView->caption() );
00315
00316
00317 KConfig *config = mCore->config();
00318 config->deleteGroup( mActiveView->caption() );
00319
00320 mViewDict.remove( mActiveView->caption() );
00321 mActiveView = 0;
00322
00323
00324
00325 mActionSelectView->setItems( mViewNameList );
00326 if ( mViewNameList.count() > 0 ) {
00327 mActionSelectView->setCurrentItem( 0 );
00328 setActiveView( mViewNameList[ 0 ] );
00329 }
00330 mActionDeleteView->setEnabled( mViewNameList.count() > 1 );
00331 }
00332 }
00333
00334 void ViewManager::addView()
00335 {
00336 AddViewDialog dialog( &mViewFactoryDict, this );
00337
00338 if ( dialog.exec() ) {
00339 QString newName = dialog.viewName();
00340 QString type = dialog.viewType();
00341
00342
00343 bool firstConflict = true;
00344 int numTries = 1;
00345 while ( mViewNameList.contains( newName ) > 0 ) {
00346 if ( !firstConflict ) {
00347 newName = newName.left( newName.length() - 4 );
00348 firstConflict = false;
00349 }
00350
00351 newName = QString( "%1 <%2>" ).arg( newName ).arg( numTries );
00352 numTries++;
00353 }
00354
00355
00356 mViewNameList.append( newName );
00357
00358
00359 KConfig *config = mCore->config();
00360 config->deleteGroup( newName );
00361 KConfigGroupSaver saver( config, newName );
00362 config->writeEntry( "Type", type );
00363
00364
00365 mActionSelectView->setItems( mViewNameList );
00366 mActionSelectView->setCurrentItem( mViewNameList.findIndex( newName ) );
00367 setActiveView( newName );
00368
00369 editView();
00370
00371 mActionDeleteView->setEnabled( mViewNameList.count() > 1 );
00372 }
00373 }
00374
00375 void ViewManager::scrollUp()
00376 {
00377 if ( mActiveView )
00378 mActiveView->scrollUp();
00379 }
00380
00381 void ViewManager::scrollDown()
00382 {
00383 if ( mActiveView )
00384 mActiveView->scrollDown();
00385 }
00386
00387 void ViewManager::createViewFactories()
00388 {
00389 const KTrader::OfferList plugins = KTrader::self()->query( "KAddressBook/View",
00390 QString( "[X-KDE-KAddressBook-ViewPluginVersion] == %1" ).arg( KAB_VIEW_PLUGIN_VERSION ) );
00391 KTrader::OfferList::ConstIterator it;
00392 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
00393 if ( !(*it)->hasServiceType( "KAddressBook/View" ) )
00394 continue;
00395
00396 KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().latin1() );
00397
00398 if ( !factory ) {
00399 kdDebug(5720) << "ViewManager::createViewFactories(): Factory creation failed" << endl;
00400 continue;
00401 }
00402
00403 ViewFactory *viewFactory = static_cast<ViewFactory*>( factory );
00404
00405 if ( !viewFactory ) {
00406 kdDebug(5720) << "ViewManager::createViewFactories(): Cast failed" << endl;
00407 continue;
00408 }
00409
00410 mViewFactoryDict.insert( viewFactory->type(), viewFactory );
00411 }
00412 }
00413
00414 void ViewManager::dropped( QDropEvent *e )
00415 {
00416 kdDebug(5720) << "ViewManager::dropped: got a drop event" << endl;
00417
00418
00419 if ( e->source() == this )
00420 return;
00421
00422 QString clipText, vcards;
00423 KURL::List urls;
00424
00425 if ( KURLDrag::decode( e, urls) ) {
00426 KURL::List::ConstIterator it = urls.begin();
00427 int c = urls.count();
00428 if ( c > 1 ) {
00429 QString questionString = i18n( "Import one contact into your addressbook?", "Import %n contacts into your addressbook?", c );
00430 if ( KMessageBox::questionYesNo( this, questionString, i18n( "Import Contacts?" ), i18n("Import"), i18n("Do Not Import") ) == KMessageBox::Yes ) {
00431 for ( ; it != urls.end(); ++it )
00432 emit urlDropped( *it );
00433 }
00434 } else if ( c == 1 )
00435 emit urlDropped( *it );
00436 } else if ( KVCardDrag::decode( e, vcards ) ) {
00437 KABC::VCardConverter converter;
00438
00439 const KABC::Addressee::List list = converter.parseVCards( vcards );
00440 KABC::Addressee::List::ConstIterator it;
00441 for ( it = list.begin(); it != list.end(); ++it ) {
00442 KABC::Addressee a = mCore->addressBook()->findByUid( (*it).uid() );
00443 if ( a.isEmpty() ) {
00444 mCore->addressBook()->insertAddressee( *it );
00445 emit modified();
00446 }
00447 }
00448
00449 mActiveView->refresh();
00450 }
00451 }
00452
00453 void ViewManager::startDrag()
00454 {
00455
00456 KABC::Addressee::List addrList;
00457 const QStringList uidList = selectedUids();
00458 if ( uidList.isEmpty() )
00459 return;
00460
00461 kdDebug(5720) << "ViewManager::startDrag: starting to drag" << endl;
00462
00463 QStringList::ConstIterator it;
00464 for ( it = uidList.begin(); it != uidList.end(); ++it )
00465 addrList.append( mCore->addressBook()->findByUid( *it ) );
00466
00467 KMultipleDrag *drag = new KMultipleDrag( this );
00468
00469 KABC::VCardConverter converter;
00470 QString vcards = converter.createVCards( addrList );
00471
00472
00473 drag->addDragObject( new QTextDrag( AddresseeUtil::addresseesToEmails( addrList ), this ) );
00474 drag->addDragObject( new KVCardDrag( vcards, this ) );
00475
00476 KTempDir tempDir;
00477
00478 if ( tempDir.status() == 0 ) {
00479 QString fileName;
00480 if ( addrList.count() == 1 )
00481 fileName = addrList[ 0 ].givenName() + "_" + addrList[ 0 ].familyName() + ".vcf";
00482 else
00483 fileName = "contacts.vcf";
00484
00485 QFile tempFile( tempDir.name() + "/" + fileName );
00486 if ( tempFile.open( IO_WriteOnly ) ) {
00487 tempFile.writeBlock( vcards.utf8() );
00488 tempFile.close();
00489
00490 KURLDrag *urlDrag = new KURLDrag( KURL( tempFile.name() ), this );
00491 drag->addDragObject( urlDrag );
00492 }
00493 }
00494
00495 drag->setPixmap( KGlobal::iconLoader()->loadIcon( "vcard", KIcon::Desktop ) );
00496 drag->dragCopy();
00497 }
00498
00499 void ViewManager::setActiveFilter( int index )
00500 {
00501 Filter currentFilter;
00502
00503 if ( ( index - 1 ) < 0 )
00504 currentFilter = Filter();
00505 else if ( ( index - 1 ) < 1 ) {
00506 currentFilter = Filter();
00507 currentFilter.setMatchRule(Filter::NotMatching);
00508 }
00509 else
00510 currentFilter = mFilterList[ index - 2 ];
00511
00512
00513
00514 if ( mActiveView ) {
00515 mActiveView->setFilter( currentFilter );
00516 mActiveView->refresh();
00517 emit selected( QString::null );
00518 }
00519 }
00520
00521 void ViewManager::configureFilters()
00522 {
00523 FilterDialog dlg( this );
00524
00525 dlg.setFilters( mFilterList );
00526
00527 if ( dlg.exec() )
00528 mFilterList = dlg.filters();
00529
00530 uint pos = mFilterSelectionWidget->currentItem();
00531 mFilterSelectionWidget->setItems( filterNames() );
00532 mFilterSelectionWidget->setCurrentItem( pos );
00533 setActiveFilter( pos );
00534 }
00535
00536 QStringList ViewManager::filterNames() const
00537 {
00538 QStringList names( i18n( "None" ) );
00539 names.append( i18n( "Unfiled" ) );
00540
00541 Filter::List::ConstIterator it;
00542 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it )
00543 names.append( (*it).name() );
00544
00545 return names;
00546 }
00547
00548 int ViewManager::filterPosition( const QString &name ) const
00549 {
00550 int pos = 0;
00551
00552 Filter::List::ConstIterator it;
00553 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it, ++pos )
00554 if ( name == (*it).name() )
00555 return pos + 2;
00556
00557 return 0;
00558 }
00559
00560 void ViewManager::initActions()
00561 {
00562 mActionSelectView = new KSelectAction( i18n( "Select View" ), 0, mCore->actionCollection(), "select_view" );
00563 #if KDE_VERSION >= 309
00564 mActionSelectView->setMenuAccelsEnabled( false );
00565 #endif
00566 connect( mActionSelectView, SIGNAL( activated( const QString& ) ),
00567 SLOT( setActiveView( const QString& ) ) );
00568
00569 KAction *action;
00570
00571 action = new KAction( i18n( "Modify View..." ), "configure", 0, this,
00572 SLOT( editView() ), mCore->actionCollection(),
00573 "view_modify" );
00574 action->setWhatsThis( i18n( "By pressing this button a dialog opens that allows you to modify the view of the addressbook. There you can add or remove fields that you want to be shown or hidden in the addressbook like the name for example." ) );
00575
00576 action = new KAction( i18n( "Add View..." ), "window_new", 0, this,
00577 SLOT( addView() ), mCore->actionCollection(),
00578 "view_add" );
00579 action->setWhatsThis( i18n( "You can add a new view by choosing one from the dialog that appears after pressing the button. You have to give the view a name, so that you can distinguish between the different views." ) );
00580
00581 mActionDeleteView = new KAction( i18n( "Delete View" ), "view_remove", 0,
00582 this, SLOT( deleteView() ),
00583 mCore->actionCollection(), "view_delete" );
00584 mActionDeleteView->setWhatsThis( i18n( "By pressing this button you can delete the actual view, which you have added before." ) );
00585
00586 action = new KAction( i18n( "Refresh View" ), "reload", 0, this,
00587 SLOT( refreshView() ), mCore->actionCollection(),
00588 "view_refresh" );
00589 action->setWhatsThis( i18n( "The view will be refreshed by pressing this button." ) );
00590
00591 action = new KAction( i18n( "Edit &Filters..." ), "filter", 0, this,
00592 SLOT( configureFilters() ), mCore->actionCollection(),
00593 "options_edit_filters" );
00594 action->setWhatsThis( i18n( "Edit the contact filters<p>You will be presented with a dialog, where you can add, remove and edit filters." ) );
00595 }
00596
00597 void ViewManager::initGUI()
00598 {
00599 QHBoxLayout *layout = new QHBoxLayout( this );
00600 mViewWidgetStack = new QWidgetStack( this );
00601 layout->addWidget( mViewWidgetStack );
00602 }
00603
00604 #include "viewmanager.moc"