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